In the Nimbus L&F when one presses the Enter key, if a button has focus, that button is clicked whether or not another button has been set as default as in:
getRootPane().setDefaultButton(myButton);
Also, using Key Binding does not work:
Action clickDefault = new AbstractAction("clickDefault") {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Got Here");
getRootPane().getDefaultButton().doClick();
}
};
InputMap im = getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
KeyStroke enter = KeyStroke.getKeyStroke("ENTER");
im.put(enter, "defaultButton");
getRootPane().getActionMap().put("defaultButton", clickDefault);
I never even see the "Got Here" message, though if I bind to another KeyStroke, such as "P" it functions as expected. So it would seem that the Enter key is being captured before it gets to this event handler.
I also tried modifying the UIDefaults:
im = (InputMap) UIManager.getDefaults().get("Button.focusInputMap");
im.put(enter, null);
im.put(enterRelease, null);
That failed as well. Anyone have any ideas how to accomplish this?
--- Update ---
Further investigation revealed that the InputMap for JButton contains {"pressed Enter": "pressed", "released ENTER": "released"} (as well as bindings for SPACE). The Key Binding of the Component in question has higher precedence than the RootPane's. See my answer below for code that resolves the problem.
Ok, finally figured out how to make this work as I wanted. Here's the code I'm using:
public class Main {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
// Use Nimbus if it's available and we're not on Mac OSX
if (!System.getProperty("os.name").equals("Mac OS X")) {
try {
for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
((InputMap) UIManager.get("Button.focusInputMap"))
.put(KeyStroke.getKeyStroke("pressed ENTER"), null);
((InputMap) UIManager.get("Button.focusInputMap"))
.put(KeyStroke.getKeyStroke("released ENTER"), null);
break;
}
}
} catch (Exception e) {
// Default Look and Feel will be used
}
}
MainWindow mainWindow = new MainWindow();
mainWindow.setVisible(true);
}
});
}
} // end class Main
One important thing I figured out was that the updates to the InputMap(s) must be made AFTER setting the Look and Feel. I wasn't aware that was required when messing with these things, but then again, I'm new at this whole Look and Feel business.