java - JavaFX ObservableList 的回调和提取器

标签 java javafx-8

代码如下:

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/

相关文章:

Java:从列表选择监听器获取结果

java - 有没有办法获取在 Spring 应用程序/容器中配置为 bean 的所有 javax.sql.DataSource 的集合?

java - 如何本地化 JavaFX FileChooser 对话框?

java - java中的Strictfp方法有什么用?

java - 使用 Eclipse 在 Java 中生成所有可能的构造函数的更快方法

java - 如何从 Java 验证 DB2 身份验证

tableview - JavaFX : bind disable property of a button to ObservableList size

java - JAVAFX中的滚动条

javafx - JavaFX Rich Text编辑器

java - 如何将java lang中的对象添加到fxml文件中