使用Platform.runLater更改非JavaFX线程中的按钮文本

时间:2019-07-10 08:50:52

标签: java javafx

我正在尝试使用Platform.runLater从非javafx线程更新按钮文本,但文本不会更改

代码:

    FXMLLoader loader = new FXMLLoader(getClass().getResource("GUI.fxml"));
    Parent root = loader.load();
    Map<String, Object> namespace = loader.getNamespace();

    Button button = (Button) namespace.get("pc");

    System.out.println("before " + button);
    Platform.runLater(() -> button.setText("test2"));
    System.out.println("after " + button);

日志:

before Button[id=pc, styleClass=button]'test1'
after Button[id=pc, styleClass=button]'test1'

1 个答案:

答案 0 :(得分:4)

在返回之前,对Platform.runLater的调用不会等待Runnable完成。来自documentation(重点是

  

在将来某个未指定的时间上,在JavaFX Application Thread上运行指定的Runnable。可以从任何线程调用此方法,该方法会将Runnable发布到事件队列中,然后然后立即返回给调用者。 Runnable将按照它们的发布顺序执行。传递给runLater方法的runnable将在传递给后续对runLater的调用的任何Runnable之前执行。如果在关闭JavaFX运行时之后调用此方法,则该调用将被忽略:不会执行Runnable并且不会引发异常。

     

...

这意味着无法保证在调用以下命令时Button的文本已被更新:

System.out.println("after " + button);

请注意,如果所有这些操作都发生在 JavaFX Application Thread 上,您仍然看不到更改。这是因为FX线程还没有机会处理Runnable,它仍然坐在事件队列中。


此外,您没有在写入text属性的FX线程和从text属性读取的后台线程之间建立先发生关系。即使FX线程在尝试将属性打印到System.out之前成功设置了属性,也不能保证您的后台线程会看到新值。