Element aus comboBox mit observableList löschen

WSchubert

Neues Mitglied
Guten Tag Forum!

Ich beschäftige mich gerade mit einem JavaFX-Projekt und bin Anfänger.
Folgendes Ziel habe ich:
In der comboBoxLK1 soll aus der observableList "items" ein Element ausgewählt werden. Dieses gewählte Element soll dann aus der observableList "items" entfernt werden. Dann soll die comboBoxLK1 deaktiviert werden. Dann soll die comboBoxLK2 mit der aktualisierten observableList "items" aktiviert werden, um dann auch hier ein Element aus "items" zu wählen. Dies soll dann noch für weitere comboBoxen so durchgeführt werden.
Ich möchte also aus der observableList "items" kein fixes Element löschen, sondern das Element, das in der ComboBox gewählt wurde.
Dies scheint nicht richtig zu funktionieren. Mein Eindruck ist, dass beim Löschen die setonAction für die comboBox nochmals durchgeführt wird. In Schleife sozusagen.

Hier der Code:

Java:
ComboBox<String> comboBoxLK1 = new ComboBox<>();
         ObservableList<String> items = FXCollections.observableArrayList();
         items.addAll("Rot", "Gelb", "Grün", "Blau", "Schwarz", "Lila");
        
         comboBoxLK1.setItems(items);
        
         ComboBox<String> comboBoxLK2 = new ComboBox<>();
        
         comboBoxLK2.setDisable(true);
        
         comboBoxLK1.setOnAction((event) -> {
             int selectionIndexLK1 = comboBoxLK1.getSelectionModel().getSelectedIndex();
             Object selectionItemLK1 = comboBoxLK1.getSelectionModel().getSelectedItem();
             System.out.println("Selection made 1: [" + selectionIndexLK1 + "] " + selectionItemLK1);
             System.out.println(items);
             comboBoxLK1.setDisable(true);
            
             items.remove(selectionIndexLK1);
             //items.remove("Grün");             
             System.out.println(items);
             comboBoxLK1.setDisable(true);
             comboBoxLK2.setItems(items);
             comboBoxLK2.setDisable(false);
                    
         });
        
        
         comboBoxLK2.setOnAction((event) -> {
             int selectionIndexLK2 = comboBoxLK2.getSelectionModel().getSelectedIndex();
             Object selectionItemLK2 = comboBoxLK2.getSelectionModel().getSelectedItem();
            
             System.out.println("Selection made 2: [" + selectionIndexLK2 + "] " + selectionItemLK2);
             System.out.println(items);
            
             items.remove(selectionItemLK2);
             //items.remove("Schwarz");
             System.out.println(items);
             comboBoxLK2.setDisable(true);
            
             //comboBoxLK3.setItems(items);
             //comboBoxLK3.setDisable(false);
                    
         });

Hier die Ausgabe der println auf der Console:
Code:
Selection made 1: [0] Rot
[Rot, Gelb, Grün, Blau, Schwarz, Lila]
Selection made 1: [-1] null
[Gelb, Grün, Blau, Schwarz, Lila]
Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 5
    at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
    at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
    at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:266)
    at java.base/java.util.Objects.checkIndex(Objects.java:359)
    at java.base/java.util.ArrayList.remove(ArrayList.java:504)
    at javafx.base@19/com.sun.javafx.collections.ObservableListWrapper.doRemove(ObservableListWrapper.java:116)
    at javafx.base@19/javafx.collections.ModifiableObservableListBase.remove(ModifiableObservableListBase.java:186)
    at FirstJavaFXProject/application.Kurswahl.lambda$0(Kurswahl.java:40)
    at javafx.base@19/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at javafx.base@19/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
    at javafx.base@19/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)

In der Console wird zunächst richtig ausgeben, dass die Farbe Rot gewählt wurde:
Selection made 1: [0] Rot
Dann wird nochmals die observablelist "items" ausgegeben:
[Rot, Gelb, Grün, Blau, Schwarz, Lila]

Dann aber scheint die setonAction-Routine nochmals zu starten, ohne dass ich in der Liste klicke, denn es wird nochmals die println ausgeführt:
Selection made 1: [-1] null

Und dann sieht man auch, dass das Löschen der zuvor gewählten Farbe (hier "Rot") auch über die Variable 'selectionIndexLK1' funktioniert, denn nun zeigt die println folgende Liste:
[Gelb, Grün, Blau, Schwarz, Lila]

Dann kommen die Fehlermeldungen mit ExceptionInThread...

Kann sich jemand dieses Verhalten erklären?

Wenn ich ein Element direkt aus der 'items'-Liste lösche (Zeilen 41 und 58 im Code aktiviert und Zeilen 40 und 57 deaktiviert), dann funktioniert es reibungslos ohne Fehlermeldungen. Aber ich will ja keine festen Elemente aus der Liste löschen sondern die zuvor gewählten.

Vielen Dank!
 

KonradN

Super-Moderator
Mitarbeiter
Also erst einmal würde ich nicht wirklich auf Actions reagieren - zumal da ja deutlich mehr Actions kommen - erkennbar an dem Parameter, den Du komplett ignorierst. (Merke: Wenn Du einen Parameter komplett ignorierst, dann ist dies meist ein Punkt, den man sich nächer anschauen sollte. Bei So UI Entwicklung mag es vorkommen, aber das ist nichts, das ich so gut finden würde.)

Aber dir geht es ja auch um die Auswahl eines Elementes und nicht generell um Actions. Daher macht es hier aus meiner Sicht Sinn, das SelectionModel zu nutzen. Da kann man z.B. die selectedProperty nutzen, um mitzubekommen, ob sich ein ausgewähltes Element ändert.

Dann ist es schlecht, die Liste zu verändern - dann dürfte das ausgewählte Element sich ja wieder ändern (Etwas, das evtl. das Kernproblem ist bei Dir!). Eine Observable List würde ich da also nicht verwenden um dieses dann an mehrere ComboBoxen zu binden. Da würde ich jedem eine eigene Liste geben und diese dann entsprechend füllen wenn es soweit ist. Dieses "Ich benutze eine Instanz an vielen Stellen für unterschiedliche Dinge" ist nicht wirklich sauber und kann durchaus zu Problemen führen.

Wenn Du das aber so beibehalten willst: Dann kannst Du auch in dem Event abprüfen, ob das Control noch aktiv ist. Wenn das Control nicht mehr aktiv ist, dann behandelst Du das Event nicht mehr. Das könnte sogar auch bei dir im Code schon ausreichen.

Java:
        comboBoxLK1.setOnAction((event) -> {
            if (comboBoxLK1.isDisabled()) return;

             int selectionIndexLK1 = comboBoxLK1.getSelectionModel().getSelectedIndex();
             Object selectionItemLK1 = comboBoxLK1.getSelectionModel().getSelectedItem();
             comboBoxLK1.setDisable(true);
             System.out.println("Selection made 1: [" + selectionIndexLK1 + "] " + selectionItemLK1);
             System.out.println(items);
            
             items.remove(selectionIndexLK1);
             //items.remove("Grün");             
             System.out.println(items);
             comboBoxLK1.setDisable(true);
             comboBoxLK2.setItems(items);
             comboBoxLK2.setDisable(false);
                    
         });

Zu guter letzt: Schön, dass Du da wenigstens keine anonymen Klassen verwendet hast, aber so Lambda Expressions über mehrere Zeilen sollte man nicht nutzen, da diese schlicht zu unübersichtlich sind. Packe es statt dessen in eine Methode und dann setzt Du nur eine Methodenreferenz. Oder da Du ja mehrfach den gleichen Code hast: Nutze Parameter! Dann hättest Du etwas wie:

Java:
        comboBoxLK1.setOnAction( event -> handleComboBoxClick(comboBoxLK1, comboBoxLK2) );


    public void handleComboBoxClick(ComboBox mainBox, ComboBox followingBox) {
        if (mainBox.isDisabled()) return;
        
        int selectedIndex = mainBox.getSelectionModel().getSelectedIndex();
        Object selectedItem = mainBox.getSelectionModel().getSelectedItem();
        mainBox.setDisable(true);
        items.remove(selectedIndex);
        followingBox.setItems(items);
        followinBox.setDisable(false);
    }

Aber wie gesagt: So würde ich es normalerweise nicht machen.
 

WSchubert

Neues Mitglied
Hallo KonradN,
vielen Dank für die ausführliche Rückmeldung!
Die verschiedenen Alternativen werde ich mal versuchen umzusetzen.
Das Einfügen der Zeile "if (comboBoxLK1.isDisabled()) return;" hat aber schon perfekt funktioniert. Jetzt läuft der Ablauf ohne Fehler durch!
Super!
Dann wäre jetzt natürlich die Frage, wo genau in der Programmausführung der Unterschied besteht zwischen "items.remove(selectionIndexLK1);" und "items.remove("Grün");"? Der eine gibt Fehler, der andere nicht.

Hintergedanke der gemeinsamen Liste war, dass das Programm kaskadenartig verschiedene ComBoxen durchlaufen soll und in jeder folgenden Box nur noch die Elemente übrig sein sollen, die in den vorherigen Boxen noch nicht gewählt wurden.

Danke nochmals!
 

KonradN

Super-Moderator
Mitarbeiter
Dann wäre jetzt natürlich die Frage, wo genau in der Programmausführung der Unterschied besteht zwischen "items.remove(selectionIndexLK1);" und "items.remove("Grün");"? Der eine gibt Fehler, der andere nicht.
Ich habe mir das nicht im Detail angesehen, aber vermutlich wird da folgendes passieren:
  • Wenn Du das aktuelle ausgewählte Element löschst, dann ändert sich die Selektion (Es ist dann nichts mehr selektiert).
  • Dadurch wird wieder ein Action Event ausgelöst
  • In dem neuen Action Event ist ja nichts mehr selektiert und die Abfrage nach dem selected Index wird vermutlich -1 zurück geben.
  • Du versuchst dann das Elemen -1 zu löschen und das geht natürlich nicht!
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
berserkerdq2 Wie greife ich auf ein Element zu, welches ich beim Scenebuilder erstellt habe AWT, Swing, JavaFX & SWT 10
J JavaFx PDF in einem Element in einem Fenster anzeigen. AWT, Swing, JavaFX & SWT 11
G FX warten bis ein anderes GUI Element ausgewählt wurde AWT, Swing, JavaFX & SWT 8
N JavaFX Tableview nach Löschen von Element falscher Index AWT, Swing, JavaFX & SWT 4
M Internal Frames und Canvas-Element AWT, Swing, JavaFX & SWT 9
kodela Swing Element einer JComboBox ausgrauen AWT, Swing, JavaFX & SWT 3
K JavaFX Element in HBOX nach rechts verschieben AWT, Swing, JavaFX & SWT 2
stroggi Swing Suche nach Kurveneditor (UI-Element) AWT, Swing, JavaFX & SWT 1
I FXML: StackPane als Root-Element AWT, Swing, JavaFX & SWT 5
ImperatorMing JavaFX Übersicht - Welches Element kann welches Erreignis AWT, Swing, JavaFX & SWT 3
D Swing "blaues" Element aus JComboBox erhalten AWT, Swing, JavaFX & SWT 6
F JavaFX Custom ListView erstellt ghost Element AWT, Swing, JavaFX & SWT 3
GreenTeaYT Wie vergebe Ich den Jframe Title den Namen aus einem Element von der Arraylist ? AWT, Swing, JavaFX & SWT 4
L JavaFX Hover Effekt über das Parent Element AWT, Swing, JavaFX & SWT 4
domjos1994 JavaFX Element auswählen auf dem der Cursor ist AWT, Swing, JavaFX & SWT 1
M Ein Element in mehreren JList selektieren AWT, Swing, JavaFX & SWT 5
R GUI Element in einer Methode aktualisieren (JTextPane) AWT, Swing, JavaFX & SWT 13
G JavaFX NullPointerException bei Zugriff auf FXML Element AWT, Swing, JavaFX & SWT 0
P Swing Nach removeAll() noch 1 Element vorhanden AWT, Swing, JavaFX & SWT 0
K Swing GUI Element wird nicht skaliert AWT, Swing, JavaFX & SWT 6
K Swing JList - Element richtig hinzufügen AWT, Swing, JavaFX & SWT 4
Z Swing Von vielen Klassen auf ein GUI-Element zugreifen AWT, Swing, JavaFX & SWT 10
M Element aus JList eines JFileChooser entfernen AWT, Swing, JavaFX & SWT 3
E selektiertes Element aus JList zurückgeben AWT, Swing, JavaFX & SWT 7
H Swing Element aus JComboBox auswählen AWT, Swing, JavaFX & SWT 2
C click auf JButton und darunter liegendes element AWT, Swing, JavaFX & SWT 5
B Element schrittweise verschieben AWT, Swing, JavaFX & SWT 2
S Ausschluss bei Klick auf GUI Element AWT, Swing, JavaFX & SWT 6
GianaSisters AWT Per Button neues Element auf den jPanel setzen AWT, Swing, JavaFX & SWT 6
M gleiches Element in JList mehrmals hintereinander auswählen AWT, Swing, JavaFX & SWT 6
GianaSisters jList nur einmal ein Element anklicken AWT, Swing, JavaFX & SWT 3
F Element anzeigen / erstellen. Maus vs Controller AWT, Swing, JavaFX & SWT 7
M Frage nach Swing Element AWT, Swing, JavaFX & SWT 3
J jList, recht Maustast => Tooltip zu Element AWT, Swing, JavaFX & SWT 8
W SWT Resize Tree-Element AWT, Swing, JavaFX & SWT 3
Landei Swing JTree - Element mit Doppelklick auswählen AWT, Swing, JavaFX & SWT 4
B Swing: letztes Element wird immer auf Fenstergröße gezogen AWT, Swing, JavaFX & SWT 3
F Swing Paint mit Canvas Element AWT, Swing, JavaFX & SWT 35
G JTree Element wird nicht markiert AWT, Swing, JavaFX & SWT 2
X Swing Swing Element gesucht -> um als Konsole zu fungieren AWT, Swing, JavaFX & SWT 4
H GridBagLayout Element komplett ausfüllen AWT, Swing, JavaFX & SWT 5
D Swing Document-Structure; Element AWT, Swing, JavaFX & SWT 4
N Nur ein Element sichtbar beim Drucken eines JFrame AWT, Swing, JavaFX & SWT 9
C Aktion durchführen bei Klick auf ein Element im JTree (Untersch. Klick und Doppklick) AWT, Swing, JavaFX & SWT 5
S Listener der mich informiert wann immer einer Liste ein Element hinzugefuegt wird? AWT, Swing, JavaFX & SWT 4
H Swing [gelöst]Neues Swing Element erstellen AWT, Swing, JavaFX & SWT 4
D Problem an Parent Element ranzukommen. AWT, Swing, JavaFX & SWT 7
G JList und ein neues Element oben in der Liste einfügen AWT, Swing, JavaFX & SWT 4
U Ein Element in einer JList farbig hervorheben ! AWT, Swing, JavaFX & SWT 2
ABstraCT JCombobox dynamisch füllen (erstes Element Problem) AWT, Swing, JavaFX & SWT 4
N JPopupMenu - ausgewähltes Element zurückgeben AWT, Swing, JavaFX & SWT 2
V Element zu Listenfeld hinzufügen AWT, Swing, JavaFX & SWT 6
S MouseListener zurückverfolgung auf element. AWT, Swing, JavaFX & SWT 7
A Element aus einer JList löschen AWT, Swing, JavaFX & SWT 5
zilti Swing-Element verändern AWT, Swing, JavaFX & SWT 13
N in jScrollPane, neues Swing Element hinzufügen AWT, Swing, JavaFX & SWT 6
M Zwei Element auf ein Contentpane AWT, Swing, JavaFX & SWT 45
G Listener (anonyme Klasse) jedem Element eines Array zuweisen AWT, Swing, JavaFX & SWT 5
V Wie heisst dieses GUI-Element? Gibt es sowas für Swing? AWT, Swing, JavaFX & SWT 10
E JTree selektiertes Element AWT, Swing, JavaFX & SWT 3
S Swing Element für Explorer-Fenster darstellung AWT, Swing, JavaFX & SWT 13
G JCombobox - Element richtig anzeigen AWT, Swing, JavaFX & SWT 5
W Element im JTree farblich markieren AWT, Swing, JavaFX & SWT 6
N JTree mehrere/ohne Root Element/e AWT, Swing, JavaFX & SWT 2
M JLIST - Ein Element selektieren und weiterverarbeiten! AWT, Swing, JavaFX & SWT 2
C leeres Element in Gridlayout einfuegen AWT, Swing, JavaFX & SWT 3
E Wie heißt dieses graphische Element (Bild inside)? AWT, Swing, JavaFX & SWT 2
G JTree. Neues Element hinzufügen und Selection beibehalten! AWT, Swing, JavaFX & SWT 3
D Element aus einer Methode heraus hinzufügen AWT, Swing, JavaFX & SWT 2
bummerland auf übergeordnetes element zugreifen AWT, Swing, JavaFX & SWT 2
T Combobox mit Autocomplete-Funktion AWT, Swing, JavaFX & SWT 7
J Eingaben aus Textfield & ComboBox speichern und in ComboBox wieder ausgeben AWT, Swing, JavaFX & SWT 3
N Promt Text der Combobox AWT, Swing, JavaFX & SWT 0
Doppel JavaFX ComboBox AWT, Swing, JavaFX & SWT 5
P JavaFX ClassCastException bei ComboBox.getValue AWT, Swing, JavaFX & SWT 4
F Wie bekomme ich den Wert der ComboBox in eine Variable gespeichert welche ich für meinen ActionListener nutzen kann? AWT, Swing, JavaFX & SWT 3
M Swing Java Swing/AWT Combobox Bug AWT, Swing, JavaFX & SWT 3
M Combobox bild anklicken AWT, Swing, JavaFX & SWT 2
L JavaFX Wiederspenstige ComboBox AWT, Swing, JavaFX & SWT 0
P Combobox und Enum AWT, Swing, JavaFX & SWT 3
L ComboBox Wert automatisch auswählen AWT, Swing, JavaFX & SWT 6
L Methode zum Füllen einer ComboBox AWT, Swing, JavaFX & SWT 4
K Nullpointer Combobox Listener AWT, Swing, JavaFX & SWT 2
K JavaFX Combobox, Textfield & setOnMouseClicked AWT, Swing, JavaFX & SWT 2
it_is_all Swing Button, ComboBox,... -- Unterschied: NetBeans Design <-> Ausführung AWT, Swing, JavaFX & SWT 2
D JavaFX ComboBox String setzen AWT, Swing, JavaFX & SWT 20
offi Combobox in TableCell AWT, Swing, JavaFX & SWT 1
D Javafx Combobox Abfrage aus mysql AWT, Swing, JavaFX & SWT 8
K Event Handling ComboBox Event Handler AWT, Swing, JavaFX & SWT 7
MrSnake ComboBox-Einträge werden unsichtbar AWT, Swing, JavaFX & SWT 0
L ComboBox: slider positionieren AWT, Swing, JavaFX & SWT 0
M JavaFX ComboBox: Update zur Laufzeit AWT, Swing, JavaFX & SWT 16
M JavaFX Combobox bindBidirectional AWT, Swing, JavaFX & SWT 4
D [Anfänger]ComboBox erstellt Einträge in einer anderen ComboBox AWT, Swing, JavaFX & SWT 3
T JavaFX Editable Combobox Text-Selektierung nach Trigger AWT, Swing, JavaFX & SWT 4
H Combobox aktualisieren AWT, Swing, JavaFX & SWT 2
G Swing ComboBox: Auswahl eines Items der Liste durch Eingabe eines Buchstabens AWT, Swing, JavaFX & SWT 3
M JavaFX ComboBox AWT, Swing, JavaFX & SWT 5
T Problem: ComboBox und addItem AWT, Swing, JavaFX & SWT 5
J ComboBox als Filter benutzen AWT, Swing, JavaFX & SWT 1

Ähnliche Java Themen

Neue Themen


Oben