Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8252566

TreeTableView: broken row layout for fixedCellSize

XMLWordPrintable

      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 from JDK-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;
              }
          }

            Unassigned Unassigned
            fastegal Jeanette Winzenburg
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: