> If there are many columns, the current TableView will stall scrolling. 
> Resolving this performance issue requires column
> virtualization. Virtualization mode is enabled when the row height is fixed 
> by the following method.
> `tableView.setFixedCellSize(height)`
> 
> This proposal includes a fix because the current code does not correctly 
> implement column virtualization.
> 
> The improvement of this proposal can be seen in the following test program.
> 
>  Java
> import java.util.Arrays;
> import java.util.Collections;
> 
> import javafx.animation.AnimationTimer;
> import javafx.application.Application;
> import javafx.beans.property.SimpleStringProperty;
> import javafx.collections.ObservableList;
> import javafx.scene.Scene;
> import javafx.scene.control.Button;
> import javafx.scene.control.TableColumn;
> import javafx.scene.control.TableView;
> import javafx.scene.layout.BorderPane;
> import javafx.scene.layout.HBox;
> import javafx.stage.Stage;
> 
> public class BigTableViewTest2 extends Application {
>       private static final boolean USE_WIDTH_FIXED_SIZE = false;
>       private static final boolean USE_HEIGHT_FIXED_SIZE = true;
> //    private static final int COL_COUNT=30;
> //    private static final int COL_COUNT=300;
> //    private static final int COL_COUNT=600;
>       private static final int COL_COUNT = 1000;
>       private static final int ROW_COUNT = 1000;
> 
>       @Override
>       public void start(final Stage primaryStage) throws Exception {
>               final TableView<String[]> tableView = new TableView<>();
> 
> //        tableView.setTableMenuButtonVisible(true); //too heavy
>               if (USE_HEIGHT_FIXED_SIZE) {
>                       tableView.setFixedCellSize(24);
>               }
> 
>               final ObservableList<TableColumn<String[], ?>> columns = 
> tableView.getColumns();
>               for (int i = 0; i < COL_COUNT; i++) {
>                       final TableColumn<String[], String> column = new 
> TableColumn<>("Col" + i);
>                       final int colIndex = i;
>                       column.setCellValueFactory((cell) -> new 
> SimpleStringProperty(cell.getValue()[colIndex]));
>                       columns.add(column);
>                       if (USE_WIDTH_FIXED_SIZE) {
>                               column.setPrefWidth(60);
>                               column.setMaxWidth(60);
>                               column.setMinWidth(60);
>                       }
>               }
> 
>               final Button load = new Button("load");
>               load.setOnAction(e -> {
>                       final ObservableList<String[]> items = 
> tableView.getItems();
>                       items.clear();
>                       for (int i = 0; i < ROW_COUNT; i++) {
>                               final String[] rec = new String[COL_COUNT];
>                               for (int j = 0; j < rec.length; j++) {
>                                       rec[j] = i + ":" + j;
>                               }
>                               items.add(rec);
>                       }
>               });
> 
>               final Button reverse = new Button("reverse columns");
>               reverse.setOnAction(e -> {
>                       final TableColumn<String[], ?>[] itemsArray = 
> columns.toArray(new TableColumn[0]);
>                       Collections.reverse(Arrays.asList(itemsArray));
>                       tableView.getColumns().clear();
>                       
> tableView.getColumns().addAll(Arrays.asList(itemsArray));
>               });
> 
>               final Button hide = new Button("hide % 10");
>               hide.setOnAction(e -> {
>                       for (int i = 0, n = columns.size(); i < n; i++) {
>                               if (i % 10 == 0) {
>                                       columns.get(i).setVisible(false);
>                               }
>                       }
>               });
> 
>               final BorderPane root = new BorderPane(tableView);
>               root.setTop(new HBox(8, load, reverse, hide));
> 
>               final Scene scene = new Scene(root, 800, 800);
>               primaryStage.setScene(scene);
>               primaryStage.show();
>               this.prepareTimeline(scene);
>       }
> 
>       public static void main(final String[] args) {
>               Application.launch(args);
>       }
> 
>       private void prepareTimeline(final Scene scene) {
>               new AnimationTimer() {
>                       @Override
>                       public void handle(final long now) {
>                               final double fps = 
> com.sun.javafx.perf.PerformanceTracker.getSceneTracker(scene).getInstantFPS();
>                               ((Stage) scene.getWindow()).setTitle("FPS:" + 
> (int) fps);
>                       }
>               }.start();
>       }
> }

yosbits has updated the pull request with a new target base due to a merge or a 
rebase. The incremental webrev excludes
the unrelated changes brought in by the merge/rebase. The pull request contains 
two additional commits since the last
revision:

 - 8185886: Fix scroll performance of TableView with many columns
 - 8185886: Fix scroll performance of TableView with many columns

-------------

Changes:
  - all: https://git.openjdk.java.net/jfx/pull/125/files
  - new: https://git.openjdk.java.net/jfx/pull/125/files/19fabf2e..dcbbfdcd

Webrevs:
 - full: https://webrevs.openjdk.java.net/?repo=jfx&pr=125&range=02
 - incr: https://webrevs.openjdk.java.net/?repo=jfx&pr=125&range=01-02

  Stats: 429339 lines in 6107 files changed: 215276 ins; 144670 del; 69393 mod
  Patch: https://git.openjdk.java.net/jfx/pull/125.diff
  Fetch: git fetch https://git.openjdk.java.net/jfx pull/125/head:pull/125

PR: https://git.openjdk.java.net/jfx/pull/125

Reply via email to