2017-12-05 3 views
0

Ich verwende LiveList, um die untergeordneten Elemente einer Gruppe an eine Liste zu binden, die die Daten der untergeordneten Elemente enthält. hier ist ein Beispiel:LiveList wird beim Aktualisieren zweimal aufgerufen

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); 
    } 
} 

Mein Problem ist, dass die gebundene Liste in intList für jede Änderung zweimal aktualisiert wird und die mehr Objekte als nötig erzeugt. Ausführen des Codes gibt:

in 
in 
Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: Children: duplicate children added: parent = [email protected] 
    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) 

ich, dass in intList für jedes Element wollen wird es eine Circle in der Gruppe Kinder sein. Warum passiert das und wie kann ich es richtig funktionieren lassen?

Antwort

0

Die Beschreibung der Ausnahme ist ein Ablenkungsmanöver - die Nachricht "doppelte Kinder hinzugefügt" wird gegeben, wenn am Ende der Änderung die Anzahl der Kinder nicht übereinstimmt, was die Änderung vorhergesagt hat.
In Ihrem Fall, was tatsächlich passiert ist, dass der Kreis nicht entfernt wird, so dass die Group mit einem einzigen Kind landet, noch clear vorausgesagten es mit 0

Der Grund, warum der Kreis nicht beendet haben sollten, ist entfernt ist, dass es nicht der gleiche Kreis ist - Ihr Mapper erstellt ein neues Objekt Circle, wenn es aufgefordert wird, die Zuordnung durchzuführen, und so erhalten Sie 1 Kreis beim Hinzufügen, und eine völlig andere beim Löschen der Liste - das neue Circle kann nicht von den Kindern der Gruppe entfernt werden, und so bleibt es bei 1 Kind auch nach dem Anruf bei clear, löst die Ausnahme aus.

Um dies zu beheben, müssten Sie sicherstellen, dass Sie dasselbe Zielobjekt für das gleiche Quellobjekt zurückgeben - dies ist möglicherweise nicht möglich, wenn Ihre Liste von Integern Duplikate enthalten könnte.

+0

Aber die 2 Kreise sind 'equals()', nein? – Mordechai

+0

Warum sollten sie sein? – Itai

+0

aber warum wird die Methode zweimal aufgerufen? – Mark

Verwandte Themen