我有一个TableView
,由一个SortedList
支持,包装一个FilteredList
,包装一个ObservableList
。过滤列表中的项目可以重复。也就是说,可能是list.get(5) == list.get(10)
的情况。
用户可以在TableView
上选择行并按删除键。当他们这样做时,所选择的项目应该被删除,而不是其他项目。
我尝试了两种解决方案,但都存在问题:
在基础 ObservableList 上使用 list.remove ( Object ) - 因为列表可能包含重复的项目,所以对象的所有副本都会被删除,而不仅仅是选定的副本。
public void removeItemsAtIndices ( List <Integer> indices ) {
List <Item> removeMe = new ArrayList<Item> ();
for ( int index : indices ) {
removeMe.add( currentListSorted.get( index ) );
}
items.removeAll( removeMe );
}
在 SortedList 上使用 list.remove (index) - 过滤后的列表会引发 UnsupportedOperationException
。
public void removeItemsAtIndices ( List <Integer> indices ) {
Collections.sort( indices, Collections.reverseOrder() );
for( int index : indices ) {
currentListSorted.remove( index ); //Exception here
}
}
以下是我设置列表的方法:
private final ObservableList <Item> items = FXCollections.observableArrayList();
private final FilteredList <Item> currentListFiltered = new FilteredList <Item>( items, p -> true );
private final SortedList <Item> currentListSorted = new SortedList <CurrentListTrack>( currentListFiltered );
有没有办法删除项目:
- 来自排序列表
- 按已过滤和排序列表的索引进行定位
- 不删除非目标重复项?
目前我能想到的唯一解决方案是使每个项目都是唯一的(即不可能 list.get(5) == list.get(10)
) 。我希望通过寻找另一种解决方案来避免这种情况。
附注如果由于某种原因它有用,下面是确定所选索引的代码:
removeMenuItem.setOnAction( new EventHandler <ActionEvent>() {
@Override
public void handle ( ActionEvent event ) {
ObservableList <Integer> selectedIndexes = currentListTable.getSelectionModel().getSelectedIndices();
List <Integer> removeMe = new ArrayList<> ( selectedIndexes );
removeItemsAtIndices ( removeMe );
}
});
最佳答案
TransformationList
(其中 SortedList
和 FilteredList
都是实现)具有 getSourceIndex(int index)
将转换列表中的索引“转换”为其源(底层)列表中的索引的方法。因此,currentListSorted(index)
给出了排序列表中具有所提供索引的项目在过滤列表中的索引,而currentListFiltered(index)
给出了原始列表中的索引items
在过滤列表中具有所提供索引的项目列表。
所以你可以这样做
items.remove(currentListFiltered.getSourceIndex(
currentListSorted.getSourceIndex(index)
));
删除可见表项(排序列表)“索引坐标”中特定索引处的项。
当然,您需要小心代码中的循环,因为删除项目时索引会发生变化。 (如果您只是从简单列表中按索引删除项目,这也是正确的。)
所以您可能需要以下内容:
List<Integer> indicesToBeRemoved = new ArrayList<>();
for (int index : indices) { // indices in the sorted list
indicesToBeRemoved.add(currentListFiltered.getSourceIndex(
currentListSorted.getSourceIndex(index)));
}
// sort with largest index first, as removing an item with
// a given index will not change the indices of items with small indices:
indicesToBeRemoved.sort(Comparator.reverseOrder());
for (Integer index : indicesToBeRemoved) {
// be careful to explicitly unbox the Integer here,
// to avoid collision between remove(Object) and remove(int):
items.remove(index.intValue());
}
关于java - 如何从具有重复条目的过滤列表中删除特定索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48490831/