Java Tip 72: Press Escape to close your Swing dialog windows

Discover how to program keystroke responses in your Dialogs' parent classes

In Microsoft Windows environments (95, 98, NT), users can press the Escape key to close dialog windows. By default, with Java applications, this behavior is offered by neither AWT nor JFC/Swing dialog windows. To present users with a more common environment, you can add this behavior to your Java programs. In Java Tip 69, "Press Escape to close your Java dialog windows," you learned how to accommodate this behavior for regular AWT dialog windows. In this tip, you'll see how much easier it is to do the same thing with JFC/Swing dialog windows.

Since the JFC/Swing dialog window is a subclass of the AWT dialog window, theoretically you could simply change the class subclassed by the earlier EscapeDialog. Instead of subclassing the AWT dialog window, the EscapeDialog could subclass the JFC/Swing JDialog window. For all practical purposes, recursively adding key listeners would work, causing the Escape key to close the JFC/Swing dialog window.

While the change of parent classes from the Dialog to JDialog would work, the JFC/Swing component library offers a much simpler approach. The JComponent class defines a couple of registerKeyboardAction() methods for just this type of behavior:

public void registerKeyboardAction(ActionListener action, KeyStroke keyStroke, int condition);
public void registerKeyboardAction(ActionListener action, String command, KeyStroke keyStroke, int condition);

All you need to do is to create a custom subclass of JDialog, define an ActionListener for closing the JDialog, and register the Escape keystroke to call the action listener. Then, when the user presses the Escape key when the JDialog is open, JDialog automatically goes away.

Here's a closer look at those three steps:

Step 1. Subclass JDialog

public class EscapeDialog extends JDialog {
  ...
}

Step 2. Define the ActionListener

ActionListener actionListener = new ActionListener() {
  public void actionPerformed(ActionEvent actionEvent) {
     setVisible(false);
  }
};

Step 3. Define and register the keystroke

Since the registerKeyboardAction() method is part of the JComponent class definition, you must define the Escape keystroke and register the keyboard action with a JComponent, not with a JDialog. The JRootPane for the JDialog serves as an excellent choice to associate the registration, as this will always be visible. If you override the protected createRootPane() method of JDialog, you can return your custom JRootPane with the keystroke enabled:

protected JRootPane createRootPane() {
  KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
  JRootPane rootPane = new JRootPane();
  rootPane.registerKeyboardAction(actionListener, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW);
  return rootPane;
}

Technically speaking, that's all there is to it with the JFC/Swing JDialog window. You can then create and use the new-and-improved EscapeDialog window in all your JFC/Swing-based applications just as you would a JDialog. From a useability perspective, you may wish to replicate the many constructors of JDialog. The accompanying source code (EscapeDialog.java) provides a common set of nine constructors, as offered by the original JDialog class. In addition, the SetupEscapeFrame.java file demonstrates its usage.

Note: Many people do not create JDialog windows directly. Instead, they create JDialog windows through the JOptionPane class with methods like JOptionPane.showMessageDialog(frame, "The Message"). When using the JDialog window through a JOptionPane, you do not have to install the Escape key handling, as the basic look-and-feel class for the option pane (BasicOptionPaneUI) already does this for you.

John Zukowski is a Software Mage with MageLang Institute, author of John Zukowski's Definitive Guide to Swing for Java 2 from Apress!, Mastering Java 2 from Sybex, and Java AWT Reference from O'Reilly & Associates, as well as the Focus on Java guide at the Mining Company.

Learn more about this topic

  • This Java Tip was excerpted from John Zukowski's Definitive Guide to Swing for Java 2, to be published by Apress! in summer 1999 http://www.apress.com/Catalog/CatalogMain.htm