【问题标题】:Status menu with JavaFX on MacOSMacOS 上带有 JavaFX 的状态菜单
【发布时间】:2019-05-18 04:29:32
【问题描述】:

有没有办法用JavaFX 创建状态菜单? JavaFX 的文档似乎没有类似的东西。

左侧菜单非常简单:

MenuBar menuBar = new MenuBar();
menuBar.useSystemMenuBarProperty().set(true);

Menu menu = new Menu("java");
MenuItem item = new MenuItem("Test");
menu.getItems().add(item);
menuBar.getMenus().add(menu);

BorderPane borderPane = new BorderPane();
borderPane.setTop(menuBar);
primaryStage.setScene(new Scene(borderPane));
primaryStage.show();

【问题讨论】:

  • 没有给出任何细节,简短的回答是“是的,有办法”。对于这个网站来说,展示如何完成这样的事情可能过于宽泛。但是,该图像看起来可以使用包含各种状态图标/控件的HBox 来完成。 ControlsFX 库有一个可能有用的StatusBar 控件。
  • 实际上我不确定如何更具体。它与视觉组件无关(如HBox),它是一个独特的MacOS 元素,可以使用特定的系统API(developer.apple.com/documentation/appkit/nsstatusbar)构建。所以我对JavaFX 是否处理这个 API 很感兴趣。举个例子就是 Bitbar:github.com/matryer/bitbar
  • 啊,我明白了。 JavaFX 没有标准的公共 API 可以做到这一点。我也不知道有任何 JavaFX 特定的库可以做到这一点。您可以查看与 JavaFX 相关的 curated list,看看是否有任何适合您的需求。我不确定它是否是同一件事,但也有java.awt.SystemTray
  • @Slaw 好的,谢谢。这正是我所期望的。如果您添加答案,我会接受。
  • 我同意@Slaw,但不清楚你是想修改Mac菜单栏还是创建自己的;这是SystemTrayexample;另见How to make an OS X menubar in JavaFX

标签: java macos javafx


【解决方案1】:

所以,有办法用java.awt.SystemTray显示菜单:

public static void showMenu(Image trayImage, String... items) {

    if (!java.awt.SystemTray.isSupported())
        throw new UnsupportedOperationException("No system tray support, application exiting.");

    java.awt.Toolkit.getDefaultToolkit();

    java.awt.SystemTray tray = java.awt.SystemTray.getSystemTray();
    java.awt.TrayIcon trayIcon = new java.awt.TrayIcon(trayImage);
    java.awt.PopupMenu rootMenu = new java.awt.PopupMenu();

    for (String item : items) rootMenu.add(new MenuItem(item));

    trayIcon.setPopupMenu(rootMenu);

    try {
        tray.add(trayIcon);
    } catch (Throwable e) {
        throw new RuntimeException("Unable to init system tray");
    }
}

SystemTray 只支持图片作为根项,但是有办法将文本转换为图片:

static BufferedImage textToImage(String text) {
    return textToImage(text, java.awt.Font.decode(null), 13);
}

static BufferedImage textToImage(String Text, Font font, float size) {
    font = font.deriveFont(size);

    FontRenderContext frc = new FontRenderContext(null, true, true);

    LineMetrics lm = font.getLineMetrics(Text, frc);
    Rectangle2D r2d = font.getStringBounds(Text, frc);
    BufferedImage img = new BufferedImage((int) Math.ceil(r2d.getWidth()), (int) Math.ceil(r2d.getHeight()), BufferedImage.TYPE_INT_ARGB);
    Graphics2D g2d = img.createGraphics();
    g2d.setRenderingHints(RenderingProperties);
    g2d.setBackground(new Color(0, 0, 0, 0));
    g2d.setColor(Color.BLACK);

    g2d.clearRect(0, 0, img.getWidth(), img.getHeight());
    g2d.setFont(font);
    g2d.drawString(Text, 0, lm.getAscent());
    g2d.dispose();

    return img;
}

最后的用法示例:

public static void main(String[] args) {
    System.setProperty("apple.awt.UIElement", "true");
    showMenu(textToImage("Hello"), "Item - 1", "Item - 2");
}

系统属性 apple.awt.UIElement=true 在您需要摆脱默认的 java 菜单和 cmd-tab 图标时很有用,因此您的应用的行为就像它的背景一样。

【讨论】:

    猜你喜欢
    • 2021-10-10
    • 2019-06-07
    • 1970-01-01
    • 1970-01-01
    • 2010-11-29
    • 1970-01-01
    • 2021-10-28
    • 2020-12-29
    • 2019-04-07
    相关资源
    最近更新 更多