Paul Tomblin said:
How do I make JDialog buttons work like the buttons in JOptionPane, where
pressing the enter/return key does the action of the selected button? At
first I thought I was my code, so I downloaded the JDialog code from two
Swing books, and both of them have the same problem - it highlights the
buttons as you tab around, but hitting return does nothing.
I've tried this on both Mac OS X and Linux, Java 1.4.2.
I wrote a utility class that maps actions to key events. Here's the
class:
import java.awt.Component;
import java.awt.DefaultKeyboardFocusManager;
import java.awt.KeyEventDispatcher;
import java.awt.KeyEventPostProcessor;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.HashMap;
import java.util.Set;
import javax.swing.Action;
import org.apache.log4j.Logger;
/**
* This class handles the default key strokes the users type
* in a panel or container by executing the registered actions. If no
* actions are registered, then nothing will happen. Any key
* stroke can be mapped to an action, however, the two main
* key strokes mapped in this object are the \<enter\> and
* \<escape\> keys. The key is a KeyEvent.VK_<key> static
* value and the action is what will be executed if
* the keystroke is typed by the user.
* @author B. Cooper
* @since v1.0.0
*/
public class DefaultKeyHandler
extends DefaultKeyboardFocusManager
implements KeyListener, KeyEventDispatcher, KeyEventPostProcessor {
/** The table that will hold the actions to execute */
private HashMap actionMap = new HashMap();
/** The logger object */
private Logger logger = Logger.getLogger( DefaultKeyHandler.class);
/**
* Default Constructor
*/
public DefaultKeyHandler() {
super();
}
/**
* @see
java.awt.KeyEventDispatcher#dispatchKeyEvent(java.awt.event.KeyEvent)
*/
public boolean dispatchKeyEvent(KeyEvent e) {
/** Add custom code here if you need to... */
return false;
}
/**
* If a KeyEvent matches the key in the actionMap object,
* the associated action will be fired.
* @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
*/
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
Set keys = actionMap.keySet();
Integer findKey = new Integer(keyCode);
if (keys.contains(findKey)) {
final Action a = (Action)actionMap.get(findKey);
try {
a.actionPerformed(
new ActionEvent(
this,
1,
(String)a.getValue(Action.ACTION_COMMAND_KEY)));
} catch (Exception ex) {
logger.error("Exception on ketPressed action!", ex);
}
}
}
/**
* @see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent)
*/
public void keyReleased(KeyEvent e) {
}
/**
* @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
*/
public void keyTyped(KeyEvent e) {
}
/**
* This method will map an action to the enter key event
* @param action
*/
public void mapEnterKeyAction(Action action) {
actionMap.put(new Integer(KeyEvent.VK_ENTER), action);
}
/**
* This method will map an action to the escape key event
* @param action
*/
public void mapEscapeKeyAction(Action action) {
actionMap.put(new Integer(KeyEvent.VK_ESCAPE), action);
}
/**
* This method will map an action to the escape key event
* @param keyEventId
* @param action
*/
public void mapKeyAction(int keyEventId, Action action) {
actionMap.put(new Integer(keyEventId), action);
}
/**
* @see
java.awt.KeyEventPostProcessor#postProcessKeyEvent(java.awt.event.KeyEvent)
*/
public boolean postProcessKeyEvent(KeyEvent e) {
/** Add custom code here if you need to... */
return false;
}
/**
* @see
java.awt.KeyEventPostProcessor#postProcessKeyEvent(java.awt.event.KeyEvent)
*/
public void processKeyEvent(Component component, KeyEvent e) {
/** Add custom code here if you need to... */
}
/**
* This method registers a component for the mapped actions.
* @param component
*/
public void registerComponent(Component component) {
component.addKeyListener(this);
if (component instanceof Container) {
Component[] comps = ((Container)component).getComponents();
for (int i = 0; i < comps.length; i++) {
registerComponent((comps
);
}
}
}
}
Here's how you would use it:
public MyPanel extends JPanel {
private DefaultKeyHandler keyHandler = new DefaultKeyHandler();
...
public MyPanel() {
keyHandler.mapEnterKeyAction(new YourOKButtonAction());
keyHandler.mapEscapeKeyAction(new YourCancelButtonAction());
keyHandler.registerComponent(this);
}
...
}
The registerComponent method will register the panel and all of it's
contained components with the actions that you defined.
Hope this helps out.
Bryan Cooper