这是代码:
package sample;
import javafx.beans.Observable;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.util.Callback;
import java.util.List;
/**
* Created by IDEA on 28/07/15.
*/
public class ListUpdateTest {
public static void main(String[] args) {
Callback<IntegerProperty, Observable[]> extractor = (IntegerProperty p) -> {
System.out.println("The extractor is called.");
Observable[] res = new Observable[]{p};
System.out.println("Result from extractor: " + res);
return res;
};
ObservableList<IntegerProperty> list = FXCollections.observableArrayList(extractor);
System.out.printf("Before adding");
IntegerProperty p1 = new SimpleIntegerProperty(10);
IntegerProperty p2 = new SimpleIntegerProperty(20);
list.addAll(p1, p2);
System.out.println("After adding");
list.addListener(new ListChangeListener<IntegerProperty>() {
@Override
public void onChanged(Change<? extends IntegerProperty> c) {
System.out.println("List is " + c.getList());
while (c.next()) {
if (c.wasUpdated()) {
System.out.println("An update is detected.");
int start = c.getFrom();
int end = c.getTo();
System.out.println(
String.format("Updated range: %d to %d",
start, end)
);
List<? extends IntegerProperty> updatedElementsList;
updatedElementsList = c.getList().subList(start, end);
System.out.println("Updated elements: " + updatedElementsList);
}
}
}
});
p1.set(100);
}
}
extractor
的作用是什么,为什么在这里需要它? 最佳答案
无论列表是否由提取器创建,ObservableList
都会在将项目添加到列表或从列表中删除时触发更改事件。
但是,如果列表中的项是可观察属性或包含对可观察属性的引用,则只有当这些属性更改时,列表才会触发更新,前提是该属性是使用提取器构造的,该提取器返回包含对这些属性的引用的数组。
这应该显示出差异:
import javafx.beans.Observable;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ListChangeListener.Change;
import javafx.collections.ObservableList;
public class ListExtractorDemo {
public static void main(String[] args) {
ObservableList<IntegerProperty> listWithoutExtractor =
FXCollections.observableArrayList();
ObservableList<IntegerProperty> listWithExtractor =
FXCollections.observableArrayList(p -> new Observable[]{p});
listWithoutExtractor.addListener(createListener("listWithoutExtractor"));
listWithExtractor.addListener(createListener("listWithExtractor"));
IntegerProperty p1 = new SimpleIntegerProperty(1);
IntegerProperty p2 = new SimpleIntegerProperty(2);
// both lists will fire change events when items are added or removed:
listWithoutExtractor.addAll(p1, p2);
listWithExtractor.addAll(p1, p2);
// only the list with the extractor will fire a change event when the observable value of an element changes:
p2.set(3);
}
private static ListChangeListener<IntegerProperty> createListener(String listId) {
return (Change<? extends IntegerProperty> c) -> {
while (c.next()) {
if (c.wasAdded()) {
System.out.println(listId + " added: "+c.getAddedSubList());
}
if (c.wasRemoved()) {
System.out.println(listId + " removed: "+c.getRemoved());
}
if (c.wasUpdated()) {
System.out.println(listId + " updated");
}
}
};
}
}
一个典型的用例是@kleopatra对JavaFX 2.0 Choice Box Issue. How to update a choiceBox, which represents a list of objects, when an object is updated?的回答
关于java - JavaFX ObservableList的回调和提取器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31687642/