RFR: 8185886: Improve scrolling performance of TableView and TreeTableView [v3]

yosbits github.com+7517141+yososs at openjdk.java.net
Mon Aug 31 18:45:26 UTC 2020


> 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


More information about the openjfx-dev mailing list