JavaFX - Binds a property to the properties of each item in an observable collection

Is there any method that associates BooleanProperty with the conjunction of each element in an ObservableList?

ObservableList<BooleanProperty> list; list = FXCollections.observableList(new ArrayList<BooleanProperty>)); BooleanProperty emptyProperty = new SimpleBooleanProperty(); emptyProperty.bind(Bindings.conunction(list));` 

Is there a method like:

 static BooleanBinding conjunction(ObservableList<BooleanProperty> op) 
+7
source share
2 answers

There is no conjunction api defined on the JavaFX 2.2 platform.

You can create a ConjunctionBooleanBinding (aka AllTrueBinding ) by subclassing BooleanBinding .

Accept the ObservableList in the constructor of your new class and use the low-level api binding in the redefined computeValue method to set the binding value based on the logical union of all the logical values ​​in the list.

Here is an example implementation. The sample can be further optimized to work and use WeakReferences, so it does not require manual configuration.

 import javafx.beans.binding.BooleanBinding; import javafx.beans.property.BooleanProperty; import javafx.collections.*; public class AllTrueBinding extends BooleanBinding { private final ObservableList<BooleanProperty> boundList; private final ListChangeListener<BooleanProperty> BOUND_LIST_CHANGE_LISTENER = new ListChangeListener<BooleanProperty>() { @Override public void onChanged( ListChangeListener.Change<? extends BooleanProperty> change ) { refreshBinding(); } }; private BooleanProperty[] observedProperties = {}; AllTrueBinding(ObservableList<BooleanProperty> booleanList) { booleanList.addListener(BOUND_LIST_CHANGE_LISTENER); boundList = booleanList; refreshBinding(); } @Override protected boolean computeValue() { for (BooleanProperty bp: observedProperties) { if (!bp.get()) { return false; } } return true; } @Override public void dispose() { boundList.removeListener(BOUND_LIST_CHANGE_LISTENER); super.dispose(); } private void refreshBinding() { super.unbind(observedProperties); observedProperties = boundList.toArray(new BooleanProperty[0]); super.bind(observedProperties); this.invalidate(); } } 

And here is a test harness to demonstrate how it works:

 import java.util.*; import javafx.beans.property.*; import javafx.collections.FXCollections; import javafx.collections.ObservableList; public class ListBindingTest { final BooleanProperty a = new SimpleBooleanProperty(true); final BooleanProperty b = new SimpleBooleanProperty(true); final BooleanProperty c = new SimpleBooleanProperty(true); final BooleanProperty d = new SimpleBooleanProperty(true); final ObservableList<BooleanProperty> booleanList = FXCollections.observableArrayList(a, b, c, d); public static void main(String[] args) { new ListBindingTest().test(); } private void test() { AllTrueBinding at = new AllTrueBinding(booleanList); System.out.println(at.get() + forArrayString(booleanList)); b.set(false); System.out.println(at.get() + forArrayString(booleanList)); b.set(true); System.out.println(at.get() + forArrayString(booleanList)); booleanList.add(new SimpleBooleanProperty(false)); System.out.println(at.get() + forArrayString(booleanList)); booleanList.remove(3, 5); System.out.println(at.get() + forArrayString(booleanList)); at.dispose(); } private String forArrayString(List list) { return " for " + Arrays.toString(list.toArray()); } } 
+5
source

You can easily implement the method as follows:

 public static BooleanBinding conjunction(ObservableList<BooleanProperty> list){ BooleanBinding and = new SimpleBooleanProperty(true).and(list.get(0)); for(int i = 1; i < list.size(); i++){ and = and.and(list.get(i)); } return and; } 
+4
source

All Articles