我正在做一个必须通过键盘读取某些字符并解释它们的应用程序。
要捕获密钥,我打开一个JDialog并设置一个KeyEventDispatcher,这样我就可以捕获dispatchKeyEvent方法中的字符。在JDialog中有一个按钮,用于删除KeyEventDispatcher并处理JDialog。
它有两个问题:
- 第一次打开JDialog时,它就像没有设置KeyEventDispatcher一样
- 当我关闭并打开这个JDialog时,KeyEventDispatchers正在累积(第1次打开,没有运行;第2次打开,第3次打开,第3次打开,第3次打开2跑,...)
似乎在JDialog关闭时未设置KeyEventDispacthers,而不是在JDialog打开时设置,并在关闭时删除。
有人可以帮助我了解发生了什么以及如何解决这个问题?
这是JDialog类的简化版本(仅包含密钥捕获部分):
public class SequenceDialog {
private JDialog dialog;
private JButton finishButton;
private DialogKeyEventDispatcher keyEventDispatcher;
public SequenceDialog() {
initializeDialog();
}
private void initializeDialog() {
dialog = new JDialog();
finishButton = new JButton("Finish");
finishButton.addActionListener(new FinishButtonListener());
dialog.setModalityType(ModalityType.APPLICATION_MODAL);
dialog.add(finishButton);
setKeyListener();
dialog.setVisible(true);
dialog.pack();
}
/** Adds the KeyEventDispacther */
private void setKeyListener() {
keyEventDispatcher = new DialogKeyEventDispatcher();
KeyboardFocusManager manager = KeyboardFocusManager
.getCurrentKeyboardFocusManager();
manager.addKeyEventDispatcher(keyEventDispatcher);
}
private class FinishButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
//Removing the KeyEventDispacther
KeyboardFocusManager manager = KeyboardFocusManager
.getCurrentKeyboardFocusManager();
manager.removeKeyEventDispatcher(keyEventDispatcher);
dialog.dispose();
}
}
/** The KeyEventDispatcher to be executed */
private class DialogKeyEventDispatcher implements KeyEventDispatcher {
public boolean dispatchKeyEvent(KeyEvent e) {
if(e.getID() == KeyEvent.KEY_PRESSED) {
System.out.println(KeyEvent.getKeyText(e.getKeyCode()));
}
return false;
}
}
}
如果有另一种方法来捕捉钥匙,我很乐意看到它。到目前为止,我尝试过:
答案 0 :(得分:4)
首先无法重现不工作。
可以重现堆叠:通过单击标题中的关闭图标关闭对话框时,不会删除调度程序。在这种情况下,在对话框关闭后打印在主框架中键入的笔划。
可以通过dispose和WindowListener(而不是在finish操作中)可靠地删除调度程序:
private void initializeDialog() {
dialog = new JDialog() {
@Override
public void dispose() {
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
manager.removeKeyEventDispatcher(keyEventDispatcher);
LOG.info("disposed: " + manager);
super.dispose();
}
};
WindowListener l = new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
manager.removeKeyEventDispatcher(keyEventDispatcher);
LOG.info("closing: " + manager);
}
};
dialog.addWindowListener(l);