请求关注 JavaFX 阶段不会更改 macOS 左上角菜单栏标题

Posted

技术标签:

【中文标题】请求关注 JavaFX 阶段不会更改 macOS 左上角菜单栏标题【英文标题】:Requesting focus on a JavaFX stage doesn't change the macOS top left menu bar title 【发布时间】:2019-06-18 20:11:48 【问题描述】:

当我尝试请求焦点时(我在 macOS Mojave 10.14.2 上),当用户从托盘图标菜单中单击“显示”按钮时,它不会更改左上角的菜单栏(例如Chrome -> java),但至少它把它带到了前面。它在全屏应用程序中根本不会出现(例如,在全屏模式下单击 Sublime Text 中的托盘图标),而是在主桌面空间中显示它而不移动到它。


菜单栏示例:

应该变成 而是

全屏示例:

点击“显示”时...

好像什么都没有发生!它会在没有焦点的情况下打开 出现在顶部,而是出现在主“桌面”空间上。


我尝试过先做 toFront()requestFocus() 或只做其中一个,但它似乎不起作用。

有人对此问题有任何修复/解决方法吗?

这是上面用来演示问题的简单应用程序:

package me.matetoes.dockvisibility;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.stage.Stage;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URL;

public class DockVisibilityTester extends Application 

    public javafx.scene.control.Button hideButton;

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

    @Override
    public void start(Stage primaryStage) 
        hideButton = new javafx.scene.control.Button("Hide");
        hideButton.setOnAction(e -> handleHide());
        Scene scene = new Scene(hideButton, 200, 100);
        primaryStage.setScene(scene);
        primaryStage.setTitle("Testing");
        Platform.setImplicitExit(false);
        createTrayIcon(primaryStage);
        primaryStage.show();
    

    private void createTrayIcon(final Stage stage) 
        if (SystemTray.isSupported()) 
            SystemTray tray = SystemTray.getSystemTray(); // get the SystemTray instance

            Image icon = null;
            try  // load an image
                URL url = new URL("http://www.digitalphotoartistry.com/rose1.jpg");
                icon = ImageIO.read(url);
             catch (IOException ex) 
                ex.printStackTrace();
            

            stage.setOnCloseRequest(e -> hide(stage)); //hide instead of close

            // to be added on "show" MenuItem and trayIcon itself
            ActionListener showListener = e -> show(stage);

            PopupMenu popup = new PopupMenu(); // create a popup menu

            MenuItem showItem = new MenuItem("Show");
            showItem.addActionListener(showListener);

            MenuItem closeItem = new MenuItem("Close");
            closeItem.addActionListener(e -> System.exit(0));

            popup.add(showItem);
            popup.addSeparator();
            popup.add(closeItem);

            assert icon != null;
            TrayIcon trayIcon = new TrayIcon(icon, "Test", popup); // construct a TrayIcon
            trayIcon.setImageAutoSize(true);
            trayIcon.addActionListener(showListener);

            try  // add the tray image
                tray.add(trayIcon);
             catch (AWTException e) 
                e.printStackTrace();
            
        
    

    private void hide(final Stage stage) 
        Platform.runLater(() -> 
            if (SystemTray.isSupported()) 
                stage.hide();
             else 
                System.exit(0);
            
        );
    

    private void show(final Stage stage) 
        Platform.runLater(() -> 
            stage.show();

            // doesn't work!
            stage.requestFocus();
            stage.toFront();
        );
    

    public void handleHide() 
        Stage stage = (Stage) hideButton.getScene().getWindow();
        hide(stage);
    

谢谢! :)

【问题讨论】:

【参考方案1】:

你可以试试useSystemMenuBar()

类似

MenuBar mnuBar;
mnuBar.useSystemMenuBar();

【讨论】:

虽然useSystemMenuBar() 会让我使用 macOS 菜单栏,但它并不能解决手头的问题,即它不会将焦点转移到 java 应用程序。 Here 是相同的示例,只是有一个示例菜单栏,但仍然存在焦点问题。 我正在做一些研究,它可能是 macOS 的一个功能See here. 我相信它只发生在后台应用程序上,你可以尝试从显示的窗口第二次 requestFocus 吗? 我已经看到了,但我不认为这是真的,因为我能够使用 Objective-C 代码编写一个 JNA 库来显示和隐藏 macOS 停靠图标,有时它会改变左上角的 macOS 菜单栏,有时不会。要么那个“安全功能”不那么安全,要么应该有某种方法来关注 macOS 菜单栏。

以上是关于请求关注 JavaFX 阶段不会更改 macOS 左上角菜单栏标题的主要内容,如果未能解决你的问题,请参考以下文章

如何在我的应用程序的javafx 2.0中更改阶段标题栏上的图标[重复]

Javafx Platform.runLater 永远不会运行

JavaFX:如何更改焦点遍历策略?

JavaFX 本机捆绑图标 OS X

JavaFX,Java - 活动线程数更改监听器

JavaFX应用程序无法启动(MacOS使用JDK11)