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



Reply via email to