Swing: как закрыть диалог при нажатии клавиши ESC? - PullRequest
59 голосов
/ 13 марта 2009

Разработка графического интерфейса с Swing.

У меня есть собственный диалог для выбора файла, который будет открыт в моем приложении; его класс расширяет javax.swing.JDialog и содержит, среди других компонентов, JFileChooser, который можно переключать для отображения или скрытия.

Компонент JFileChooser уже сам обрабатывает клавишу ESC: когда отображается средство выбора файлов (встроено в мой диалог), и я нажимаю ESC, средство выбора файлов скрывается.

Теперь я хотел бы, чтобы мой диалог делал то же самое: когда я нажимаю ESC, я хочу, чтобы диалог закрывался. Напоминаем, что когда показывается встроенный селектор файлов, ключ ESC должен его только скрывать.

Есть идеи?

Ответы [ 5 ]

63 голосов
/ 19 марта 2009

Вы можете использовать следующий фрагмент. Это лучше, потому что rootPane будет получать события от любого компонента в диалоге. Вы можете заменить setVisible (false) на dispose (), если хотите.

public static void addEscapeListener(final JDialog dialog) {
    ActionListener escListener = new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            dialog.setVisible(false);
        }
    };

    dialog.getRootPane().registerKeyboardAction(escListener,
            KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
            JComponent.WHEN_IN_FOCUSED_WINDOW);

}
59 голосов
/ 13 марта 2009

Используйте InputMap и ActionMap для работы с ключевыми действиями в Swing. Чтобы закрыть диалоговое окно, отправьте ему событие закрытия окна.

Из моего блога :

private static final KeyStroke escapeStroke = 
    KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); 
public static final String dispatchWindowClosingActionMapKey = 
    "com.spodding.tackline.dispatch:WINDOW_CLOSING"; 
public static void installEscapeCloseOperation(final JDialog dialog) { 
    Action dispatchClosing = new AbstractAction() { 
        public void actionPerformed(ActionEvent event) { 
            dialog.dispatchEvent(new WindowEvent( 
                dialog, WindowEvent.WINDOW_CLOSING 
            )); 
        } 
    }; 
    JRootPane root = dialog.getRootPane(); 
    root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( 
        escapeStroke, dispatchWindowClosingActionMapKey 
    ); 
    root.getActionMap().put( dispatchWindowClosingActionMapKey, dispatchClosing 
    ); 
}
13 голосов
/ 20 июня 2014

Если вы ищете технику, использующую новые функции Java 8, попробуйте лямбда-выражение:

dialog.getRootPane().registerKeyboardAction(e -> {
    window.dispose();
}, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);

или

KeyStroke k = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
int w = JComponent.WHEN_IN_FOCUSED_WINDOW;
dialog.getRootPane().registerKeyboardAction(e -> window.dispose(), k, w);
4 голосов
/ 11 августа 2014

У меня были проблемы с реализацией обоих лучших ответов. Вот довольно компактная версия, использующая AbstractAction для автоматической реализации большинства Action методов, которая работает в текстовых полях (согласно запросу @ pratikabu):

final AbstractAction escapeAction = new AbstractAction() {
    private static final long serialVersionUID = 1L;

    @Override
    public void actionPerformed(ActionEvent ae) {
        dispose();
    }
};

getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
        .put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "ESCAPE_KEY");
getRootPane().getActionMap().put("ESCAPE_KEY", escapeAction);

Ссылки

2 голосов
/ 11 мая 2017

Вот мое, я добавляю Ctrl W как закрывающий ярлык, а также

    Action closeAction = new AbstractAction(){
        public void actionPerformed(ActionEvent e){
            dispose();
        }
    };

    KeyStroke esc = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0);
    getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(esc, "closex");
    getRootPane().getActionMap().put("closex", closeAction);

    KeyStroke ctrlW = KeyStroke.getKeyStroke("control W");
    getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ctrlW, "close");
    getRootPane().getActionMap().put("close", closeAction); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...