Swing: как закрыть диалоговое окно при нажатии клавиши ESC?
разработки GUI с использованием Swing.
у меня есть пользовательский диалог для выбора файла, который будет открыт в моем приложении; его класс расширяется javax.swing.JDialog
и содержит, среди прочих компонентов, a JFileChooser
, который может быть переключен для отображения или скрытия.
The JFileChooser
компонент уже сам обрабатывает клавишу ESC: когда отображается средство выбора файлов (встроенное в мой диалог), и я нажимаю ESC, средство выбора файлов скрывается.
Теперь я хотел бы, чтобы мой диалог сделал то же самое: когда я нажимаю ESC, я хочу, чтобы диалоговое окно закрылось. Имейте в виду, когда отображается встроенный файл выбора, клавиша ESC должна только скрыть его.
какие идеи ?
5 ответов:
использовать
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 ); }
вы можете использовать следующий фрагмент. Это лучше, потому что 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); }
Если вы ищете технику, использующую новые функции 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);
у меня были проблемы с реализацией обоих верхних ответов. Вот довольно компактная версия с использованием
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);
ссылки
- вышеуказанные ответы
- http://www.coderanch.com/t/335357/GUI/java/KeyPressed-JDialog
вот мой, я добавляю Ctrl W как закрытие shorcut также
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);