LiveList вызывается дважды при обновлении

Я использую LiveList привязать детей группы к списку, содержащему данные детей. вот пример:

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) {
        ObservableList<Integer> intList = FXCollections.observableArrayList();
        LiveList<Circle> circleList = LiveList.map(intList, i -> {
            System.out.println("in");
            return new Circle(i);
        });

        Group group = new Group();
        Bindings.bindContent(group.getChildren(), circleList);

        intList.add(2);
        intList.clear();
    }

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

Моя проблема в том, что для каждого изменения в intList связанный список обновляется дважды и создает больше объектов, чем необходимо. Запуск кода дает:

in
in
Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: Children: duplicate children added: parent = Group@68887c42
    at javafx.scene.Parent$2.onProposedChange(Parent.java:454)
    at com.sun.javafx.collections.VetoableListDecorator$VetoableSubListDecorator.clear(VetoableListDecorator.java:529)
    at com.sun.javafx.binding.ContentBinding$ListContentBinding.onChanged(ContentBinding.java:114)
    at org.reactfx.collection.ChangeListenerWrapper.onChange(LiveList.java:439)
    at org.reactfx.collection.ChangeListenerWrapper.onChange(LiveList.java:417)
    at org.reactfx.util.ListNotifications.lambda$takeHead$0(NotificationAccumulator.java:317)
    at org.reactfx.ObservableBase.notifyObservers(ObservableBase.java:68)
    at org.reactfx.ObservableBase.notifyObservers(ObservableBase.java:57)
    at org.reactfx.collection.MappedList.sourceChanged(MappedList.java:41)
    at org.reactfx.collection.LiveList.lambda$observeQuasiChanges$7(LiveList.java:256)
    at com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(ListListenerHelper.java:164)
    at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
    at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
    at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
    at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
    at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
    at com.sun.javafx.collections.ObservableListWrapper.clear(ObservableListWrapper.java:157)
    at test1.Main.start(Main.java:27)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
    at java.lang.Thread.run(Thread.java:748)

Я хочу, чтобы для каждого элемента в intList там будет Circle в группе детей. Почему это происходит и как я могу заставить его работать должным образом?

1 ответ

Описание исключения - красная сельдь - сообщение "добавлены повторяющиеся дочерние элементы" выдается всякий раз, когда в конце изменения число дочерних элементов не соответствует ожидаемому изменению.
В вашем случае на самом деле происходит то, что круг не удаляется, поэтому Group заканчивается одним ребенком, но clear предсказал, что это должно было закончиться с 0.

Причина, по которой круг не удален, состоит в том, что он не совпадает с кругом - ваш картограф создает новый Circle объект всякий раз, когда его просят выполнить сопоставление, и поэтому вы получаете 1 кружок при его добавлении и совершенно другой при очистке списка - это новый Circle не может быть удален из группы детей, и поэтому остается с 1 ребенком даже после вызова clearвызывая исключение.

Чтобы решить эту проблему, вам нужно убедиться, что вы возвращаете один и тот же целевой объект для того же исходного объекта - это может быть невозможно, если ваш список целых чисел может содержать дубликаты.

Другие вопросы по тегам