Is there a way to use Nimbus LAF (Look And Feel) on OS X while still being able to use the Meta key for cut/copy/paste and select-all operations?
I curren
Different components use different keys, so to map all of them, you will have to define different keys. For example (base found from here):
private void addOSXKeyStrokes(InputMap inputMap) {
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.META_DOWN_MASK), DefaultEditorKit.copyAction);
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, KeyEvent.META_DOWN_MASK), DefaultEditorKit.cutAction);
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, KeyEvent.META_DOWN_MASK), DefaultEditorKit.pasteAction);
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.META_DOWN_MASK), DefaultEditorKit.selectAllAction);
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.META_DOWN_MASK), "copy");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.META_DOWN_MASK), "selectAll");
}
This can then be mapped to different components as follows:
// This must be performed immediately after the LaF has been set
if (System.getProperty("os.name", "").startsWith("Mac OS X")) {
// Ensure OSX key bindings are used for copy, paste etc
// Use the Nimbus keys and ensure this occurs before any component creation
addOSXKeyStrokes((InputMap) UIManager.get("EditorPane.focusInputMap"));
addOSXKeyStrokes((InputMap) UIManager.get("FormattedTextField.focusInputMap"));
addOSXKeyStrokes((InputMap) UIManager.get("PasswordField.focusInputMap"));
addOSXKeyStrokes((InputMap) UIManager.get("TextField.focusInputMap"));
addOSXKeyStrokes((InputMap) UIManager.get("TextPane.focusInputMap"));
addOSXKeyStrokes((InputMap) UIManager.get("TextArea.focusInputMap"));
addOSXKeyStrokes((InputMap) UIManager.get("Table.ancestorInputMap"));
addOSXKeyStrokes((InputMap) UIManager.get("Tree.focusInputMap"));
}
A full list of Aqua (OS X Look and Feel) action names is here
Using the getMenuShortcutKeyMask() method works with NimbusLookAndFeel
to enable the ⌘ key, as shown in this example. See also this related answer.
In the particular case of a JTextField
, you can use the mask in a key binding that evokes the original action.
int MASK = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
JTextField jtf = new JTextField("Test");
jtf.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_A, MASK), "select-all");
jtf.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_C, MASK), "copy");
jtf.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_X, MASK), "cut");
jtf.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_V, MASK), "paste");