2017-02-24 9 views
0

ObservableList<Person>があるとします。ここでPersonには、年齢、性別があります。目標は、ObservableListにバインドできる Map<Gender, Map<Age, List<Person>>>のような観測可能な(すべてのレベルで)地図を作成することです。JavaFXグループ複数のパラメータによるObservableListをマップにバインドしてバインドします。

このようなグループ化に基づいてライブ集約データを抽出する必要があるためです。

+0

を使用することが可能だ場合、私はちょうど疑問に思います(乱用?) 'TreeItem'クラスはこのようなデータを表現します。ツリーアイテムのタイプを管理するのは難しいかもしれません(第1レベルのアイテムの型には 'Gender'、第2レベルには' Integer'、第3レベルには 'Person'が必要です)。 'TreeItem 'を使ってください)。しかし、利点は、['TreeItem'](http://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/TreeItem.html)はツリーの上に修正イベントを発生させるイベント構造体を定義しています集計データを最新の状態に保つためにここで必要となるものと正確に一致する可能性があります。 –

答えて

1

これは、各プロパティにリスナーを追加し、すべてのPersonのための2人のリスナーを作成しないように性質のためにBeanを指定する必要があります:

private final ObjectProperty<Gender> gender = new SimpleObjectProperty<>(this, "gender"); 
private final IntegerProperty age = new SimpleIntegerProperty(this, "age"); 
public static void main(String[] args) { 
    ObservableList<Person> data = FXCollections.observableArrayList(); 
    ObservableMap<Gender, ObservableMap<Number, ObservableList<Person>>> grouped = FXCollections.observableHashMap(); 
    ChangeListener<Gender> genderChangeListener = (observable, oldValue, newValue) -> { 
     ObservableMap<Number, ObservableList<Person>> m = grouped.get(oldValue); 
     Person person = (Person) ((Property) observable).getBean(); 

     // remove person from list and remove list, if it becomes empty 
     m.compute(person.getAge(), (a, lp) -> { 
      lp.remove(person); 
      return lp.isEmpty() ? null : lp; 
     }); 

     // remove age map, if it's empty 
     if (m.isEmpty()) { 
      grouped.remove(oldValue); 
     } 

     // add person at new position generating the Map/List, if necessary 
     grouped.computeIfAbsent(newValue, g -> FXCollections.observableHashMap()) 
       .computeIfAbsent(person.getAge(), a -> FXCollections.observableArrayList()) 
       .add(person); 
    }; 
    ChangeListener<Number> ageChangeListener = (observable, oldValue, newValue) -> { 
     Person person = (Person) ((Property) observable).getBean(); 
     ObservableMap<Number, ObservableList<Person>> map = grouped.get(person.getGender()); 

     // remove person from list and remove list, if it becomes empty 
     map.compute(oldValue, (a, lp) -> { 
      lp.remove(person); 
      return lp.isEmpty() ? null : lp; 
     }); 

     // add person at new position generating the List, if necessary 
     map.computeIfAbsent(newValue, a -> FXCollections.observableArrayList()) 
       .add(person); 
    }; 
    data.addListener((ListChangeListener.Change<? extends Person> c) -> { 
     while (c.next()) { 
      for (Person p : c.getRemoved()) { 
       // unregister the listeners of removed Persons 
       p.genderProperty().removeListener(genderChangeListener); 
       p.ageProperty().removeListener(ageChangeListener); 

       // remove person from grouped 
       ObservableMap<Number, ObservableList<Person>> m = grouped.get(p.getGender()); 
       m.compute(p.getAge(), (a, lp) -> { 
        lp.remove(p); 
        return lp.isEmpty() ? null : lp; 
       }); 
       if (m.isEmpty()) { 
        grouped.remove(p.getGender()); 
       } 
      } 
      for (Person p : c.getAddedSubList()) { 
       // add listeners to person 
       p.genderProperty().addListener(genderChangeListener); 
       p.ageProperty().addListener(ageChangeListener); 

       // add person to grouped generating the Map/List, if necessary 
       grouped.computeIfAbsent(p.getGender(), g -> FXCollections.observableHashMap()) 
         .computeIfAbsent(p.getAge(), a -> FXCollections.observableArrayList()) 
         .add(p); 
      } 
     } 
    }); 

    // test 
    Person p = new Person("Frank", Gender.MALE, 20); 
    Person p2 = new Person("Lisa", Gender.FEMALE, 32); 
    Person p3 = new Person("Nora", Gender.FEMALE, 52); 
    Person p4 = new Person("Carl", Gender.MALE, 62); 

    System.out.println(grouped); 
    data.addAll(p, p2, p3, p4); 
    System.out.println(grouped); 
    p3.setAge(32); 
    System.out.println(grouped); 
    p.setGender(Gender.FEMALE); 
    System.out.println(grouped); 
    data.remove(p3); 
    System.out.println(grouped); 
    data.remove(p4); 
    System.out.println(grouped); 
} 
関連する問題