Reputation: 631
I am using a TableView to visualize a SortedList backed up by an ObservableList.
The comparator of the SortedList is bound to the comparator of the TableView:
sortedList().comparatorProperty().bind(tableView.comparatorProperty());
The SortedList sorts as expected (by the comparator of the TableView chosen) when I add an item to the underlying ObservableList.
Although when I change a Property of the ObservableList (with a CheckBoxTableCell, but that shouldn't matter), the SortedList doesn't sort again.
Is this supposed to work or do I have to find a workaround?
I am using jdk 8 b121.
Upvotes: 4
Views: 1875
Reputation: 51525
Note: this answer assumes that "change a property of the ObservableList" actually should read "change a property of an item of the ObservableList". It the assumption is incorrect, I'll delete.
A SortedList is the clean solution for sortable data in a TableView - it's designed and implemented to keep itself sorted when the wrapped list is changed. Provided, the backing list notifies its listeners about the change. That's working without needing additional client code for modifications to the list (like add/remove/set of items).
On the other hand, there is no general way it can know about modifications of properties of a contained item: client code must provide an extractor (aka callback that returns an array of Observables) that allows the list to fire update events to its listeners.
An example (Person a demo bean with obvious properties - replace with your favourite example bean), the edit-button simply prepends a "z" to the last name of the selected person.
public class TableViewSortSample extends Application {
private Parent getContent() {
// wrap the backing list into an observableList with an extractor
ObservableList<Person> persons = FXCollections.observableList(
Person.persons(),
person -> new Observable[] {person.lastNameProperty(), person.firstNameProperty()}
);
// wrap the observableList into a sortedList
SortedList<Person> sortedPersons = new SortedList<>(persons);
// set the sorted list as items to a tableView
TableView<Person> table = new TableView<>(sortedPersons);
// bind the comparator of the sorted list to the table's comparator
sortedPersons.comparatorProperty().bind(table.comparatorProperty());
TableColumn<Person, String> firstName = new TableColumn<>("First Name");
firstName.setCellValueFactory(new PropertyValueFactory<>("firstName"));
TableColumn<Person, String> lastName = new TableColumn<>("Last Name");
lastName.setCellValueFactory(new PropertyValueFactory<>("lastName"));
table.getColumns().addAll(firstName, lastName);
Button edit = new Button("Edit");
edit.setOnAction(e -> {
Person person = table.getSelectionModel().getSelectedItem();
if (person != null) {
person.setLastName("z" + person.getLastName());
}
});
VBox pane = new VBox(table, edit);
return pane;
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setScene(new Scene(getContent()));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Upvotes: 2