使用JavaFX创建托盘图标

我想通过JavaFx写一个托盘图标,但我发现只能用awt编写。 有没有办法可以用JavaFx编写它?

它看起来像Windows 10中的这些托盘图标:

在此处输入图像描述

如果可以相信,JavaFX将在未来的更新中使用托盘图标。 然后坚持AWT。 在JDK错误系统上使用此线程跟踪开发。 希望这可以帮助。

您不能使用纯JavaFX,但可以将AWT与JavaFX一起使用:

 import javafx.application.*; import javafx.geometry.Pos; import javafx.scene.*; import javafx.scene.control.Label; import javafx.scene.layout.*; import javafx.scene.paint.Color; import javafx.stage.*; import javax.imageio.ImageIO; import java.io.IOException; import java.net.URL; import java.text.*; import java.util.*; // Java 8 code public class JavaFXTrayIconSample extends Application { // one icon location is shared between the application tray icon and task bar icon. // you could also use multiple icons to allow for clean display of tray icons on hi-dpi devices. private static final String iconImageLoc = "http://icons.iconarchive.com/icons/scafer31000/bubble-circle-3/16/GameCenter-icon.png"; // application stage is stored so that it can be shown and hidden based on system tray icon operations. private Stage stage; // a timer allowing the tray icon to provide a periodic notification event. private Timer notificationTimer = new Timer(); // format used to display the current time in a tray icon notification. private DateFormat timeFormat = SimpleDateFormat.getTimeInstance(); // sets up the javafx application. // a tray icon is setup for the icon, but the main stage remains invisible until the user // interacts with the tray icon. @Override public void start(final Stage stage) { // stores a reference to the stage. this.stage = stage; // instructs the javafx system not to exit implicitly when the last application window is shut. Platform.setImplicitExit(false); // sets up the tray icon (using awt code run on the swing thread). javax.swing.SwingUtilities.invokeLater(this::addAppToTray); // out stage will be translucent, so give it a transparent style. stage.initStyle(StageStyle.TRANSPARENT); // create the layout for the javafx stage. StackPane layout = new StackPane(createContent()); layout.setStyle( "-fx-background-color: rgba(255, 255, 255, 0.5);" ); layout.setPrefSize(300, 200); // this dummy app just hides itself when the app screen is clicked. // a real app might have some interactive UI and a separate icon which hides the app window. layout.setOnMouseClicked(event -> stage.hide()); // a scene with a transparent fill is necessary to implement the translucent app window. Scene scene = new Scene(layout); scene.setFill(Color.TRANSPARENT); stage.setScene(scene); } /** * For this dummy app, the (JavaFX scenegraph) content, just says "hello, world". * A real app, might load an FXML or something like that. * * @return the main window application content. */ private Node createContent() { Label hello = new Label("hello, world"); hello.setStyle("-fx-font-size: 40px; -fx-text-fill: forestgreen;"); Label instructions = new Label("(click to hide)"); instructions.setStyle("-fx-font-size: 12px; -fx-text-fill: orange;"); VBox content = new VBox(10, hello, instructions); content.setAlignment(Pos.CENTER); return content; } /** * Sets up a system tray icon for the application. */ private void addAppToTray() { try { // ensure awt toolkit is initialized. java.awt.Toolkit.getDefaultToolkit(); // app requires system tray support, just exit if there is no support. if (!java.awt.SystemTray.isSupported()) { System.out.println("No system tray support, application exiting."); Platform.exit(); } // set up a system tray icon. java.awt.SystemTray tray = java.awt.SystemTray.getSystemTray(); URL imageLoc = new URL( iconImageLoc ); java.awt.Image image = ImageIO.read(imageLoc); java.awt.TrayIcon trayIcon = new java.awt.TrayIcon(image); // if the user double-clicks on the tray icon, show the main app stage. trayIcon.addActionListener(event -> Platform.runLater(this::showStage)); // if the user selects the default menu item (which includes the app name), // show the main app stage. java.awt.MenuItem openItem = new java.awt.MenuItem("hello, world"); openItem.addActionListener(event -> Platform.runLater(this::showStage)); // the convention for tray icons seems to be to set the default icon for opening // the application stage in a bold font. java.awt.Font defaultFont = java.awt.Font.decode(null); java.awt.Font boldFont = defaultFont.deriveFont(java.awt.Font.BOLD); openItem.setFont(boldFont); // to really exit the application, the user must go to the system tray icon // and select the exit option, this will shutdown JavaFX and remove the // tray icon (removing the tray icon will also shut down AWT). java.awt.MenuItem exitItem = new java.awt.MenuItem("Exit"); exitItem.addActionListener(event -> { notificationTimer.cancel(); Platform.exit(); tray.remove(trayIcon); }); // setup the popup menu for the application. final java.awt.PopupMenu popup = new java.awt.PopupMenu(); popup.add(openItem); popup.addSeparator(); popup.add(exitItem); trayIcon.setPopupMenu(popup); // create a timer which periodically displays a notification message. notificationTimer.schedule( new TimerTask() { @Override public void run() { javax.swing.SwingUtilities.invokeLater(() -> trayIcon.displayMessage( "hello", "The time is now " + timeFormat.format(new Date()), java.awt.TrayIcon.MessageType.INFO ) ); } }, 5_000, 60_000 ); // add the application tray icon to the system tray. tray.add(trayIcon); } catch (java.awt.AWTException | IOException e) { System.out.println("Unable to init system tray"); e.printStackTrace(); } } /** * Shows the application stage and ensures that it is brought ot the front of all stages. */ private void showStage() { if (stage != null) { stage.show(); stage.toFront(); } } public static void main(String[] args) throws IOException, java.awt.AWTException { // Just launches the JavaFX application. // Due to way the application is coded, the application will remain running // until the user selects the Exit menu option from the tray icon. launch(args); } } 

代码源

要制作系统托盘,请尝试以下代码:

原始文档链接: 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(); URL url = System.class.getResource("/images/new.png"); Image image = Toolkit.getDefaultToolkit().getImage(url); final TrayIcon trayIcon = new TrayIcon(image); 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."); } 

Windows 10中的系统托盘映像示例

系统托盘程序示例

要从awt事件处理程序调用Javafx的方法,您可以采用以下方法:

 yourAwtObject.addActionListener(e -> { Platform.runLater(() -> primaryStage.show()); });