Bill Milagro
Bill Milagro

Reputation: 131

Why does my JavaFX have this program flow problem?

Using JavaFX and FXML I'm trying to display a screen with some basic information, and then when an HTTP call returns, update that screen. What happens instead is the screen is not displayed at all until the call returns. Below is minimum case test of the problem, with a delay meant to simulate the HTTP call.

I'd expect the screen to be displayed, the first label updated, a ten second delay, and then the second label updated. Instead, the screen isn't displayed until after the delay has finished, and that happens no matter where I put the delay. I'm hoping I'm overlooking something simple instead of having to create multiple threads to do something so simple. Below is enough code I think for anyone able to answer the problem. I can include more code if needed.

@Override
public void start(Stage stage) throws IOException {

    this.stage = stage;
    FXMLLoader loader = new FXMLLoader();
    loader.setLocation(App.class.getResource("primary.fxml"));
    anchroot = (AnchorPane) loader.load();
    // Show the scene containing the root layout.
    Scene scene = new Scene(anchroot);
    stage.setScene(scene);
    // Give the controller access to the main app.
    PrimaryController controller = loader.getController();
    controller.setMainApp(this);
    stage.show();

    //change the first label
    controller.setLabel0();

    //timer to simulate IO
    try {
        TimeUnit.SECONDS.sleep(10);
    } catch (Exception e) {
        e.printStackTrace();
    }

    //try to change the second label 10 sec later
    controller.setLabel1();

}

Upvotes: 0

Views: 109

Answers (1)

Miss Chanandler Bong
Miss Chanandler Bong

Reputation: 4258

Calling TimeUnit.SECONDS.sleep(10); will make JavaFX thread to block for 10 seconds. In this case you will not be able to see any changes in the GUI thread until the sleep period is finished. In JavaFX, you can use a Timeline to make updates after a certain period:

controller.setLabel0();
new Timeline(new KeyFrame(Duration.seconds(10), event -> controller.setLabel1())).play();

Upvotes: 2

Related Questions