Sean Schofield wrote:
Here is the proposal for the new tree component.
I've attached two screen shots of our actual Tiles version of this component for reference (all data has been faked to protect the innocent.) The basically correspond to two different use cases.
Case #1 - Simple tree with an unspecified number of levels
There are probably plenty of cases where this would apply. This is basically what the current tree component supports now. The new version would support javascript on the client to expand and collapse folders. The idea is that through the JSF tags, you would configure the image for the "open" and "closed" branches as well as the "leaf" image. These configuration settings would be applied as appropriate to all nodes in the tree regardless of level.
Here is some sample JSF text that one might use to configure such a tree:
<x:tree>
<x:tree-config value="#{treeData}" var="node">
<f:facet name="branch-open">
<h:graphicImage value="/images/open-folder.gif"/>
<h:outputText value="#{node.description}"/>
</f:facet>
<f:facet name="branch-closed">
<h:graphicImage value="/images/closed-folder.gif"/>
<h:outputText value="#{node.description}"/>
</f:facet> <f:facet name="leaf">
<h:graphicImage value="/images/document.gif"/>
<h:commandLink immediate="true" value="#{node.description}"/>
</f:facet> </x:tree-config>
</x:tree>
I would merge the x:tree and x:tree-config like
<x:tree value="#{treeData}" var="node">...
</x:tree>
as I can not see the advantage of another level of nested tags. But I like the idea of using facets so you can create a custom presentation of your tree nodes.
Case #2 - Complex tree where developer needs control of some/all of the levels in the tree
The second image shows a more complicated (and realistic) example. It
often will not suffice to have the same image for every branch in the
tree. It would be nice to be able to specify multiple <x:tree-config>
tags so you can customize the look of one or more branches in a tree. In addition, I am thinking it would be cool if you could nest these
<x:tree-config> tags so that you could configure secondary levels of
the tree, etc.
One idea that comes to mind is to use method bindings to obtain the icon like
<x:tree value="#{treeData}" var="node">
<f:facet name="branch-open">
<h:graphicImage value="#{node.branchOpenIcon}"/>
<h:outputText value="#{node.description}"/>
</f:facet>
<f:facet name="branch-closed">
<h:graphicImage value="#{node.branchClosedIcon}"/>
<h:outputText value="#{node.description}"/>
</f:facet> <f:facet name="leaf">
<h:graphicImage value="#{node.leafIcon}"/>
<h:commandLink immediate="true" value="#{node.description}"/>
</f:facet> </x:tree>
But this way the data has to know how it will be represented in the user interface, so actually that's not an option to me. The current tree implementation already offers an interface called org.apache.myfaces.custom.tree.IconProvider to deal with the requirement of different node icons. In case an icon provider is specified the tree renderer will ask the provider for the image url of any node displayed in the tree. This is a very simple but flexible way to specify icons. So the sample could look like
<x:tree value="#{treeData}" var="node">
<x:treeIconProvider class="my.very.special.NodeIconProvider"/>
<f:facet name="branch-open">
<x:treeNodeIcon/>
<h:outputText value="#{node.description}"/>
</f:facet>
<f:facet name="branch-closed">
<x:treeNodeIcon/>
<h:outputText value="#{node.description}"/>
</f:facet> <f:facet name="leaf">
<x:treeNodeIcon/>
<h:commandLink immediate="true" value="#{node.description}"/>
</f:facet> </x:tree>
and the icon provider implementation:
public class NodeIconProvider implements IconProvider {
public String getIconUrl(Object userObject, int childCount, boolean isLeaf, boolean isExpanded) {
if (userObject instanceof MotorBiker) {
if (childCount == 0) {
return "motorbikerEmpty.png";
} else {
return isExpanded ? "motorbikerOpen.png" : "motorbikerClosed.png";
}
} else if {userObject instance of Folder) {
Folder folder = (Folder)userObject;
if (folder.isGreen()) {
return isExpanded ? "greenFolderOpen.png" : "greenFolderClosed.png";
} else {
return isExpanded ? "yellowFolderOpen.png" : "yellowFolderClosed.png";
}
} else if ( ... ) {
...
}
}
}
I hope you get the idea.
Oliver
The second case is obviously going to be complicated. I'd like to get some general feedback on the proposed tags that I've shown for the first use case. This is just a rough draft but I wanted to throw it out there and see if I could get some feedback.
Also, would people be interested in this kind of tree in general? I'm assuming the answer is yes (if done correctly.) But maybe I am alone in these requirements. I have looked at the open source and commercial offerings in this area and find them to be lacking this kind of functionality.
TIA,
sean
------------------------------------------------------------------------
------------------------------------------------------------------------
-- Oliver Rossmueller Software Engineer and IT-Consultant Hamburg, Germany http://www.rossmueller.com

