-
Bug
-
Resolution: Unresolved
-
P3
-
jfx20, jfx17, jfx19
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
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