在为另一个项目的UI工作时,我发现我需要运行后台任务以保持UI响应,同时在循环中更新它的元素。不知道怎么做,我做了一个测试项目,但仍然不知道如何做到这一点,它失败了,我不知道为什么。理解并解决问题,我会感激一些帮助。
这个测试应该让两个窗格每半秒交换颜色十次。它实际上在做什么取决于if语句和sleep语句。
if(i%2 == 1)
使控制台打印
Pressed
0
1
然后一两秒钟后,蓝色窗格变灰,整个停止。 当语句更改为
时if(i%2 == 0)
控制台打印相同的东西,但这次两个窗格成功交换颜色一次,然后几秒钟后都变灰。
当睡眠语句被注释掉时,一切都按预期运行(控制台至少打印出预期的东西),但很快就会发现,这就是为什么首先需要睡眠语句。
以下是代码:
public class Test extends Application{
@Override
public void start(Stage primaryStage){
HBox root = new HBox();
Pane a = new Pane();
Pane b = new Pane();
Button c = new Button("Swap");
a.setPrefSize(100, 100);
a.setStyle("-fx-background-color: grey;");
b.setPrefSize(100, 100);
b.setStyle("-fx-background-color: blue;");
c.setOnAction(event -> {
System.out.println("Pressed");
Task<Void> task = new Task<Void>() {
@Override protected Void call() throws Exception {
for(int i = 0; i < 10; ++i){
System.out.println(i);
if(i%2 == 1){
b.setStyle("-fx-background-color: grey;");
a.setStyle("-fx-background-color: blue;");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
a.setStyle("-fx-background-color: grey;");
b.setStyle("-fx-background-color: blue;");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
System.out.println("Out of loop");
return null;
}
};
new Thread(task).start();
});
root.getChildren().addAll(a, b, c);
primaryStage.setScene(new Scene(root, 300, 100));
primaryStage.show();
}
}