That's a possibility. We've gotten our "lazy load" to work as follows (which admittedly is sub-optimal, since it doesn't use the navigation icon features built into the component):
<x:tree2 id="serverTree" value="#{treeBacker.treeData}" var="node" varNodeToggler="t" clientSideToggle="false" showNav="false"> <f:facet name="module"> <h:panelGroup style="font-size: 10"> <h:commandLink immediate="true" action="#{t.toggleExpanded}"> <h:graphicImage value="/images/iminus.gif" rendered="#{t.nodeExpanded && !t.node.leaf}" border="0"/> <h:graphicImage value="/images/iplus.gif" rendered="#{!t.nodeExpanded && !t.node.leaf}" border="0"/> <f:actionListener type="com.test.myfaces.examples.tree2.TreeBacker"/> </h:commandLink> <h:graphicImage value="/images/ibar.gif" rendered="#{t.node.leaf}" border="0"/> <h:graphicImage value="/images/reference_modules.gif" border="0"/> <h:outputLink value="#" style="font-family: arial; color: blue" onclick="alert(#{node.id})"> <h:outputText value="#{node.name}"/> </h:outputLink> </h:panelGroup> </f:facet> ... </x:tree2> The idea that we've been going with is that, as long as we can catch the expand/collapse event, we're happy. And the above JSF code does cause our action listener to catch the event. Our action listener then bubbles up the component parent hierarchy until it hits something of type HtmlTree, at which point it can access the Node and test whether it is expanded, whether the children have already been fetched, etc. If the children have not already been fetched, our listener calls the back end to fetch the children, then addes them to the list, and returns. It's working pretty well so far. The only problem we've been running into with the current component is capturing the expand/collapse event when showNav="true" and we're not using our own navigation icons. I'm not sure whether this can be addressed using the current architecture or not. - Brendan ------------ As promised I'd like to kick off a mini tree2 summit where we can discuss some of the ideas that are being kicked around. Yesterday I closed out some of the easier tree2 related issues in JIRA. There are a few remaining which I'd like to address now. Most of the outstanding bugs can be addressed once we resolve a few key issues. One possible change to tree2 that we might want to consider is making TreeModel an interface and moving the code in the current TreeModel class to a new DefaultTreeModel class. The idea would be that users could supply their own TreeModel using something like <x:tree2 model=#{MyModel} ...> If no model was specified, the DefaultTreeModel could be used (basically what you have now.) This might help users who want to specify their data dynamically. Instead of requiring that the user have all of the data loaded at once in a node hierarchy, you could implement the getNode() methods, etc. in any manner that you wanted. Of course, this would only really apply to server side toggle (sst). Client side toggle (cst) might be possible with Ajax but lets not go down that road just yet :-) I don't have a current need for this type of feature so those of you looking to have dynamic trees in this manner should comment on whether or not this change would be helpful. Also, my thinking is that we still require the node data to implement the TreeNode interface. Its just that your custom model can wrap the data on the fly as needed (instead of doing this for all of your data at once.) There could be another possible impact on adding a TreeModel interace. We could add methods for determining the expand/collapse state of nodes. I haven't thought this through completely but the thinking was that TreeModel (and DefaultTreeModel) would have isNodeExpanded() and isNodeSelected() methods. Mathias Werlitz has also suggested that UITreeData could extend UIData. The code behind the current UITreeData is heavily influenced by UIData. It deals with many of the same complex challenges (like iterrating over the data when encoding and decoding.) My thinking on this is that we leave UITreeData as extending UIComponentBase but that we fine tune it to deal with the use case of containing other components that render their own children. So those are some thoughts to get us started. sean