Intercept Property Binding

Following situation:

DoubleProperty p1 = new SimpleDoubleProperty(1.0);
DoubleProperty p2 = new SimpleDoubleProperty(5.5);

p1.bind(p2);

Is it somehow possible to modify this straight-forward way to intercept the value setting process in order to modify the set value?

2 answers

  • answered 2017-10-19 12:39 Lino

    If SimpleDoubleProperty is not final you can override the bind() function as follows and create an anonymous subclass:

    DoubleProperty p1 = new SimpleDoubleProperty(1.0){
        @Override
        public void bind(DoubleProperty property){
            // do your interception-magic here
        }
    };
    

  • answered 2017-10-19 12:39 James_D

    If you just want to perform simple arithmetic on the value, you can use the bindings API, which supports a pretty rich set of arithmetic functions:

    p1.bind(p2.multiply(p2).add(1));
    

    will make sure that p1 is always equal to p2*p2+1 (just as an arbitrary example), and

    p1.bind(Bindings
        .when(p2.lessThan(0))
        .then(0)
        .otherwise(p2));
    

    will ensure that p1 is always equal to p2 when p2 is non-negative, and p1 is zero otherwise.

    If that doesn't suffice for your needs, you can use a custom binding, for example:

    p1.bind(Bindings.createDoubleBinding(() -> {
        double p2Value = p2.getValue();
        double interceptedValue = ... ;
        return interceptedValue ;
    }, p2);
    

    The last argument is a varargs of Observable, so you can list any properties (or other observables) there that you want to trigger an invalidation of the binding.

    An equivalent way is to subclass DoubleBinding:

    p1.bind(new DoubleBinding() {
        {
            bind(p2); // and to other properties if needed...
        }
    
        @Override
        protected double computeValue() {
            double p2Value = p2.getValue();
            double interceptedValue = ... ;
            return interceptedValue ;
        }
    });