tags:

views:

2143

answers:

3

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

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.

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.

Any ideas ?

+16  A: 

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 
    ); 
}
Tom Hawtin - tackline
This was to fast for my fingers... you won ;)
Markus Lausberg
+1  A: 

As an aside, you could also just enable the WindowsLookAndFeel for your dialog, which includes out of the box functionality to close JDialogs on "ESC" keypresses.

Tried it withUIManager.setLookAndFeel(new com.sun.java.swing.plaf.windows.WindowsLookAndFeel());That does not work.
Leonel
ATM, I don't have a handy java dev environment to test this, but it should work. Did you use a JFrame to test? It won't work in a JFrame. What I can tell you is that the LookAndFeel simulates the Look (display of buttons, textboxes, etc..) And Feel (ie. close JDialog on ESC) of the underlying OS.
And that's why this functionality is only available with the WindowsLookAndFeel, because Windows is the only OS where you can close a Dialog on an ESC keypress.
A: 

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

}
Ayman
Sounds nice. I'd just replace dialog.setVisible(false) with some code to actually cancel the dialog. I'll give it a try.
Leonel