JavaFX ObservableList的回调和提取器

这是代码:

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 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 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() { @Override public void onChanged(Change 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 updatedElementsList; updatedElementsList = c.getList().subList(start, end); System.out.println("Updated elements: " + updatedElementsList); } } } }); p1.set(100); } } 

什么是extractor ,为什么我们需要它?

ObservableList将在列表中添加和删除项目时触发更改事件,无论是否使用提取程序创建项目。

但是,如果列表中的项目是或者包含对可观察属性的引用,则列表将在这些属性更改时触发更新,只有在使用提取器构造时才会更新,该提取器返回包含对这些属性的引用的数组。

这应该certificate了区别:

 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 listWithoutExtractor = FXCollections.observableArrayList(); ObservableList 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 createListener(String listId) { return (Change 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的回答。 如何在更新对象时更新表示对象列表的choiceBox?