Wie kann ich folgende Methode schreiben?
Ich bin dabei mit JavaFX einen Vokabeltrainer zu programmieren und möchte das man im Programm die Funktion hat eine Vokabel auch wieder zu Löschen. Wie bekomme ich das hin?
1 Antwort
Bei deinem Modell müsstest du über alle Kindelemente der VBox iterieren und dann je Eintrag das erste Kindelement der HBox auf seinen Inhalt prüfen. Wenn es sich um die gesuchte Vokabel handelt, müsste die HBox entfernt werden.
rows.getChildren().remove(foundRow);
Es wäre aber besser, wenn du dein Programm anders aufbauen / strukturieren würdest. Die reinen Daten sollten von der View getrennt werden. Dafür bräuchtest du eine Modelklasse:
public class VocabularyPair {
private StringProperty french;
private StringProperty german;
// setter + getter ...
}
die in einer ObservableList gehalten wird. Diese Liste bindest du an eine ListView. Den Aufbau einzelner Listeneinträge kann man via CellFactory definieren. Lies mehr zur ListView hier und recherchiere zu Properties in JavaFX.
Ziel sollte es sein, nur die Liste ändern zu müssen, ohne dafür das View anzufassen. Der Zugriff an die reinen Daten (Vokabeln) wäre dann auch viel leichter.
Die Indexzählung bei einer ObservableList beginnt bei 0. Der Wert von lastElement muss also noch um 1 substrahiert werden.
Auch wenn ich
int lastElement = rows.getChildren().size() -1;
schreibe bekomme ich eine Fehlermeldung.
Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 0
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.get(ArrayList.java:427)
at javafx.base/com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrapper.java:89)
at javafx.base/com.sun.javafx.collections.VetoableListDecorator.get(VetoableListDecorator.java:305)
at javafx.graphics/javafx.scene.Parent$3.onProposedChange(Parent.java:530)
at javafx.base/com.sun.javafx.collections.VetoableListDecorator.remove(VetoableListDecorator.java:328)
at Quiz/application.SceneNewQuiz.delVocMethod(SceneNewQuiz.java:134)
at Quiz/application.SceneNewQuiz.newVocMethod(SceneNewQuiz.java:115)
at Quiz/application.SceneNewQuiz$3.handle(SceneNewQuiz.java:72)
at Quiz/application.SceneNewQuiz$3.handle(SceneNewQuiz.java:1)
at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
at
javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
at javafx.graphics/javafx.scene.Node.fireEvent(Node.java:8792)
at javafx.controls/javafx.scene.control.Button.fire(Button.java:203)
at javafx.controls/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:208)
at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3897)
at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1878)
at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2623)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:450)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449)
at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:557)
at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:943)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
at java.base/java.lang.Thread.run(Thread.java:833)
Du darfst nur Einträge entfernen, wenn es Kindelemente gibt.
int lastElement = rows.getChildren().size() - 1;
if (lastElement > -1) {
rows.getChildren().remove(lastElement);
}
Die Bedingung wird (ich habe es ausprobiert) nicht wahr.
Wenn es keine Kindelemente gibt, ist das so richtig. Das entspricht auch dem Zustand, bei dem du die Methode in deinem obigen Snippet aufrufst. Die VBox hat zu diesem Zeitpunkt noch keine Kinder.
Ich habe erst Textfelder hinzugefügt und dann auf den delete Button geklickt und es ist nicht passiert.
Ich denke, da wirst du einmal mit dem Debugger durchgehen müssen, um zu prüfen, wieso du Liste zu dem Zeitpunkt leer ist.
Ich habe versucht die remove Methode in mein Programm zu integrieren. Wenn ich das Programm starte und auf den Button klicke bekomme ich eine Fehlermeldung. Ich glaube ich habe noch nicht ganz verstanden wie ich das deiner Meinung nach machen soll.
Das ist der Code: