Reputation: 11559
When I work with the TableView<T>
in JavaFX, I often call it's setAll()
to give it a new List<T>
. However, if the number of rows are somewhat large the scrollbar will go crazy as items are removed and added.
How do I stop this behavior? Is there a way I can "turn off" the visual updating while it is populating the new List<T>
? It may feel unpolished and annoying to the user if it behaves like this.
TableView<MyType> tableView = ...;
tableView.getItems().setAll(someList); //goes crazy for a second
UPDATE I was asked to provide an SSCCE, and I came up with this. It does not reflect the problem as severely as my prod application. But if you move the scrollbar to the center and then click the "REBUILD" button it does jump around. Is there a way I can keep the scrollbar fixed during refresh? I imagine if I can do that, it will resolve my larger issue.
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);
}
}
Upvotes: 2
Views: 534
Reputation: 66
I've tried using the setAll() method and indeed it starts acting a bit weird when using very large collections. I would suggest replacing the getItems().setAll() with the following.
tableView.setItems(FXCollections.observableArrayList(yourList));
the setAll() method will iterate over both collections which I think makes the scrollbar jump, while setItems() just throws out the old Collection and replaces it with the new one. When using a very large dataset, the scrollbar will still shrink as the collection is added one by one into the observable collection, but not as eratically as with setAll().
If you want to keep the sorting, you probably want to get the sortColumn and sortType before you do the setItems as this will be removed when adding the new collection.
Upvotes: 2