The reason that I'm still a bit opposed to this kind of layout is that
the way I'm currently using trees is to have different requirements
for each layer in the tree's hierarchy.  That is, different icons at
different levels, and different nodes being enabled or disabled.

We currently have a javascript-based tree we are using, but it
requires that we rebuild our internal data structure into the
tree-data structure.  Our models cannot be tied to the tree,
unfortunately (this means they cannot implement a TreeNode interface),
and ideally, we would like to not have to recreate our entire model
hierarchy in tree nodes because this effectively doubles the data
size, and generally our data sets we are displaying with the tree are
fairly large (> 500 nodes).

What this means for me is at a bare minimum I'd need to have different
logic for each layer of the tree.  Obviously, for trees that do not
have a pre-defined depth, it would also be best to allow all branches
to be defined in a given way, and all leaves to be defined in a given
way, as you are doing now.

Here is the type of JSP I would be looking for, for this type of
functionality.  The example below illustrates the use of the tree with
a backing data model that is three levels deep.  Each level can be a
POJO that contains an arbitrary property that binds to a Collection
(or a List if we are doing selections), of children.  By defining the
levels recursively within one another, we can render the tree without
having to build an explicit data model.  Additionally, this approach
could have two <x:treeLevel />'s as siblings, which could produce two
sets of TreeNodes with different renderings on the same level of the
tree.

<x:tree root="#{bean.root}">
  <x:treeNode>
    <%-- this would be arbitrary JSF content that would be rendered as the
            tree node.  --%>
    <h:graphicImage src="rootImage.gif" />
    <h:outputText value="#{root.text}" />
  </x:treeNode>
  <x:treeLevel value="#{root.children}" var="child>
    <x:treeNode>
      <h:graphicImage src="childImage.gif" />
      <h:outputText value="#{child.text}" />
    </x:treeNode>
    <x:treeLevel value="#{child.grandChildren}" var="grandChild">
      <x:treeNode>
        <h:graphicImage src="grandChildImage.gif" />
        <h:outputText value="#{grandChild.text}" />
      </x:treeNode>
    </x:treeLevel>
  </x:treeLevel>
</x:tree>

Now, we still have an issue where we need to be able to accomodate
trees without a defined depth.  The data models in this case would
always have to have the same interface (which would be the case when
recursively iterating through any data structure without a predefined
depth).

Lets add to the previous example a 4th level that would continue
infinitely as long as there are children present at a given node:

<x:tree root="#{bean.root}">
  <x:treeNode>
    <%-- this would be arbitrary JSF content that would be rendered as the
            tree node.  --%>
    <h:graphicImage src="rootImage.gif" />
    <h:outputText value="#{root.text}" />
  </x:treeNode>
  <x:treeLevel value="#{root.children}" var="child>
    <x:treeNode>
      <h:graphicImage src="childImage.gif" />
      <h:outputText value="#{child.text}" />
    </x:treeNode>
    <x:treeLevel value="#{child.grandChildren}" var="grandChild">
      <x:treeNode>
        <h:graphicImage src="grandChildImage.gif" />
        <h:outputText value="#{grandChild.text}" />
      </x:treeNode>
       <%-- this tag represents a traverser starting at the 'start'
value and continuing with the 'loop' ValueBinding.  This would
traverse until it has reached all leaves --%>
      <x:recursiveTreeLevel start="#{grandChild.spawns}" var="spawn"
loop="#{spawn.spawns}">
        <x:treeNode>
          <h:graphicImage src="spawnBranch.gif" 
            rendered="#{not empty spawn.spawns}"/>
          <h:graphicImage src="spawnLeaf.gif"
            rendered="#{empty spawn.spawns}"/>
          <h:outputText src="#{spawn.text}" />
        </x:treeNode>
      </x:recursiveTreeLevel>
    </x:treeLevel>
  </x:treeLevel>
</x:tree>

With this implementation, the tags mearly define rendering logic for
each point in the data structure, and allow for multiple nodes with
each traversal, if desired, or multiple definitions with selective
rendering.  The main advantage is that there is no "TreeNode"
interface that would need to be implemented, which means that you
could represent the presentation of the entire tree simply by the
iterative pieces.



On Wed, 2 Feb 2005 23:16:21 -0500, Sean Schofield
<[EMAIL PROTECTED]> 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
> 


-- 
-Heath Borders-Wing
[EMAIL PROTECTED]

Reply via email to