Sean,
maintaining the expanded state adds a requirement to the node objects that is not necessary from my POV. This is pure presentation stuff so why should we annoy the implementer of the model with that kind of things. In fact it would be nice to use the 'rendered' attribute. But if the consequence is that I have to deal with presentation stuff in the model than it's a -1 for me. Just because it's in Bergsten's book makes this no better to me.
The condition part of a rendering rule as proposed is just optional and can be used for more complex rendering logic. I think the rule syntax is quite straightforward and even more explicit than the proposed facet naming scheme. Even if you are not familiar with the tree component you will get an understanding of what happens.
Besides, if you don't like IconProvider and don't like rules and conditions, too, so where in the new tree should I place my icon logic? I'm also currious about how the client-side node expansion will work. I suppose we have to render the complete tree from the root node down to any leaf to some kind of javascript datastructure you can deal with in the browser. So how does the icon logic fit in there? And how will the client-side tree state be synchronized with the server-side tree component state?
Oliver
Sean Schofield wrote:
Oliver,
The rendering rule is an interesting concept. This idea (or a variation of it) might work. I still find myself wondering if we can't make this simpler by avoiding introducing these rules and conditions into the mix.
Take this simple example:
<f:facet name="foo-folder"> <h:panelGroup> <h:commandLink immediate="true" action="#{t.toggleExpanded}"> <h:graphicImage value="folder-open.png" rendered="#{node.expanded}" border="0"/> <h:graphicImage value="folder-closed.png" rendered="#{!node.expanded}" border="0"/> </h:commandLink> <h:outputText value="#{node.description}" styleClass="nodeFolder"/> </h:panelGroup> </f:facet>
Now I know you mentioned that you are not wild about having info on the nodes expansion state in the node. I thought the same thing but I changed my mind slightly after thinking about it and reading up on Bergsten's O'Reilly example.
What I've done so far is to have setExpanded and isExpanded as part of the TreeNode interface. This makes the JSF *much* simpler to code, plus you can take advantage of the existing rendered attribute which is already well known to users.
The reason why I feel this is ok is because the end user only is responsible for populating the nodes other data. They do not have to (nor should they) specify the node expansion state.
In my initial pass of the HtmlTree code I store the expand/collapse info in a HashSet that is part of the HtlmTree component. HtmlTree calls setExpanded on each node before its rendered by checking this information. You can continually update your data model on each post (assuming its a request scope bean) and expand/collapse status of each of the nodes is restored along with the component tree.
What do you think about this approach? I think it simplifies things without requiring the node to maintain the expand/collapse info between requests. These methods are just there to assist in rendering. We could consider something along the lines you are proposing but I am not sure it will be necessary.
sean
On Sun, 06 Feb 2005 15:26:32 +0100, Oliver Rossmueller
<[EMAIL PROTECTED]> wrote:
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
-- Oliver Rossmueller Software Engineer and IT-Consultant Hamburg, Germany http://www.rossmueller.com

