Reputation: 3
When I run this code, stage shows after task finishing. Why does it happend? How to make a stage appear before a task?
private List<SensorEntity> detectSensors() throws URISyntaxException {
Task<List<SensorEntity>> task = new TryDetectTask(sensorForDiscover, wifiController);
ProgressIndicator indicator = new ProgressIndicator();
indicator.setProgress(ProgressIndicator.INDETERMINATE_PROGRESS);
indicator.progressProperty().bind(task.progressProperty());
Stage stage = new Stage();
stage.setHeight(100);
stage.setWidth(200);
stage.initModality(WINDOW_MODAL);
stage.setScene(new Scene(indicator));
stage.show();
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<List<SensorEntity>> futureTask = executor.submit(task, null);
try {
return futureTask.get(30, SECONDS);
}
catch (InterruptedException | ExecutionException | TimeoutException e) {
log.error(e);
e.printStackTrace();
}
executor.shutdown();
return null;
}
Same result for pane.getScene().setRoot(), alert.show(), Platform.runLater and other, but showAndWait() works fine.
Upvotes: 0
Views: 36
Reputation: 82461
futureTask.get(30, SECONDS)
blocks until the result is available or until the 30 seconds have passed. Since you're doing this on the JavaFX application thread any updates to the GUI are blocked during this time.
showAndWait
"works" since this call ensures the GUI still updates, but this method only returns when the stage is closed which means you simply freeze the GUI later.
You'd be better off passing a Consumer<List<SensorEntity>>
to the method that executes the code using the task result.
private void detectSensors(Consumer<List<SensorEntity>> consumer) throws URISyntaxException {
final boolean[] boolRef = new boolean[1];
Task<List<SensorEntity>> task = new TryDetectTask(sensorForDiscover, wifiController);
task.setOnSucceeded(evt -> {
if (!boolRef[0]) {
boolRef[0] = true;
// submit result unless timeout happened
consumer.accept(task.getValue());
}
});
ProgressIndicator indicator = new ProgressIndicator();
indicator.setProgress(ProgressIndicator.INDETERMINATE_PROGRESS);
indicator.progressProperty().bind(task.progressProperty());
Stage stage = new Stage();
stage.setHeight(100);
stage.setWidth(200);
stage.initModality(WINDOW_MODAL);
stage.setScene(new Scene(indicator));
stage.show();
// a thread does not need to be shut down
Thread thread = new Thread(task);
thread.setDaemon(true);
PauseTransition pause = new PauseTransition(Duration.seconds(30));
pause.setOnFinished(evt -> {
if (!boolRef[0]) {
boolRef[0] = true;
// submit null unless task has finished successfully
consumer.accept(null);
}
});
thread.start();
pause.play();
}
Upvotes: 1