Klok
Klok

Reputation: 3

Javafx Stage.show() opens later

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

Answers (1)

fabian
fabian

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

Related Questions