【问题标题】:Issue with removing multiple rows at once from JavaFX TableView从 JavaFX TableView 一次删除多行的问题
【发布时间】:2013-09-09 14:20:23
【问题描述】:

I am trying to make a button that, when multiple rows in a TableView are selected, all of the selected rows are removed.

我正在使用getSelectedIndicies 创建一个可观察列表,但它无法正常工作。

如果我选择前三行,我会在删除它们时打印出索引,然后打印 0,1,然后删除第一行和第三行,但不会删除三行的中间。

delBtn.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent e) {
        ObservableList<Integer> index = 
            table.getSelectionModel().getSelectedIndices();

        for (int location: index) {
            System.out.println(location);
            data.remove(location);
        }

        table.getSelectionModel().clearSelection();
    }
});

【问题讨论】:

  • 问题是你的for循环。您正在按索引删除。如果您有项目 1,2,3,4 并删除索引 0,那么您现在有 2,3,4。然后删除索引 1(现在是 3)处的项目,留下 2,4。
  • 您对我应该怎么做有什么建议吗?我认为这可能与 for 循环有关,我只是不确定如何修复它。

标签: java javafx-2 javafx


【解决方案1】:

由于某种原因,这行得通:

 b.setOnAction(new EventHandler<ActionEvent>() {

                @Override
                public void handle(ActionEvent arg0) {
                    List items =  new ArrayList (treeTable.getSelectionModel().getSelectedItems());  
                    data.removeAll(items);
                    table.getSelectionModel().clearSelection();

                }
            });

我怀疑 selectedItems 列表 ( com.sun.javafx.collections.ObservableListWrapper ) 的内部实现可能有一些错误。

编辑 是的,这绝对是一个错误:https://javafx-jira.kenai.com/browse/RT-24367

【讨论】:

  • 但有时您可能在列表中有多个相同引用的项目,您可能只想删除其中一个,而不是两个或更多,因此在这种情况下使用此方法不起作用,因为它将删除所有此类项目引用。例如,假设您的 ListView 包含 {Apple, Banana, Banana, Orange},并且您只想删除第一个 Banana,然后使用 removeAll 将删除所有代表相同对象的 Bananas,您可能想要在某些情况下要做...
【解决方案2】:

无法使用索引删除,因为每次抑制时剩余的索引都会发生变化。

您可以删除 selectedItems

delBtn.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent e) {
        data.removeAll(table.getSelectionModel().getSelectedItems());
        table.getSelectionModel().clearSelection();
    }
});

【讨论】:

  • 这似乎应该可以工作,但是当我这样做时,无论我突出显示什么,它都会清除整个表格。我尝试在那里使用 getSelectedIndicies() ,但它没有删除任何东西。
  • 轻微修正。它会删除最高突出显示行下方的所有内容。因此,如果有 100 行并且我突出显示第 10-20 行 roes 10-99 将被删除。
【解决方案3】:

您可以使用 for 循环,它对您的表格选择进行快照并在其中进行迭代。例如:

@FXML
private void deleteButtonFired(ActionEvent actionEvent) throws InterruptedException {
    for(Object o : table.getSelectionModel().getSelectedItems()){
        table.getItems().remove(o);
    }
    table.getSelectionModel().clearSelection();
}

我希望他们修复这个错误。

【讨论】:

    【解决方案4】:

    我在使用 ListView(在我的例子中是 selectedView)时遇到了类似的问题,并且猜测的项目也被索引删除了。所以我放弃了使用如下所示的循环

    selectedView.getSelectionModel().getSelectedItems().forEach(i -> selectedView.getItems().remove(i));
    

    改成

    selectedView.getItems().removeAll(selectedView.getSelectionModel().getSelectedItems());
    

    效果很好。希望这对任何人都有帮助。

    【讨论】:

    • @Wingle 我找到了解决方案 - 请参阅我的答案:-D
    【解决方案5】:

    有一种解决方法,使用 getSelectedIndices(),作为 OP 最初需要的。这是解决方案:

        ArrayList<Integer> list = new ArrayList<>(listView.getSelectionModel().getSelectedIndices());
    
        Comparator<Integer> comparator = Comparator.comparingInt(Integer::intValue);
        comparator = comparator.reversed();
        list.sort(comparator);
    
        for(Integer i : list) {
    
            listView.getItems().remove(i.intValue());
        }
    

    之所以有效,是因为它按降序对索引进行排序,因此只首先删除最高的索引,以便其他要删除的项目的索引不会因删除而改变。

    有时您不能使用getSelectedItems()removeAll(...) 函数,因为removeAll 将删除所有引用对象的出现。如果您的列表包含多个具有相同引用对象的条目,而您只想删除其中一个引用怎么办?这就是您需要使用getSelectedIndices() 函数的原因。

    【讨论】:

      猜你喜欢
      • 2014-10-21
      • 1970-01-01
      • 2019-02-26
      • 2012-06-19
      • 2014-04-29
      • 2017-03-04
      • 1970-01-01
      • 2021-09-07
      • 1970-01-01
      相关资源
      最近更新 更多