Uploaded image for project: 'ZK'
  1. ZK
  2. ZK-2562

Wrong tree rendering after adding node with tree model

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 6.5.2, 7.0.4
    • Fix Version/s: 6.5.8, 7.0.5
    • Component/s: None
    • Security Level: Jimmy
    • Labels:

      Description

      I try to update a node using treemodel. But after adding the node to the model, and firing an INTERVAL_ADDED event for the added node, as well as CONTENTS_CHANGED events for all parent nodes, the tree rendering is corrupted. as can be seen in the attached screenshots. It seems that this only occurs for some tree constellations.

      For testing I created following ZK page:

      index.zul
      <window id="mainWin"  height="100%" width="100%" border="none" mode="embedded"
              apply="mytest.Main" use="mytest.MainWin">
       <vbox width="100%" height="100%" >
        <button id="mybtn" label="Insert node" forward="mainWin.onTestInsert" />
        <tree id="mytree" >
          <treecols>
            <treecol label="Name"/>
          </treecols>
        </tree>
       </vbox>
      </window>
      

      When clicking on the button mybtn, a node shall be added to the tree.
      The code for the initialization of the tree and the button click handler is as follows:

      MainWin.java
      public class MainWin extends Window 
      {
          private MyTreeModel mymodel;
          private MyNode level2;
      
          public void doInit()
          {
              Tree mytree = (Tree) getFellow("mytree");
      
              MyNode level1 = new MyNode("Level1");
              level2 = new MyNode("Level2");
              level2.children.add(new MyNode("Content1"));
              level2.children.add(new MyNode("Content2"));
              level1.children.add(level2);
      
              MyNode myroot = new MyNode("TreeRoot");
              myroot.children.add(level1);
      
              mymodel = new MyTreeModel(myroot);
              mytree.setModel(mymodel);
              mymodel.addOpenPath(new int[] {0});
              mymodel.addOpenPath(new int[] {0, 0});
          }
      
          public void onTestInsert()
          {
              level2.children.add(new MyNode("Content added"));
              mymodel.fireEvent(TreeDataEvent.INTERVAL_ADDED, new int[] {0,0}, 2, 2);
              mymodel.fireEvent(TreeDataEvent.CONTENTS_CHANGED, new int[] {0}, 0, 0);
              mymodel.fireEvent(TreeDataEvent.CONTENTS_CHANGED, new int[] {}, 0, 0);
          }    
      }
      

      As can be seen, the onTestInsert() method adds the node to the model and fires the tree events. Note that the changed events are required in my application, as the content of parent nodes could change in case new nodes are added.

      For completeness following the code of the tree model:

      MyTreeModel.java
      public class MyTreeModel extends AbstractTreeModel
      {
          private MyNode root;
      
          public MyTreeModel(MyNode root)
          {
              super(root);
              this.root = root;
          }
      
          public boolean isLeaf(Object item)
          {
              if (item instanceof MyNode) {
                  MyNode node = (MyNode) item;
                  return (node.children.isEmpty());
              } else {
                  return true;
              }
          }
      
          public Object getChild(Object parent, int index)
          {
              if (parent instanceof MyNode) {
                  MyNode node = (MyNode) parent;
                  return node.children.get(index);
              } else {
                  return null;
              }
          }
      
          public int getChildCount(Object item)
          {
              if (item instanceof MyNode) {
                  MyNode node = (MyNode) item;
                  return node.children.size();
              } else {
                  return 0;
              }
          }
      }
      

      And the node model:

      MyNode.java
      public class MyNode
      {
          public String title;
          public List children = new ArrayList();
      
          public MyNode(String title)
          {
              this.title = title;
          }
      
          public String toString()
          {
              return title;
          }
      }
      

      Tested with Firefox. Tested with ZK version 7.0.4. Same problem exists when I use latest ZK 6.5.7 version.

      Please find the complete test application as war file attached.

        Attachments

        1. DefaultTreeNodeComposer.java
          1 kB
        2. tree_after_insert_corrupted.PNG
          tree_after_insert_corrupted.PNG
          5 kB
        3. tree_before_insert.PNG
          tree_before_insert.PNG
          4 kB
        4. tree-change.zul
          0.3 kB
        5. zktest_src.zip
          4 kB
        6. ZkTest.war
          6.70 MB

          Activity

            People

            Assignee:
            jumperchen jumperchen
            Reporter:
            mpaula mpaula
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved: