Sean Schofield wrote:
I have some more ideas in response to your initial feedback.
I'm not sure that the IconProvider is necessary (although I will look
at it in more detail tonight.) Suppose the following in your model
1) Common interface called Node
2) Two default classes that implement the Node interface, one called
Branch and one called Leaf
3) The node interface will have getters and setters for "type" and description.
4.) Branch has additional methods for adding children, etc. (aka
Composite pattern)
Now in your JSP you would just configure the various icons for each
type through the facets. Maybe we provide default icons in the
implementation like there are now. That doesn't seem to hurt anybody
and could save time configuring. In that case, you would not even
need any facets (or could just override the ones you wanted to.)
The next simplest case would be something like what we discussed
before. There is no need for an Icon Provider because the images are
configured right inside the facet. This seems to be more intuitive to
use. Its where you configure style and other things related to the
view so why not?
<x:tree 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>
Then for more complicated cases (Use Case#2) you could have:
<x:tree value="#{treeData}" var="node">
<f:facet name="person-open">
<h:graphicImage value="/images/person.gif"/>
<h:outputText value="#{node.description}"/>
</f:facet>
<f:facet name="person-closed">
<h:graphicImage value="/images/person.gif"/>
<h:outputText value="#{node.description}"/>
</f:facet>
<f:facet name="foo-open">
<h:graphicImage value="/images/yellow-folder-open.gif"/>
<h:outputText value="#{node.description}"/>
</f:facet>
<f:facet name="foo-closed">
<h:graphicImage value="/images/yellow-folder-closed.gif"/>
<h:outputText value="#{node.description}"/>
</f:facet>
<f:facet name="bar-open">
<h:graphicImage value="/images/green-folder-open.gif"/>
<h:outputText value="#{node.description}"/>
</f:facet>
<f:facet name="bar-closed">
<h:graphicImage value="/images/green-folder-closed.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>
This will work for most scenarios I suppose. But consider a scenario
where the icons depend on the type of a node object but also on other
attributes like the state of respective node object. That's the scenario
for using IconProvider as you are able to implement any kind of decision
logic there. But I think if makes sense to support both ways. You can
see the IconProvider just as a utility class, a kind of a backing bean
to obtain your image urls.
So basically the renderer would take care of a lot things for you. It
would ask each node if it was an instanceof branch or not (so it could
write the appropriate javascript, etc.) Then it could ask the node
what "type" of node it was. For leaf instances, it could look up the
facet by the type. For branch instances, it could look up the facet
by appending "-open" and "-closed" to the type.
Heath, I'm not sure why we would need the IconProvider at all so I'm
not sure how to respond to your suggestion. I will look more
carefully at IconProvider tonight. I'll try to think of what it could
give us that my approach would not.
Regards,
sean
--
Oliver Rossmueller
Software Engineer and IT-Consultant
Hamburg, Germany
http://www.rossmueller.com