changeset 7295:561b5d8d4971

RT-37502: [TreeView] StackOverflow when overriding TreeItem getChildren() method with selection set
author jgiles
date Thu, 12 Jun 2014 16:02:53 +1200
parents fdcebfd4841f
children 70b72d969e74
files modules/controls/src/main/java/javafx/scene/control/TreeItem.java modules/controls/src/main/java/javafx/scene/control/TreeUtil.java modules/controls/src/test/java/javafx/scene/control/TreeViewTest.java
diffstat 3 files changed, 53 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/modules/controls/src/main/java/javafx/scene/control/TreeItem.java	Thu Jun 12 11:02:31 2014 +1200
+++ b/modules/controls/src/main/java/javafx/scene/control/TreeItem.java	Thu Jun 12 16:02:53 2014 +1200
@@ -369,7 +369,7 @@
     // It is important that interactions with this list go directly into the
     // children property, rather than via getChildren(), as this may be 
     // a very expensive call.
-    private ObservableList<TreeItem<T>> children;
+    ObservableList<TreeItem<T>> children;
 
     // Made static based on findings of RT-18344 - EventHandlerManager is an
     // expensive class and should be reused amongst classes if at all possible.
--- a/modules/controls/src/main/java/javafx/scene/control/TreeUtil.java	Thu Jun 12 11:02:31 2014 +1200
+++ b/modules/controls/src/main/java/javafx/scene/control/TreeUtil.java	Thu Jun 12 16:02:53 2014 +1200
@@ -108,7 +108,7 @@
         List<TreeItem<T>> siblings;
         
         while (!i.equals(root) && p != null) {
-            siblings = p.getChildren();
+            siblings = p.children;
             
             // work up each sibling, from the current item
             int itemIndex = siblings.indexOf(i);
--- a/modules/controls/src/test/java/javafx/scene/control/TreeViewTest.java	Thu Jun 12 11:02:31 2014 +1200
+++ b/modules/controls/src/test/java/javafx/scene/control/TreeViewTest.java	Thu Jun 12 16:02:53 2014 +1200
@@ -1937,4 +1937,55 @@
 
         sl.dispose();
     }
+
+    @Test public void test_rt_37502() {
+        final TreeView<Long> tree = new TreeView<>(new NumberTreeItem(1));
+        tree.setCellFactory(new Callback<TreeView<Long>, TreeCell<Long>>() {
+            @Override
+            public TreeCell<Long> call(TreeView<Long> param) {
+                return new TreeCell<Long>() {
+                    @Override
+                    protected void updateItem(Long item, boolean empty) {
+                        super.updateItem(item, empty);
+                        if (!empty) {
+                            setText(item != null ? String.valueOf(item) : "");
+                        } else{
+                            setText(null);
+                        }
+                    }
+                };
+            }
+        });
+
+        StageLoader sl = new StageLoader(tree);
+
+        tree.getSelectionModel().select(0);
+        tree.getRoot().setExpanded(true);
+        Toolkit.getToolkit().firePulse();
+
+        sl.dispose();
+    }
+
+    private static class NumberTreeItem extends TreeItem<Long>{
+        private boolean loaded = false;
+
+        private NumberTreeItem(long value) {
+            super(value);
+        }
+
+        @Override public boolean isLeaf() {
+            return false;
+        }
+
+        @Override public ObservableList<TreeItem<Long>> getChildren() {
+            if(!loaded){
+                final ObservableList<TreeItem<Long>> children =  super.getChildren();
+                for (int i = 0; i < 10; i++) {
+                    children.add(new NumberTreeItem(10 * getValue() + i));
+                }
+                loaded = true;
+            }
+            return super.getChildren();
+        }
+    }
 }