Длинный работающий код никогда не следует помещать в поток приложений JavaFX, так как это приведет к зависанию GUI и перестанет отвечать на запросы.
В простых ситуациях вы можете использовать:
Executors.newSingleThreadExecutor().execute(() -> doComputation());
чтобы опубликовать работу в другой ветке и:
Platform.runLater(() -> updateDisplay());
чтобы опубликовать обновление GUI в ветке приложения.
Однако, более рекомендуемое решение - использовать Service
.
Этот класс можно расширить и предоставить метод createTask()
, который затем можно асинхронно вызывать и прослушивать ответы.
Например:
public class SortService extends Service<int[]> {
private int[] array;
public void sortArray(int[] array) {
this.array = array;
restart(); // restart() restarts the service regardless of its status
}
@Override
public Task<int[]> createTask() {
return new Task<int[]> {
@Override
protected int[] call() throws Exception {
// do your sorting and then return the result
return sortedArray;
}
}
}
}
После настройки этого класса вы можете создать экземпляр, установить массив и прослушать результаты.
SortService service = new SortService();
service.valueProperty().addListener((obs, oldValue, newValue) -> {
// run on JavaFX Application Thread, safe to update GUI
System.out.println("Hello from JavaFX Application Thread");
System.out.println(Arrays.toString(newValue));
// newValue is our sorted int[] (it is the value you return in your service's createTask())
});
service.sortArray(Arrays.asList(1, 2, 5, 4, 3)); // launch the service
Если вы хотите изменить значение во время работы вашего Service
, прежде чем вернуться, вы можете позвонить updateValue(newValue)
(возможно, вы хотите отобразить каждый этап сортировки, а не только конечный результат).