-
Bug
-
Resolution: Fixed
-
P4
-
fx2.1, 7u6
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;
}
}
}
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;
}
}
}