Почему у моего JavaFX такая проблема с программным потоком? - PullRequest
0 голосов
/ 24 января 2020

Использование JavaFX и F XML Я пытаюсь отобразить экран с некоторой базовой информацией c, а затем, когда возвращается HTTP-вызов, обновить этот экран. Вместо этого происходит то, что экран вообще не отображается, пока не вернется вызов. Ниже приведен минимальный пример проверки проблемы с задержкой, предназначенной для имитации HTTP-вызова.

Я ожидаю, что будет отображен экран, обновлена ​​первая метка, задержка на десять секунд, а затем обновится вторая метка. Вместо этого экран не отображается до тех пор, пока не закончится задержка, и это происходит независимо от того, куда я положил задержку. Я надеюсь, что упускаю из виду что-то простое вместо того, чтобы создавать несколько потоков, чтобы сделать что-то такое простое. Ниже достаточно кода, я думаю, для любого, кто может ответить на проблему. Я могу включить больше кода, если это необходимо.

@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();

}

1 Ответ

2 голосов
/ 24 января 2020

При вызове TimeUnit.SECONDS.sleep(10); поток JavaFX будет заблокирован на 10 секунд. В этом случае вы не сможете увидеть никаких изменений в потоке GUI, пока не закончится период ожидания. В JavaFX вы можете использовать Timeline для обновления после определенного периода:

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