gpt4 book ai didi

awt - 系统托盘中的 JavaFX 应用程序

转载 作者:行者123 更新时间:2023-12-02 04:41:45 35 4
gpt4 key购买 nike

我正在使用 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中,该监听器回调Platform.runLater中的JavaFX 。这将在 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();
}
});
}
};

默认情况下,应用程序将 shutdown when it's last window is hidden 。要覆盖此默认行为,请调用 Platform.setImplicitExit(false)在展示第一个应用程序阶段之前。然后,您需要显式调用 Platform.exit()当您需要应用程序真正关闭时。

<小时/>

我创建了一个demo for using the AWT system tray within a JavaFX application .

关于awt - 系统托盘中的 JavaFX 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12571329/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com