user3626720
user3626720

Reputation: 125

java.lang.UnsupportedOperationException for removing a row from the javafx tableview

I am trying to delete the selected record from the tableview in javafx. Below is how I am populating the table with the data:

public void setMainApp(MainAppClass mainApp){
    this.mainApp = mainApp;

    FilteredList<FileModel> filteredData = new FilteredList<>(mainApp.getFileData(), p -> true);

    // 2. Set the filter Predicate whenever the filter changes.
    filterField.textProperty().addListener((observable, oldValue, newValue) -> {
        filteredData.setPredicate(files -> {
            // If filter text is empty, display all files.
            if (newValue == null || newValue.isEmpty()) {
                return true;
            }

            String lowerCaseFilter = newValue.toLowerCase();
            if (files.getFileSubject().toLowerCase().indexOf(lowerCaseFilter) != -1) {
                return true; // Filter matches Subject.
            }
                else if (files.getFileDate().toLowerCase().indexOf(lowerCaseFilter) != -1) {
                return true; // Filter matches last name.
            }
            return false; // Does not match.
        });
    });

    // 3. Wrap the FilteredList in a SortedList. 
    SortedList<FileModel> sortedData = new SortedList<>(filteredData);

    // 4. Bind the SortedList comparator to the TableView comparator.
    sortedData.comparatorProperty().bind(fileTable.comparatorProperty());

    // 5. Add sorted (and filtered) data to the table.

    fileTable.setItems(sortedData);
}

And thats how I am removing the record:

@FXML
private void deleteFile() {
    int selectedIndex = fileTable.getSelectionModel().getSelectedIndex();
    if (selectedIndex >= 0) {
        fileTable.getItems().remove(selectedIndex);
    } else {
        // Nothing selected.
        Alert alert = new Alert(AlertType.WARNING);
        alert.initOwner(mainApp.getPrimaryStage());
        alert.setTitle("No Selection");
        alert.showAndWait();
    }
} 

But it gives java.lang.UnsupportedOperationException error. I have done the same thing in my sample project and it goes fine. So, how can I resolve this issue?

Upvotes: 2

Views: 3866

Answers (2)

Andreas Billmann
Andreas Billmann

Reputation: 206

SortedList and FilteredList inherit the remove method from AbstractList which does not support remove(index). You have to remove the object from the source list (mainApp.getFileData()) As the selected index might not be the correct index in the source list (after filtering), there is a method to get the correct index in the source list

sortedData.getSourceIndexFor(mainApp.getFileData(), selectedIndex);

So you should change your code to

@FXML
private void deleteFile() {
  int selectedIndex = fileTable.getSelectionModel().getSelectedIndex();
  if (selectedIndex >= 0) {
    int sourceIndex = sortedData.getSourceIndexFor(mainApp.getFileData(), selectedIndex);
    mainApp.getFileData().remove(sourceIndex);
  }
}

I have removed the else cause in this example to reduce it to the minimum.

Upvotes: 4

James_D
James_D

Reputation: 209553

Remove the data from the underlying list, not the filtered/sorted list:

FileModel selectedItem = fileTable.getSelectionModel().getSelectedItem();
if (selectedItem != null) {
    mainApp.getFileData().remove(selectedItem);
}

Upvotes: 5

Related Questions