java - FXCollections.unmodifiableObservableList 的用途是什么?

标签 java javafx javafx-8

为了向我的 API 的客户端返回一个不可变的可观察列表,我使用了 FXCollections.unmodifiableObservableList(list) 包装器,如下所示:

private final ObservableList<Person> persons = FXCollections.observableArrayList();

public ObservableList<Person> getPersons() {
    return FXCollections.unmodifiableObservableList(persons);
}

但是,当客户端将 ListChangeListener 添加到返回的列表时,它不会在发生更改时收到通知。这显然是因为 FXCollections 类创建的包装器在包装列表上设置了一个弱监听器,并且这个弱监听器被垃圾收集。

我是不是漏掉了这个包装器的某些内容?

返回不可变可观察列表的正确方法是什么?

最佳答案

您走在正确的轨道上:包装器列表向包装器列表添加一个弱监听器以避免内存泄漏,如果您不持有对包装器列表的引用,它将被垃圾收集。

查看此测试(取自 here ):

private ObservableList<String> s = FXCollections.observableArrayList();

@Override
public void init() throws Exception {
    FXCollections.unmodifiableObservableList(s).addListener((ListChangeListener.Change<? extends String> c) -> 
        System.out.println(c));
    s.setAll("A1");
    s.setAll("A2");
    System.gc();
    s.setAll("A3"); // <- Doesn't trigger the listener
}

它打印:

{ [A1] added at 0 }
{ [A1] replaced by [A2] at 0 }

但是如果您添加对列表的引用:

private ObservableList<String> s = FXCollections.observableArrayList();

@Override
public void init() throws Exception {
    // create a reference 
    final ObservableList<String> wrapperList = FXCollections.unmodifiableObservableList(s); 

    wrapperList.addListener((ListChangeListener.Change<? extends String> c) -> 
        System.out.println(c));
    s.setAll("A1");
    s.setAll("A2");
    System.gc();
    s.setAll("A3"); // <- Triggers the listener
}

现在打印:

{ [A1] added at 0 }
{ [A1] replaced by [A2] at 0 }
{ [A2] replaced by [A3] at 0 }

关于java - FXCollections.unmodifiableObservableList 的用途是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44341400/

相关文章:

JavaFX 8 Spinner 控件不更新显示的值

java - 自定义 DatePicker 以选择年份和月份

Java 泛型不兼容类型(不存在类型变量 T 的实例)

Java Char 添加没有任何意义(对我来说)

JavaFX 进度指示器未正确更新

text - 如何在 javafx 2.2 中创建可编辑标签

java - 如何在 JavaFX 中嵌入 Piccolo 2D Canvas ?

java - 如何将 jar 从库项目导出到 Eclipse 中的引用项目?

java - 简化 if 语句

JavaFX——在场景中创建多个 Pane