【问题标题】:Mac Keyboard Shortcuts with Nimbus LAF带有 Nimbus LAF 的 Mac 键盘快捷键
【发布时间】:2012-03-20 00:50:13
【问题描述】:

有没有办法在 OS X 上使用 Nimbus LAF(外观和感觉),同时仍然能够使用 Meta 键进行剪切/复制/粘贴和全选操作?

我目前在我的 Swing 应用程序的 main 方法中有以下代码,它根据操作系统更改 LAF(OS X 的默认值,所有其他的 Nimbus):

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);
    }
}

我这样做是一种解决方法,因为 Nimbus 覆盖了 OS X 上用于剪切/复制/粘贴和全选的键盘快捷键(Meta 键与 Ctrl 键)。如果不覆盖键盘快捷键,我更愿意一直使用 Nimbus。

【问题讨论】:

    标签: java macos swing keyboard-shortcuts nimbus


    【解决方案1】:

    使用getMenuShortcutKeyMask() 方法与NimbusLookAndFeel 一起启用 键,如example 所示。另请参阅此相关answer

    JTextField 的特殊情况下,您可以在 key binding 中使用掩码来唤起原始操作。

    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");
    

    【讨论】:

    • 我不明白这是如何回答这个问题的。即使您在注册自定义键盘快捷键时调用 getMenuShortcutKeyMask(),这也不能修复在 OSX 上使用 NimbusLookAndFeel 时默认 Swing TextField 中不正确的 Ctrl-C、Ctrl-V 等。
    • @yonran:我已经在上面详细说明了。
    • 似乎每个组件的操作名称不同。因此,要映射“复制”操作,您还需要映射 DefaultEditorKit.copyAction。
    • @JouniAro:不一定;这些操作已经在文本字段的ActionMap 中,在 UI 委托初始化期间(按名称)放置在那里;看到这个article
    • 对不起,我的意思是每个组件类型。因此,对于每个 Table,ActionMap 都包含“复制”,而对于每个 TextField,它都包含“复制到剪贴板”(=DefaultEditorKit.copyAction)
    【解决方案2】:

    不同的组件使用不同的键,因此要映射所有组件,您必须定义不同的键。例如(从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 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"));
    }
    

    Aqua(OS X 外观)动作名称的完整列表是 here

    【讨论】:

    • 感谢源链接!
    • 谢谢。我花了很长时间才找到一个清晰的例子,所以我也想在这里分享它——加上我自己的补充。
    猜你喜欢
    • 2014-11-17
    • 1970-01-01
    • 2010-12-04
    • 2010-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多