5 Replies Latest reply on Jan 25, 2011 4:57 AM by franckoliver

    Richtree on Demand Loading

    gewuerzgurke

      Hi everyone,


      I've got a problem using rich:tree to display some data. I'm using Richfaces 3.2.2 GA, Seam 2.2.0 GA on a Jboss 5.0.1 GA.


      I want the tree to display some rootnodes. By clicking on one rootnode the necessary data must be loaded by my component. Because I've got a tree with around 22000 nodes this kind of lazy-loading is the only possible way to display that much data.


      Here is my xhtml:


      
      <h:panelGrid columns="2">
       <rich:panel id="selectedNodes">
        </rich:panel>
       <rich:tree value="#{selectCategoryTree.nodes}" var="node" id="tree" treeNodeVar="nodeTree" ajaxSubmitSelection="true" switchType="ajax" ajaxKeys="#{null}" changeExpandListener="#{selectCategoryTree.processExpansion}" nodeSelectListener="#{selectCategoryTree.processSelection}">
        <rich:treeNode type="parent" icon="/img/iconset/box_48.png" iconCollapsed="/img/iconset/arrow_right_48.png" iconExpanded="/img/iconset/arrow_down_48.png" >#{node.name}
        </rich:treeNode>
       </rich:tree>
      </h:panelGrid>
      



      And the selectCategoryTree Component:


      
      @Name("selectCategoryTree")
      @Scope(ScopeType.SESSION)
      public class SelectCategoryTree {
           @Logger
           Log log;
           
           @In
           EbayDriver ebayDriver;
           
           private TreeNode<Category> root;
           
           private List<TreeNode<Category>> selectedCategories;
           
           protected void addNode(TreeNode<Category> parent, List<Category> categories, Integer level) {
                int count = 0;          
                for( Category cat : categories ) {
                     if( ! cat.getLevel().equals(1) && ! cat.getInternalParentId().equals(parent.getData().getInternalId()) ) {
                          continue;
                     }
                     if( cat.getLevel().equals(level) ) {                    
                               TreeNode<Category> add = new TreeNodeImpl<Category>();
                               add.setData(cat);          
                               if( ! cat.getLevel().equals(1) ) {
                                    add.setParent(parent);
                               }
                               parent.addChild(count++, add);                              
                     }
                }          
           }
           
           public void processExpansion(NodeExpandedEvent event) {
                HtmlTreeNode source = (HtmlTreeNode)event.getSource();
                UITree tree = ((HtmlTreeNode)source).getUITree();
                Object rowKey = tree.getRowKey();
                TreeNode<Category> selectedNode = tree.getModelTreeNode(rowKey);
                addNode(selectedNode, ebayDriver.getEbayChildCategories(selectedNode.getData()), selectedNode.getData().getLevel()+1);
           }
           
           public void processSelection(NodeSelectedEvent event) {
                HtmlTree tree = (HtmlTree)event.getComponent();                         
                Object rowKey = tree.getRowKey();
                TreeNode<Category> selectedNode = tree.getModelTreeNode(rowKey);
                addNode(selectedNode, ebayDriver.getEbayChildCategories(selectedNode.getData()), selectedNode.getData().getLevel()+1);
           }
           
           protected void buildNodes() {
                List<Category> categories = ebayDriver.getEbayCategories();
                Category internalRoot = new Category();
                internalRoot.setName("Root");
                root = new TreeNodeImpl<Category>();
                root.setData(internalRoot);               
                root.setParent(null);
                // Build demo stuff
                addNode(root, categories, 1);
           }
           
           public TreeNode<Category> getNodes() {
                if( root == null )
                     buildNodes();
                
                return root;
           }
      
           public List<TreeNode<Category>> getSelectedCategories() {
                return selectedCategories;
           }
      
           public void setSelectedCategories(List<TreeNode<Category>> selectedCategories) {
                this.selectedCategories = selectedCategories;
           }
      }
      



      Now I'm faced with different problems:



      1. The root nodes don't contain childs (they should be loaded on demand). So I cannot really expand the single root nodes

      2. When I select a node the right listener is called and data is fetched, but isn't displayed

      3. Google'd around a lot and even bought a Richfaces book, cannot figure out if it's even possible to load data on demand for rich:tree



      Any ideas?


      Best Regards,


      Alexander Müller