我注意到Platform.runLater()在运行后没有立即更新舞台/屏幕,因此我猜测这幅画正在其他地方或其他排队的事件中发生。在运行完成后,我对在屏幕上实际绘制或渲染的时间或方式排队或发出信号感到好奇。
以下代码将1.begin, 1.end, 2.begin, 2.end, 3.begin, 3.end
打印到控制台,但标签从不显示1
,但第二个runLater()等待。
package main;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.concurrent.Task;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.util.concurrent.CountDownLatch;
public class SmallRunLater extends Application {
SimpleStringProperty labelValue = new SimpleStringProperty("0");
@Override
public void start(Stage stage) throws InterruptedException {
Scene scene = new Scene(new Group());
stage.setWidth(550);
stage.setHeight(550);
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
Label label = new Label();
label.textProperty().bind(labelValue);
Button startBtn = new Button("Start");
vbox.getChildren().addAll(startBtn, label);
startBtn.setOnAction((action) -> {
try {
Task task = new Task<Void>() {
@Override
protected Void call() throws Exception {
SmallWork work = new SmallWork();
work.doWork(labelValue);
return null;
}
};
new Thread(task).start();
} catch (Exception e) {
e.printStackTrace();
}
});
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
class SmallWork {
public void doWork(SimpleStringProperty labelValue) throws InterruptedException {
Platform.runLater(() -> {
System.out.println("1.begin");
labelValue.set("1");
System.out.println("1.end");
});
runNow(() -> {
System.out.println("2.begin");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
labelValue.set("2");
System.out.println("2.end");
});
Platform.runLater(() -> {
System.out.println("3.begin");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
labelValue.set("3");
System.out.println("3.end");
});
}
public static void runNow(Runnable r){
final CountDownLatch doneLatch = new CountDownLatch(1);
Platform.runLater(() -> {
try {
r.run();
} catch (Exception e) {
e.printStackTrace();
} finally {
doneLatch.countDown();
}
});
try {
doneLatch.await();
} catch (Exception e) {
e.printStackTrace();
}
}
}
答案 0 :(得分:3)
是的,你是对的,Platform.runLater()
(如名称所示)不会立即运行,只是将Runnable
推送到内部队列。内部渲染刻度深入。 Runnable
对象将在渲染之前的更新标记中执行。标签从未显示&#34; 1&#34;简单地与你的runNow()
被立即调用的事实相吻合,因此两个Runnable
对象被推送到同一队列并在JavaFX
内部循环内的相同时钟中执行。因此,会发生以下情况:
我已尝试运行上面的代码,有时我可以看到1,这意味着两个Runnable
对象被推入不同的刻度。这样的事情: