I have a TableView with data changing asynchronously. The TableView has a sort and I'd like updated rows to be sorted according to the current sort. New rows added to the model are sorted correctly, but changing the data doesn't get reflected in the current sort.
Is the only solution to call TableView.sort() after each update to the data?
import javafx.application.Application;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.SortedList;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class SortingItOut extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
ObservableList<Person> data = FXCollections.observableArrayList();
Person c = new Person("C", 120);
data.addAll(new Person("A", 100), new Person("B", 50), c, new Person("D", 25));
TableColumn<Person, String> nameColumn = new TableColumn<>("Name");
nameColumn.setCellValueFactory(param -> param.getValue().name);
TableColumn<Person, Number> ageColumn = new TableColumn<>("Age");
ageColumn.setCellValueFactory(param -> param.getValue().age);
TableView<Person> table = new TableView<>(data);
table.getColumns().addAll(nameColumn, ageColumn);
table.getSortOrder().add(ageColumn);
SortedList<Person> sortedList = new SortedList<>(data);
sortedList.comparatorProperty().bind(table.comparatorProperty());
table.setItems(sortedList);
Button modify = new Button("modify C age");
modify.setOnAction(e -> c.setAge(c.getAge() == 120 ? 75 : 120));
Button add = new Button("add");
add.setOnAction(e -> data.add(new Person("E", (int) (Math.random() * 100))));
VBox box = new VBox(10);
box.setAlignment(Pos.CENTER);
box.getChildren().addAll(table, modify, add);
Scene scene = new Scene(box);
primaryStage.setScene(scene);
primaryStage.show();
}
public class Person {
private final SimpleStringProperty name = new SimpleStringProperty("");
private final SimpleIntegerProperty age = new SimpleIntegerProperty(0);
public Person(String name, Integer age) {
setName(name);
setAge(age);
}
public String getName() {
return name.get();
}
public void setName(String name) {
this.name.set(name);
}
public void setAge(Integer age) {
this.age.set(age);
}
public Integer getAge() {
return age.get();
}
}
public static void main(String[] args) {
launch(args);
}
}