Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8126079

Two issues/bugs with FXCollections.observableList and extractor

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 8
    • fx2.1, 7u6
    • javafx

      It seems this method does not work as expected:

      http://docs.oracle.com/javafx/2/api/javafx/collections/FXCollections.html#observableList%28java.util.List,%20javafx.util.Callback%29

      Expected result: changes to one of the Observables trigger an update change in the ListChangeListener, as described in the JavaDoc.

      However, the change does not trigger.
      See also here:
      https://forums.oracle.com/forums/thread.jspa?messageID=10447614
      (The usage seems to be correct)
      I think the problem is, that the extractor callback is not called for elements being already in the List, which you pass.


      If I use this method instead:
      http://docs.oracle.com/javafx/2/api/javafx/collections/FXCollections.html#observableArrayList%28javafx.util.Callback%29

      it works, but here is another bug:
      In the ListChangeListener, the change.wasAdded() returns true, which is wrong in my opinion. It should return false - nothing was added.
      change.wasUpdated returns also true (which is correct), all other was* methods return false (also correct).


      Sample:

      import javafx.beans.Observable;
      import javafx.beans.property.SimpleStringProperty;
      import javafx.beans.property.StringProperty;
      import javafx.collections.FXCollections;
      import javafx.collections.ListChangeListener;
      import javafx.collections.ObservableList;
      import javafx.util.Callback;

      import java.util.ArrayList;
      import java.util.List;


      public class TestApp2 {

          public static void main(String[] args) {

              System.out.println("testObservableListWithExtractor");
              testObservableListWithExtractor();

              System.out.println("testObservableArrayListWithExtractor");
              testObservableArrayListWithExtractor();

          }

          private static void testObservableListWithExtractor() {
              List<MyObservable> arrayList = new ArrayList<MyObservable>();
              arrayList.add(new MyObservable("Test"));
              arrayList.add(new MyObservable("Test2"));

              ObservableList<MyObservable> list = FXCollections.observableList(arrayList, new Callback<MyObservable, Observable[]>() {
                  @Override
                  public Observable[] call(MyObservable myTreeData) {
                      // This is only called for elements added to "list", not elements which already exist in "arrayList".
                      System.out.println("Extractor: " + myTreeData.name.get());
                      Observable[] observables = new Observable[1];
                      observables[0] = myTreeData.nameProperty();
                      return observables;
                  }
              });
              list.add(new MyObservable("Test3"));

              list.addListener(new ListChangeListener<MyObservable>() {

                  @Override
                  public void onChanged(Change change) {
                      while (change.next()) {
                          System.out.println("Added:" + change.wasAdded());
                          System.out.println("Removed:" + change.wasRemoved());
                          System.out.println("Permutated:" + change.wasPermutated());
                          System.out.println("Replaced:" + change.wasReplaced());
                          System.out.println("Updated:" + change.wasUpdated());
                      }
                  }
              });

              list.get(0).nameProperty().set("Hi");
          }

          private static void testObservableArrayListWithExtractor() {
              ObservableList<MyObservable> list = FXCollections.observableArrayList(new Callback<MyObservable, Observable[]>() {
                  @Override
                  public Observable[] call(MyObservable myTreeData) {
                      Observable[] observables = new Observable[1];
                      observables[0] = myTreeData.nameProperty();
                      return observables;
                  }
              });
              list.add(new MyObservable("Test"));
              list.add(new MyObservable("Test2"));


              list.addListener(new ListChangeListener<MyObservable>() {

                  @Override
                  public void onChanged(Change change) {
                      while (change.next()) {
                          System.out.println("Added:" + change.wasAdded());
                          System.out.println("Removed:" + change.wasRemoved());
                          System.out.println("Permutated:" + change.wasPermutated());
                          System.out.println("Replaced:" + change.wasReplaced());
                          System.out.println("Updated:" + change.wasUpdated());
                      }
                  }
              });

              list.get(0).nameProperty().set("Hi");
          }

          private static class MyObservable {

              public MyObservable(String name) {
                  this.name.set(name);
              }

              public StringProperty name = new SimpleStringProperty();

              public StringProperty nameProperty() {
                  return name;
              }
          }
      }

            msladecek Martin Sládeček
            cschudtjfx Christian Schudt (Inactive)
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported: