2016-06-13 21 views
0

Hallo Ich habe eine Anwendung, die sowohl auf GUI (Java FX) als auch Befehlszeile ausgeführt wird. Wenn als GUI ausgeführt, zeige ich den Status im Textbereich. Das funktioniert gut.Java FX: Öffnen Popup von verschiedenen FX-Thread

Aber das Problem ist, wenn ich versuche, einen Fehler (über Popup) aus verschiedenen (nicht javafx) Klasse anzuzeigen, zeigt es mir Java Fx - Thread Ausnahme nicht auf FX-Thread.

Unten ist mein Code

Dies ist meine Java FX-Klasse, wo ich Popup zeigen wollen.

public class DeploymentProcesController implements Initializable { 


@FXML 
private TextArea statusTextArea; 

@Override 
public void initialize(URL location, ResourceBundle resources) { 

} 

public void updateGUIMessage(String message) { 
    if (Platform.isFxApplicationThread()) { 
     statusTextArea.appendText(message); 
    } else { 
     Platform.runLater(new Runnable() { 
      @Override 
      public void run() { 
       statusTextArea.appendText(message); 
      } 
     }); 
    } 
} 

public void displayAlertMessages(final String message) { 
    Platform.setImplicitExit(false); 
    Task<Void> task = new Task<Void>() { 
     @Override public Void call() { 
      Platform.runLater(new Runnable() { 
       public void run() { 
        Alert alert = new Alert(AlertType.INFORMATION, message, ButtonType.OK); 
        alert.showAndWait(); 
       } 
      }); 

      return null; 
     } 
    }; 
    new Thread(task).start(); 
} 

}

Ich habe eine nicht FX-Klasse, die der Eintrittspunkt ist. Basierend auf dem Lauftyp (Kommandozeile/GUI) aktualisiere ich den Status.

Hier ist, wie ich rufe, um den Status zu aktualisieren.

Ich habe keine Probleme, wenn ich die updateGUIMessage-Methode aus non-fx-Klasse aufrufen. Dies liegt daran, dass sich das statusArea-Element im FX-Thread (Mitglied dieser fx-Klasse) befindet.

Auch ich habe keine Probleme, eine Alarmbox auf einigen Knopf klicken, , aber um eine Alarm-Box aus einer anderen Klasse anzuzeigen- Ich habe Probleme seit, sobald ich versuche, eine Warnmeldung zu generieren, stürzt die Anwendung ab , sag nicht auf fx thread.

Ich verstehe, dass die Warnung ein Popup ist und daher möglicherweise nicht behandelt wird. Aber kann mir jemand helfen, ich möchte dem Benutzer eine Alarmbox aus verschiedenen Klassen zeigen.

+0

Jede Klasse jede JavaFX Klasse oder Methode aufrufen frei ist, aber das Anruf hat auf der Java-FX-Thread ausgeführt werden, egal welche Klasse macht die Anruf. Wenn Sie nicht möchten, dass eine bestimmte Klasse Platform importiert, schreiben Sie eine Methode in eine andere Klasse, die Platform.runLater verwendet, und rufen Sie die Methode "non fx" auf. – VGR

Antwort

0

schließlich die Lösung gefunden,

Da Java FX läuft auf einzelnen Thread, alles muss in demselben Thread sein. Für jede Aufgabe (z. B. Popup), bei der der Hintergrund angehalten werden muss, müssen wir FutureTask verwenden.

fand ich diesen Artikel hier:

JavaFX2: Can I pause a background Task/Service?

1

Alles in der Benutzeroberfläche muss vom UI-Anwendungsthread ausgeführt werden. Genau das bedeutet die Fehlermeldung.

Zum Glück können Sie einfach Ihren Anruf wickeln, so dass es in dem UI-Thread ausgeführt wird:

if(isCommandLineRun) { 
    System.out.println(simpleDateFormat.format(new Date()) + " - " + message); 
} else { 
    Platform.runLater(() -> controller.displayAlertMessages(message)); 
} 
+0

Hat nicht funktioniert, Zunächst ist promptUser-Methode in einer Java-FX-Klasse, so muss ich Plattform importieren (was ich nicht möchte - Intend JavaFX-Klassen in separate Klasse zu halten). Auch nach dem Versuch stürzt meine Anwendung ab und zeigt kein Popup. Ausnahme: java.lang.IllegalStateException: Nicht im FX-Anwendungs-Thread; currentThread = Thread-6 –

+0

Auch Plattform.runLater sollte für kleine Operationen verwendet werden, Ich möchte eine Alarmbox anzeigen, in der ich showaAndWait() verwenden werde, daher ist die Verwendung von Platform.runLater nicht ratsam –

+0

Beim Aufruf der Methode 'controller.displayAlertMessages' muss das Update durchgeführt werden auf dem UI-Thread. Sie können also den Aufruf von "Platform.runLater" auf die andere Seite verschieben und nur den Teil des Codes umbrechen, der die Benutzeroberfläche tatsächlich aktualisiert. – hotzst

Verwandte Themen