正确编写具有用于视图绑定的属性的模型

时间:2010-09-23 14:31:25

标签: java swing concurrency

我有一个类MyModel,其中包含一个属性datalogEnabled(和其他一些,但让我们从那里开始),我希望能够正确实现它以用于UI /视图绑定。

public class MyModel  { 
    static final String KEY_DATALOG_ENABLED = "datalogEnabled";
    final private PropertyChangeSupport pcs = new PropertyChangeSupport(this); 
    final private Object syncLock = new Object();   
    final private Datalogger datalogger = new Datalogger();

    public void addPropertyChangeListener(PropertyChangeListener pcl)
    {
        this.pcs.addPropertyChangeListener(pcl);
    }
    public void removePropertyChangeListener(PropertyChangeListener pcl)
    {
        this.pcs.removePropertyChangeListener(pcl);
    }    
    public boolean isDatalogEnabled() 
    {
        synchronized (this.syncLock) 
        {
            return this.datalogEnabled; 
        }
    }
    public void setDatalogEnabled(final boolean enable) {
        boolean old;
        synchronized (this.syncLock) {
            old = this.datalogEnabled;
            this.datalogEnabled=enable;             
        }
            /* begin snippet X: this is wrong for threading reasons */
        this.pcs.firePropertyChange(KEY_DATALOG_ENABLED, old, enable);      
            setDatalogEnabledNow(enable);
            /* end snippet X */
    }   
    setDatalogEnabledNow(boolean b)
    {
        this.datalogger.setEnable(b);
    }
    /* other methods */
}

public class Datalogger() { 
    public void setEnable(boolean enable) { ... }
}

除了代码片段X,这个似乎正确,但我不确定。让我感到震惊的是,访问/设置/监听属性的各种方式可能发生在不同的线程上,而我需要做的是在某处(在一些文件I / O中执行)datalogEnabled属性我的Datalogger类,在Swing UI线程之外的另一个线程上,因为我不希望UI线程无响应。

如何正确重写代码段X?

在我的整体计划中,我有一个ExecutorService的实例。我可以在ExecutorService类中添加ExecutorMyModel的超类)作为构造函数参数,并为代码段X执行此操作:

this.pcs.firePropertyChange(KEY_DATALOG_ENABLED, old, enable);      
this.executor.execute(new Runnable() {
     @Override public void run() { setDatalogEnabledNow(enable); }
});

我是否应该将firePropertyChange调用放入延迟的Runnable任务中? (应该立即调用firePropertyChange,或者在属性更改后真正生效)

或者Datalogger类也应该有一个Executor,以便它可以协调各种任务吗?

我对这个感到困惑....

1 个答案:

答案 0 :(得分:1)

模型的侦听器可以是uis组件或域组件。如果一个监听器是一个ui组件,它必须在edt上运行,而不是在监听器是域的情况下运行。

该事件来自ui组件或域组件。如果事件来自ui组件,则fire方法位于edt上,如果事件来自域,则不是。

所以它有点复杂......我的观点是每个听众应该为自己工作:如果不是,ui听众会继续使用edt,如果不存在,则域名不会。所以fire方法保留在它的原始线程上。

2 cts。