从可观察列表中删除项目

时间:2020-05-17 07:54:19

标签: java javafx

我有一个listVeiw,它是HBox的列表,带有一个按钮,用于从HBox中删除该listView

但是问题是当我按下该按钮时,它将引发异常。 我尝试从另一个不在listView内的按钮中删除该HBox的条目,并且它起作用了。

myObservableList.remove(lastIndex);

但是我希望每个HBox内的删除按钮删除该条目,而不是使用全局按钮删除最后一个条目。

编辑:添加例外:

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

完成后:

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

我知道了

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)

第二编辑:

我有一个名为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);
        });
    }
}

和一个名为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;
    }
}

2 个答案:

答案 0 :(得分:2)

您正在处理两个单独的线程。 JFX主线程和事件线程。 (队列中的)事件线程应使用以下命令同步到主JFX线程

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

答案 1 :(得分:0)

我认为您必须在执行删除操作之前先检查headerCount

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