property improvement suggestion

Tom Eugelink tbee at tbee.org
Sun Oct 7 00:10:58 PDT 2012


As far as I understand, the current the approach is that properties should accept any value, and the usage of these properties have to work with that. Personally I'm prefer a different approach, because I feel the responsibility to have sensible values should be constrained to one place. Therefore I often override the set method of my properties to make sure the value is within the range that my remaining code expect it to be; either by throwing an exception or by clamping the value to a range.

But this I can only do with my own properties. It would be nice to also do this to existing properties and therefor I would like to suggest to extend the property concept with constraints or conditions. The important point being that these constraints are applied before the value is set, and not (like a change listener approach) afterwards and then correct value; a value should never be outside it allowed range.

The constraints or conditions could have an if-then structure: if value < 0 then 0. An example in Java 8 lambda notation:
someNode.widthProperty().*constraint*( w -> w < 0, 0);

This would also be something relevant to binding, especially when doing calculations:
someNode.widthProperty().bind( otherNode.widthProperty().substract(10).*constraint*( w -> w < 0, 0) );

There is a difference between a permanent constraint on the property and a constraint only applicable to a binding. The notation above is is too similar to my taste and too easily a binding constraint can become a property constaint. To make this difference more explicit, the word "if" could be better on binding:
someNode.widthProperty().*constraint*( w -> w < 0, 0);
someNode.widthProperty().bind( otherNode.widthProperty().substract(10).*if*( w -> w < 0, 0) );

Something to think about is how far these constraints should be taken. These are simple if-then constraints. But what if "else", "elsif" constructions or "case" statements are needed to express the range? In order to keep all options open, maybe the best approach would be to provide constraining listeners. A constraining listener would get the to-be-set value as a parameter and return the new value. For example:

widthProperty.addConstrainingListener( v -> { if (v < 0.0) return 0.0; return v; } );

or in normal notation:

widthProperty.addConstrainingListener( new ConstaintListener<Double>() {
     public Double constaint<Double>(Double value) {
         if (value < 0.0) return 0.0;
         return value;
     }
});

(NB: I'm not sure how to use Java 8 lambda with the addListener method, differentiating between a change, invalidation and constraint listener.)

This constraining listener approach would allow for all scenario's to be handled. So that is the final improvement I would like to suggest: constrainting listeners.
someNode.widthProperty().*constraint*( v -> { if (v < 0.0) return 0.0; return v; } );
someNode.widthProperty().bind( otherNode.widthProperty().substract(10).*if*( v -> { if (v < 0.0) return 0.0; return v; } ) );

And if possible normal constraints, because that is a easier notation.

I'd like to hear if I'm making sense or am missing the ball completely.

Tom


More information about the openjfx-dev mailing list