第一次打开JDialog并在之后删除它时运行KeyEventDispacther

时间:2012-01-22 12:41:11

标签: java swing keyboard-events jdialog keyevent

我正在做一个必须通过键盘读取某些字符并解释它们的应用程序。

要捕获密钥,我打开一个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;
        }
    }
}

如果有另一种方法来捕捉钥匙,我很乐意看到它。到目前为止,我尝试过:

  • KeyListener,即使我将它添加到JButton和contentPane
  • 也没有用
  • KeyEventPostProcessor与使用KeyEventDispatcher
  • 具有相同的效果
  • KeyBinding,没有工作,似乎不是最好的选择,因为我必须捕捉所有类型

1 个答案:

答案 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);