如何将JMenuBar移到Mac OS X屏幕菜单栏?

7

当我将 JMenuBar 移动到 Mac OS X 的屏幕菜单栏上时,它会留下一些空白空间,这些空白处原本是我的窗口菜单; 我需要移除那个空间。 我正在使用

System.setProperty("apple.laf.useScreenMenuBar", "true")

要将我的JMenuBar移动到屏幕菜单栏。我的朋友使用Mac时报告说,如果我没有设置该属性,菜单所在的位置会留下一些丑陋的垂直空间。解决这个问题的最佳方法是什么?
编辑:以下是我的源代码示例:
public static void main(String[] args) {
    System.setProperty("apple.laf.useScreenMenuBar", "true");
    System.setProperty("com.apple.mrj.application.apple.menu.about.name", "Name");

    JFrame frame = new JFrame("Gabby");
    final DesktopMain dm = new DesktopMain();

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(dm);
    frame.setSize(160, 144);
    frame.setLocationRelativeTo(null);
    frame.setIgnoreRepaint(true);

    JMenuBar menuBar = new JMenuBar();
    JMenu fileMenu = new JMenu("File");
    menuBar.add(fileMenu);

    // Populating the menu bar code goes here

    frame.setJMenuBar(menuBar);
    frame.setVisible(true);
}

1
你能发布一下代码吗?通常布局会自动调整以利用所有的空间。 - Eelke
4个回答

12

根据操作的时机不同,在程序启动后设置该属性可能来不及生效。因此,应在启动时添加该设置。

java -Dapple.laf.useScreenMenuBar=true -jar MyApplication.jar

或者,按照Mac OS X上Java部署选项Java Dictionary Info.plist Keys关于 Info.plist KeysJava 运行时系统属性 中讨论的方法,在应用程序捆绑包的 Info.plist 中设置该属性。

<key>Properties</key>
<dict>
    <key>apple.laf.useScreenMenuBar</key>
    <string>true</string>
    ...
</dict>

补充说明:如下所示,采用@Urs Reupke或我建议的方法并不会出现问题。你(缺失的)DesktopMain可能有问题。

屏幕截图

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;

/** @see https://dev59.com/5l_Va4cB1Zd3GeqPUYkC */
public class NewMain {

    public static void main(String[] args) {
        System.setProperty("apple.laf.useScreenMenuBar", "true");
        System.setProperty(
            "com.apple.mrj.application.apple.menu.about.name", "Name");
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {

                JFrame frame = new JFrame("Gabby");
                final JPanel dm = new JPanel() {

                    @Override
                    public Dimension getPreferredSize() {
                        return new Dimension(320, 240);
                    }
                };
                dm.setBorder(BorderFactory.createLineBorder(Color.blue, 10));

                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(dm);
                frame.pack();
                frame.setLocationByPlatform(true);

                JMenuBar menuBar = new JMenuBar();
                JMenu fileMenu = new JMenu("File");
                menuBar.add(fileMenu);
                frame.setJMenuBar(menuBar);
                frame.setVisible(true);
            }
        });
    }
}

trashgod,那似乎不对 - 我在我的代码中这样做,但我还没有听到任何抱怨。 - Urs Reupke
@UrsReupke:好观点,已编辑。我无法重现这种效果,但我看到过像这样的报告 - trashgod

4
作为对trashgod建议的替代方案,您可以继续做您正在做的事情 - 但是在初始化UI之前非常早地这样做。
此外,您可以考虑使用以下代码在应用程序栏中显示应用程序名称:
    System.setProperty("com.apple.mrj.application.apple.menu.about.name", "MyApplication");

+1 tnecniv:请提供一个 sscce,展示您所描述的问题。 - trashgod
@trashgod 我添加了我的源代码示例。 - tnecniv

4

我知道这个问题已经很久了,但对我有效的方法是创建了一个名为Main的新类,然后设置系统属性,如下所示:

System.setProperty("apple.laf.useScreenMenuBar", "true");
System.setProperty("apple.awt.application.name", "My app");

适用于JDK15。


它需要在任何Swing类被初始化之前设置。 - Anthony

0

对于Java 8,请使用以下代码

System.setProperty("apple.awt.application.name", "My app");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接