[英]Swing: how do I close a dialog when the ESC key is pressed?
GUI development with Swing. 使用Swing进行GUI开发。
I have a custom dialog for choosing a file to be opened in my application; 我有一个自定义对话框,用于选择要在我的应用程序中打开的文件; its class extends javax.swing.JDialog
and contains, among other components, a JFileChooser
, which can be toggled to be shown or hidden. 它的类扩展了javax.swing.JDialog
并包含一个JFileChooser
,它可以切换为显示或隐藏。
The JFileChooser
component already handles the ESC key by itself: when the file chooser is shown (embedded in my dialog) and I press ESC, the file chooser hides itself. JFileChooser
组件已经自己处理ESC键:当显示文件选择器(嵌入在我的对话框中)并按ESC时,文件选择器隐藏自己。
Now I would like my dialog to do the same: when I press ESC, I want the dialog to close. 现在我希望我的对话框也能这样做:当我按下ESC时,我想要关闭对话框。 Mind you, when the embedded file chooser is shown, the ESC key should only hide it. 请注意,当显示嵌入式文件选择器时,ESC键应该只隐藏它。
Any ideas ? 有任何想法吗 ?
You can use the following snippet. 您可以使用以下代码段。 This is better because the rootPane will get events from any component in the dialog. 这是更好的,因为rootPane将从对话框中的任何组件获取事件。 You can replace setVisible(false) with dispose() if you want. 如果需要,可以用dispose()替换setVisible(false)。
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);
}
Use InputMap
and ActionMap
for dealing with key actions in Swing. 使用InputMap
和ActionMap
处理Swing中的关键操作。 To close the dialog cleanly, send a window closing event to it. 要干净地关闭对话框,请向其发送窗口关闭事件。
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
);
}
If your looking for a technique using new features of Java 8 , try a lambda expression: 如果您正在寻找使用Java 8新功能的技术,请尝试使用lambda表达式:
dialog.getRootPane().registerKeyboardAction(e -> {
window.dispose();
}, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);
or 要么
KeyStroke k = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
int w = JComponent.WHEN_IN_FOCUSED_WINDOW;
dialog.getRootPane().registerKeyboardAction(e -> window.dispose(), k, w);
I had problems implementing both of the top answers. 我在实现两个最佳答案时遇到了问题。 Here's a rather compact version using AbstractAction
to auto-implement most of Action
's methods, which works within text-based fields (per @pratikabu's request): 这是一个相当紧凑的版本,使用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);
Here's mine, I add Ctrl W as closing shorcut aswell 这是我的,我将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);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.