Reputation: 137
I am trying to make a button that, when multiple rows in a TableView are selected, all of the selected rows are removed.
I am creating an observable list using getSelectedIndicies
and it isn't working right.
If I select the first three rows, I have it print out the indicies as it removes them and it prints 0,1 and then it removes the first and third row, but the middle of the three rows is not removed.
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();
}
});
Upvotes: 3
Views: 5744
Reputation:
There is a way round this, using getSelectedIndices()
, as the OP originally required. Here is the solution:
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());
}
This works because it sorts the indices in descending order, and so only removes the highest index first so that the indices of other items to be removed are not changed as a result of the removal.
Sometimes you can't use the
getSelectedItems()
andremoveAll(...)
functions becauseremoveAll
will remove all occurences of the referenced objects. What if your list contains multiple entries with the same referenced object, and you only want to remove one of those references? That's why you need to use thegetSelectedIndices()
function.
Upvotes: 0
Reputation: 121
I came across a similar issue using ListView (selectedView in my case) and also guessed items were removed by indices. So I gave up on using a loop looking like the following
selectedView.getSelectionModel().getSelectedItems().forEach(i -> selectedView.getItems().remove(i));
changing it to
selectedView.getItems().removeAll(selectedView.getSelectionModel().getSelectedItems());
which worked just fine. Hope this helps anybody.
Upvotes: 0
Reputation: 1272
You can use a for loop, it make a snapshoot of your table selection and iterate in it. For exmple:
@FXML
private void deleteButtonFired(ActionEvent actionEvent) throws InterruptedException {
for(Object o : table.getSelectionModel().getSelectedItems()){
table.getItems().remove(o);
}
table.getSelectionModel().clearSelection();
}
I hope they fix this bug.
Upvotes: 0
Reputation: 565
For some reason, this works:
b.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent arg0) {
List items = new ArrayList (treeTable.getSelectionModel().getSelectedItems());
data.removeAll(items);
table.getSelectionModel().clearSelection();
}
});
I doubt that the internal implementation of the selectedItems list ( com.sun.javafx.collections.ObservableListWrapper ) might have some bug.
Edit Yes it's definitely a bug: https://javafx-jira.kenai.com/browse/RT-24367
Upvotes: 6
Reputation: 29540
Removing using index can't work since at each suppression the remaining indexes change.
You could remove the selectedItems
:
delBtn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
data.removeAll(table.getSelectionModel().getSelectedItems());
table.getSelectionModel().clearSelection();
}
});
Upvotes: 4