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