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

前端 未结 5 1276
春和景丽
春和景丽 2020-12-24 00:52

GUI development with Swing.

I have a custom dialog for choosing a file to be opened in my application; its class extends javax.swing.JDialog and contain

相关标签:
5条回答
  • 2020-12-24 01:04

    Use InputMap and ActionMap for dealing with key actions in 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 
        ); 
    }
    
    0 讨论(0)
  • 2020-12-24 01:04

    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.

    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);
    
    }
    
    0 讨论(0)
  • 2020-12-24 01:07

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

    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

    • the above answers
    • http://www.coderanch.com/t/335357/GUI/java/KeyPressed-JDialog
    0 讨论(0)
  • 2020-12-24 01:12

    Here's mine, I add CtrlW as closing shorcut aswell

        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); 
    
    0 讨论(0)
  • 2020-12-24 01:14

    If your looking for a technique using new features of Java 8 , try a lambda expression:

    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);
    
    0 讨论(0)
提交回复
热议问题