Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: GUI и Java FX приложения > Закрыть диалог по нажатию ESCAPE


Автор: coderinside 7.7.2007, 14:16
Подскажите как сделать так, чтобы модальный диалог закрывался по нажатию кнопки ESCAPE.

Автор: nornad 7.7.2007, 15:41
Код

KeyAdapter cancel = new KeyAdapter() {
    public void keyPressed( KeyEvent e ) {
        if ( e.getKeyCode() == KeyEvent.VK_ESCAPE )
            doCancel(); // ну или сразу System.exit() какой-нибудь
    }
};

Автор: coderinside 7.7.2007, 21:18
Да, но это будет работать только для компонента на котором установлен фокус ввода. А как сделать чтобы отслеживалось нажатие ESC для диалога в целом. Чтобы без разницы было что сейчас в фокусе?

Автор: _Michael 7.7.2007, 21:49
coderinside не вижу никаких проблем smile. Имплементируеш в классе твоего диалога Keylistener, и в нем метод keyPressed реализируеш примерно так:
Код

    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_ESCAPE)
            dispose();
    }


Только не забудь в конструкторе вписать this.addKeyListener(this); иначе твой диалог никаких клавиш слушать не будет smile
Только-что испробовал, етот вариант проходит когда никаких контролов в диалоге нет. Если ж оные имеются, тогда наверное надо на каждый контрол повешать один и тот же KeyListener, который бы при нажатии ESC закрывал твой диалог.

Автор: nornad 8.7.2007, 00:36
Цитата(coderinside @  8.7.2007,  00:18 Найти цитируемый пост)
Чтобы без разницы было что сейчас в фокусе?

Цитата(_Michael @  8.7.2007,  00:49 Найти цитируемый пост)
Только не забудь в конструкторе вписать this.addKeyListener(this);

Я и подразумевал, что KeyAdapter проставляется диалогу. Лично у меня этот код работает прекрасно.

Автор: w1nd 8.7.2007, 01:31
Свои клавиатурные слушатели в этом случае совершенно ни к чему, не нужно изобретать этот велосипед снова. Регистрировать обработчик клавиатуры для компонента, если он должен срабатывать вне зависимости от текущей принадлежности фокуса, нужно так:

Код
yourComponent.getActionMap().put("myAction", new AbstractAction() {
    public void actionPerformed(ActionEvent event) {
        // perform your action
    }
});

yourComponent.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
    KeyStroke.getKeyStroke("ESCAPE"), "myAction"
);


Или, на худой конец, так:

Код

ActionListener listener = new ActionListener() {
    public void actionPerformed(ActionEvent event) {
        // perform your action
    }
}; 
        
yourComponent.registerKeyboardAction(
    listener, KeyStroke.getKeyStroke("ESCAPE"), JComponent.WHEN_IN_FOCUSED_WINDOW
);

Второй вариант - на деле обёртка первого.

Автор: nornad 8.7.2007, 10:51
w1nd, если не трудно, расскажи, почему такой вариант предпочтительнее. Есть подозрения, но хотелось бы услышать из уст знающего. А доку копать пока не сильно тянет. smile

Автор: w1nd 8.7.2007, 19:18
Цитата(nornad @ 8.7.2007,  10:51)
w1nd, если не трудно, расскажи, почему такой вариант предпочтительнее. Есть подозрения, но хотелось бы услышать из уст знающего. А доку копать пока не сильно тянет. smile

Хотя бы  потому, что всё уже реализовано ;)
А вообще, вот:
  • Не нужно иметь доступ к объектам-контейнерам компонента и другим компонентам, чтобы обработать событие на уровне окна.
  • Простой и удобный способ изменения поведения компонента в зависимости от окружения.
  • InputMap'ы и ActionMap'ы можно использовать повторно, компоненты могут использовать их совместно. 
  • От компонента всегда можно получить список обрабатываемых им клаиатурных комбинаций с описанием действий, ими вызываемых.
  • Можно расширить или изменить реакцию компонента на ту или иную клавиатурную комбинацию; отключить реакцию на некоторые комбинации; напрямую вызывать зарегистрированные action'ы. 
  • Зарегистрированные таким образом комбинации всегда обрабатываются корректно - не нужно в обработчике проверять наличие фокуса, состояние флага enabled и т. п.
  • Корректное взаимодействие с имеющимися компонентами вроде текстовых полей, кнопок по умолчанию.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)