首先,为了让我的工作更容易解释,这里是我的一些代码:
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,而不必手动输入新值(这种类型使得微调器的目的无法实现)。我该怎么做?
答案 0 :(得分:4)
我知道这不是动作听众......但也许这对你有用吗?
text.addKeyListener( new KeyAdapter() {
@Override
public void keyReleased( final KeyEvent e ) {
if ( e.getKeyCode() == KeyEvent.VK_ENTER ) {
System.out.println( "enter pressed" );
}
}
} );
答案 1 :(得分:1)
我刚刚遇到了与此相关的问题。在我的例子中,我有一个SpinnerNumberModel
设置的JSpinner,所以我可以输入数字ID值,然后从远程数据库中检索它们。使用JButton作为查询的触发器,这一切都很顺利,但是我希望能够通过Tab将焦点切换到字段,并按Enter键,并且还可以通过输入带数字键的ID来更改值,然后按回车。
给我提出最多问题的是用数字键手动输入ID,然后按回车键。当我这样做时,查询仍然会发生,但它查询的是先前的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()
现在在新值而不是前一个值上进行查询,当按下回车时,因为JSpinner已将其值更新为新输入的值。
我假设这样做的原因是输入的值不会正式应用于JSpinner
,直到您按Enter键,这也会触发查询的键侦听器。自定义[query]键侦听器的KeyEvent
似乎是队列中的第一个,因此它首先运行其代码,然后KeyEvent
将值应用于JSpinner
来自内部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
,其中SwingUtilities.invokeLater()
方法允许微调器模型自动删除任何无效字符,并且继续查询。
无论如何,我对Java仍然缺乏经验,所以如果我对此的理解不正确,请在评论中告诉我。