Richtree on Demand Loading
gewuerzgurke Sep 16, 2009 10:16 AMHi 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:
- The root nodes don't contain childs (they should be loaded on demand). So I cannot really expand the single root nodes
- When I select a node the right listener is called and data is fetched, but isn't displayed
- 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