Используйте Platform.runLater(...)
для быстрых и простых операций, а также Task
для сложных и больших операций.
Пример: Почему нельзя использовать Platform.runLater(...)
для долгих расчетов (взято из ссылки ниже).
Проблема: фоновый поток, который просто считает от 0 до 1 миллиона и обновляет индикатор выполнения в пользовательском интерфейсе.
Код с использованием 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();
Это отвратительный кусок кода, преступление против природы (и программирования в целом). Во-первых, вы потеряете клетки мозга, просто глядя на это двойное вложение Runnables. Во-вторых, очередь событий заполнится маленькими Runnables - на самом деле миллионом. Ясно, что нам нужен был некоторый API, чтобы упростить написание фоновых рабочих, которые затем взаимодействуют с пользовательским интерфейсом.
Код с использованием задачи:
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();
он не страдает ни одним из недостатков, представленных в предыдущем коде
Ссылка:
Worker Threading в JavaFX 2.0
Platform.runLater
: Если вам нужно обновить компонент графического интерфейса пользователя из потока, отличного от графического интерфейса, вы можете использовать это, чтобы поместить свое обновление в очередь, и оно будет обработано потоком графического интерфейса как можно скорее.Task
реализуетWorker
интерфейс, который используется, когда вам нужно запустить длинную задачу вне потока графического интерфейса пользователя (чтобы избежать зависания приложения), но на каком-то этапе все еще необходимо взаимодействовать с графическим интерфейсом.Если вы знакомы с Swing, первый эквивалент,
SwingUtilities.invokeLater
а второй - концепцииSwingWorker
.В javadoc Task есть много примеров, которые должны прояснить, как их можно использовать. Вы также можете обратиться к руководству по параллелизму .
источник
Platform.runLater(new Runnable() {public void run() {updateYourGuiHere();}});
Теперь его можно изменить на лямбда-версию
@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); } }); }
источник
Platform.runLater(() -> progressBar.setProgress(X/Y));
Одна из причин использования явного Platform.runLater () может заключаться в том, что вы связали свойство в пользовательском интерфейсе со свойством службы (результата). Поэтому, если вы обновляете свойство привязанной службы, вы должны сделать это через runLater ():
В потоке пользовательского интерфейса, также известном как поток приложения JavaFX:
в реализации Сервиса (фоновый работник):
... Platform.runLater(() -> result.add("Element " + finalI)); ...
источник