如何使JavaFX舞台在关闭时最小化到系统托盘?

8

我有一个包含两个阶段的应用程序,我不希望用户关闭第二个阶段,只是将其最小化。

目前我正在使用oncloseRequest处理程序将窗口最小化 -

secondaryStage.setOnCloseRequest(event -> {
    secondaryStage.setIconified(true);
    event.consume();
});

当用户关闭窗口时,我希望在系统托盘中显示一个图标。用户应该能够从托盘中重新打开窗口。

另外,我如何确保当主舞台关闭时,第二舞台也关闭?


3
JavaFX 中没有内置的功能来实现这个。但在 Windows 平台上,可以利用一些工具将应用程序图标化到系统托盘中。唯独在 AWT(抽象窗口工具包)中有相关功能,请参考:https://docs.oracle.com/javase/tutorial/uiswing/misc/systemtray.html。如果您懂德语,可以查看这篇不错的指南来实现 JavaFX 应用程序图标化到系统托盘:http://blog.essential-bytes.de/wie-man-javafx-applikationen-in-das-system-tray-verbannt/ 或者查看英文版本的 jewelsea 给出的代码片段:https://gist.github.com/jewelsea/e231e89e8d36ef4e5d8a - aw-think
谢谢!另外,当主舞台关闭时,如何关闭第二个窗口? - Darth Ninja
2个回答

8

在start方法中设置以下属性

Platform.setImplicitExit(false);

然后设置关闭事件。
secondaryStage.setOnCloseRequest(event -> {
    // Your code here
});

要在系统托盘中尝试以下代码:

原始文档链接:https://docs.oracle.com/javase/tutorial/uiswing/misc/systemtray.html

    //Check the SystemTray is supported
    if (!SystemTray.isSupported()) {
        System.out.println("SystemTray is not supported");
        return;
    }
    final PopupMenu popup = new PopupMenu();

    URL url = System.class.getResource("/images/new.png");
    Image image = Toolkit.getDefaultToolkit().getImage(url);

    final TrayIcon trayIcon = new TrayIcon(image);

    final SystemTray tray = SystemTray.getSystemTray();

    // Create a pop-up menu components
    MenuItem aboutItem = new MenuItem("About");
    CheckboxMenuItem cb1 = new CheckboxMenuItem("Set auto size");
    CheckboxMenuItem cb2 = new CheckboxMenuItem("Set tooltip");
    Menu displayMenu = new Menu("Display");
    MenuItem errorItem = new MenuItem("Error");
    MenuItem warningItem = new MenuItem("Warning");
    MenuItem infoItem = new MenuItem("Info");
    MenuItem noneItem = new MenuItem("None");
    MenuItem exitItem = new MenuItem("Exit");

    //Add components to pop-up menu
    popup.add(aboutItem);
    popup.addSeparator();
    popup.add(cb1);
    popup.add(cb2);
    popup.addSeparator();
    popup.add(displayMenu);
    displayMenu.add(errorItem);
    displayMenu.add(warningItem);
    displayMenu.add(infoItem);
    displayMenu.add(noneItem);
    popup.add(exitItem);

    trayIcon.setPopupMenu(popup);

    try {
        tray.add(trayIcon);
    } catch (AWTException e) {
        System.out.println("TrayIcon could not be added.");
    }

示例系统托盘图像:

系统托盘程序示例

要从awt事件处理程序调用Javafx方法,您可以按照以下方式进行:

yourAwtObject.addActionListener(e -> {
    Platform.runLater(() -> primaryStage.show());
});

0
另外,我该如何确保主阶段关闭时,第二阶段也关闭?
您可以使用以下代码来在主阶段关闭时关闭次要阶段:
primaryStage.setOnCloseRequest((WindowEvent we) -> {
    secondaryStage.close();
}

因为已经存在其他的onCloseRequest处理程序,这样做会将secondaryStage图标化吗? - Puce
你可以在你的次要 onCloseRequest 处理程序中添加一个 if 语句,检查主舞台是否正在关闭。 - Kaman

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