Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Setting root on a Tree goes in infinite loop

    Hello Community,
    I'm having a problem setting the root of a Tree (com.smartgwt.client.widgets.tree.Tree). I'm using SmartGwt version 6.1 (build 2018-03-09).

    I've made a short test example to explain the problem.

    In this example I create a small Tree with just two nodes. The Tree is configured in TreeModelType.PARENT mode.

    Only to visually represent the Tree, I draw it in a TreeGrid but this is actually not important. Indeed, in our real application the Tree is drawn in a Canvas. The problem seems isolated in the Tree data structure.

    After the component has been drawn, following some external triggers, I need to change the root of the Tree, making one of the TreeNode the new root. I simulate this behaviour with the two buttons, each one setting the root of the Tree to one of the nodes in the Tree.

    In each case, the setRoot() method seems to go in an infinite loop. After some code debugging, I noticed that the loop is originated when it tries to set the root's parent as the root itself.


    Thank you for any feedback you can give me if this is actually a bug or it's me not doing the correct steps to change the root of a Tree.

    TreeRootExample.java
    Code:
    import com.google.gwt.core.client.EntryPoint;
    import com.smartgwt.client.types.TreeModelType;
    import com.smartgwt.client.widgets.Button;
    import com.smartgwt.client.widgets.events.ClickEvent;
    import com.smartgwt.client.widgets.events.ClickHandler;
    import com.smartgwt.client.widgets.layout.VLayout;
    import com.smartgwt.client.widgets.tree.Tree;
    import com.smartgwt.client.widgets.tree.TreeGrid;
    import com.smartgwt.client.widgets.tree.TreeNode;
    
    public class TreeRootExample implements EntryPoint {
    
        @Override
        public void onModuleLoad() {
    
            final TreeNode node1 = new TreeNode();
            node1.setAttribute("id", "111");
            node1.setAttribute("parentId", (String) null);
            node1.setAttribute("name", "Node 1");
            final TreeNode node2 = new TreeNode();
            node2.setAttribute("id", "222");
            node2.setAttribute("parentId", "111");
            node2.setAttribute("name", "Node 2");
            final TreeNode[] nodes = { node1, node2 };
    
            final Tree tree = new Tree();
            tree.setModelType(TreeModelType.PARENT);
            tree.setData(nodes);
    
            final TreeGrid grid = new TreeGrid();
            grid.setData(tree);
    
            final Button rootNode1 = new Button("MAKE ROOT 1");
            rootNode1.addClickHandler(new ClickHandler() {
                @Override
                public void onClick(ClickEvent event) {
                    tree.setRoot(node1);
                }
            });
    
            final Button rootNode2 = new Button("MAKE ROOT 2");
            rootNode2.addClickHandler(new ClickHandler() {
                @Override
                public void onClick(ClickEvent event) {
                    tree.setRoot(node2);
                }
            });
    
            final VLayout layout = new VLayout();
            layout.setWidth(150);
            layout.setHeight(150);
            layout.addMember(grid);
            layout.addMember(rootNode1);
            layout.addMember(rootNode2);
            layout.draw();
        }
    
    }

    #2
    While we'd like to avoid this crashing outright, the approach you're taking probably isn't what you want. See tree.showRoot: the default is for root to be an implicit Node, not shown. You should either redo the tree by removing all nodes under root, or set showRoot:true and provide a root node that will be visible.

    Comment


      #3
      Thank you for your explanation.

      Indeed, I'm porting an application created with SmartGwt 4.1 to the newest version.
      Probably the idea in the mind of the creator was the second one you provided: setting a root node and making it visible with setShowRoot(true), thus eliminating the implicit "/" root node.

      I would like to report that even this smaller test example suffers the same issue of infinite loop:

      TreeRootExample.java
      Code:
      import com.google.gwt.core.client.EntryPoint;
      import com.smartgwt.client.types.TreeModelType;
      import com.smartgwt.client.widgets.layout.VLayout;
      import com.smartgwt.client.widgets.tree.Tree;
      import com.smartgwt.client.widgets.tree.TreeGrid;
      import com.smartgwt.client.widgets.tree.TreeNode;
      
      public class TreeRootExample implements EntryPoint {
      
          @Override
          public void onModuleLoad() {
      
              final TreeNode node1 = new TreeNode();
              node1.setAttribute("id", "111");
              node1.setAttribute("parentId", (String) null);
              node1.setAttribute("name", "Node 1");
              final TreeNode node2 = new TreeNode();
              node2.setAttribute("id", "222");
              node2.setAttribute("parentId", "111");
              node2.setAttribute("name", "Node 2");
              final TreeNode[] nodes = { node1, node2 };
      
              final Tree tree = new Tree();
              tree.setModelType(TreeModelType.PARENT);
              tree.setShowRoot(true);
              tree.setRoot(node1);
              tree.setData(nodes);
      
              final TreeGrid grid = new TreeGrid();
              grid.setData(tree);
      
              grid.draw();
          }
      
      }

      Comment


        #4
        That second snippet is invalid in a similar way: you can't provide a root node, then put the root node somewhere in the data under root. That's an invalidly looping tree model.

        Comment


          #5
          Thank you, I think I've understood the logic behind it now.

          Basically, our code was created using SmartGwt 4.1 (and before). A lot of the logic was to create a full tree, then prune it by setting the root node to one of the TreeNode of the tree itself.
          Probably this was bad habit even in SmartGwt 4.1 but it was working.

          As you said, the best way to do it is to redo the tree, for example creating a new one and copying only the required nodes. We would avoid using setRoot(), especially setting the root node as one of the nodes inside the tree itself.

          Comment

          Working...
          X