当我在JavaFX中使用TableView<T>时,通常称它为setAll()以为其赋予新的List<T>。但是,如果行数太大,则滚动条将在删除和添加项目时发疯。

如何停止这种行为?有没有办法在填充新的List<T>时“关闭”视觉更新?如果它表现为这样,可能会使用户感到不舒服和烦恼。

TableView<MyType> tableView = ...;

tableView.getItems().setAll(someList); //goes crazy for a second


更新
我被要求提供SSCCE,我想到了这个。它没有像我的prod应用程序那样严重地反映问题。但是,如果将滚动条移动到中心,然后单击“重新构建”按钮,它确实会跳来跳去。有没有一种方法可以使刷新期间的滚动条保持固定?我想如果可以的话,它将解决更大的问题。

public final class TableViewJumpTest extends Application {

    private Random rand = new Random();

    private final Supplier<List<Integer>> listSupplier = () -> IntStream.range(0,rand.nextInt(100000))
            .mapToObj(i -> rand.nextInt(10000)).collect(Collectors.toList());

    @Override
    public void start(Stage stage) throws Exception {

        TableView<Integer> tableView = new TableView<>();

        TableColumn<Integer,Number> col = new TableColumn<>("VALUE");
        col.setCellValueFactory(cb -> new ReadOnlyIntegerWrapper(cb.getValue()));
        tableView.getColumns().add(col);

        tableView.getItems().setAll(listSupplier.get());


        VBox vBox = new VBox();

        vBox.getChildren().add(tableView);

        Button bttn = new Button("REBUILD");
        bttn.setOnAction(e -> tableView.getItems().setAll(listSupplier.get()));

        vBox.getChildren().add(bttn);

        stage.setScene(new Scene(vBox));

        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

}

最佳答案

我已经尝试过使用setAll()方法,并且实际上在使用非常大的集合时,它开始表现得有些怪异。我建议将getItems()。setAll()替换为以下内容。

tableView.setItems(FXCollections.observableArrayList(yourList));


setAll()方法将遍历两个集合,我认为这会使滚动条跳转,而setItems()只是抛出旧的Collection并将其替换为新的Collection。当使用非常大的数据集时,滚动条仍会缩小,因为将收藏夹一个一个地添加到可观察的收藏夹中,但是不像setAll()那样可笑。

如果要保持排序,则可能需要在执行setItems之前获取sortColumn和sortType,因为添加新集合时将删除它们。

10-08 20:13