简体   繁体   中英

remove item from observable list

I have an listVeiw which is a list of HBox with a button to delete that HBox from listView .

but the problem is that when I press that button, it will throw an exception. I try to remove that entry of listView from another button that is not reside inside HBox and it worked.

myObservableList.remove(lastIndex);

but I want a delete button inside each HBox to delete that entry instead of having a global button to remove the last entry.

EDIT: add exception:

Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1787)
    at javafx.fxml/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1670)
    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.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.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.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$ClickGenerator.postProcess(Scene.java:3597)
    at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3899)
    at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1885)
    at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2618)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:409)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:299)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:447)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:412)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:446)
    at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:556)
    at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:942)
    at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:277)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
    at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:273)
    at javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
    at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1784)
    ... 39 more
Caused by: java.lang.IndexOutOfBoundsException: Index 1 out of bounds for length 1
    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:248)
    at java.base/java.util.Objects.checkIndex(Objects.java:372)
    at java.base/java.util.ArrayList.remove(ArrayList.java:535)
    at javafx.base/com.sun.javafx.collections.ObservableListWrapper.doRemove(ObservableListWrapper.java:116)
    at javafx.base/javafx.collections.ModifiableObservableListBase.remove(ModifiableObservableListBase.java:179)
    at http_client.ui.main.center_panel.header.HeaderController.deleteHeaderField(HeaderController.java:60)
    at http_client.ui.main.center_panel.header.single_header.SingleHeaderController.onTapDelete(SingleHeaderController.java:27)
    ... 50 more

after doing:

Platform.runLater(() -> {
  ....// your code
});

I got:

Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: Index 1 out of bounds for length 1
    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:248)
    at java.base/java.util.Objects.checkIndex(Objects.java:372)
    at java.base/java.util.ArrayList.remove(ArrayList.java:535)
    at javafx.base/com.sun.javafx.collections.ObservableListWrapper.doRemove(ObservableListWrapper.java:116)
    at javafx.base/javafx.collections.ModifiableObservableListBase.remove(ModifiableObservableListBase.java:179)
    at http_client.ui.main.center_panel.header.HeaderController.lambda$deleteHeaderField$0(HeaderController.java:60)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
    at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:277)
    at java.base/java.lang.Thread.run(Thread.java:834)

SECOND EDIT:

I have a package named list_entries:

public class ListEntriesController implements Initializable {
    Integer headerCounts = 0;
    private ObservableList<HBox> fields = FXCollections.observableArrayList();

    @FXML
    private JFXListView<HBox> listView;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        addHeaderFiled();
    }

    @FXML
    private void onTapAddNewHeader(MouseEvent mouseEvent) {
        addHeaderFiled();
    }

    @FXML
    private void removeHeaderFiled(MouseEvent mouseEvent) {
        fields.remove(headerCounts - 1);
        headerCounts--;
        listView.setItems(fields);
    }

    private void addHeaderFiled() {
        FXMLLoader entryFiledLoader = new FXMLLoader(getClass().getResource("/http_client/ui/main/center_panel/header/single_header/single_header.fxml"));
        try {
            HBox entryFiled = entryFiledLoader.load();
            fields.add(entryFiled);
            headerCounts++;
            listView.setItems(fields);
            SingleHeaderController controller = headerFiledLoader.getController();
            controller.setHeaderIndex(headerCounts - 1);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void deleteHeaderField(int index) {
        System.out.println(index);
        Platform.runLater(() -> {
            fields.remove(index);
            headerCounts--;
            listView.setItems(fields);
        });
    }
}

and a package named entry:

public class EntryController implements Initializable {
    private int entryIndex;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {}

    @FXML
    private void onTapDelete() {
        FXMLLoader EntryLoader = new FXMLLoader(getClass().getResource("/http_client/ui/main/center_panel/header/header.fxml"));
        try {
            EntryLoader.load();
        } catch (IOException e) {
            e.printStackTrace();
        }
        ListEntriesController controller = headerFiledLoader.getController();
        controller.deleteHeaderField(headerIndex);
    }

    public void setEntryIndex(int index) {
        entryIndex = index;
    }
}

You are dealing with two separate threads. The main JFX thread and the event thread. The event thread (in the queue) should be synchronized to the main JFX thread with

Platform.runLater(() -> {
  ....// your code
});

I think you have to check the headerCount before doing the remove

private void removeHeaderFiled(MouseEvent mouseEvent) {
    if (headerCounts > 0) { // avoid negative value
      fields.remove(headerCounts - 1);
      headerCounts--;
      listView.setItems(fields);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM