Java 8中的SortedList TableView不刷新

4
我将用一个TableView来可视化由ObservableList支持的SortedList。
SortedList的比较器被绑定到TableView的比较器上:
sortedList().comparatorProperty().bind(tableView.comparatorProperty());

当我向基础的ObservableList添加一个项目时,SortedList按照预期排序(按照选择的TableView比较器)。

但是,当我更改ObservableList的属性(使用CheckBoxTableCell,但这不应该有影响)时,SortedList不再排序。

这是否应该正常工作,还是我需要找到解决方法?

我正在使用jdk 8 b121。


2
TableView的比较器与SortedList的比较器绑定在一起 => 不,正好相反。你为什么要使用一个有序列表呢?我期望当items列表被改变(添加/移除)时,TableView的排序会被“刷新”,但不会在单个item被改变时进行排序。所以你可能需要在复选框上添加一个监听器,并通过编程重新对表格进行排序。 - assylias
1
我主要使用SortedList是因为它是新的,而且认为它在排序方面更有效率。但是SortedList不能手动排序(可能有一些解决方法),所以我转而显示ObservableList,并且它可以工作(我必须在每次更改时调用FXCollections.sort())。 - Lukas Leitinger
其实,我也不得不手动获取TableView的Comparator来进行.compareTo()函数的操作,但现在它可以工作了! - Lukas Leitinger
1
@LukasLeitinger 你应该添加一个答案并接受它。 - gontard
1个回答

2
注意:本答案假设“更改ObservableList的属性”实际上应该读作“更改ObservableList中某个项目的属性”。如果这个假设是不正确的,我会删除它。
SortedList是TableView中可排序数据的干净解决方案 - 它被设计和实现为在包装列表发生更改时保持自身排序。前提是,支持列表通过通知其侦听器来实现更改。这样就不需要额外的客户端代码来修改列表(如添加/删除/设置项)。
另一方面,它无法普遍地了解所包含项目的属性修改:客户端代码必须提供一个提取器(即返回Observable数组的回调函数),以允许列表向其侦听器触发更新事件。
例如(Person是一个演示bean,具有明显的属性 - 可以用您喜欢的示例bean进行替换),编辑按钮只是将选定人员的姓氏前缀添加“z”。
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);
    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接