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

时间:2013-10-13 15:57:09

标签: java javafx

我从这行代码中随机出现了一个奇怪的错误:

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 "";
                }

            }
        };
    }

}

1 个答案:

答案 0 :(得分:0)

是的,触及GUI的所有内容(例如场景图)必须在应用程序线程上执行,因此如果从后台线程更新,则关于使用runLater的假设是正确的。

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

所以标题中的问题的一般答案是“不”,只有“是”,如果该属性以某种方式连接到场景图。