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

Issues synchronizing 2 TreeViews via their scrollbar bindBidirectional

XMLWordPrintable

    • b01
    • generic
    • generic

      ADDITIONAL SYSTEM INFORMATION :
      Windows 10 Enterprise/openjdk11/JavaFX 19
      Also reproducible with openjdk17 and JavaFX 20 (early release)

      A DESCRIPTION OF THE PROBLEM :
      The problem seems to have been introduced in version 17 (version 16 seems to be working fine) and it happens with 2 TreeViews (that share the same content/root) are synchronized via their corresponding scrollbars valueProperty().bindBidirectional.

      I may be wrong, but I suspect about the following version 17 commit: https://github.com/openjdk/jfx/commit/8e547571fb3d40df843c27fc11921b5d4765c481

      REGRESSION : Last worked in version 16

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Things work fine if the scrollbar is at the very top (value = 0), as soon as you scroll down and expand or collapse any items, the content of the 2 TreeViews gets out of sync (same content will be displayed in different lines).

      The issue corrects itself when scroll again up/down, selecting a different row or the application loses focus.

      See source code below that shows the issue.



      ---------- BEGIN SOURCE ----------
      package javafx.test;

      import java.util.ArrayList;
      import java.util.List;

      import javafx.application.Application;
      import javafx.scene.Group;
      import javafx.scene.Parent;
      import javafx.scene.Scene;
      import javafx.scene.control.ScrollBar;
      import javafx.scene.control.TreeItem;
      import javafx.scene.control.TreeView;
      import javafx.scene.layout.HBox;
      import javafx.stage.Stage;

      public class TreeViewSyncScrollingSample extends Application {

      private static final int CHILDREN_PER_LEVEL = 5;
      private static final int NUMBER_OF_LEVELS = 3;

      public static void main(String[] args) {
      Application.launch(args);
      }

      @Override
      public void start(Stage stage) {

      final String version = String.format("Java: %s, JavaFX: %s",
      System.getProperty("java.runtime.version"), System.getProperty("javafx.version"));
      stage.setTitle(version);
      final Scene scene = new Scene(new Group(), 500, 400);
      Group sceneRoot = (Group) scene.getRoot();

      final TreeItem<String> root = createRootNode();
      final TreeView<String> treeView1 = new TreeView<>(root);

      // treetable 2
      final TreeView<String> treeView2 = new TreeView<>(root);

      // create the layout and start
      final HBox hbox = new HBox(treeView1, treeView2);
      sceneRoot.getChildren().add(hbox);
      stage.setScene(scene);
      stage.show();

      final ScrollBar scrollBar1 = findVerticalScrollBar(treeView1);
      final ScrollBar scrollBar2 = findVerticalScrollBar(treeView2);
      scrollBar1.valueProperty().bindBidirectional(scrollBar2.valueProperty());
      }

        private ScrollBar findVerticalScrollBar(Parent table) {
          return (ScrollBar)table.lookup(".scroll-bar:vertical");
        }
         
        private List<TreeItem<String>> createChildren(int level, String idPrefix) {
         if (level == NUMBER_OF_LEVELS) {
         return null;
         }
      final List<TreeItem<String>> thisLevelChildren = new ArrayList<>();
      for (int i = 0; i < CHILDREN_PER_LEVEL; i++) {
      final String id = String.format("%s%s", idPrefix, i);
      final TreeItem<String> child = new TreeItem<>(String.format("Child %s", id));
      final List<TreeItem<String>> nextLevelChildren = createChildren(level+1, id);
      if (nextLevelChildren != null) {
      child.setExpanded(true);
      child.getChildren().setAll(nextLevelChildren);
      }
      thisLevelChildren.add(child);
      }
      return thisLevelChildren;
        }
         
        private TreeItem<String> createRootNode() {

         final TreeItem<String> root = new TreeItem<>("Root");
         final List<TreeItem<String>> childNodes = createChildren(0, "");
      root.setExpanded(true);
      root.getChildren().setAll(childNodes);
      return root;
        }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      N/A so far, any temporary workaround would be appreciated.

      FREQUENCY : always


        1. Capture.PNG
          25 kB
          Praveen Narayanaswamy
        2. Capture2.PNG
          23 kB
          Praveen Narayanaswamy
        3. Capture3.PNG
          25 kB
          Praveen Narayanaswamy
        4. TreeViewSyncScrollingSample.java
          3 kB
          Praveen Narayanaswamy

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: