Mac 状态栏项目但不在 Dock 上

Posted

技术标签:

【中文标题】Mac 状态栏项目但不在 Dock 上【英文标题】:Mac status bar item but not on Dock 【发布时间】:2012-05-26 16:03:27 【问题描述】:

我正在尝试在 Mac 上制作一个 Java 应用程序,在状态栏中放置一个图标,但我不希望 Mac 底座上的罐子图标(纸上有咖啡杯的那个)。所以我尝试使用 System.setProperty(java.awt.headless, true) 技术,但是我无法在 SystemTray 菜单栏中放置任何内容,因为我得到了 HeadlessException。如果有人知道解决此问题的方法,我们将不胜感激。

【问题讨论】:

理想情况下,您希望您的应用成为“UI 元素”。对于 Cocoa 应用程序,这意味着在 Info.plist 中将 LSUIElement 键设置为 1。对于 Java 应用程序不知道。 “状态栏”是指菜单栏吗?您显然可以更改停靠图标,但我不知道以编程方式删除停靠图标的任何方法。这需要本机 Cocoa 代码和管理员权限。 由于“无头异常”,我想知道这是否是由于 Apple 安全问题(即受感染的网站产生静默和恶意 Java 应用程序的可能性)。 我只是想如果其他应用程序可以做到并且您可以同时删除这两个应用程序,那么您可以只删除一个。考虑到这是出于安全原因,我觉得这很有意义,他们不会让你两个都做。 【参考方案1】:

这很容易......如果你知道如何:)

首先将您的 jar 文件包装在 mac 应用程序包中

要么使用 mac 开发者工具附带的“jar bundler”应用程序 或使用-unrelated-jarbundler ant 任务http://jarbundler.sourceforge.net/

然后进入生成的包的内容并打开 info.plist。 只需添加 LSUIElement 属性并将其设置为 1。这会在启动时从 Dock 中删除应用程序。 也可以在这里查看苹果文档:http://developer.apple.com/library/ios/#documentation/general/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html


为了完整性:还有另一种方法可以做到这一点,但更痛苦。 有一个可可命令允许您动态显示/隐藏停靠图标: SetSystemUIMode (https://developer.apple.com/library/mac/#documentation/Carbon/reference/Dock_Manager/Reference/reference.html) 您可以尝试使用 rococoa 调用此命令,也可以编写自己的 jni lib。 或者,我会有一个 xcode 项目,它在我的 github 帐户中执行非常相似的操作 - 隐藏菜单栏:https://github.com/kritzikratzi/jAppleMenuBar/ 您只需更改 src/native/jAppleMenuBar.m 文件中的一些参数。

【讨论】:

非常感谢!这是一个很大的帮助。 很酷,但现在作为一个意想不到的副作用,当我尝试在应用程序已经运行时启动它时,它不会启动。当有人尝试再次启动它时,有没有办法在最初运行的应用程序中知道它?如果他们在应用程序已经运行时双击该应用程序,我想打开它。 要么挖掘 eawt [1] 和/或 lwawt [2]。这些是与 jdk for mac 捆绑在一起的 osx 类(禁用 IDE 中的禁止引用)。或者看看你是否可以实现 NSApplicationDelegate [3](例如使用 Rococoa)链接:[1] hg.openjdk.java.net/macosx-port/macosx-port/jdk/file/… [2] hg.openjdk.java.net/macosx-port/macosx-port/jdk/file/… [3] developer.apple.com/library/mac/documentation/cocoa/reference/…【参考方案2】:

这避免了停靠中的任何东西:

System.setProperty("apple.awt.UIElement", "true");

这会添加托盘图标,如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();
        final TrayIcon trayIcon =
                new TrayIcon(createImage("images/bulb.gif", "tray icon"));
        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.");
        

【讨论】:

以上是关于Mac 状态栏项目但不在 Dock 上的主要内容,如果未能解决你的问题,请参考以下文章

如何改变macOS顶部状态栏的颜色?

Android Draw 在状态栏后面但不在导航栏后面

导航栏颜色不在状态栏下

状态栏重叠

C# Winform程序添加了dotnetbarmanager控件的窗口,怎样固定住菜单栏和状态栏分别在最上面和最下面?

Mac的Dock栏是什么?Mac Dock栏使用技巧