Używaj Platform.runLater(...)
do szybkich i prostych operacji oraz Task
do złożonych i dużych operacji.
Przykład: Dlaczego nie możemy używać Platform.runLater(...)
do długich obliczeń (wzięte z poniższego odniesienia).
Problem: Wątek w tle, który liczy od 0 do 1 miliona i aktualizuje pasek postępu w interfejsie użytkownika.
Kod przy użyciu 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();
To ohydny kawałek kodu, zbrodnia przeciwko naturze (i ogólnie programowaniu). Po pierwsze, stracisz komórki mózgowe, patrząc na podwójne zagnieżdżenie Runnables. Po drugie, kolejka wydarzeń zostanie zalana małymi Runnables - w rzeczywistości milionem z nich. Oczywiście potrzebowaliśmy interfejsu API, aby ułatwić pisanie procesów roboczych w tle, które następnie komunikują się z interfejsem użytkownika.
Kod przy użyciu zadania:
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();
nie ma żadnych wad ujawnionych w poprzednim kodzie
Odniesienie:
wątki robocze w JavaFX 2.0
Platform.runLater
: Jeśli chcesz zaktualizować komponent GUI z wątku innego niż GUI, możesz użyć tego do umieszczenia aktualizacji w kolejce i zostanie ona obsłużona przez wątek GUI tak szybko, jak to możliwe.Task
implementujeWorker
interfejs, który jest używany, gdy musisz uruchomić długie zadanie poza wątkiem GUI (aby uniknąć zamrożenia aplikacji), ale nadal potrzebujesz na pewnym etapie interakcji z GUI.Jeśli znasz Swing, pierwsza z nich jest równoważna,
SwingUtilities.invokeLater
a druga z koncepcjąSwingWorker
.Plik javadoc programu Task podaje wiele przykładów, które powinny wyjaśniać, w jaki sposób można ich używać. Możesz również zapoznać się z samouczkiem dotyczącym współbieżności .
źródło
Platform.runLater(new Runnable() {public void run() {updateYourGuiHere();}});
Można go teraz zmienić na wersję lambda
@Override public void actionPerformed(ActionEvent e) { Platform.runLater(() -> { try { //an event with a button maybe System.out.println("button is clicked"); } catch (IOException | COSVisitorException ex) { Exceptions.printStackTrace(ex); } }); }
źródło
Platform.runLater(() -> progressBar.setProgress(X/Y));
Jednym z powodów użycia jawnej Platform.runLater () może być powiązanie właściwości w interfejsie użytkownika z właściwością usługi (wyniku). Więc jeśli zaktualizujesz powiązaną właściwość usługi, musisz to zrobić za pomocą runLater ():
W wątku interfejsu użytkownika, znanym również jako wątek aplikacji JavaFX:
w implementacji usługi (praca w tle):
... Platform.runLater(() -> result.add("Element " + finalI)); ...
źródło