2012-09-24 14 views
16

sto facendo una semplice applicazione utilizzando JavaFX interfaccia utente, l'applicazione semplicemente farlo:JavaFX applicazione nel vassoio di sistema

  • ha un'icona systray, che se cliccato mostra una finestra, quando si fa clic di nuovo lo nasconde, sulla rightclick mostra un menu con 1 "uscita" voce

ho già fatto l'interfaccia utente e mettere l'App nel vassoio Sys, ma non riesco a vedere/nascondere utilizzando il metodo normale ActionListener, ma ho ottenuto questo errore:

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

ecco il codice:

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

risposta

19

Avvolgere il codice che ActionListener, che richiama a JavaFX in Platform.runLater. Questo eseguirà il codice che si interfaccia con il sistema JavaFX sul thread dell'applicazione JavaFX piuttosto che provare a farlo sul thread dell'evento Swing (che è ciò che sta causando problemi).

Ad esempio:

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

Per impostazione predefinita l'applicazione verrà shutdown when it's last window is hidden. Per ignorare questo comportamento predefinito, richiamare Platform.setImplicitExit(false) prima di mostrare la prima fase di applicazione. Dovrai quindi chiamare esplicitamente lo Platform.exit() quando hai bisogno che l'applicazione si spenga veramente.


Ho creato un demo for using the AWT system tray within a JavaFX application.

+0

Sì, ho appena scoperto che nella pagina di documentazione, thx alot. Ma quando lo nascondo, non appare di nuovo anche se uso show() – amrlab

+0

Risposta aggiornata per spiegare il comportamento di uscita implicito/esplicito. – jewelsea

+0

davvero, Thx molto, ho cercato molto per questo !! – amrlab

4

Si dovrebbe modificare solo le classi JavaFX sul filo JavaFX, gli ascoltatori sulla icona della barra sono suscettibili di essere in esecuzione sul filo swing. È possibile farlo inviando un eseguibile per piattaforma # runLater in questo modo:

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

La barra delle applicazioni non è ancora supportata in JavaFX. È possibile tenere traccia dei progressi su questa attività nel seguente problema JIRA: https://bugs.openjdk.java.net/browse/JDK-8090475
Il problema fornisce anche una soluzione alternativa, che potrebbe essere utilizzata in JavaFX 8 per ottenere il supporto di base.

La funzione non è prevista per JavaFX 8, quindi potrebbe essere rilasciato in uno dei seguenti aggiornamenti o anche in JavaFX 9.

+4

Sarebbe bello vedere il contenuto di jira senza registrarsi. – aphex

+1

Il monitoraggio delle funzionalità è ora disponibile in: https://bugs.openjdk.java.net/browse/JDK-8092115 –

Problemi correlati