I have a class MyModel
with a property datalogEnabled
(and other ones, but let's start there) that I would like to be able to implement properly for use with UI/view binding.
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) { ... }
}
Except for snippet X, this seems right, but I'm not sure. What's getting me is that the various ways of accessing/setting/listening to the property may happen on different threads, and what I need to do is to act upon the datalogEnabled
property somewhere (do some file I/O) within my Datalogger class, on another thread besides the Swing UI thread, because I don't want the UI thread to be unresponsive.
How can I properly rewrite snippet X?
In my overall program, I have an instance of ExecutorService
. I could add an Executor
(superclass of ExecutorService
) as a constructor parameter in the MyModel
class, and do this for snippet X:
this.pcs.firePropertyChange(KEY_DATALOG_ENABLED, old, enable);
this.executor.execute(new Runnable() {
@Override public void run() { setDatalogEnabledNow(enable); }
});
Should I put the firePropertyChange
call into the deferred Runnable task as well? (is firePropertyChange supposed to be called immediately or after a property change really takes effect)
Or should the Datalogger class have an Executor
as well so it can coordinate various tasks?
I'm confused on this one....