我自己遇到了一个与此相关的问题。就我而言,我有一个带有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
将值应用于JSpinner
from 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仍然有些缺乏经验,所以如果我对此的理解不正确,请在评论中告诉我。