import java.awt.*; import java.awt.event.*; import javax.swing.*; /** * Convenience Action to dispose of a Swing Window by using the Escape key. * Before disposing of the window the Action will first attempt to hide * any popups. In this case the user will need to invoke the Escape key a * second time before the Window is disposed. */ public class EscapeAction extends AbstractAction { private static final String KEY_STROKE_AND_KEY = "ESCAPE"; private static final KeyStroke ESCAPE_KEY_STROKE = KeyStroke.getKeyStroke( KEY_STROKE_AND_KEY ); public EscapeAction() { super("Escape"); } /** * Implement the Escape Action. First attempt to hide a popup menu. * If no popups are found then dispose the window. */ @Override public void actionPerformed(ActionEvent e) { // When a popup is visible the root pane of the Window will // (generally) have focus Component component = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); JComponent rootPane = (JComponent)component; // In some cases a component added to a popup menu may have focus, but // we need the root pane to check for popup menu key bindings if ( ! (rootPane instanceof JRootPane) ) { rootPane = (JComponent)SwingUtilities.getAncestorOfClass(JRootPane.class, component); } // Hide the popup menu when an ESCAPE key binding is found, // otherwise dispose the Window ActionListener escapeAction = getEscapeAction( rootPane ); if (escapeAction != null) { escapeAction.actionPerformed(null); } else { Window window = SwingUtilities.windowForComponent(component); window.dispose(); } } private ActionListener getEscapeAction(JComponent rootPane) { // Search the parent InputMap to see if a binding for the ESCAPE key // exists. This binding is added when a popup menu is made visible // (and removed when the popup menu is hidden). InputMap im = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); if (im == null) return null; im = im.getParent(); if (im == null) return null; Object[] keys = im.keys(); if (keys == null) return null; for (Object keyStroke: keys) { if (keyStroke.equals(ESCAPE_KEY_STROKE)) { Object key = im.get(ESCAPE_KEY_STROKE); return rootPane.getActionMap().get( key ); } } return null; } /** * Convenience method for JDialogs to register the EscapeAction * * ¶m dialog the JDialog the EscapeAction is registered with */ public void register(JDialog dialog) { register( dialog.getRootPane() ); } /** * Register the EscapeAction on the specified JRootPane * * ¶m rootPane the JRootPane the EscapeAction is registered with */ public void register(JRootPane rootPane) { rootPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(ESCAPE_KEY_STROKE, KEY_STROKE_AND_KEY); rootPane.getActionMap().put(KEY_STROKE_AND_KEY, this); } }