让 ENTER 与 JSpinner 一起工作,就像与 JTextField 一起工作一样

发布于 2024-07-10 18:26:25 字数 977 浏览 18 评论 0原文

首先,为了让我的工作解释起来更容易一些,这是我的一些代码:

JSpinner spin = new JSpinner();
JFormattedTextField text = getTextField(spin);

text.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent evt) {
            // Do stuff...
    }
});

...

private JFormattedTextField getTextField(JSpinner spinner) {
    JComponent editor = spinner.getEditor();

    if (editor instanceof JSpinner.DefaultEditor) {
        return ((JSpinner.DefaultEditor )editor).getTextField();
    } else {
        System.err.println( "Unexpected editor type: "
                           + spinner.getEditor().getClass()
                           + " isn't a descendant of DefaultEditor" );
        return null;
    }
}

正如您所看到的,我已经做到了这一点。 事实上,当我在微调器的文本字段组件 (JFormattedTextField) 中输入一个值,然后按 ENTER 键时,它就起作用了。

我现在想要的是能够让文本字段响应 ENTER,而无需手动输入新值(这有点违背了用它制作旋转器的目的)。 我怎么做?

First, to make my job explaining a bit easier, here's some of my code:

JSpinner spin = new JSpinner();
JFormattedTextField text = getTextField(spin);

text.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent evt) {
            // Do stuff...
    }
});

...

private JFormattedTextField getTextField(JSpinner spinner) {
    JComponent editor = spinner.getEditor();

    if (editor instanceof JSpinner.DefaultEditor) {
        return ((JSpinner.DefaultEditor )editor).getTextField();
    } else {
        System.err.println( "Unexpected editor type: "
                           + spinner.getEditor().getClass()
                           + " isn't a descendant of DefaultEditor" );
        return null;
    }
}

So as you can see, I got that far. And indeed, when I type in a value into the text field component of the spinner (JFormattedTextField), and THEN press ENTER, it works.

What I want now is to be able to have the text field respond to ENTER without having to manually type in a new value (which sorta defeats the purpose of making a spinner out of it). How do I do that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不弃不离 2024-07-17 18:26:25

我知道这不是动作监听器......但这也许对你有用?


    text.addKeyListener( new KeyAdapter() {
            @Override
            public void keyReleased( final KeyEvent e ) {
                if ( e.getKeyCode() == KeyEvent.VK_ENTER ) {
                    System.out.println( "enter pressed" );
                }
            }
        } );

I know this is not the action listener...but maybe this can work for you?


    text.addKeyListener( new KeyAdapter() {
            @Override
            public void keyReleased( final KeyEvent e ) {
                if ( e.getKeyCode() == KeyEvent.VK_ENTER ) {
                    System.out.println( "enter pressed" );
                }
            }
        } );

怀念你的温柔 2024-07-17 18:26:25

我自己刚刚遇到了与此相关的问题。 就我而言,我有一个带有 SpinnerNumberModel 设置的 JSpinner,这样我就可以输入数字 ID 值,然后从远程数据库检索它们。 使用 JButton 作为查询触发器时,这一切都很好,但我希望能够通过 Tab 将焦点切换到该字段,然后按 Enter 键,并且还能够通过使用数字键输入 ID 来更改值,然后按 Enter 键。

给我带来最多问题的是用数字键手动输入 ID,然后按 Enter 键。 当我这样做时,查询仍然会发生,但它查询的是以前的 ID,而不是我刚刚输入的 ID,因此我必须再次按 Enter 来查询新 ID(请参阅代码)

((JSpinner.DefaultEditor) minRng.getEditor()).getTextField().addKeyListener(new KeyAdapter() {
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            queryData();
        }
    }
});

和查询方法:

private void queryData() {
    int minVal = Integer.parseInt(minRng.getValue().toString());
    queryDataBase(minVal);
}

为了解决这个问题,我所要做的就是强制查询等待运行,直到微调器更新其值,这可以通过使用 SwingUtilities.invokeLater() 强制它结束来轻松完成EDT 队列的,如下所示:

((JSpinner.DefaultEditor) minRng.getEditor()).getTextField().addKeyListener(new KeyAdapter() {
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    queryData();
                }
            });
        }
    }
});

感谢 invokeLater(),当按 Enter 键时,查询现在发生在新值而不是前一个值上,因为 JSpinner 随后已将其值更新为新值输入一。

我假设其原因是输入的值在您按 Enter 键之前并未正式应用于 JSpinner,这也会触发查询的关键侦听器。 自定义 [query] 键侦听器的 KeyEvent 似乎是队列中的第一个,因此它首先运行其代码,然后运行用于将值应用到的 KeyEvent来自内部 JFormattedTextFieldJSpinner,这就是它查询旧值的原因。 SwingUtilities.invokeLater() 只是将查询本身放在队列末尾,因此它允许其他 KeyEvent 在运行查询之前完成其代码。

编辑:

实现此目的的另一种方法是直接从 JFormattedTextField 而不是 JSpinner 请求值,因为这也应该返回新输入的值值,因为 JFormattedTextField 包含您输入的值,但它尚未传递到 JSpinner,这似乎是问题所在。

private void queryData() {
    JFormattedTextField tf = ((JSpinner.DefaultEditor) minRng.getEditor()).getTextField();
    int minVal = Integer.parseInt(tf.getText());
    queryDataBase(minVal);
}

此方法的唯一问题是,在解析值时,您必须捕获任何 NumberFormatException,其中 SwingUtilities.invokeLater() 方法允许微调器模型删除任何无效字符,自动,并继续查询。

不管怎样,我对Java还是有点缺乏经验,所以如果我的理解不正确,请在评论中告诉我。

I just ran into an issue relating to this, myself. In my case, I had a JSpinner with a SpinnerNumberModel setup so I could input numerical ID values, and then retrieve them from a remote database. This worked all well and good with a JButton as my trigger for the query, but I wanted to be able to switch focus to the field via Tab, and hit enter, and also be able to change the value by entering an ID with numerical keys, then hit enter.

The one that was giving me the most issues was manually entering the ID with numerical keys, then pressing enter. When I would do this, the query would still happen, but it was querying the previous ID rather than the one I just entered, so I'd have to hit enter again to query the new ID (see code)

((JSpinner.DefaultEditor) minRng.getEditor()).getTextField().addKeyListener(new KeyAdapter() {
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            queryData();
        }
    }
});

and the query method:

private void queryData() {
    int minVal = Integer.parseInt(minRng.getValue().toString());
    queryDataBase(minVal);
}

In order to fix this, all I had to do was force the query to wait to run until the spinner updated its value, which was easily done by using SwingUtilities.invokeLater() to force it to the end of the EDT queue, like so:

((JSpinner.DefaultEditor) minRng.getEditor()).getTextField().addKeyListener(new KeyAdapter() {
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    queryData();
                }
            });
        }
    }
});

Thanks to the invokeLater() the query now happens on the new value rather than the previous one, when pressing enter, as the JSpinner has then updated its value to the newly input one.

I'm assuming the reason for this is that the value entered is not officially applied to the JSpinner until you hit enter, which also fires the key listener for the query. The KeyEvent for the custom [query] key listener appears to be the first one in the queue, so it runs its code first, and THEN the KeyEvent for applying the value to the JSpinner from the internal JFormattedTextField, which is why it queries the old value. SwingUtilities.invokeLater() just puts the query itself at the end of the queue, so it allows the other KeyEvent to finish its code before running the query.

Edit:

Another way to achieve this is to request the value directly from the JFormattedTextField rather than the JSpinner, as this should also return the newly entered value since the JFormattedTextField contains the value you typed in, but it hasn't yet been passed to the JSpinner, which appears to be where the issue lies.

private void queryData() {
    JFormattedTextField tf = ((JSpinner.DefaultEditor) minRng.getEditor()).getTextField();
    int minVal = Integer.parseInt(tf.getText());
    queryDataBase(minVal);
}

The only problem with this method is that you then have to catch any NumberFormatExceptions, when parsing the value, where the SwingUtilities.invokeLater() approach allows the spinner model to remove any invalid characters, automatically, and continue with the query.

Anyway, I'm still somewhat inexperienced with Java, so if my understanding of this is incorrect, please let me know in the comments.

陌上芳菲 2024-07-17 18:26:25

我认为您要问的是,当我们手动编辑 JSpinner 显示的值时,它实际上并没有改变它,而只是显示为它。

原因是JSpinner使用了一个叫做编辑器的东西并且有一个值。 编辑器负责显示当前值并更改它(但只能使用箭头按钮)

如果我们想自己编辑它,那么我们需要使用

spinner.commitEdit();

查看此以获取更多知识,

https://docs.oracle.com/javase/7/docs/api/javax /swing/JSpinner.html

I think what you are asking is that when we manually edit the JSpinner shown value, it doesn't actually change it but only show as it.

The reason is that JSpinner use something called editor and has a value. The editor is responsibe for showing the current value and also, changing it (but only using arrow buttons)

If we want to edit it by ourselves then we need to use

spinner.commitEdit();

Have a look into this for further knowledge,

https://docs.oracle.com/javase/7/docs/api/javax/swing/JSpinner.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文