Java 防止使用重复的transferFocus()中断JTextField/JDialog
我有一个非常奇怪的场景,不幸的是,我无法阻止它发生在我的Swing应用程序中。然而,当它发生时,它对我有重大的影响。也许有人能帮忙 基本设置如下所示:Java 防止使用重复的transferFocus()中断JTextField/JDialog,java,swing,jtextfield,jdialog,Java,Swing,Jtextfield,Jdialog,我有一个非常奇怪的场景,不幸的是,我无法阻止它发生在我的Swing应用程序中。然而,当它发生时,它对我有重大的影响。也许有人能帮忙 基本设置如下所示: Linux环境 JFrame中有多个JTextFields 按下Enter键时,JTextFields将推送transferFocus() 离开其中一个字段时会弹出一个JDialog,需要按Enter键才能将其删除 造成这一问题的情况如下: 按下回车键几秒钟 当按下enter键时,焦点显然会穿过不同的文本字段。显示该对话框时,enter键
- Linux环境
- JFrame中有多个JTextFields
- 按下Enter键时,JTextFields将推送transferFocus()
- 离开其中一个字段时会弹出一个JDialog,需要按Enter键才能将其删除
- 按下回车键几秒钟
public class TestSwing extends JFrame {
JTextField jtfText1, jtfText2, jtfText3;
TextHandler handler = null;
public TestSwing() {
super("TextField Test Demo");
Container container = getContentPane();
container.setLayout(new FlowLayout());
jtfText1 = new MyJTextField(10);
jtfText2 = new MyJTextField(10);
jtfText3 = new MyJTextField(10);
container.add(jtfText1);
container.add(jtfText2);
container.add(jtfText3);
handler = new TextHandler();
jtfText3.addActionListener(handler);
setSize(325, 100);
setVisible(true);
}
private class TextHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
JOptionPane.showConfirmDialog(null, "wait!");
}
}
public static void main(String args[]) {
TestSwing test = new TestSwing();
test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
自定义JTextField:
public class MyJTextField extends JTextField {
public MyJTextField(int len) {
super(len);
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent evt) {
int key = evt.getKeyCode();
if (key == KeyEvent.VK_ENTER)
transferFocus();
}
});
}
}
要提前回答任何潜在问题,请执行以下操作:
- 必须使用Enter键转移焦点
- 输入键的垃圾邮件来自用户在键盘上留下的东西(这是在零售环境中,所以这种情况经常发生)
- 简单地关闭和重新启动应用程序实际上不是一个选项,因为没有鼠标插入计算机。应用程序在启动时会自动启动,这使得这种情况具有破坏性,因为解决问题的唯一方法是重新启动机器
- 这些机器的功能不是很强大(处理和内存),这在某种程度上导致问题的发生比在开发机器上重新创建时要快得多
Xandel不使用KeyEvents。KeyEvents通常用于AWT。Swing有更新更好的API可供使用(在大多数情况下)。在这种情况下,JTextField被设计为在按下Enter键时响应ActionEvent 您可以尝试跟踪上次按下Enter键的时间,并忽略在操作系统重复率范围内调用的事件。我的重复频率似乎在35毫秒左右:
import java.awt.event.*;
import javax.swing.*;
public class MyJTextField extends JTextField
{
private static long lastTime = System.currentTimeMillis();
public MyJTextField(int len)
{
super(len);
addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
long diff = evt.getWhen() - lastTime;
System.out.println(diff);
if (diff > 50)
{
transferFocus();
}
lastTime = evt.getWhen();
}
});
}
}
这是个好主意,谢谢!简单、整洁、有效。不幸的是,我的JDialog也使用了keylister,因为没有实际的按钮可点击,所以我扩展了您的解决方案,使用了一个“系统范围”的lastTime变量,并将相同的概念应用到我的JDialog实现中。