[英]JavaFX TableView sorting consistency on property update
我有一個數據異步更改的 TableView。 TableView 有一個排序,我希望根據當前排序對更新的行進行排序。 添加到模型中的新行已正確排序,但更改數據不會反映在當前排序中。
是每次更新數據后調用 TableView.sort() 的唯一解決方案嗎?
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);
}
}
當您更改現有元素中的值時,該表無法自動重新排序,因為您沒有為SortedList
提供任何機制來“知道”這些更改何時發生。
如果您在模型類中公開 JavaFX 屬性:
public class Person {
private final StringProperty name = new SimpleStringProperty("");
private final IntegerProperty age = new SimpleIntegerProperty(0);
public Person(String name, Integer age) {
setName(name);
setAge(age);
}
public StringProperty nameProperty() {
return name ;
}
public IntegerProperty ageProperty() {
return 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();
}
}
並使用提取器創建基礎列表,以便在感興趣的屬性更改時觸發事件:
ObservableList<Person> data = FXCollections.observableArrayList(p ->
new Observable[] {p.nameProperty(), p.ageProperty()});
然后SortedList
將在屬性更改時接收事件,並且能夠根據需要“自動”重新排序元素。
正如@Enigo 指出的那樣,此解決方案將確保在更新每個列表項中的屬性后表具有正確的排序。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.