javafx.beans.binding.Bindings.select*(ObservableValue<?> root, java.lang.String... steps):
to select some chain of properties one should write something like:
BooleanBinding bb = Bindings.selectBoolean(control.sceneProperty(), "window", "isShowing");
When having templates and lambdas this API looks legacy. This kind of usage is not type-safe, may lead to runtime errors and involves reflection in the implementation.
The idea is to use type-safe functional-style 'selector' like this:
@FunctionalInterface
public interface Selector<T, E> {
ObservableValue<E> selectValue(T t);
}
and the helper interface (class):
public interface SelectElement<E> {
<K> SelectElement<K> select(Selector<E, K> p);
<K extends Boolean> BooleanBinding selectBoolean(Selector<E, K> p);
<K extends Integer> IntegerBinding selectInteger(Selector<E, K> p);
<K extends Long> LongBinding selectLong(Selector<E, K> p);
<K extends Float> FloatBinding selectFloat(Selector<E, K> p);
<K extends Double> DoubleBinding selectDouble(Selector<E, K> p);
<K extends String> StringBinding selectString(Selector<E, K> p);
<K> ObjectBinding selectObject(Selector<E, K> p);
}
The new Bindings method replacing all select*() methods:
publci static <E> SelectElement<E> select(ObservableValue<E> o);
With the new API the example above would look like:
BooleanBinding bb = Bindings.select(control.sceneProperty()).
select(s -> s.windowProperty()).
selectBoolean(w -> w.showingProperty());
The benefits of the new API:
* Static type checking - no chances for a mistake when selecting long
chain of properties
* IDE code assisting for property selection
* not restricted to properties only, but might be used with any
observable. I.e. one may want to select an element from observable
collection at any selection step
* might be implemented without reflection, which may result in some
performance gain
to select some chain of properties one should write something like:
BooleanBinding bb = Bindings.selectBoolean(control.sceneProperty(), "window", "isShowing");
When having templates and lambdas this API looks legacy. This kind of usage is not type-safe, may lead to runtime errors and involves reflection in the implementation.
The idea is to use type-safe functional-style 'selector' like this:
@FunctionalInterface
public interface Selector<T, E> {
ObservableValue<E> selectValue(T t);
}
and the helper interface (class):
public interface SelectElement<E> {
<K> SelectElement<K> select(Selector<E, K> p);
<K extends Boolean> BooleanBinding selectBoolean(Selector<E, K> p);
<K extends Integer> IntegerBinding selectInteger(Selector<E, K> p);
<K extends Long> LongBinding selectLong(Selector<E, K> p);
<K extends Float> FloatBinding selectFloat(Selector<E, K> p);
<K extends Double> DoubleBinding selectDouble(Selector<E, K> p);
<K extends String> StringBinding selectString(Selector<E, K> p);
<K> ObjectBinding selectObject(Selector<E, K> p);
}
The new Bindings method replacing all select*() methods:
publci static <E> SelectElement<E> select(ObservableValue<E> o);
With the new API the example above would look like:
BooleanBinding bb = Bindings.select(control.sceneProperty()).
select(s -> s.windowProperty()).
selectBoolean(w -> w.showingProperty());
The benefits of the new API:
* Static type checking - no chances for a mistake when selecting long
chain of properties
* IDE code assisting for property selection
* not restricted to properties only, but might be used with any
observable. I.e. one may want to select an element from observable
collection at any selection step
* might be implemented without reflection, which may result in some
performance gain
- relates to
-
JDK-8274771 Map, FlatMap and OrElse fluent bindings for ObservableValue
- Resolved
-
JDK-8091396 Provide default value for select, valueAt methods
- Open