What makes a model change get propagated via JFace databinding?
In order to understand how JFace databindings is working, I have a model object with two properties. Changing one property should set the other to the same value:
public class Model {
private double x;
private double y;
private PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);
public void addPropertyChangeListener(String propertyName,
PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(listener);
}
public void setX(double x) {
propertyChangeSupport.firePropertyChange("x", this.x, this.x = x);
}
public double getX() {
return x;
}
public void setY(double y) {
propertyChangeSupport.firePropertyChange("y", y, this.y = y);
setX(y);
}
public double y() {
return y;
}
}
Now in a separate class I define two Text widgets, xText
and yText
, which are bound to this object like this:
DataBindingContext bindingContext = new DataBindingContext();
bindingContext.bindValue(WidgetProperties.text(SWT.Modify).observe(xText),
BeanProperties.value(HumidityScanParameters.class,"x").observe(getModel()));
bindingContext.bindValue(WidgetProperties.text(SWT.Modify).observe(yText),
BeanProperties.value(HumidityScanParameters.class, "y").observe(getModel()));
I have found that if I change the text in yText
, then the setter is automatically called as expected, and this sets both y
and x
in the model. However, xText
is not updated. Why is this? Shouldn't the firePropertyChange()
call arrange for the Text to be updated?
Thanks, Graham.
The compiler was optimising away the initial value of this.x
and this.y
, which led the PropertyChangeSupport
instance to discard the change notification. It didn't think anything had changed. If I introduce a temporary variable like this:
public void setX(double x) {
double oldValue = this.x;
this.x = x;
propertyChangeSupport.firePropertyChange("x", oldValue, x);
}
then the notifications occur as I might expect.
I guess it's because you put this.x
to your event before haveing it updated properly.
Try this:
public void setX(double x) {
this.x = x; // update the model!
propertyChangeSupport.firePropertyChange("x", this.x, x);
}
(see comments ;-) )
精彩评论