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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/642925/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 17:18:47  来源:igfitidea点击:

Swing: how do I close a dialog when the ESC key is pressed?

javauser-interfaceswing

提问by Leonel

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.JDialogand contains, among other components, a JFileChooser, which can be toggled to be shown or hidden.

我有一个自定义对话框,用于选择要在我的应用程序中打开的文件;它的类扩展javax.swing.JDialog并包含,除其他组件外, aJFileChooser可以切换为显示或隐藏。

The JFileChoosercomponent 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. Mind you, when the embedded file chooser is shown, the ESC key should only hide it.

现在我希望我的对话框也这样做:当我按 ESC 时,我希望对话框关闭。请注意,当显示嵌入的文件选择器时,ESC 键应该只隐藏它。

Any ideas ?

有任何想法吗 ?

采纳答案by Tom Hawtin - tackline

Use InputMapand ActionMapfor dealing with key actions in Swing. To close the dialog cleanly, send a window closing event to it.

使用InputMapActionMap用于处理在Swing中的主要行动。要干净地关闭对话框,请向其发送窗口关闭事件。

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

回答by Ayman

You can use the following snippet. This is better because the rootPane will get events from any component in the dialog. You can replace setVisible(false) with dispose() if you want.

您可以使用以下代码段。这更好,因为 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);

}

回答by Java42

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

回答by skia.heliou

I had problems implementing both of the top answers. Here's a rather compact version using AbstractActionto 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

参考

回答by Wesos de Queso

Here's mine, I add CtrlWas closing shorcut aswell

这是我的,我也添加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);