2012-09-24 26 views
16

Tôi Làm một App đơn giản sử dụng JavaFX UI, Ứng dụng đơn giản chỉ làm điều đó:ứng dụng JavaFX trong System Tray

  • có một biểu tượng ở khay hệ thống, mà khi nhấp thấy một cửa sổ, khi nhấp một lần nữa giấu nó, trên rightclick hiển thị menu có mục "thoát" 1 số

Tôi đã tạo giao diện người dùng và đặt ứng dụng vào khay Sys, nhưng tôi không thể hiển thị/ẩn nó bằng phương thức Normal Actionlistener, nhưng tôi gặp lỗi này:

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

đây là Code:

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"); 
      } 
     // 
    } 
} 

Trả lời

19

Bó mã trong ActionListener trong đó kêu gọi trở về JavaFX trong Platform.runLater. Điều này sẽ thực thi mã mà giao diện với hệ thống JavaFX trên chuỗi ứng dụng JavaFX thay vì cố gắng thực hiện nó trên luồng sự kiện Swing (đó là những gì đang gây ra cho bạn các vấn đề).

Ví dụ:

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

Theo mặc định, ứng dụng sẽ shutdown when it's last window is hidden. Để ghi đè hành vi mặc định này, hãy gọi Platform.setImplicitExit(false) trước khi bạn hiển thị Giai đoạn ứng dụng đầu tiên. Sau đó, bạn sẽ cần gọi rõ ràng Platform.exit() khi bạn cần ứng dụng thực sự tắt máy.


Tôi đã tạo một demo for using the AWT system tray within a JavaFX application.

+0

Vâng, tôi chỉ thấy rằng trong trang Tài liệu, thx rất nhiều. Nhưng khi tôi ẩn nó, nó không xuất hiện trở lại ngay cả khi tôi sử dụng show() – amrlab

+0

Câu trả lời được cập nhật để giải thích hành vi ngầm định/thoát. – jewelsea

+0

thực sự, Thx rất nhiều, tôi đã tìm kiếm rất nhiều cho điều này !! – amrlab

4

Bạn chỉ nên sửa đổi các lớp JavaFX trên thread JavaFX, người nghe vào biểu tượng trên khay có thể sẽ được chạy trên sợi xích đu. Bạn có thể làm điều này bằng cách đăng một Runnable đến nền tảng # runLater như vậy:

Platform.runLater(new Runnable() { 
    public void run() { 
     primaryStage.hide(); 
    } 
}); 
1

Khay hệ thống chưa được hỗ trợ trong JavaFX. Bạn có thể theo dõi tiến trình của tác vụ này theo vấn đề JIRA sau: https://bugs.openjdk.java.net/browse/JDK-8090475
Vấn đề này cũng cung cấp cách giải quyết, có thể được sử dụng trong JavaFX 8 để nhận hỗ trợ cơ bản.

Tính năng này không được lên kế hoạch cho JavaFX 8, vì vậy nó có thể được phát hành trong một trong các bản cập nhật sau hoặc thậm chí trong JavaFX 9.

+4

Sẽ rất tuyệt khi xem nội dung jira mà không cần đăng ký. – aphex

+1

Theo dõi tính năng hiện có tại: https://bugs.openjdk.java.net/browse/JDK-8092115 –

Các vấn đề liên quan