5

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

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 而无需手动输入新值(这有点违背了制作微调器的目的)。我怎么做?

4

2 回答 2

5

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


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

于 2008-12-19T00:15:14.507 回答
1

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

给我最多的问题是使用数字键手动输入 ID,然后按 Enter。当我这样做时,查询仍然会发生,但它正在查询以前的 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()查询现在发生在新值而不是前一个值上,当按下回车时,JSpinner 已将其值更新为新输入的值。

我假设这样做的原因是输入的值没有正式应用于 ,JSpinner直到您按 Enter 键,这也会触发查询的键侦听器。自KeyEvent定义 [query] 键侦听器似乎是队列中的第一个,因此它首先运行其代码,然后KeyEvent将值应用于JSpinnerfrom the internal JFormattedTextField,这就是它查询旧值的原因。 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在解析值时捕获任何 s,该SwingUtilities.invokeLater()方法允许微调器模型自动删除任何无效字符并继续查询。

无论如何,我对Java仍然有些缺乏经验,所以如果我对此的理解不正确,请在评论中告诉我。

于 2016-06-10T17:47:15.193 回答