Sean,
I don't like to have information like if a node is expanded or not in the tree data. I was reflecting on that topic and following idea came to my mind: what about introducing a rendering rule component.
<x:tree value="#{treeData}" var="node">
<x:treeRenderingRule branch="true" expanded="true">
<h:graphicImage value="open-folder.gif"/>
<h:outputText value="#{node.description}"/>
</x:treeRenderingRule>
<x:treeRenderingRule branch="true" expanded="false">
<h:graphicImage value="closed-folder.gif"/>
<h:outputText value="#{node.description}"/>
</x:treeRenderingRule>
<x:treeRenderingRule branch="false">
<h:graphicImage value="document.gif"/>
<h:commandLink immediate="true" value="#{node.description}"/>
</x:treeRenderingRule>
</x:tree>This way we don't have to expose the expanded/collapsed state. And we can make the rules even more flexible:
<x:tree value="#{treeData}" var="node">
<x:treeRenderingRule branch="true" expanded="true"
condition="#{node.locked}">
<h:graphicImage value="open-folder-locked.gif"/>
<h:outputText value="#{node.description}"/>
</x:treeRenderingRule>
<x:treeRenderingRule branch="true" expanded="false"
condition="#{node.locked}">
<h:graphicImage value="closed-folder-locked.gif"/>
<h:outputText value="#{node.description}"/>
</x:treeRenderingRule>
<x:treeRenderingRule branch="true" expanded="true">
<h:graphicImage value="open-folder.gif"/>
<h:outputText value="#{node.description}"/>
</x:treeRenderingRule>
<x:treeRenderingRule branch="true" expanded="false">
<h:graphicImage value="closed-folder.gif"/>
<h:outputText value="#{node.description}"/>
</x:treeRenderingRule>
<x:treeRenderingRule leaf="true">
<h:graphicImage value="document.gif"/>
<h:commandLink immediate="true" value="#{node.description}"/>
</x:treeRenderingRule>
</x:tree>Logic is that a rule with a condition is evaluated before a rule without a condition, and rules with a condition are evaluated in the order they are defined. I guess most use cases can be handled this way, even the ones I need an IconProvider for at the moment.
Oliver
Sean Schofield wrote:
I wanted to start a new thread concerning some of the progress I have been making with the new tree component.
The first bit of news is that I discovered that Hans Bergsten, author of the O'Reilly JSF book, has a fairly complete example of a custom tree component. Its been simplified somewhat but it did manage to solve a few of the problems I was grappling with. Also, it used a similar approach to some of the ideas that I have proposed on this list. I contacted Hans and he gave me permission to use portions of his code in the new component.
I've also given some more thought to how the JSF tags should work. Here is a revised example.
<x:tree value="#{treeData}" var="node"> <f:facet name="branch"> <h:panelGroup> <h:graphicImage value="open-folder.gif" rendered="#{treeData.nodeExpanded}"/> <h:graphicImage value="closed-folder.gif" rendered="#{!treeData.nodeExpanded}"/> <h:outputText value="#{node.description}"/> </h:panelGroup> </f:facet> <f:facet name="leaf"> <h:panelGroup> <h:graphicImage value="document.gif"/> <h:commandLink immediate="true" value="#{node.description}"/> </h:panelGroup> </f:facet> </x:tree>
The major change is that I've consolidated the "open" and "close" graphic images into a single panel group. I've added a getNodeExpanded method to the the TreeModel so that you can render the appropriate image. I also enclose everything in the facet inside a panel group. I discovered this was necessary after some testing (I guess facet can only handle a single child).
If you look at all of the options this gives you, it doesn't seem like
an IconProvider is necessary. You've go the "var" attribute which you
can combine with existing attributes like "rendered" and "disabled". You should be able to use backing beans and/or subclass of TreeNode to
get all of the behavior that Oliver mentioned in his use case (locked
node, etc.)
I personally like specifying the image file and location right on the jsp page. I am not really wild about burying the details of the images in some class somewhere. It seems like we could avoid this with the solution I am proposing.
I am working on an initial version of the tree to check in (see earlier email on the dev list). It should be ready by the end of next week. It will contain a very solid starting point for people to evaluate and make suggestions. It probably will not have any of the expand collapse features for another few weeks but it will be coming shortly.
I think this is going to be a sweet little JSF component. I already know it works and looks great in its current incarnation as a Tiles component. Now I am starting to get excited about how it will work in JSF. Also, I am getting an increasing appreciation for how powerful of a framework JSF really is.
Looking forward to your feedback,
sean
-- Oliver Rossmueller Software Engineer and IT-Consultant Hamburg, Germany http://www.rossmueller.com

