简体   繁体   English

如何在带有 JavaFX 的 mac 顶部工具栏上有一个菜单?

[英]How to have a menu on the mac top toolbar with JavaFX?

On Mac OS, applications that run in the background sometimes have their icon attached to a gui or menu in the right corner of the screen.在 Mac OS 上,在后台运行的应用程序有时会将其图标附加到屏幕右上角的 gui 或菜单上。 I believe it is similar to what Windows has on the bottom-right corner.我相信它与右下角的 Windows 类似。 However I want this for my JavaFX application as well.但是,我也希望将其用于我的 JavaFX 应用程序。 And I don't know how to google for that.而且我不知道如何用谷歌搜索。 All I found was JavaFX' MenuBar, what unfortunately is not what I'm looking for.我发现的只是 JavaFX 的 MenuBar,不幸的是这不是我想要的。

我想要的应用程序示例

You need to set a system property in order to move it out from your JFrame: 您需要设置一个系统属性才能将其从JFrame中移出:

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

This will show your JMenuBar in the MacOS Toolbar. 这将在MacOS工具栏中显示您的JMenuBar。

Or you could check if you are running MacOS and then set the property: 或者,您可以检查是否正在运行MacOS,然后设置属性:

  if (System.getProperty("os.name").contains("Mac")) {
  System.setProperty("apple.laf.useScreenMenuBar", "true");

}
public class SystemTray {
    private static final Logger logger = LogManager.getLogger(Main.class);
    public static java.awt.SystemTray tray = java.awt.SystemTray.getSystemTray();              // set up a system tray icon.
    public static TrayIcon trayIcon;
    public static Image trayIconImage;
    public static MenuItem startRecording;
    public static MenuItem stopRecording;
    public static MenuItem playRecording;
    public static MenuItem pauseRecording;
    public static MenuItem startOver;
    public static MenuItem exitItem;
    final static PopupMenu popup=new PopupMenu();
    public static boolean windows = Main.checkOS();

    public SystemTray() {
    }

    public static void addAppToTray() {
        try {
            // ensure awt toolkit is initialized.
            Toolkit.getDefaultToolkit();
            URL IconPath;
            // app requires system tray support, just exit if there is no support.
            if (!java.awt.SystemTray.isSupported()) {
                System.out.println("No system tray support, application exiting.");
                return;
                //Platform.exit();
            }

            if (windows) {
            File file = new File("./resources/main/cogwheel-win.png");
           // IconPath =this.getClass().getResource("cogwheel-windows.png");
            IconPath =file.toURI().toURL();

            }
            else {
            File file = new File("./resources/main/cogwheel-mac.png");
           // IconPath =this.getClass().getResource("cogwheel-mac.png");
            IconPath =file.toURI().toURL();
            }

            logger.info(IconPath.getFile().toString());
            trayIconImage = ImageIO.read(IconPath);
            trayIcon = new TrayIcon(trayIconImage);
            startRecording = new MenuItem("Start Recording (Shift+Space)");
            stopRecording = new MenuItem("Stop Recording (Shift+Space)");
            playRecording = new MenuItem("Play Recording (Shift+P)");
            pauseRecording = new MenuItem("Pause Recording (Shift+P)");
            startOver = new MenuItem("Start Over (Shift+R)");
            //openItem.addActionListener(event -> Platform.runLater(this::showStage));

            // and select the exit option, this will shutdown JavaFX and remove the
            // tray icon (removing the tray icon will also shut down AWT).

            exitItem = new MenuItem("Quit CAD");
            exitItem.addActionListener(event -> {
                Platform.exit();
                tray.remove(trayIcon);
            });

            // setup the popup menu for the application.
            popup.add(startRecording);
            popup.add(stopRecording);
            popup.addSeparator();
            popup.add(playRecording);
            popup.add(pauseRecording);
            popup.addSeparator();
            popup.add(startOver);
            popup.addSeparator();
            popup.add(exitItem);
            trayIcon.setPopupMenu(popup);
            // add the application tray icon to the system tray.
            tray.add(trayIcon);

           // startRecording.addActionListener(event -> Platform.runLater(Creator::startRecording));

        } catch (AWTException | IOException e) {
            System.out.println("Unable to init system tray");
           logger.info(e.getMessage());
        }
    }
}

I write apps like this a lot, and this is what I discovered as being the easiest and most effective way to use Java/FX to create an app on MacOS that only exists as an icon in the system tray.我经常编写这样的应用程序,这是我发现的最简单和最有效的方法,可以使用 Java/FX 在 MacOS 上创建仅作为图标存在于系统托盘中的应用程序。

I utilize the FXTrayIcon library to accomplish this as that library does the conversions between JavaFX and AWT quite nicely.我利用FXTrayIcon 库来完成此操作,因为该库很好地完成了 JavaFX 和 AWT 之间的转换。

First I just add this to my POM file:首先,我将其添加到我的 POM 文件中:

<dependency>
    <groupId>com.dustinredmond.fxtrayicon</groupId>
    <artifactId>FXTrayIcon</artifactId>
    <version>3.3.0</version>
</dependency>

Then I use a Launcher class which takes advantage of what AWT can do that JavaFX cannot which is get rid of the Dock icon (not to mention still no native FX support for the system tray).然后我使用了启动器 class,它利用了 AWT 可以做到的 JavaFX 无法做到的,这是摆脱了 Dock 图标(更不用说系统托盘仍然没有本机 FX 支持)。

import java.awt.*;

public class Launcher {
    public static void main(String[] args) {
        System.setProperty("apple.awt.UIElement", "true");
        Toolkit.getDefaultToolkit();
        Main.main(args);
    }
}

Then here is a simple Main class that is fully functional然后这里是一个功能齐全的简单 Main class

import com.dustinredmond.fxtrayicon.FXTrayIcon;
import javafx.application.Application;
import javafx.stage.Stage;

import java.net.URL;

public class Main extends Application {

    private URL icon = Main.class.getResource("icon.png");

    @Override public void start(Stage primaryStage) throws Exception {
        new FXTrayIcon.Builder(primaryStage, icon, 22, 22)
                .menuItem("Say Hello", e->helloIcon())
                .separator()
                .addExitMenuItem("Exit", e-> System.exit(0))
                .show()
                .build();
    }

    private void helloIcon() {
        System.out.println("Hello Icon");
    }

    public static void main(String[] args) {
        launch(args);
    }
}

This is what it looks like, and no Dock icon at all nor does the app show up in the CMD+TAB app switching.这就是它的样子,根本没有Dock图标,也没有应用程序显示在CMD+TAB应用程序切换中。

截屏

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM