更新属性是否需要在主线程上进行? [英] Does updating a property need to happen on the main thread?

查看:137
本文介绍了更新属性是否需要在主线程上进行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've been getting an odd error at random times from this line of code:

playHead.setValue(atTime)(playHead是 SimpleObjectProperty

playHead.setValue(atTime) (playHead is a SimpleObjectProperty)

playHead 用作 Binding 的一部分,其中一个 GUI 元素( TableView )依赖于它的价值。这是否意味着任何时候 playHead 都会更新,它需要在主线程上吗?

playHead is used as part of a Binding which a GUI element (a TableView) relies on for its value. Does this mean that any time playHead is updated, it needs to be on the main thread?

如同,应该是:

javafx.application.Platform.runLater(new Runnable() {
    @Override
    public void run() {
        playHead.setValue(atTime);                  
    }
});

这似乎很奇怪,因为包含 playHead 应该能够独立于GUI运行。有没有办法定义绑定,以便它在主线程上执行?这样,我可以保持良好的设计实践。

This seems odd, as the class that contains the playHead should be able to function independently of the GUI. Is there any way to define the binding so that it executes on the main thread? That way, I can maintain good design practices.

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

Here is the callback for the TableView that returns the binding:

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

            }
        };
    }

}


推荐答案

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

Yes, everything that touches the GUI (e.g. the scenegraph) must be executed on the application thread, so your assumption about using runLater is correct if you are updating from a background thread.

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

What you could do to make your domain logic independent of your UI logic is to have a sort of "proxy" property in your UI related code that is not bound to anything in the UI; that than would be safe to bind from a background thread. Then set a listener on the proxy, within that listener use runLater to update the actual UI property.

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

So the general answer to the question in the title is "no", only "yes" if that property is somehow connected to the scenegraph.

这篇关于更新属性是否需要在主线程上进行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆