Search code examples
databasebuildprimefacesmenubartreenode

Building TreeNode from DataBase PrimeFaces


I need some example to build a TreeNode from DataBase for to build a MenuBar of PrimeFaces that needs a TreeNode. Here my code of the view of my menu.

I need build a TreeNode from my ManagedBean with a DataBase and my menu use this TreeNode for paint the Submenus and menu items.

I need a method that allow me from ManagedBean process a query from database and create the structure of these TreeNode and some idea about the structure of the table with the menus, I only want the titles of menus stored. Help please :(

    <p:menubar style="width: auto;" autoDisplay="false">
    <c:forEach items="#{treeBean.root.children}" var="nodos">
        <p:submenu label="#{nodos.getData()[0].toString()}" icon="#{nodos.getData()[2].toString()}">
            <c:forEach items="#{nodos.children}" var="hojas">
                <c:if test="#{hojas.isLeaf()==false}">
                    <p:submenu label="#{hojas.getData()[0].toString()}" icon="#{hojas.getData()[2].toString()}">
                        <c:forEach items="#{hojas.children}" var="menus">
                            <c:when test="#{menus.leaf}">
                                <c:if test="#{menus.leaf==false}">
                                    <p:submenu label="#{menus.getData().toString()}">
                                        <c:forEach items="#{menus.children}" var="menus2">
                                            <p:menuitem value="#{menus2.getData()[0].toString()}" action="#{menus2.getData()[1].toString()}"
                                            ajax="false" icon="#{menus2.getData()[2].toString()}" />
                                        </c:forEach>
                                    </p:submenu>
                                </c:if>
                                <c:if test="#{menus.leaf}">
                                    <p:menuitem value="#{menus.getData()[0].toString()}" action="#{menus.getData()[1].toString()}"
                                    ajax="false" icon="#{menus.getData()[2].toString()}" />
                                </c:if>
                            </c:when>
                        </c:forEach>
                    </p:submenu>
                </c:if>
                <c:if test="#{hojas.isLeaf()==true}">
                    <p:menuitem value="#{hojas.getData()[0].toString()}" action="#{hojas.getData()[1].toString()}"
                    ajax="false" icon="#{hojas.getData()[2].toString()}" />
                </c:if>
            </c:forEach>
            <c:if test="#{nodos.getData()[0].toString()=='Favoritos'}">
                <p:menuitem value="Agregar Favorito" action="verPrueba" ajax="false" />
            </c:if>
        </p:submenu>
    </c:forEach>
    <f:facet name="options">
        <p:commandButton value="Cerrar Sesión" icon="ui-icon-cerrarSesion" action="verPrueba"
        />
    </f:facet>
</p:menubar>

Solution

  • I found the answer here the code of my recursive method for to build a TreeNode from DataBase and to build a Menu bar:

    public void recursivo(List<Menustab> liste, int id, TreeNode node) {
        subList2 = new ArrayList<Menustab>();
        subList2 = subMenus(id);
        for (Menustab k : subList2) {
            TreeNode childNode = new DefaultTreeNode(k.getTitulo(), node);
            recursivo(subList2, k.getId(), childNode);
    
        }
    
    }
    
    public static List<Menustab> subMenus(int i) {
        listaHijos = new ArrayList<Menustab>();
        for (Menustab k : getListaMenus()) {
            if (k.getPadre() == i) {
                listaHijos.add(k);
            }
        }
        return listaHijos;
    }
    

    My view with menuBar:

    <h:form >
    
    
            <div id="header" align="left">
    
                <p:menubar  autoDisplay="false"> 
                    <c:forEach items="#{constructorMenuMB.root.children}" var="nodos" >
    
                        <p:submenu   label="#{nodos.getData().toString()}"   >
    
                            <c:forEach items="#{nodos.children}" var="hojas">
    
                                <c:if test="#{hojas.isLeaf()==false}">
    
    
                                    <p:submenu  label="#{hojas.getData().toString()}"  >
    
    
    
    
                                        <c:forEach items="#{hojas.children}" var="menus">
    
    
    
                                            <c:when test="#{menus.leaf}">
                                                <c:if test="#{menus.leaf==false}">
                                                    <p:submenu  label="#{menus.getData().toString()}" >
    
                                                        <c:forEach items="#{menus.children}" var="menus2">
                                                            <p:menuitem  value="#{menus2.getData().toString()}"  ajax="false" />
                                                        </c:forEach>
                                                    </p:submenu>
                                                </c:if>
                                                <c:if test="#{menus.leaf}">
                                                    <p:menuitem value="#{menus.getData().toString()}"  ajax="false" />
                                                </c:if>
                                            </c:when>
    
                                        </c:forEach>
    
    
    
                                    </p:submenu>
    
                                </c:if>
    
                                <c:if test="#{hojas.isLeaf()==true}">
    
                                    <p:menuitem value="#{hojas.getData().toString()}"  ajax="false" />
    
    
                                </c:if>
    
    
                            </c:forEach>
    
    
                            <c:if test="#{nodos.getData().toString()=='Favoritos'}">
    
                                <p:menuitem value="Agregar Favorito" action="verPrueba"  ajax="false"/>
                            </c:if>
    
    
    
                        </p:submenu>
    
                    </c:forEach>
    
    
                </p:menubar>
    
    
    
            </div>
    
    
    
        </h:form> 
    

    and now my complete bean:

    public class ConstructorMenuMB {
    
    private TreeNode root = new DefaultTreeNode("Root", null);
    private static List<Menustab> listaMenus;
    private static List<Menustab> listaHijos;
    private List<Menustab> subList2;
    
    @EJB
    public MenuSB sb;
    
    /**
     * Creates una nueva instancia de ConstructorMenuMB
     */
    public ConstructorMenuMB() {
    }
    
    @PostConstruct
    public void construirMenu() {
        listaMenus = new ArrayList<Menustab>();
        listaMenus = sb.consultarArbolMenus();
        recursivo(listaMenus, 1, root);
    }
    
    /**
     * Método recursivo para construir un árbol(TreeNode) desde una lista de arreglos de
     * cadenas obtenida desde la base de datos.
     *
     * @param ArrayList<String[]> lista de menus.
     * @return No devuelve ningun valor.
     * @throws No dispara ninguna excepcion.
     */
    public void recursivo(List<Menustab> liste, int id, TreeNode node) {
        subList2 = new ArrayList<Menustab>();
        subList2 = subMenus(id);
        for (Menustab k : subList2) {
            TreeNode childNode = new DefaultTreeNode(k.getTitulo(), node);
            recursivo(subList2, k.getId(), childNode);
    
        }
    
    }
    
    public static List<Menustab> subMenus(int i) {
        listaHijos = new ArrayList<Menustab>();
        for (Menustab k : getListaMenus()) {
            if (k.getPadre() == i) {
                listaHijos.add(k);
            }
        }
        return listaHijos;
    }
    
    public static List<Menustab> getListaMenus() {
        return listaMenus;
    }
    
    
    public TreeNode getRoot() {
        return root;
    }
    

    }

    and my session bean where use the entity manager for consult my table with menus:

    public class MenuSB {
    @PersistenceContext(unitName = "MenuGeneralPU")
    private EntityManager em;
    
    
     public List<Menustab> consultarArbolMenus(){
    
        return em.createNamedQuery("Menustab.findAll").getResultList();
    
    }
    

    }

    My entity for Menus:

    public class Menustab implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @NotNull
    @Column(name = "id")
    private Integer id;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 50)
    @Column(name = "titulo")
    private String titulo;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 50)
    @Column(name = "url")
    private String url;
    @Basic(optional = false)
    @NotNull
    @Column(name = "padre")
    private int padre;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 50)
    @Column(name = "icono")
    private String icono;
    
    
    public Menustab() {
    }
    
    public Menustab(Integer id) {
        this.id = id;
    }
    
    public Menustab(Integer id, String titulo, String url, int padre, String icono) {
        this.id = id;
        this.titulo = titulo;
        this.url = url;
        this.padre = padre;
        this.icono = icono;
    }
    
    public Integer getId() {
        return id;
    }
    
    public void setId(Integer id) {
        this.id = id;
    }
    
    public String getTitulo() {
        return titulo;
    }
    
    public void setTitulo(String titulo) {
        this.titulo = titulo;
    }
    
    public String getUrl() {
        return url;
    }
    
    public void setUrl(String url) {
        this.url = url;
    }
    
    public int getPadre() {
        return padre;
    }
    
    public void setPadre(int padre) {
        this.padre = padre;
    }
    
    public String getIcono() {
        return icono;
    }
    
    public void setIcono(String icono) {
        this.icono = icono;
    }
    
    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }
    
    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Menustab)) {
            return false;
        }
        Menustab other = (Menustab) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }
    
    @Override
    public String toString() {
        return "Entidad.Menustab[ id=" + id + " ]";
    }
    

    }

    and finally the structure of my table in database:

    ID | Titulo | URL | Padre | Icono

    I use the basic in my algoritm, the id 'ID' of one menu and its pattern 'PADRE' for to build a TreeNode and the title 'TITULO' for the text of menus, I'm working for to paint the icons.