随线程一起更新场景



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

到目前为止,我有

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

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

你调用Thread.run,它在当前线程上运行Threadrun方法。您需要改用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 更新后进行计时,因为这也可能需要一些时间。

最新更新