Mehmet Ethem SULAN :: Java Recursive Methods JPA(Java Persistence API), Hibernate JSF(Java Server Faces) PrimeFaces :: Dynamic Treeview Recursively JSF PrimeFaces(Create Dynamic Category Java)

JSF, PrimeFaces ve JPA kullanarak dynamic olarak bir tree view oluşturmaya çalıştım. Yani dynamic olarak oluşturulabilen bir kategori uygulaması yazmaya çalıştım. Bunun için en önemli kısım aşağıda yazılan recursive methodtur.
Recursive method

//Dynamic tree viewi olutruan method.
    public  void recursive(List<Kategoriler> liste, int id,TreeNode node){
            subList2=new ArrayList<Kategoriler>();
            subList2=subKategori(id);
          for(Kategoriler k:subList2){
            TreeNode childNode=new DefaultTreeNode(k.getKategoriAdi(), node);
//Veritabaninda kategori tablosunu tree view seklinde dynamic olarak olusturmayi saglar.
             recursive(subList2, k.getKategoriId(),childNode);
          }

Mesela örnekte donanım altına telefon ve onun da altına android kategorleri ekleyebilmek için recursive olarak yazmak gerekiyor.
Tek tablo ile bütün kategorileri tutuyorum. Aşağıdaki resimde görüldüğü gibi hangi kategoriye alt kategori ekliyorsam onun id sini alıyorum ve kat_ust_id olarak kaydediyorum. En temelde kategorler diye bir node oluşturdum ve onun ust id si 0 dır. Yani sağdaki hiç bir id ile aynı değil.

database table


Aşağıdaki şekilde de anlaşıldığı gibi önce bir ana kategori seçip ve alt kategori ismi girilerek istediğimiz kadar alt kategori girebiliriz.

Yukardaki örnekte üst kategori Donanım ve alt kategori de Telefon olarak oluşturuldu.

android


Parent node: Telefon child node: Android

Yukardaki işlemleri sağlayan jsf bean ve index.xhtml
JSF PrimeFaces Datatable Pagination Example
index.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.prime.com.tr/ui"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <ul id="d">

        </ul>
        <h:form>
            <p:panel id="panelId">
                <p:tree value="#{nodeBean.root}" var="node" dynamic="true"
                        selectionMode="single" selection="#{nodeBean.selectedNode}">
                    <p:treeNode>
                        <h:outputText value="#{node}"/>
                    </p:treeNode>
                </p:tree>
                <h:panelGrid columns="2">
                    <h:outputLabel value="Alt kategori ismi*:"/>
                    <h:inputText id="id" value="#{nodeBean.kategIsmi}" required="true">
                        <f:validateLength minimum="1" maximum="30"/>
                    </h:inputText>
                    <p:commandButton value="Yeni Kategori Ekle" update="panelId" action="#{nodeBean.yeniKatEkle}" async="true"/>

                </h:panelGrid>
                <h:message for="id"/>
            </p:panel>
        </h:form>

        <h:form>
            <p:panel>
                <p:column>
                    <h:commandButton action="edit" value="Edit Sayfasina Gidin"/>
                </p:column>
            </p:panel>
        </h:form>

    </h:body>
</html>

NodeBean.java


package com.Bean;

import com.kategori.Kategoriler;
import com.kategori.KategorilerJpaController;
import java.util.ArrayList;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;


/**
 *
 * @author ubuntu
 */
public class NodeBean {

    private TreeNode root;
    private TreeNode donanim;
    private TreeNode selectedNode;
    private static  List<Kategoriler> liste;
    private static List<Kategoriler> araListe;
    private KategorilerJpaController katCont;
    private Kategoriler katNesnesi;
    private List<Kategoriler> subList2;
    private String kategIsmi;
    public NodeBean() {
        liste=new ArrayList<Kategoriler>();
        root=new DefaultTreeNode("Root",null);
        katCont=new KategorilerJpaController();
        liste=katCont.findKategorilerEntities();
        donanim=new DefaultTreeNode("", root);
//Butun kategorileri tutan bir ana kategori olusturuyor.
//Dynamic olarak sub kategori ekliyor. Recursive olarak hepsini kontrol edilmesi lazim.
        recursive(liste, 0,donanim);

    }
//Dynamic tree viewi olutruan method.
    public  void recursive(List<Kategoriler> liste, int id,TreeNode node){
            subList2=new ArrayList<Kategoriler>();
            subList2=subKategori(id);
          for(Kategoriler k:subList2){
            TreeNode childNode=new DefaultTreeNode(k.getKategoriAdi(), node);
//Veritabaninda kategori tablosunu tree view seklinde dynamic olarak olusturmayi saglar.
             recursive(subList2, k.getKategoriId(),childNode);
          }

    }
//herhangi bir tree nodenin childlarini buluyor.
    public static List<Kategoriler> subKategori(int i)
    {
        araListe=new ArrayList<Kategoriler>();
        for(Kategoriler k:getListe()){
            if(k.getKatUstId()==i){
                araListe.add(k);
            }
        }
        return araListe;
    }
    public static List<Kategoriler> getListe() {
        return liste;
    }
    public Kategoriler getKatNesnesi() {
        return katNesnesi;
    }
    public void setKatNesnesi(Kategoriler katNesnesi) {
        this.katNesnesi = katNesnesi;
    }
    public TreeNode getRoot() {
        return root;
    }
    
    public TreeNode getSelectedNode() {
        return selectedNode;
    }

    public void setSelectedNode(TreeNode selectedNode) {
        this.selectedNode = selectedNode;
    }
    public void secilenNode(NodeSelectEvent event){
        FacesMessage msg=new FacesMessage(FacesMessage.SEVERITY_INFO, "selected", event.getTreeNode().getData().toString());
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }
   
    public String getKategIsmi() {
        return kategIsmi;
    }

    public void setKategIsmi(String kategIsmi) {
        this.kategIsmi = kategIsmi;
    }


    public void yeniKatEkle(){
//        JOptionPane.showMessageDialog(null,katCont.kategoriIdDonder(getSelectedNode().getData().toString()).getKategoriId());
        katNesnesi=new Kategoriler(getKategIsmi(), katCont.kategoriIdDonder(getSelectedNode().getData().toString()).getKategoriId());
         katCont.create(katNesnesi);
         setKategIsmi(null);
    }
    
}

pagination

Edit.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:p="http://primefaces.prime.com.tr/ui"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h:form>
            <p:panel header="PrimeFaces ile listeleme">
                <p:dataTable value="#{editBean.allRecordList}" var="items" paginator="true"
                             rows="5" rowsPerPageTemplate="5,10,30"
                             paginatorTemplate="{FirstPageLink} {PageLinks} {NextPageLink}
                             {RowsPerPageDropdown}">
                    <p:column>
                        <f:facet name="header">Ad</f:facet>
                        <h:outputText value="#{items.kategoriAdi}"/>
                    </p:column>
                    <p:column>
                        <f:facet name="header">Ust Kategori Id</f:facet>
                        <h:outputText value="#{items.katUstId}"/>
                    </p:column>
                    <p:column>
                        <f:facet name="header">Edit</f:facet>
                        <h:outputLink value="EditComplete.xhtml">
                            <f:param name="id" value="#{items.kategoriId}"/>Düzenle
                        </h:outputLink>
                    </p:column>
                </p:dataTable>
                <h:outputLink value="index.xhtml">Ana Sayfa</h:outputLink>
            </p:panel>
        </h:form>
    </h:body>
</html>

EditBean.java

package com.Bean;

import com.kategori.Kategoriler;
import com.kategori.KategorilerJpaController;
import com.kategori.exceptions.NonexistentEntityException;
import java.util.List;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;


/**
 *
 * @author ubuntu
 */
public class EditBean {
    private KategorilerJpaController contObje;
    private Kategoriler kategoriObje;
    private List<Kategoriler> allRecordList;

    public List<Kategoriler> getAllRecordList() {
        return allRecordList;
    }
    public Kategoriler getKategoriObje() {
        return kategoriObje;
    }
    public void setKategoriObje(Kategoriler kategoriObje) {
        this.kategoriObje = kategoriObje;
    }
    public void setAllRecordList(List<Kategoriler> allRecordList) {
        this.allRecordList = allRecordList;
    }
    
    public EditBean() {
        contObje=new KategorilerJpaController();
        allRecordList=contObje.findKategorilerEntities();
        kategoriObje=new Kategoriler();
//Request nesnesi olusturup <h:outputLink> ile
//<f:param name="id" value="#{items.kategoriId}"/> degeri aliniyor
        FacesContext context=FacesContext.getCurrentInstance();
        HttpServletRequest request=(HttpServletRequest) context.getExternalContext().getRequest();
        if(request.getParameter("id")!=null){
            int katId=Integer.parseInt(request.getParameter("id"));
            kategoriObje=contObje.findKategoriler(katId);
        }
    }
    public void editCpmlete() throws NonexistentEntityException, Exception{
//<h:selectOneMenu value="#{editBean.kategoriObje.katUstId}"> ta ust kategori secilir ve
//<h:inputText value="#{editBean.kategoriObje.kategoriAdi}" required="true"/> alanina da kategori ismi duzenlenir
//secilen deger ve kategori adi edi() hazir medotu ile guncellenir bilgiler. Bu da kategorId primarykey iel guncellenir.
        contObje.edit(kategoriObje);
    }
//reset ile nesneye null deger atadim.
    public void reset(){
        getKategoriObje().setKatUstId(null);
        getKategoriObje().setKategoriAdi(null);
        getKategoriObje().setKategoriId(null);
    }
}

select menu

EditComplete.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:p="http://primefaces.prime.com.tr/ui"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h:form>
            <p:panel>
                <h:inputHidden value="#{editBean.kategoriObje.kategoriId}"/>
                <h:panelGrid columns="2" id="yenile">
                    <h:outputText value="Kategori Adi"/>
                    <h:inputText value="#{editBean.kategoriObje.kategoriAdi}" required="true"/>
                    <h:outputText value="Ust Kategori ID"/>
                    <h:selectOneMenu value="#{editBean.kategoriObje.katUstId}">
                        <f:selectItems value="#{editBean.allRecordList}" var="items"
                                       itemLabel="#{items.kategoriAdi}" itemValue="#{items.kategoriId}"/>
                    </h:selectOneMenu>
                    <h:commandButton value="Kaydet" action="#{editBean.editCpmlete}"/>
                    <p:commandButton value="Reset" action="#{editBean.reset}" update="yenile"/>
                </h:panelGrid>
            </p:panel>
            <p:button outcome="geri" value="Geri Don"/>
        </h:form>
    </h:body>
</html>

Kategoriler.java

package com.kategori;

import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

/**
 *
 * @author ubuntu
 */
@Entity
@Table(name = "kategoriler")
@NamedQueries({
    @NamedQuery(name = "Kategoriler.findAll", query = "SELECT k FROM Kategoriler k"),
    @NamedQuery(name = "Kategoriler.findByKategoriId", query = "SELECT k FROM Kategoriler k WHERE k.kategoriId = :kategoriId"),
    @NamedQuery(name = "Kategoriler.findByKategoriAdi", query = "SELECT k FROM Kategoriler k WHERE k.kategoriAdi = :kategoriAdi"),
    @NamedQuery(name = "Kategoriler.findByKatUstId", query = "SELECT k FROM Kategoriler k WHERE k.katUstId = :katUstId")})
public class Kategoriler implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "kategori_id")
    private Integer kategoriId;
    @Basic(optional = false)
    @Column(name = "kategori_adi")
    private String kategoriAdi;
    @Column(name = "kat_ust_id")
    private Integer katUstId;

    public Kategoriler() {
    }

    public Kategoriler(Integer kategoriId) {
        this.kategoriId = kategoriId;
    }

    public Kategoriler(String kategoriAdi) {
        this.kategoriAdi = kategoriAdi;
    }

    public Kategoriler(Integer kategoriId, String kategoriAdi) {
        this.kategoriId = kategoriId;
        this.kategoriAdi = kategoriAdi;
    }

    public Kategoriler(String kategoriAdi, Integer katUstId) {
        this.kategoriAdi = kategoriAdi;
        this.katUstId = katUstId;
    }

    public Integer getKategoriId() {
        return kategoriId;
    }

    public void setKategoriId(Integer kategoriId) {
        this.kategoriId = kategoriId;
    }

    public String getKategoriAdi() {
        return kategoriAdi;
    }

    public void setKategoriAdi(String kategoriAdi) {
        this.kategoriAdi = kategoriAdi;
    }

    public Integer getKatUstId() {
        return katUstId;
    }

    public void setKatUstId(Integer katUstId) {
        this.katUstId = katUstId;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (kategoriId != null ? kategoriId.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 Kategoriler)) {
            return false;
        }
        Kategoriler other = (Kategoriler) object;
        if ((this.kategoriId == null && other.kategoriId != null) || (this.kategoriId != null && !this.kategoriId.equals(other.kategoriId))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.kategori.Kategoriler[kategoriId=" + kategoriId + "]";
    }

}

persistence


persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  <persistence-unit name="KategorilerPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <non-jta-data-source/>
    <class>com.kategori.Kategoriler</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
      <property name="hibernate.connection.username" value="root"/>
      <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
      <property name="hibernate.connection.password" value="123"/>
      <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/odev"/>
      <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
      <property name="hibernate.hbm2ddl.auto" value="update"/>
    </properties>
  </persistence-unit>
</persistence>

faces-config


faces-config.xml

<?xml version='1.0' encoding='UTF-8'?>

<!-- =========== FULL CONFIGURATION FILE ================================== -->

<faces-config version="2.0"
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
    <navigation-rule>
        <from-view-id>/index.xhtml</from-view-id>
        <navigation-case>
            <from-outcome>edit</from-outcome>
            <to-view-id>/Edit.xhtml</to-view-id>
        </navigation-case>
    </navigation-rule>
    <managed-bean>
        <managed-bean-name>nodeBean</managed-bean-name>
        <managed-bean-class>com.Bean.NodeBean</managed-bean-class>

        <managed-bean-scope>request</managed-bean-scope></managed-bean>
    <managed-bean>
        <managed-bean-name>editBean</managed-bean-name>
        <managed-bean-class>com.Bean.EditBean</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
    </managed-bean>
    <navigation-rule>
        <from-view-id>/EditComplete.xhtml</from-view-id>
        <navigation-case>
            <from-outcome>geri</from-outcome>
            <to-view-id>/Edit.xhtml</to-view-id>
        </navigation-case>
    </navigation-rule>
</faces-config>

Ben NetBeans 6.9.1 kullandığımdan PrimeFaces default olarak gelmiyor. Bunun için
1. primafaces-2.2.1.jar kütüphanesini ekledim
2. web-fragment.xml dosyasını oluşturdum. Aşağıda o dosya içeriği var.
3.

xmlns:p="http://primefaces.prime.com.tr/ui"

xml namespacesini ekledim.

web-fragment.xml

<web-fragment xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd"
	version="3.0">

	<name>PrimeFaces</name>

    <servlet>
		<servlet-name>PrimeFaces Resource Servlet</servlet-name>
		<servlet-class>org.primefaces.resource.ResourceServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>PrimeFaces Resource Servlet</servlet-name>
		<url-pattern>/primefaces_resource/*</url-pattern>
	</servlet-mapping>

</web-fragment>

Uygulamayi indirmek için tiklayin. Ubuntuda uygulamayı .zip haline getiriyorum. Eğer açamazsanız veya link bozuksa dm atabilirim.

Comments

There are 6 comments for this post.

  1. Bogdan Marian on Ağustos 31, 2011 7:10 am

    Hi,

    Would’ve been great to have this tutorial written in English too …

  2. rags on Aralık 30, 2011 5:53 am

    Good Tutorials …. How do I get English Version of these tutorials ?

  3. ethemsulan on Aralık 30, 2011 7:44 am

    Hi, i write only Turkish. You can download source code: http://freecode.com/projects/treeview

  4. faranak on Kasım 18, 2012 11:41 am

    thanksssssssssssssssssssssssssssssss,asheghetammmm!!!! f from iran!

  5. faranak on Kasım 19, 2012 8:27 am

    hi , thanks for this great tutorial ;just how to set icon for nods dynamically??

  6. Dinesh on Eylül 15, 2014 9:10 pm

    Hi nice work!.. But when I tried to run the project using the source code from http://freecode.com/projects/treeview. I got lots of errors.

    An Error Occurred:
    Cant instantiate class: com.Bean.NodeBean.
    +Stack Trace
    +Component Tree

    Also I noticed in your controller bean (NodeBean.java) you don’t have JSF annotation,. Like (@ManagedBean and @ViewScope). If you could send me correct working that would be very helpful. dinbtechit@gmail.com is my email id.

Write a Comment

Let me know what you think?