7

BooleanPropertyをObservableListのすべての要素の接続詞にバインドするメソッドはありますか?

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

次のような方法はありますか?

static BooleanBinding conjunction(ObservableList<BooleanProperty> op)
4

2 に答える 2

5

JavaFX2.2プラットフォームで定義されている接続APIはありません。

BooleanBindingをサブクラス化することにより、 ConjunctionBooleanBinding(別名)を作成できます。 AllTrueBinding

新しいクラスのコンストラクターでObservableListを受け入れ、オーバーライドされたcomputeValueメソッドで低レベルのバインディング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());
  }
}
于 2012-12-07T23:18:29.170 に答える
5

このメソッドは、次のように簡単に実装できます。

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;
}
于 2014-01-15T08:56:47.230 に答える