Verwendung Platform.runLater(...)
für schnelle und einfache Operationen sowie Task
für komplexe und große Operationen.
Beispiel: Warum können wir nicht Platform.runLater(...)
für lange Berechnungen verwenden (entnommen aus der folgenden Referenz).
Problem: Hintergrund-Thread, der nur von 0 bis 1 Million zählt und den Fortschrittsbalken in der Benutzeroberfläche aktualisiert.
Code mit Platform.runLater(...)
:
final ProgressBar bar = new ProgressBar();
new Thread(new Runnable() {
@Override public void run() {
for (int i = 1; i <= 1000000; i++) {
final int counter = i;
Platform.runLater(new Runnable() {
@Override public void run() {
bar.setProgress(counter / 1000000.0);
}
});
}
}).start();
Dies ist ein schrecklicher Teil des Codes, ein Verbrechen gegen die Natur (und die Programmierung im Allgemeinen). Erstens verlieren Sie Gehirnzellen, wenn Sie nur diese doppelte Verschachtelung von Runnables betrachten. Zweitens wird es die Ereigniswarteschlange mit kleinen Runnables überschwemmen - eine Million davon sogar. Natürlich brauchten wir eine API, um das Schreiben von Hintergrundarbeitern zu vereinfachen, die dann wieder mit der Benutzeroberfläche kommunizieren.
Code mit Aufgabe:
Task task = new Task<Void>() {
@Override public Void call() {
static final int max = 1000000;
for (int i = 1; i <= max; i++) {
updateProgress(i, max);
}
return null;
}
};
ProgressBar bar = new ProgressBar();
bar.progressProperty().bind(task.progressProperty());
new Thread(task).start();
es leidet an keinem der Fehler, die im vorherigen Code gezeigt wurden
Referenz:
Worker Threading in JavaFX 2.0
Platform.runLater
: Wenn Sie eine GUI-Komponente von einem Nicht-GUI-Thread aktualisieren müssen, können Sie damit Ihr Update in eine Warteschlange stellen. Es wird so schnell wie möglich vom GUI-Thread verarbeitet.Task
Implementiert dieWorker
Schnittstelle, die verwendet wird, wenn Sie eine lange Aufgabe außerhalb des GUI-Threads ausführen müssen (um ein Einfrieren Ihrer Anwendung zu vermeiden), aber dennoch irgendwann mit der GUI interagieren müssen.Wenn Sie mit Swing vertraut sind, entspricht
SwingUtilities.invokeLater
das erstere dem Konzept von und das letztere dem Konzept vonSwingWorker
.Das Javadoc von Task enthält viele Beispiele, die verdeutlichen sollen, wie sie verwendet werden können. Sie können sich auch auf das Tutorial zur Parallelität beziehen .
quelle
Platform.runLater(new Runnable() {public void run() {updateYourGuiHere();}});
Es kann jetzt auf Lambda-Version geändert werden
quelle
Platform.runLater(() -> progressBar.setProgress(X/Y));
Ein Grund für die Verwendung einer expliziten Platform.runLater () könnte sein, dass Sie eine Eigenschaft in der Benutzeroberfläche an eine Service- (Ergebnis-) Eigenschaft gebunden haben. Wenn Sie also die Eigenschaft des gebundenen Dienstes aktualisieren, müssen Sie dies über runLater () tun:
Im UI-Thread, der auch als JavaFX-Anwendungsthread bezeichnet wird:
in der Service-Implementierung (Hintergrundarbeiter):
quelle