Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bidirectional beans synchronization

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.

like image 445
AgostinoX Avatar asked Feb 20 '26 09:02

AgostinoX


1 Answers

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.

like image 142
Uhlen Avatar answered Feb 22 '26 21:02

Uhlen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!