2012-12-07 6 views
7

ObservableListのすべての要素の論理和にBooleanPropertyをバインドするメソッドは存在しますか?JavaFX - オブザーバブルのすべての要素のプロパティへのプロパティのバインド

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

などの方法があります:JavaFXの2.2プラットフォームで定義されたconjunction APIはありません

static BooleanBinding conjunction(ObservableList<BooleanProperty> op) 

答えて

5

が。

BooleanBindingをサブクラス化してConjunctionBooleanBinding(別名AllTrueBinding)を作成することができます。

は、新しいクラスのコンストラクタで ObservableListを受け入れ、論理的に一緒にリスト内のブール値の全てをAND演算に基づいて結合値を設定するためにオーバーライド computeValue方法で low level binding apiを使用しています。

ここに実装例があります。このサンプルはさらにパフォーマンスを最適化し、WeakReferencesを使用することができますので、手動で処理する必要はありません。

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(); 
    } 
} 

そして、ここではそれがどのように機能するかを実証するためのテストハーネスです:

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()); 
    } 
} 
+0

おかげで、私はあなたのアドバイスを使用。 – dpelisek

4

次のように、簡単にメソッドを実装することができます

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; 
} 
関連する問題