与线程一起更新场景

时间:2018-03-12 06:34:31

标签: java javafx

我正在尝试让一个场景逐步显示对我在一个线程中定期更新的类实例所做的更改。

到目前为止我已经

 public void start(Stage primaryStage) {   
    Environment env = new Environment(10, 10);
    StackPane layout = new StackPane();

    primaryStage.setTitle("Vacuum World");
    Button btn = new Button();
    btn.setText("Start");

    Text text = new Text();

    btn.setOnAction(new EventHandler<ActionEvent>() {
        public void handle(ActionEvent event) {
            Thread t = new updateThread(env, text);
            t.run();
        }
    });

    layout.getChildren().add(btn);
    layout.getChildren().add(text); 
    primaryStage.setScene(new Scene(layout));
    primaryStage.show();
}

和有问题的话题:

public class updateThread extends Thread {
    Environment env;
    Text text;

    public updateThread(Environment env, Text text) {
        this.env = env;
        this.text = text;
    }

    public void run() {
        int updatesPerSecond = 2;
        int nbUpdates = 0;
        int targetTime = 1000 / updatesPerSecond;
        long currentTime;
        long lastTime = System.nanoTime();
        long elapsedTime;
        long sleepTime;

        while (nbUpdates < 10) {
            currentTime = System.nanoTime();

            elapsedTime = currentTime - lastTime;
            lastTime = currentTime;

            this.env.update();
            text.setText(this.env.show());

            nbUpdates++;
            sleepTime = targetTime - (elapsedTime / 1000000000);

            if (sleepTime < 0) {
                sleepTime = 1;
            }

            try {
                Thread.sleep(sleepTime);
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    }
}

我最终得到的是按下按钮后,线程运行并正确更新环境,但场景仅在线程完成运行后更改一次,并且在线程运行时不更新。关于如何获得我追求的结果的任何想法?

1 个答案:

答案 0 :(得分:1)

您致电Thread.run,在 当前主题 上运行Thread run方法。您需要使用Thread.start来创建新线程。

此外,应使用Platform.runLater

完成其他线程的更新
...
this.env.update();
final String newText = this.env.show();
Platform.runLater(() -> text.setText(newText))
...

另请注意,纳秒为10^-9秒= 10^-6毫秒。您应该除以1_000_000而不是1_000_000_000,并且可能会在环境/ UI更新后进行计时,因为这可能需要一些时间。