-
Bug
-
Resolution: Unresolved
-
P3
-
jfx14, jfx15
The example below is a TreeTableView with enough rows to show a vertical scrollBar and many columns (to see the misbehavior clearly): after scrolling horizontally to/near the end and then scroll vertically, empty space shows at the beginning of some rows
To reproduce, compile and run the example:
- drag the thumb of the horizontal scrollbar to the right end
- note that the row layout is as expected, that is all cell content appears where it is expected (the second # shown is the column index) and each visible column is aligned properly with its header
- drag the thumb of the vertical scrollbar
- expected: row layout keeps same as before vertical scrolling
- actual: some (or all, exact number seems to be spurious) rows scrolled into the viewport have empty space at the left and the cells of those rows are not properly aligned with their respective headers
- also note that on appearance of the first mis-aligned row, the horizontal thumb jumps a bit from the end to slightly before the end
Another misbehavior (not always reproducible)
- after the above, drag the vertical thumb to the end
- drag the horizontal thumb slightly to the left, then back to the end
- drag the vertical thumb up
- expected: rows are scrolled accordingly
- actually: rows remain where they are
Could be related to the broken horizontal virtualization as noted in JDK-8185887 - can't be certain, because that issue has no example to test ;) Also it seems to be fixed by https://github.com/openjdk/jfx/pull/125
The example (adapted/simplified fromJDK-8166956)
public class TreeTableViewBrokenRowLayout extends Application {
// constants to play with
private static int COLS = 100;
private static int PARENT_ROWS = 2;
private static int CHILD_ROWS = 20;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
BorderPane content = new BorderPane();
Scene scene = new Scene(content);
stage.setTitle("TreeTable broken row layout");
TreeItem<List<String>> root = new TreeItem<>(createItemContent("Root", true));
TreeTableView<List<String>> treeTableView = new TreeTableView<>(root);
treeTableView.setFixedCellSize(24);
treeTableView.setPrefWidth(800);
treeTableView.setPrefHeight(500);
content.setCenter(treeTableView);
// add top-level children (and nesting)
for (int i = 0; i < PARENT_ROWS; ++i) {
TreeItem<List<String>> child = addNodes("parent", root);
// nesting
// child = addNodes("child", child);
// child = addNodes("child", child);
// child = addNodes("child", child);
}
TreeTableColumn<List<String>, String> column = new TreeTableColumn<>("TreeColumn");
// column.setPrefWidth(150);
column.setCellValueFactory(cc -> new ReadOnlyStringWrapper(cc.getValue().getValue().get(0)));
treeTableView.getColumns().add(column);
for (int i = 1; i < COLS; ++i) {
int ii = i;
TreeTableColumn<List<String>, String> col = new TreeTableColumn<>("" + i);
col.setCellValueFactory(cc -> new ReadOnlyStringWrapper(cc.getValue().getValue().get(ii)));
treeTableView.getColumns().add(col);
}
stage.setScene(scene);
stage.show();
}
int dirCount;
private TreeItem<List<String>> addNodes(String itemText, TreeItem<List<String>> parent) {
parent.setExpanded(true);
TreeItem<List<String>> childRoot = new TreeItem<>(createItemContent(itemText, false));
childRoot.setExpanded(true);
parent.getChildren().add(childRoot);
for (int i = 0; i < CHILD_ROWS; ++i) {
List<String> content = createItemContent(dirCount++);
TreeItem<List<String>> childNode = new TreeItem<>(content);
childRoot.getChildren().add(childNode);
}
return childRoot;
}
private List<String> createItemContent(int row) {
List<String> content = new ArrayList<>();
for (int col = 0; col < COLS; col++) {
content.add(row + "/" + col);
}
return content;
}
private List<String> createItemContent(String text, boolean isRoot) {
List<String> content = new ArrayList<>();
if (isRoot) {
content.add(text);
} else {
content.add(text + dirCount++);
}
for (int col = 1; col < COLS; col++) {
content.add("");
}
return content;
}
}
To reproduce, compile and run the example:
- drag the thumb of the horizontal scrollbar to the right end
- note that the row layout is as expected, that is all cell content appears where it is expected (the second # shown is the column index) and each visible column is aligned properly with its header
- drag the thumb of the vertical scrollbar
- expected: row layout keeps same as before vertical scrolling
- actual: some (or all, exact number seems to be spurious) rows scrolled into the viewport have empty space at the left and the cells of those rows are not properly aligned with their respective headers
- also note that on appearance of the first mis-aligned row, the horizontal thumb jumps a bit from the end to slightly before the end
Another misbehavior (not always reproducible)
- after the above, drag the vertical thumb to the end
- drag the horizontal thumb slightly to the left, then back to the end
- drag the vertical thumb up
- expected: rows are scrolled accordingly
- actually: rows remain where they are
Could be related to the broken horizontal virtualization as noted in JDK-8185887 - can't be certain, because that issue has no example to test ;) Also it seems to be fixed by https://github.com/openjdk/jfx/pull/125
The example (adapted/simplified from
public class TreeTableViewBrokenRowLayout extends Application {
// constants to play with
private static int COLS = 100;
private static int PARENT_ROWS = 2;
private static int CHILD_ROWS = 20;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
BorderPane content = new BorderPane();
Scene scene = new Scene(content);
stage.setTitle("TreeTable broken row layout");
TreeItem<List<String>> root = new TreeItem<>(createItemContent("Root", true));
TreeTableView<List<String>> treeTableView = new TreeTableView<>(root);
treeTableView.setFixedCellSize(24);
treeTableView.setPrefWidth(800);
treeTableView.setPrefHeight(500);
content.setCenter(treeTableView);
// add top-level children (and nesting)
for (int i = 0; i < PARENT_ROWS; ++i) {
TreeItem<List<String>> child = addNodes("parent", root);
// nesting
// child = addNodes("child", child);
// child = addNodes("child", child);
// child = addNodes("child", child);
}
TreeTableColumn<List<String>, String> column = new TreeTableColumn<>("TreeColumn");
// column.setPrefWidth(150);
column.setCellValueFactory(cc -> new ReadOnlyStringWrapper(cc.getValue().getValue().get(0)));
treeTableView.getColumns().add(column);
for (int i = 1; i < COLS; ++i) {
int ii = i;
TreeTableColumn<List<String>, String> col = new TreeTableColumn<>("" + i);
col.setCellValueFactory(cc -> new ReadOnlyStringWrapper(cc.getValue().getValue().get(ii)));
treeTableView.getColumns().add(col);
}
stage.setScene(scene);
stage.show();
}
int dirCount;
private TreeItem<List<String>> addNodes(String itemText, TreeItem<List<String>> parent) {
parent.setExpanded(true);
TreeItem<List<String>> childRoot = new TreeItem<>(createItemContent(itemText, false));
childRoot.setExpanded(true);
parent.getChildren().add(childRoot);
for (int i = 0; i < CHILD_ROWS; ++i) {
List<String> content = createItemContent(dirCount++);
TreeItem<List<String>> childNode = new TreeItem<>(content);
childRoot.getChildren().add(childNode);
}
return childRoot;
}
private List<String> createItemContent(int row) {
List<String> content = new ArrayList<>();
for (int col = 0; col < COLS; col++) {
content.add(row + "/" + col);
}
return content;
}
private List<String> createItemContent(String text, boolean isRoot) {
List<String> content = new ArrayList<>();
if (isRoot) {
content.add(text);
} else {
content.add(text + dirCount++);
}
for (int col = 1; col < COLS; col++) {
content.add("");
}
return content;
}
}
- relates to
-
JDK-8166956 JavaFX TreeTableView slow scroll performance
- Closed
-
JDK-8185887 TableRowSkinBase fails to correctly virtualize cells in horizontal direction
- Open
- links to
-
Review(master) openjdk/jfx/1644