26 June 2009

Quick close a dialog by escape key

I Windows there is a convention that a dialog is closed (and canceled) if the user pressed the Esc key. There is also a convention that pressing Enter closes (and confirms) the dialog. In Java there is no default implementation of this.

So we need to implement this ourself. A naive approach would be to add a KeyListener to the dialog. This will not work if the keyboard focus is in a nested component (for example a text field). So how about to add a key listener to both the dialog and all its subcomponents? Well this would work, and I have successfully implemented this using a ContainerListener in the dialog so any components added in the dialog also gets a key listener. But there is a simpler way: the key bindings way!
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.*;

@SuppressWarnings("serial")
public class QuickCloseDialog extends JDialog {

public QuickCloseDialog() {
initCloseListener();
add(new JTextField("A text field"));
pack();
}

private void initCloseListener() {
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE , 0), "close");
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "close");
getRootPane().getActionMap().put("close", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
}

public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JDialog dialog = new QuickCloseDialog();
dialog.setVisible(true);
}
});
}
}

With a key binding you don't have to care where the keyboard focus is.

Update: My solution is probably not thread safe, this alternative solution is: http://stackoverflow.com/questions/642925/swing-how-do-i-close-a-dialog-when-the-esc-key-is-pressed

1 comment: