简体   繁体   English

Swing:当按下ESC键时如何关闭对话框?

[英]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. 使用InputMapActionMap处理Swing中的关键操作。 To close the dialog cleanly, send a window closing event to it. 要干净地关闭对话框,请向其发送窗口关闭事件。

From my weblog : 从我的博客

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);

References 参考

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.

相关问题 按esc键时如何停止关闭JDialog - How to stop to close the JDialog when esc key is press Java swing:如何检测按下的键是否在我的JTextArea中显示输出? - Java swing: How do i detect if the key pressed will display output in my JTextArea? Java Swing-如何使关闭对话框不会关闭整个程序? - Java Swing - How do I make it so that closing a Dialog box doesn't close the entire program? 如何在Java Swing中使用[Esc]键最小化JInternalFrame? - How to minimize JInternalFrame using [Esc] key in Java Swing? 如何在Java Swing中关闭PrinterJob对话框? - How to close a PrinterJob dialog in Java Swing? 在Java中,当按下某个键(例如字母)时,如何防止该键输出分配给jTextPane的字母? - In Java, when a key is pressed such as a letter, how do I prevent the key from outputting the letter that it is assigned to a jTextPane? JDialog:如何禁用“模态”对话框的ESC键? - JDialog: How to disable the ESC key of my Modal dialog? 有谁知道如何在按下 X 时关闭对话框窗口? - Does anyone know how to make dialog window close when X is pressed? Java Swing:在按下键时执行某些操作 - Java Swing: Do something while the key is being pressed 当按下不是数字的键时,如何正确使用此事件? - How do I properly consume this event when a key is pressed that's NOT a number?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM