Java 是否需要在主线程上更新属性?

Java 是否需要在主线程上更新属性?,java,javafx,Java,Javafx,我从这行代码中随机得到一个奇怪的错误: playHead.setValue(atTime)(playHead是一个SimpleObjectProperty) playHead用作Binding的一部分,GUI元素(一个TableView)依赖于它的值。这是否意味着每当更新playHead时,它都需要在主线程上 如中所示,应为: javafx.application.Platform.runLater(new Runnable() { @Override public void r

我从这行代码中随机得到一个奇怪的错误:

playHead.setValue(atTime)
(playHead是一个
SimpleObjectProperty

playHead
用作
Binding
的一部分,
GUI
元素(一个
TableView
)依赖于它的值。这是否意味着每当更新
playHead
时,它都需要在主线程上

如中所示,应为:

javafx.application.Platform.runLater(new Runnable() {
    @Override
    public void run() {
        playHead.setValue(atTime);                  
    }
});
这似乎有些奇怪,因为包含
playHead
的类应该能够独立于GUI运行。有没有办法定义绑定,使其在主线程上执行?这样,我就可以保持良好的设计实践

以下是返回绑定的
TableView
的回调:

public class CuePreWaitCallback implements Callback<TableColumn.CellDataFeatures<Cue,String>, ObservableValue<String>> {

    @Override
    public ObservableValue<String> call(final CellDataFeatures<Cue, String> param) {
        final Timeline preWait = param.getValue().getCueTimeline().getPreWait();
        return new StringBinding() {
            {
                super.bind(param.getValue().getCueTimeline().getPreWait().playhead());
                super.bind(param.getValue().getCueTimeline().getPreWait().waitTime());
            }

            @Override
            protected String computeValue() {
                try {
                    System.out.println("Value Called---------------------------------------------->");
                    return preWait.getAbsoluteDuration().subtract(preWait.getPlayhead()).toString();
                } catch (Exception e) {
                    e.printStackTrace();
                    System.exit(0);
                    return "";
                }

            }
        };
    }

}
公共类CuePreWaitCallback实现回调{
@凌驾
公共observeValue调用(最终CellDataFeatures参数){
最终时间线预等待=param.getValue().getCueTimline().getPreWait();
返回新的StringBinding(){
{
super.bind(param.getValue().getCueTimline().getPreWait().playhead());
super.bind(param.getValue().getCueTimline().getPreWait().waitTime());
}
@凌驾
受保护的字符串computeValue(){
试一试{
System.out.println(“调用的值------------------------------------------>”);
返回preWait.getAbsoluteDuration().subtract(preWait.getPlayhead()).toString();
}捕获(例外e){
e、 printStackTrace();
系统出口(0);
返回“”;
}
}
};
}
}

是的,所有与GUI有关的操作(如场景图)都必须在应用程序线程上执行,因此如果您是从后台线程更新,那么您关于使用runLater的假设是正确的

要使域逻辑独立于UI逻辑,您可以做的是在与UI相关的代码中有一种“代理”属性,它不绑定到UI中的任何内容;这比从后台线程绑定更安全。然后在代理上设置一个侦听器,在该侦听器中使用runLater更新实际的UI属性

因此,标题中问题的一般答案是“否”,只有当该属性以某种方式连接到场景图时才是“是”