系统托盘中的 JavaFX 应用程序

2024-04-03

我正在使用 JavaFX UI 制作一个简单的应用程序,该应用程序只需执行以下操作:

  • 有一个系统托盘图标,单击时显示一个窗口,再次单击时隐藏它,右键单击时显示一个带有 1 个“退出”项的菜单

我已经制作了 UI 并将应用程序放入系统托盘中,但我无法使用普通 Actionlistener 方法显示/隐藏它,但我收到此错误:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Not on FX application thread; currentThread = AWT-EventQueue-0

这是代码:

import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionListener;


import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application{
    public static void main(String[] args) { 
        launch(args);       
    }

    @Override
    public void start(final Stage primaryStage) {
        primaryStage.setTitle("Hello World!");
        Button btn = new Button();
        btn.setText("Say 'Hello World'");
        btn.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                System.out.println("Hello World!");            }
        });

        StackPane root = new StackPane();
        root.getChildren().add(btn);
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();

        if (SystemTray.isSupported()) {         
            SystemTray tray = SystemTray.getSystemTray();
            Image image = Toolkit.getDefaultToolkit().getImage("Germany-politcal-map.jpg");
            PopupMenu popup = new PopupMenu();
            MenuItem item = new MenuItem("Exit");

            popup.add(item);

            TrayIcon trayIcon = new TrayIcon(image, "Amr_Trial", popup);

            ActionListener listener = new ActionListener() {                
                @Override
                public void actionPerformed(java.awt.event.ActionEvent arg0) {
                    // TODO Auto-generated method stub
                    System.exit(0);                 
                }               
            };                       

            ActionListener listenerTray = new ActionListener() {                
                @Override
                public void actionPerformed(java.awt.event.ActionEvent arg0) {
                    // TODO Auto-generated method stub                  
                    primaryStage.hide();
                }                   
            };            

            trayIcon.addActionListener(listenerTray);
            item.addActionListener(listener);

            try{
              tray.add(trayIcon);
            }catch (Exception e) {
              System.err.println("Can't add to tray");
            }
          } else {
            System.err.println("Tray unavailable");
          } 
        //
    }
}

将代码包装在 actionListener 中,该回调回调到 JavaFX平台.runLater http://docs.oracle.com/javafx/2/api/javafx/application/Platform.html#runLater%28java.lang.Runnable%29。这将在 JavaFX 应用程序线程上执行与 JavaFX 系统交互的代码,而不是尝试在 Swing 事件线程上执行此操作(这正是导致问题的原因)。

例如:

ActionListener listenerTray = new ActionListener() {                
  @Override public void actionPerformed(java.awt.event.ActionEvent event) {
    Platform.runLater(new Runnable() {
      @Override public void run() {
        primaryStage.hide();
      }
    });
  }                   
};            

默认情况下,应用程序将当最后一个窗口隐藏时关闭 http://docs.oracle.com/javafx/2/api/javafx/application/Application.html。要覆盖此默认行为,请调用Platform.setImplicitExit(假) http://docs.oracle.com/javafx/2/api/javafx/application/Platform.html#setImplicitExit%28boolean%29在展示第一个应用程序阶段之前。然后您需要显式调用平台.exit() http://docs.oracle.com/javafx/2/api/javafx/application/Platform.html#exit%28%29当您需要应用程序真正关闭时。


我创建了一个在 JavaFX 应用程序中使用 AWT 系统托盘的演示 https://gist.github.com/jewelsea/e231e89e8d36ef4e5d8a.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

系统托盘中的 JavaFX 应用程序 的相关文章

  • 有没有办法在坐标平面上动态绘制点之间的线?

    我正在完成一个项目 在该项目中我实现了一个暴力算法来解决凸包问题 我还需要为该算法创建视觉效果 我试图在 x 轴和 y 轴上创建一个范围从 100 100 的坐标平面 绘制完整集中的所有点 并在点之间动态绘制线条以创建凸包 例如 假设我有
  • RichTextFx CodeArea 中的文本背景颜色

    我正在使用 RichTextFx CodeArea 来突出显示我的代码 我想更改某些关键字的文本背景颜色并使用下面的 css parameter rtfx background color yellow But it s changes b
  • 如何在javafx中通过事件传递参数?

    我有以下示例 我想将参数 文本 与事件一起传递 当单击按钮 bla 时 我该怎么做 EventHandler
  • 使用 JSeperator - Java 时出现异常间隙

    我一直在开发 Swing GUI 并在添加后出现一些不寻常和不需要的间隙JSeperator 知道如何删除它们吗 或者任何其他选择来很好地实现这一目标 视觉描述 之前差距就很明显了JLabel 速度 及之后JSlider 相关代码 cont
  • JavaFX 使用动画最小化和最大化未装饰的舞台

    我在这个问题中使用已接受的答案 JavaFX 最小化未修饰的阶段 https stackoverflow com questions 26972683 javafx minimizing undecorated stage正确最小化我的应用
  • 像耐心/克朗代克纸牌游戏一样拖动节点

    我正在做克朗代克游戏 逻辑一切正常 我只是在使用 javafx 中的 UI 时遇到问题 我一直在尝试从 桌面堆 周围移动 拖动卡片 但没有达到预期的结果 我的卡片是一个 ImageView 里面有一个图像 这些卡片位于窗格内 Pane ta
  • Javafx-场景快照不显示值和系列

    我制作了一个非常短的应用程序 它使用 javafx 生成图表 应用程序显示正确的值 图表 但当我做快照时 图像仅显示轴和标签 但不显示系列和值 stage setTitle Line Chart Sample final DateAxis
  • 使用 TextFlow 在 TableView 中突出显示文本

    我读到 从 JavaFX 8 开始 您可以使用 TextFlow 来突出显示文本 但我不知道如何将它用于我的 TableView 在我的控制器类中 我有这个 TableView
  • 从后台线程更新可观察列表的正确方法

    我正在尝试遵循 MVC 进行测试项目 因此我的模型应该完全独立于我的观点 但是我不确定应该如何更新在后台线程中更新的可观察列表 正在给出有关上传的字符串 文件 以便消息显示在 UI 上的 ListView 中 我正在使用 JavaFX 并尝
  • 如何从我自己的线程安全地修改 JavaFX GUI 节点?

    我尝试更改线程中的 JavaFX GUI 节点 但看到以下错误 线程 Thread 8 中的异常 java lang IllegalStateException 不存在 FX应用线程 当前线程 线程 8 生成错误的示例代码 public c
  • 如何将 BufferedImage 转换/转换为图像?

    我想转换一个BufferedImage to an java awt Image 我的源图像是 tif 所以我使用 JAI 将其读取为PlanarImage PlanarImage 源 JAI create 文件加载 IMG DIR tag
  • JavaFX TabPane - 每个选项卡一个控制器

    我是 Fx 新手 我有一个带有 10 个选项卡的 TabPanel 每个选项卡都有很多控件 图表 按钮等 我想要的是为每个选项卡分配一个控制器 SceneBuilder 只让我为整个视图分配一个控制器 我的意思是 只有顶部面板 根 具有 控
  • 如何使用 Java 11 和 JavaFX 11 运行 ControlsFX 示例应用程序

    ControlFX 网站 http fxexperience com controlsfx says 如果您想使用 ControlsFX 示例应用程序 只需 下载 ControlsFX 版本并在上运行以下命令 命令提示符 请务必将 替换为实
  • 如何在JavaFX中获得一个小的ProgressBar

    我正在尝试获得一个类似 iTunes 的进度条 该进度条非常小 高度约为 5 像素 但我似乎无法低于 19 或 20 像素 我尝试在周围的窗格上设置 fx max height 但没有效果 请注意 这个值确实会改变高度 我只是不能让它小于大
  • 如何使 AnchorPane 大小响应最大化的屏幕视图

    我不知道什么是灰色地带以及如何扩展我的Anchorpane到整个屏幕Image https i stack imgur com m5HqA png 不是未最大化的视图是这样的image2 https i stack imgur com 14
  • 按日期对图表中的 X 轴进行排序 - JavaFX

    如何按日期对折线图 X 轴进行排序 现在我的折线图看起来像这样 我试图剪切日期并将其转换为 int 但现在我不知道该怎么办 datesToCompare addAll LastHoursAndDates keySet dates in St
  • SwingUtilities.invokeLater

    我的问题与SwingUtilities invokeLater 我应该什么时候使用它 每次需要更新 GUI 组件时都必须使用吗 它到底有什么作用 是否有替代方案 因为它听起来不直观并且添加了看似不必要的代码 Do I have to use
  • 在 jTextfield 中禁用“粘贴”

    我有一个用 Swing awt 编写的应用程序 我想阻止用户将值粘贴到文本字段中 有没有办法在不使用动作监听器的情况下做到这一点 您可以使用 null 参数调用 setTransferHandler 如下所示 textComponent s
  • 错误:缺少 JavaFX 运行时组件,并且需要使用 Gradle 示例来运行此应用程序

    我知道这个问题已被问过多次 但我似乎找不到解决方案 摘自官方指南示例 https openjfx io openjfx docs gradle https openjfx io openjfx docs gradle我继续添加了我的构建 g
  • KeyPressed 和 KeyTyped 混淆[重复]

    这个问题在这里已经有答案了 我搜索过之间的区别KeyPressedand KeyTyped事件 但我仍然不清楚 我发现的一件事是 Keypressed 比 KeyTyped 首先被触发 请澄清一下这些事件何时被准确触发 哪个适合用于哪个目的

随机推荐