Swing:按下 ESC 键时如何关闭对话框?
Posted
技术标签:
【中文标题】Swing:按下 ESC 键时如何关闭对话框?【英文标题】:Swing: how do I close a dialog when the ESC key is pressed? 【发布时间】:2010-10-13 04:15:25 【问题描述】:使用 Swing 进行 GUI 开发。
我有一个自定义对话框,用于选择要在我的应用程序中打开的文件;它的类扩展了javax.swing.JDialog
并包含JFileChooser
以及其他组件,可以切换为显示或隐藏。
JFileChooser
组件已经自己处理了 ESC 键:当显示文件选择器(嵌入在我的对话框中)并且我按下 ESC 时,文件选择器会自行隐藏。
现在我希望我的对话框也这样做:当我按下 ESC 时,我希望对话框关闭。请注意,当显示嵌入式文件选择器时,ESC 键应该只隐藏它。
有什么想法吗?
【问题讨论】:
【参考方案1】:使用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
);
【讨论】:
@Tom 你好,感谢你的精彩帖子,如果我在对话框中有任何文本库组件,你能否告诉我最佳实践。因为如果焦点在他们身上就行不通了。【参考方案2】:这是我的,我也添加了 CtrlW 作为关闭快捷键
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);
【讨论】:
【参考方案3】:如果您正在寻找使用 Java 8 新功能的技术,请尝试使用 lambda 表达式:
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】:我在实现两个最佳答案时遇到了问题。这是一个相当紧凑的版本,使用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【讨论】:
给别人的小记。我发现如果你不做escapeAction
,final
,那么你会得到一个例外。我的 IDE 中没有显示它必须是 final
。运行时出现异常。【参考方案5】:
你可以使用下面的sn-p。这更好,因为 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);
【讨论】:
听起来不错。我只是用一些代码替换 dialog.setVisible(false) 以实际取消对话框。我试试看。以上是关于Swing:按下 ESC 键时如何关闭对话框?的主要内容,如果未能解决你的问题,请参考以下文章