How to implement bidirectional sinchronization between two bound properties? The utility class PropertyChangeSupport provides a trivial mechanism that avoids infinite loop. In some cases I find it to be insufficient. Is there a better alternative?
Take the simplest possible class with a String bounded property:
private String myProperty;
//obviuos getter and setter omitted. (ok, setter contains propertyChangeSupport.firePropertyChange. should be obvious the same)
public void addPropertyChangeListener(PropertyChangeListener listener) {
//delegate to propertyChangeSupport
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
//delegate to propertyChangeSupport
}
ok. Now I try to use notifications in order to perform bidirectional sincronization between this property value, owned by two instances of this class.
This is the (quite simple) code:
public static void main(String [] args) {
final T01 o1 = new T01();
final T01 o2 = new T01();
o1.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
o2.setMyProperty(o1.getMyProperty());
}
});
o2.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
o1.setMyProperty(o2.getMyProperty());
}
});
o1.setMyProperty("test");
}
Here there is no infinite loop, because the开发者_开发技巧 PropertyChangeSupport suppress the notification when it turns back to the originating class, because the oldValue is equal than the newValue.
IMHO this is a "trivial" implementation, while a better principle may be that "an event should NOT be notified to the class that has caused it".The problems with this implementation based on "equal values" are:
1. raises a unnecessary, redundant event to the originating class of the change (that THEN the originating class suppresses) 2. suppresses the event when the oldvalue equals newvalue also if it is a new one and not a "turning back" one. In most cases the suppression is correct, but in some (rare) cases the event may however be useful. Be itself "informative". Think to a timeout that has to be cleared each time an event is received. 3. it has a "strange" implementation. If you do:o1.setMyProperty(null); <br/>
you get the infinite loop and the consequent stackoverflow.
Because the event is suppressed if the values are equals AND not null. But "null" is in many cases a legitimate value.You can try jGoodies Binding Library and the PropertyConnector:
final T01 o1 = new T01();
final T01 o2 = new T01();
PropertyConnector.connect(o1, "myProperty", o2, "myProperty").updateProperty2();
Now the bound property myProperty
of o1
will be synchronized with o2
and vice versa.
精彩评论