有没有一种方法可以使用 JMenuBar 显示 KeyBindings,类似于 MacOS 上的原生显示方式?

Is there a way to show KeyBindings with the JMenuBar similar to how is natively shown on MacOS?

我正在使用 Java Swing 来尝试构建一个在 Mac 上感觉尽可能原生的应用程序。我的应用程序有很多用于菜单操作的键绑定,我希望它们像在 Safari 中一样显示在菜单栏中(请参见下面的屏幕截图)。有什么建议吗?

How to Use Menus

import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import Whosebug.Main.TestPane;

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JMenuBar menuBar = new JMenuBar();
                JMenu fileMenu = new JMenu("File");
                fileMenu.setMnemonic('F');
                menuBar.add(fileMenu);

                fileMenu.add(createMenuItem("New Window", 'N', KeyStroke.getKeyStroke(KeyEvent.VK_N, KeyEvent.META_DOWN_MASK)));
                fileMenu.add(createMenuItem("New Private Window", 'W', KeyStroke.getKeyStroke(KeyEvent.VK_N, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)));
                fileMenu.add(createMenuItem("New Tab", 'T', KeyStroke.getKeyStroke(KeyEvent.VK_T, KeyEvent.META_DOWN_MASK)));
                fileMenu.add(createMenuItem("Open File...", 'O', KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.META_DOWN_MASK)));
                fileMenu.add(createMenuItem("Open Location...", 'L', KeyStroke.getKeyStroke(KeyEvent.VK_L, KeyEvent.META_DOWN_MASK)));
                fileMenu.addSeparator();
                fileMenu.add(createMenuItem("Close Window", 'C', KeyStroke.getKeyStroke(KeyEvent.VK_W, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)));
                fileMenu.add(createMenuItem("Close All Windows", 'A', KeyStroke.getKeyStroke(KeyEvent.VK_W, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)));
                fileMenu.add(createMenuItem("Close Tab", KeyStroke.getKeyStroke(KeyEvent.VK_W, KeyEvent.META_DOWN_MASK)));
                fileMenu.add(createMenuItem("Save As...", KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)));
                fileMenu.addSeparator();
                fileMenu.add(createMenuItem("Share"));
                fileMenu.add(createMenuItem("Export as PDF..."));
                fileMenu.addSeparator();
                fileMenu.add(createMenuItem("Impory From"));
                fileMenu.add(createMenuItem("Export Bookmarks..."));
                fileMenu.addSeparator();
                fileMenu.add(createMenuItem("Print...", 'P', KeyStroke.getKeyStroke(KeyEvent.VK_P, KeyEvent.META_DOWN_MASK)));

                JFrame frame = new JFrame();
                frame.setJMenuBar(menuBar);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public JMenuItem createMenuItem(String text, char mnemonic) {
        return createMenuItem(text, mnemonic, null);
    }

    public JMenuItem createMenuItem(String text, char mnemonic, KeyStroke keyStroke) {
        JMenuItem menuItem = new JMenuItem(text);
        menuItem.setMnemonic(mnemonic);
        menuItem.setAccelerator(keyStroke);
        return menuItem;
    }

    public JMenuItem createMenuItem(String text, KeyStroke keyStroke) {
        JMenuItem menuItem = new JMenuItem(text);
        menuItem.setAccelerator(keyStroke);
        return menuItem;
    }

    public JMenuItem createMenuItem(String text) {
        return new JMenuItem(text);
    }

    public class TestPane extends JPanel {

        public TestPane() {
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.dispose();
        }

    }
}

如果您想将它放在“本机菜单栏”中,您也可以使用 Desktop#setDefaultMenuBar

Desktop.getDesktop().setDefaultMenuBar(menuBar);

JFrame frame = new JFrame();
//frame.setJMenuBar(menuBar);

我建议您熟悉 Desktop API,因为这对您在 Mac 平台

上非常有帮助