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