Запуск KeyEventDispacther при первом открытии JDialog и последующее его удаление - PullRequest
4 голосов
/ 22 января 2012

Я делаю приложение, которое должно читать некоторые символы с клавиатуры и интерпретировать их.

Чтобы захватить ключи, я открываю JDialog и устанавливаю KeyEventDispatcher, чтобы я мог захватывать символы в методе dispatchKeyEvent,В JDialog есть кнопка, которая удаляет KeyEventDispatcher и удаляет JDialog.

Есть две проблемы с ним:
- при первом открытии JDialog это похоже на то, что KeyEventDispatcher не был установлен
- Когда я закрываю и открываю этот JDialog, KeyEventDispatchers накапливаются (открыть 1-й раз, никто не работает; открыть 2-й раз, один работает, открыть 3-й раз, 2 работает, ...)

Кажется, что KeyEventDispacthers устанавливаются, когда JDialog закрывается и не удаляется, а не устанавливается, когда JDialog открывается и удаляется при его закрытии.

Someneone может помочь мне понять, что происходити как я могу это исправить?

Вот упрощенная версия класса 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 Ответ

4 голосов
/ 22 января 2012

Невозможно воспроизвести неработающий в первую очередь.

Может воспроизводить наложение: диспетчер не удаляется при закрытии диалога, если щелкнуть значок закрытия в заголовке.В этом случае штрихи, набранные в главном фрейме, печатаются после закрытия диалогового окна.

Диспетчер может быть надежно удален с помощью so в утилите dispose и WindowListener (вместо действия завершения):

    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);
...