当我在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,因为添加新集合时将删除它们。