【问题标题】:JavaFX ObservableList remove element in listener throws exceptionJavaFX ObservableList 删除侦听器中的元素引发异常
【发布时间】:2017-09-14 08:33:30
【问题描述】:

当我将侦听器附加到可观察列表并在该侦听器中尝试删除某些元素时,在某些情况下它会通过,在某些情况下它会崩溃。

场景: 项目已从列表中删除。它触发了监听器,在那个监听器中我尝试删除另一个项目。

  1. 如果在侦听器中我尝试删除不只是最初删除的元素,它可以正常工作。
  2. 如果在侦听器中我尝试删除刚刚删除的元素,它会因 UnsupportedOperationException 而崩溃!!!

有人遇到过类似的问题吗?您有任何提示、建议或解决方法吗?

我知道您可以同时删除两者,但问题是在侦听器中我需要检测我还需要删除哪些项目,所以我在那里删除 i。

这是 ObservableList 中的错误吗?

我希望它总是有效,或者至少总是崩溃。

这里是代码示例:

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class ListRemoveFromListener extends Application {

    boolean changing = false;

    @Override
    public void start(Stage primaryStage) throws Exception {
        VBox vbox = new VBox();

        Button buttonSuccess = new Button("remove success");
        buttonSuccess.setOnAction(e -> {
            removeSuccess();
        });

        Button buttonBreak = new Button("Remove breaks");
        buttonBreak.setOnAction(e -> {
            removeBreaks();
        });

        vbox.getChildren().addAll(buttonSuccess, buttonBreak);

        Scene scene = new Scene(vbox);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * If we try in listener to remove element just next to one that was
     * initially removed, exception is thrown.
     */
    private void removeBreaks() {
        ObservableList<String> list = FXCollections.observableArrayList();
        list.add("first");
        list.add("second");
        list.add("third");
        list.add("fourth");
        list.add("fifth");
        list.add("sixth");

        list.addListener(new ListChangeListener<String>() {

            @Override
            public void onChanged(Change<? extends String> c) {
                list.remove("second");
            }
        });

        list.remove("third");
    }

    /**
     * If we try in listener to remove element that is not just next to initially
     * removed element, element is removed and all works O.
     */
    private void removeSuccess() {
        ObservableList<String> list = FXCollections.observableArrayList();
        list.add("first");
        list.add("second");
        list.add("third");
        list.add("fourth");
        list.add("fifth");
        list.add("sixth");

        list.addListener(new ListChangeListener<String>() {

            @Override
            public void onChanged(Change<? extends String> c) {
                list.remove("fifth");
            }
        });

        list.remove("third");
    }

    public static void main(String[] args) {
        launch(args);
    }

}

【问题讨论】:

  • Change doc 以粗体表示:“无法在侦听器内部修改源列表”。
  • 谢谢!令人困惑的是,如果您不删除后续项目,它实际上可以正常工作。

标签: javafx javafx-8 observablelist


【解决方案1】:

ListChangeListener.Change 文档状态:

无法在监听器内部修改源列表

您可以使用Platform.runLater 调用来解决此问题,以安排在未来某个时间执行的其他更改:

list.addListener((ListChangeListener<String>) c -> {
    if (list.contains("second")) {
        Platform.runLater(() -> list.remove("second"));
    }
});

这样做时要小心,以免导致更改的级联无限循环。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-10
    • 2020-11-06
    • 2012-03-04
    相关资源
    最近更新 更多