I think even the solution using AWTEventListener would work, I would suggest avoid using AWTEventListener if another solution is available. It is because it's so powerful that it intercepts all kinds of events globally before they reach their real targets, so if anything went wrong (such as a NullPointerException) in the middle, the whole application would stop working.
My proposed solution makes use of input map & action map which adds handling of Enter key to any focused component in a particular container.
The advantage:
- Safer because it affects only components in a container instead of all components.
The disadvantage:
- The same handling code has to apply to all containers that need this behavior, but this could be easily accomplished by a static utility method.
Here is the sample program:
public MainFrame() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(500, 500);
setLayout(new GridLayout(2, 2));
addAllComponents();
addEnterKeyAsFocusTraversal();
}
private void addAllComponents() {
add(new JTextField());
add(new JTextField());
add(new JButton("OK"));
add(new JButton("Cancel"));
}
private void addEnterKeyAsFocusTraversal() {
final String ENTER_KEY_ACTION = "EnterKeyAction";
// Here uses the content pane of type Container so a cast is required,
// in other case it could be the root container which may already be an instance of JComponent.
JComponent contentPane = (JComponent) getContentPane();
contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), ENTER_KEY_ACTION);
contentPane.getActionMap().put(ENTER_KEY_ACTION, createEnterKeyAction());
}
private AbstractAction createEnterKeyAction() {
return new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
if (focusOwner != null) {
if (focusOwner instanceof AbstractButton) {
((AbstractButton) focusOwner).doClick();
} else {
focusOwner.transferFocus();
}
}
}
};
}