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



Reply via email to