Java Tips Weblog

  • Blog Stats

    • 2,571,450 hits
  • Categories

  • Archives

Escape Key and Dialog

Posted by Rob Camick on October 17, 2010

In some applications that use dialogs the Escape key can be used to close the dialog. This feature is not support in the base JDK but can easily be added.

Like many Swing features, this support can be added by using Key Bindings. In this case, as discussed in my blog article on Key Bindings, you would add a key binding to the JRootPane of the dialog. The Action for the Escape key would simply dispose the current window that has focus. This approach is easy to implement and works well. Unfortunately it works too well. In some cases the dialog will close when you don’t want it to.

For example, when you have a JPopupMenu displayed on the dialog, the Escape key should close the popup menu first. Then the second time you use the Escape key the dialog should be closed. Therefore, our custom Action needs to have a little smarts built into it.

Upon trying to understand a little better how a JPopupMenu works I made the follow observations:

  • the JRootPane has focus when a popup menu is visible
  • the “cancel” Action is used from the JRootPane ActionMap to hide popup menus

Using this information I was able to create a simple EscapeAction that is invoked when the Escape key is pressed. The EscapeAction will invoke the default Escape key Action when a popup menu is visible, otherwise it will simply dispose of the focused dialog. You must register each dialog with the EscapeAction. The basic code would be:

EscapeAction escapeAction = new EscapeAction();
escapeAction.register(dialog1);
escapeAction.register(dialog2);

Although the EscapeAction was written with the JDialog in mind, the functionality is actually added to the JRootPane so it will also work with a JWindow or JFrame.

escapeAction.register(frame.getRootPane());

Get The Code

EscapeAction.java

See Also

Key Bindings

2 Responses to “Escape Key and Dialog”

  1. Kleopatra said

    Rob,

    interesting – and got me filing and starting on an issue in swingx

    Issue #1358: JXRootPane – popups not closed with CancelButton

    As a general rule, I wouldn’t recommend to use componentInputMap (that is those of type WHEN_IN_FOCUSED_WINDOW) except if we can’t help it. That’s why SwingX JXRootPane binds its cancelButton support in the WHEN_ANCESTOR map. What I learned (and liked :-) from your solution is the check for an maybe managed popup. Now did the same check in the cancelAction – different from yours in its enabled method.

    Thanks
    Jeanette

    • Rob Camick said

      Thanks Jeanette. I”ve changed the key bindings to use the WHEN_ANCECTOR… map. After reading your comments about the popup and focus owner problem I’ve also rewritten the entire Action to search the InputMap of the root pane to see if any key bindings have been added. It should handle the case when the root pane or some other component has focus.

Leave a comment