Поддержка встроенной строки меню Swing для MacOS X в Java

Выделяется ссылка http://www.devdaily.com/blog/post/jfc-swing/handling-main-mac-menu-in-swing-application/ однако строка меню в Mac OS X отображается как имя пакета как напротив имени приложения. Я использую код по приведенной выше ссылке безуспешно, поэтому я не уверен, что что-то изменилось в последних версиях Mac OS.

Вот выдержка:

public RootGUI() {
    super("Hello");
    JMenuBar menuBar = new JMenuBar();
    JMenu file = new JMenu("File");
    JMenuItem item = new JMenuItem("Woah");
    file.add(item);
    menuBar.add(file);
    setJMenuBar(menuBar);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(100, 100);
    pack();
    setVisible(true);
}
public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            try {
                System.setProperty("apple.laf.useScreenMenuBar", "true");
                System.setProperty("com.apple.mrj.application.apple.menu.about.name", "Test");
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                new RootGUI();
            }
            catch(ClassNotFoundException e) {
                System.out.println("ClassNotFoundException: " + e.getMessage());
            }
            catch(InstantiationException e) {
                System.out.println("InstantiationException: " + e.getMessage());
            }
            catch(IllegalAccessException e) {
                System.out.println("IllegalAccessException: " + e.getMessage());
            }
            catch(UnsupportedLookAndFeelException e) {
                System.out.println("UnsupportedLookAndFeelException: " + e.getMessage());
            }

        }
    });
}

Первый пункт меню в строке меню должен отображаться как «тест», к сожалению, это не так. С другой стороны, меню файлов работает нормально. Любые идеи?


person Kezzer    schedule 20.11.2008    source источник
comment
о, посмотри на все эти исключения   -  person brendan    schedule 10.07.2012
comment
@brendan это было 4 года назад, да ладно ;)   -  person Kezzer    schedule 10.07.2012


Ответы (8)


@Кеззер

Кажется, я вижу, что происходит. Если вы поместите метод main() в другой класс, все будет работать. Итак, вам нужно что-то вроде:

public class RootGUILauncher {
  public static void main(String[] args) {
    try {
                System.setProperty("apple.laf.useScreenMenuBar", "true");
                System.setProperty("com.apple.mrj.application.apple.menu.about.name", "Test");
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch(ClassNotFoundException e) {
                System.out.println("ClassNotFoundException: " + e.getMessage());
        }
        catch(InstantiationException e) {
                System.out.println("InstantiationException: " + e.getMessage());
        }
        catch(IllegalAccessException e) {
                System.out.println("IllegalAccessException: " + e.getMessage());
        }
        catch(UnsupportedLookAndFeelException e) {
                System.out.println("UnsupportedLookAndFeelException: " + e.getMessage());
        }
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            new RootGUI();
        }
    });
}

А затем поместите свой класс RootGUI в другой файл.

person Matt Solnit    schedule 21.11.2008
comment
Администраторы только что объединили эту тему с моей корневой учетной записью, поэтому я отметил это как правильный ответ для вас сейчас :) - person Kezzer; 27.12.2008
comment
@Matt Solnit: у меня тоже была такая же проблема. Этот ответ решил мою проблему. - person Sandeep Kumar; 03.05.2012

Вам нужно установить системное свойство «com.apple.mrj.application.apple.menu.about.name» в основном потоке, а не в потоке Swing (другими словами, просто сделайте его первой строкой в ​​программе).

person Matt Solnit    schedule 20.11.2008

Насколько я понимаю, вы хотите переименовать меню приложения, отображаемое в строке меню OS X. Ну, я не нашел системного свойства, но нашел параметр командной строки:

-Xdock:name="YourNameHere"

это сработало для меня.

Кстати: свойство syystem com.apple.mrj.application.apple.menu.about.name предназначено для переименования пункта меню «О программе» в меню вашего приложения, а не самой строки меню.

См. эту ссылку здесь (старая ссылка, вероятно, была удалена через некоторое время после приобретения sun-oracle).

person Daniel Hiller    schedule 21.11.2008

Вы также можете использовать Macify при создании приложения, чтобы изменить любой код.

person Jay Askren    schedule 22.07.2010

Если вы хотите доставить приложение, которое выглядит родным для Mac OS X, одной важной частью является доставка пакета приложений. В пакете приложений вы сможете предоставить файл списка свойств для решения этой проблемы.

Немного официальной информации: Руководство по разработке Java для Mac OS X

person Vincent Robert    schedule 21.11.2008

Если вы запускаете несколько JFrame и используете меню Mac, то один из JFrame может заменять нужный JFrame тем, который имеет другую структуру меню. Я не уверен, что вы можете использовать один JMenuBar для нескольких JFrames, но вы можете просто создать широкую панель меню приложения, которая будет создавать экземпляры всех фреймов.

person ramsey0    schedule 09.02.2014

для всех, кто интересуется, хотя этому вопросу 6 лет, у меня была такая же проблема. Меню Swing не отображаются на собственной панели Mac. Я нашел более простое и прямое решение... Просто добавьте в свой JFrame компонент меню Java.awt вместо JMenu, и он автоматически отобразится в родной панели меню!

person Pietro Pozzoli    schedule 03.10.2015

Разговор о позднем хите, но я могу подтвердить это (удивительно)

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

... а затем сработала установка JMenuBar в JFrame, поместив строку меню вверху, как это предпочтительнее для macOS.

jFrame.setJMenuBar(jMenuBar);

...работает на macOS Big Sur (11.2.3) и JDK 16.

person Will Iverson    schedule 23.04.2021