Currently Browsing
trabajo
El componente tree2 de MyFaces
- 20 February //
- Posted in informática, trabajo //
- Tags :
- 5 Comments
MyFaces se una implementación GPL de las librerías Java Server Faces de Sun Microsystems. Cuenta con un número importante de componentes añadidos que evitan al programador el trabajo de crearlas. Uno de ellos es el de los “árboles”, que puede verse en la imagen de abajo:

Resulta que me encuentro con la necesidad de implementar un árbol deslpegable y voy a la documentación de MyFaces donde busco el componente Tree2 (olvidemos el Tree “uno” que es menos interesante). La documentación debería estar ahí: http://myfaces.apache.org/tomahawk/tree2.html. Pero para mi sorpresa, la documentación es inexistente.
Después de media mañana perdida, descubro varios weblogs donde se explica someramente el proceso. Mi intención es explicarlo aquí con un poco más de detalle y en español para que quede constancia
.
Prerequisitos
- Tomcat instalado y funcionando y capacidad de despliege de aplicaciones.
- Una estructura de directorios correcta: WEB-INF conteniendo lib y classes.
- El filtro de extensiones de MyFaces configurado en el web.xml. Supondré que actúa sobre los mismos elementos que el FacesServlet (/faces/*).
En primer lugar hay que pensar en la estructura del árbol. En este caso vamos a analizar una estructura simple. Consta de una compañía (company), que tiene como “hijos” los departamentos (department) Programacion y Diseño. Dentro de cada departamento puede haber personas (person) o cosas (thing). Los nombres en inglés entre paréntesis son lso identificadores que habrá que usar al crear la estructura del árbol y al indicársela al componente tree2 de MyFaces. Empecemos por esto último.
Para especificar los elementos de que consta el árbol es necesario entre los tags de <x:tree> y </x:tree> situar un <f:facelet> por cada elemento. Como en el siguiente ejemplo:
<t:tree2 value="#{treeBean.treeData}" var="node" clientSideToggle="true">
<f:facet name="company">
<h:panelGroup>
<t:graphicImage value="images/tree/yellow-folder-open.png" styleClass="iconImage"/>
<h:outputText value="#{node.description}" styleClass="label"/>
</h:panelGroup>
</f:facet>
<f:facet name="departemt">
<h:panelGroup>
<t:graphicImage value="images/tree/yellow-folder-open.png" styleClass="iconImage"/>
<h:outputText value="#{ node.description}" styleClass="label"/>
</h:panelGroup>
</f:facet>
<f:facet name="person">
<h:panelGroup>
<t:graphicImage value="images/tree/yellow- folder-open.png" styleClass="iconImage"/>
<h:outputText value="#{node.description}" styleClass="simpleText"/>
</h:panelGroup>
</f:facet>
<f:facet name="thing">
<h:panelGroup>
<t:graphicImage value="images/tree/yellow-folder-open.png" styleClass="iconImage"/>
<h:outputText value="#{ node.description}" styleClass="simpleText"/>
</h:panelGroup>
</f:facet>
</t:tree2>
Hay que fijarse principalmente en el atributo “name” de los facets. Esos valores serán los valores que se podrán especificar al crear en la estructura del árbol.
Las opciones de los facets anteriores pueden estar mucho más elaborados (commandLinks, varias imágenes que pueden cambiar, etc). Sin embargo en el presente ejemplo nos conformamos con una imagen para cada elemento (images/tree/yellow- folder-open.png) y un texto que tiene como valor “#{node.description}”. Esto significa que al mostrar ese elemento, se mostrará el texto de su descripción. La descripción de cada elemento está almacenada en la estructura del árbol. La estructura del árbol debe estar almacenada en un Bean que en el ejemplo se llama treeBean. Ese Bean debe tener un método (en el ejemplo getTreeData()) que permita obtener la estructura del árbol. El objetivo siguiente es hacer ese Bean y definirlo en el faces-config.xml.
Añadimos lo siguiente en faces-config.xml para hacer el Bean accesible a la página JSF.
<managed-bean>
<managed-bean-name>treeBean</managed-bean-name>
<managed-bean-class>tree.TreeModelBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
El siguiente código es el código más sencillo para devolver una estructura de árbol. Es muy ineficiente y no debería ser usado para producción. Lo ideal sería crear la estructura del árbol desde un fichero xml y almacenarla en un Bean accesible por toda la aplicación, o que se recuperara mediante una llamada a EJB.
Paso a comentar el código. Se puede ver que el bean sólo dispone de un método de devuelve un TreeNode, este TreeNode que devolveremos al final del método es el nodo raíz (root) del árbol y de él cuelgan todos los demás elementos. Lo creamos instanciando un nuevo TreeNodeBase y le damos un “tipo de elemento”, que debe coincidir con el nombre de un facet; una descripción y un boolean que indica si es un nodo terminal (true) o no (false).
A continuación vamos rellenando una estructura de hijos llamando al método add() de la lista que devuelve el método getChildren() de los TreeNode.
Por último devolvemos el TreeNode root.
package tree;
import org.apache.myfaces.custom.tree2.TreeNode;
import org.apache.myfaces.custom.tree2.TreeNodeBase;
public class TreeModelBean {
public TreeNode getTreeData() {
TreeNode root = new TreeNodeBase("company","Krube - Informatica para todos",false);
TreeNode child = new TreeNodeBase("departemt", "Programacion","d1",false);
TreeNode pChild = new TreeNodeBase("person", "David","p1",true);
child.getChildren().add(pChild);
pChild = new TreeNodeBase("thing","Ordenador", "t1", true);
child.getChildren().add(pChild);
TreeNode child2 = new TreeNodeBase("department", "Diseño", "d2", false);
TreeNode pChild2 = new TreeNodeBase("person", "Juana", "p2", true);
child2.getChildren().add(pChild2);
pChild2 = new TreeNodeBase("thing", "Pincel", "t2", true);
child2.getChildren().add(pChild2);
root.getChildren().add(child);
root.getChildren().add(child2);
return root;
}
}
Si todo ha ido bien, el tree2 está listo y ya podemos dedicarnos a usarlo para algo de verdad. Espero que haya servidod de ayuda.