问题
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 currently have the following code in my Swing app's main method, which changes up the LAF based on the operating system (default for OS X, Nimbus for all others):
if (!System.getProperty("os.name", "").startsWith("Mac OS X")) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(LicenseInspectorUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(LicenseInspectorUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(LicenseInspectorUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(LicenseInspectorUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
}
I do this as a workaround because Nimbus overrides the keyboard shortcuts for cut/copy/paste and select-all on OS X (Meta key versus Ctrl key). I would prefer to use Nimbus all the time, if only the keyboard shortcuts weren't overridden.
回答1:
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");
回答2:
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
来源:https://stackoverflow.com/questions/9780028/mac-keyboard-shortcuts-with-nimbus-laf