Takip et

PrimeFaces Tree, TreeNode ve TreeTable: Hiyerarşik Veri Gösterimi ve Yönetimi İçin Kapsamlı Bir Kılavuz

PrimeFaces Tree, TreeNode ve TreeTable: Hiyerarşik Veri Gösterimi ve Yönetimi İçin Kapsamlı Bir Kılavuz Giriş Modern web uygulamalarında, ve

PrimeFaces Tree, TreeNode ve TreeTable: Hiyerarşik Veri Gösterimi ve Yönetimi İçin Kapsamlı Bir Kılavuz

Giriş

Modern web uygulamalarında, veriler genellikle düz bir liste veya basit bir tablo yapısından daha karmaşık ilişkiler içerir. Özellikle hiyerarşik veriler, ebeveyn-çocuk ilişkileriyle birbirine bağlı öğelerden oluşan ağaç benzeri yapılar sunar. Dosya sistemleri, organizasyon şemaları, ürün kategorileri, menü yapıları veya yorum dizileri gibi birçok senaryo, bu tür hiyerarşik yapıları etkin bir şekilde görselleştirmeyi ve yönetmeyi gerektirir.

PrimeFaces, JavaServer Faces (JSF) tabanlı uygulamalar için zengin bir bileşen kütüphanesi sunarak geliştiricilerin kullanıcı arayüzlerini hızlı ve kolay bir şekilde oluşturmalarına olanak tanır. Bu kütüphanenin en güçlü ve esnek bileşenlerinden ikisi, hiyerarşik verilerin gösterimi ve etkileşimi için tasarlanmış (Ağaç) ve (Ağaç Tablosu) bileşenleridir. Bu makalede, bu bileşenlerin temel yapı taşından başlayarak (TreeNode), kapsamlı kullanım örnekleri ve ileri seviye konularla birlikte derinlemesine incelenecektir. Amacımız, geliştiricilerin PrimeFaces Tree ve TreeTable bileşenlerini projelerinde güvenle ve etkin bir şekilde kullanabilmeleri için gerekli tüm bilgileri sağlamaktır.

TreeNode Temelleri: Hiyerarşinin Yapı Taşı

PrimeFaces Tree ve TreeTable bileşenlerinin kalbinde org.primefaces.model.TreeNode arayüzü yer alır. Bu arayüz, ağaç yapısındaki her bir düğümü (node) temsil eder ve hiyerarşinin temel yapı taşıdır. Bir TreeNode nesnesi, ağaçtaki bir öğenin verilerini, çocuklarını, ebeveynini ve durumunu (genişletilmiş mi, seçili mi vb.) tutar.

TreeNode Arayüzünün Temel Özellikleri

TreeNode arayüzü, bir düğümün temel özelliklerini ve davranışlarını tanımlar:

* Object getData() ve void setData(Object data): Bu metotlar, düğümün temsil ettiği gerçek veri nesnesine erişim sağlar. Örneğin, bir dosya sistemi ağacında bu bir File nesnesi, bir organizasyon şemasında ise bir Employee veya Department nesnesi olabilir.
* List getChildren(): Bir düğümün doğrudan altındaki çocuk düğümlerinin listesini döndürür. Bu liste, ağaç yapısının hiyerarşisini oluşturur.
* TreeNode getParent() ve void setParent(TreeNode parent): Düğümün ebeveyn düğümünü temsil eder. Kök düğümün ebeveyni null olur.
* String getType() ve void setType(String type): Düğümün tipini belirten bir string değeridir. Bu, farklı düğüm tipleri için farklı simgeler veya görünümler tanımlamak için kullanılır (örneğin, “klasör”, “dosya”, “çalışan”, “departman”).
* boolean isExpanded() ve void setExpanded(boolean expanded): Düğümün kullanıcı arayüzünde genişletilmiş (açık) olup olmadığını gösterir.
* boolean isSelected() ve void setSelected(boolean selected): Düğümün kullanıcı arayüzünde seçili olup olmadığını gösterir.
* boolean isPartialSelected() ve void setPartialSelected(boolean partialSelected): Bir düğümün tüm çocukları seçili değilse ancak bazı çocukları seçiliyse bu durum true olur. Genellikle checkbox seçim modunda kullanılır.
* boolean isLeaf(): Düğümün çocuk düğümü olup olmadığını kontrol eder. Eğer hiç çocuğu yoksa true döndürür.
* void addChild(TreeNode node) ve void removeChild(TreeNode node): Düğüme çocuk ekleme veya çıkarmayı sağlar.

DefaultTreeNode Sınıfı ve Kullanımı

PrimeFaces, TreeNode arayüzünün standart bir uygulamasını org.primefaces.model.DefaultTreeNode sınıfı ile sunar. Çoğu durumda, kendi özel TreeNode uygulamanızı yazmak yerine DefaultTreeNode kullanmak yeterlidir.

Bir ağaç yapısı oluşturmak için genellikle kök (root) düğüm ile başlanır ve ardından bu kök düğüme veya diğer düğümlere alt düğümler eklenir.

Örnek DefaultTreeNode Oluşturma:

import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;

public class TreeBean {

    private TreeNode root;

    public TreeBean() {
        root = new DefaultTreeNode("Root", null); // Kök düğüm, verisi "Root", ebeveyni yok.

        // Belge düğümü oluşturma
        TreeNode documents = new DefaultTreeNode("Belgeler", root);
        new DefaultTreeNode("word", "Rapor.docx", documents);
        new DefaultTreeNode("pdf", "Makale.pdf", documents);

        // Resim düğümü oluşturma
        TreeNode images = new DefaultTreeNode("Resimler", root);
        new DefaultTreeNode("jpg", "Manzara.jpg", images);
        new DefaultTreeNode("png", "Logo.png", images);

        // Alt klasör ve dosya
        TreeNode subFolder = new DefaultTreeNode("Klasör", "Önemli Belgeler", documents);
        new DefaultTreeNode("txt", "Notlar.txt", subFolder);
    }

    public TreeNode getRoot() {
        return root;
    }

    public void setRoot(TreeNode root) {
        this.root = root;
    }
}

Yukarıdaki örnekte, DefaultTreeNode kurucusunun üç farklı aşırı yüklemesi kullanılmıştır:
1. new DefaultTreeNode(Object data, TreeNode parent): Sadece veri ve ebeveyn belirterek varsayılan tipte (genellikle “default”) bir düğüm oluşturur.
2. new DefaultTreeNode(String type, Object data, TreeNode parent): Düğüm tipini, verisini ve ebeveynini belirterek daha özelleştirilmiş bir düğüm oluşturur. Bu, farklı düğüm tipleri için farklı görünümler sağlamak açısından önemlidir.

Bu şekilde, hiyerarşik veri yapısı bellekte TreeNode nesneleri aracılığıyla temsil edilir ve PrimeFaces bileşenleri bu yapıyı görselleştirmek için kullanır.

PrimeFaces Tree () Bileşeni

bileşeni, hiyerarşik verileri görsel olarak çekici ve etkileşimli bir ağaç yapısında sunmak için tasarlanmıştır. Kullanıcıların düğümleri genişletmesine, daraltmasına ve seçmesine olanak tanır.

Genel Bakış ve Temel Kullanım

bileşeni, dosya gezginleri, kategori listeleri, menüler ve organizasyon şemaları gibi birçok senaryoda kullanılır.

Temel Nitelikler:
* value: Ağacın kök düğümünü (bir TreeNode nesnesi) belirten bir EL ifadesidir.
* var: Ağaçtaki her bir düğüm için döngüde kullanılan geçici değişkenin adıdır.
* selectionMode: Düğüm seçimi davranışını belirler. Olası değerler:
* "single": Aynı anda yalnızca bir düğüm seçilebilir.
* "multiple": Ctrl/Cmd tuşu ile birden fazla düğüm seçilebilir.
* "checkbox": Düğümlerin yanında onay kutuları görünür ve birden fazla düğüm seçilebilir. Ebeveyn-çocuk ilişkileri dikkate alınır (bir ebeveyn seçildiğinde tüm çocukları da seçilir).
* selection: Seçilen TreeNode nesnesini veya TreeNode nesnelerinin listesini (selectionMode’a bağlı olarak) tutan bir EL ifadesidir.
* nodeVar: node alt bileşeninde düğüm verisine erişim için kullanılan değişken adıdır.

Ağaç Yapısını Oluşturma ve Görüntüleme

Ağacın her bir düğümünün nasıl görüntüleneceği, alt bileşeni kullanılarak tanımlanır. Birden fazla tanımlayarak farklı düğüm tipleri için farklı görünümler sağlayabilirsiniz.

Örnek XHTML Kodu:





Yukarıdaki örnekte, varsayılan bir kullanılmıştır. Bu, type özelliği belirtilmediğinde tüm düğümler için geçerli olur. treeBean.root kök düğümünü alır ve node değişkeniyle her bir düğümün verisine erişilir.

Farklı Düğüm Tipleri Kullanma:
DefaultTreeNode oluştururken type parametresini kullanmıştık. Bu tipleri ile eşleştirerek her tip için farklı bir görünüm sağlayabiliriz.

Örnek (Managed Bean’de type kullanarak):

// ... TreeBean constructor'da ...
TreeNode root = new DefaultTreeNode("Root", null);
TreeNode documents = new DefaultTreeNode("folder", "Belgeler", root); // type: folder
new DefaultTreeNode("file", "Rapor.docx", documents); // type: file
new DefaultTreeNode("file", "Makale.pdf", documents); // type: file
TreeNode images = new DefaultTreeNode("folder", "Resimler", root); // type: folder
new DefaultTreeNode("image", "Manzara.jpg", images); // type: image
new DefaultTreeNode("image", "Logo.png", images); // type: image

Örnek XHTML Kodu (Farklı Düğüm Tipleriyle):



    
        
    

    
        
    

    
        
    

    
        
    

Burada icon niteliğiyle PrimeIcons kütüphanesinden simgeler ekledik. type="default" ise, belirtilen diğer tiplere uymayan düğümler için kullanılır.

Düğüm Seçimi ve Olay Yönetimi

PrimeFaces Tree, kullanıcı etkileşimlerini (düğüm seçimi, genişletme/daraltma) yakalamak için çeşitli Ajax olayları sunar.

* nodeSelect: Bir düğüm seçildiğinde tetiklenir.
* nodeUnselect: Bir düğümün seçimi kaldırıldığında tetiklenir.
* nodeExpand: Bir düğüm genişletildiğinde tetiklenir.
* nodeCollapse: Bir düğüm daraltıldığında tetiklenir.

Bu olaylar, bileşeni ile dinlenebilir ve backend’de ilgili metotlar çağrılabilir.

Örnek Managed Bean Metotları:

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.event.NodeExpandEvent;
import org.primefaces.event.NodeCollapseEvent;
// ... diğer import'lar ...

@ManagedBean
@ViewScoped
public class TreeBean implements Serializable {
    // ... root ve selectedNode tanımlamaları ...
    private TreeNode[] selectedNodes; // Multiple veya Checkbox seçimi için

    public void onNodeSelect(NodeSelectEvent event) {
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Seçilen Düğüm", event.getTreeNode().getData().toString());
        FacesContext.getCurrentInstance().addMessage(null, message);
    }

    public void onNodeUnselect(NodeSelectEvent event) {
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Seçimi Kaldırılan Düğüm", event.getTreeNode().getData().toString());
        FacesContext.getCurrentInstance().addMessage(null, message);
    }

    public void onNodeExpand(NodeExpandEvent event) {
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Genişletilen Düğüm", event.getTreeNode().getData().toString());
        FacesContext.getCurrentInstance().addMessage(null, message);
    }

    public void onNodeCollapse(NodeCollapseEvent event) {
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Daraltılan Düğüm", event.getTreeNode().getData().toString());
        FacesContext.getCurrentInstance().addMessage(null, message);
    }

    // Seçili düğümleri gösterme metodu (tekli veya çoklu)
    public void displaySelectedSingle() {
        if (selectedNode != null) {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Tek Seçim", selectedNode.getData().toString());
            FacesContext.getCurrentInstance().addMessage(null, message);
        } else {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_WARN, "Uyarı", "Hiçbir düğüm seçilmedi.");
            FacesContext.getCurrentInstance().addMessage(null, message);
        }
    }

    public void displaySelectedMultiple() {
        if (selectedNodes != null && selectedNodes.length > 0) {
            StringBuilder builder = new StringBuilder();
            for (TreeNode node : selectedNodes) {
                builder.append(node.getData().toString()).append(", ");
            }
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Çoklu Seçim", builder.toString());
            FacesContext.getCurrentInstance().addMessage(null, message);
        } else {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_WARN, "Uyarı", "Hiçbir düğüm seçilmedi.");
            FacesContext.getCurrentInstance().addMessage(null, message);
        }
    }
    // ... getter/setter'lar ...
}

Örnek XHTML Kodu (Ajax ile):


    
    
    
    

    
        
    
    
        
    
    
        
    


Sürükle ve Bırak (Drag & Drop)

PrimeFaces Tree, düğümler arasında sürükle ve bırak işlevselliği sunarak ağaç yapısını dinamik olarak değiştirmeyi sağlar.
* draggable="true": Düğümlerin sürüklenebilir olmasını sağlar.
* droppable="true": Düğümlerin üzerine başka düğümlerin bırakılabilir olmasını sağlar.
* dragdropScope: Sürükle ve bırak işleminin kapsamını belirler. Aynı kapsamdaki öğeler arasında sürükle ve bırak yapılabilir.
* nodeDragDrop olayı: Bir düğüm sürüklendiğinde ve başka bir düğümün üzerine bırakıldığında tetiklenir. org.primefaces.event.NodeDragDropEvent nesnesi, sürüklenen ve bırakılan düğümler hakkında bilgi içerir.

Özelleştirme ve Stil

PrimeFaces Tree, çeşitli CSS sınıfları ve style, styleClass nitelikleri aracılığıyla görünümünü özelleştirmenize olanak tanır. Ayrıca, icon niteliğiyle her düğüm tipine özel simgeler atayabilirsiniz (PrimeIcons veya Font Awesome gibi kütüphanelerle).

PrimeFaces TreeTable () Bileşeni

bileşeni, hiyerarşik verileri standart bir tablo formatında, ancak her satırın bir ağaç düğümünü temsil ettiği ve genişletilebilir/daraltılabilir olduğu bir yapıda sunar. Bu, özellikle her bir hiyerarşik öğe için birden fazla sütunlu veri göstermeniz gerektiğinde ‘den daha kullanışlıdır.

Genel Bakış ve Tree Bileşeni ile Farkları

* Amacı: Hiyerarşik verileri tablo sütunları ile birlikte göstermek. Örneğin, bir dosya gezgininde dosya adının yanı sıra dosya boyutu, değiştirilme tarihi gibi bilgileri de göstermek istediğinizde TreeTable idealdir.
* Ne Zaman Tercih Edilmeli?
* : Odak noktanız sadece hiyerarşinin kendisi ve düğüm isimleri ise. Daha kompakt ve basit bir görünüm sunar.
* : Her hiyerarşik öğe için birden fazla öznitelik (sütun) göstermeniz gerekiyorsa. Daha zengin veri gösterimi sağlar.

Temel Kullanım ve Kolon Yapısı

‘ın temel nitelikleri ile benzerdir (value, var, selectionMode, selection). Ancak, alt bileşenleri ile tablo sütunları tanımlanır.

Önemli Özellikleri:
* : Bu özel sütun, hiyerarşik yapıyı genişletmek/daraltmak için kullanılan bir “toggler” simgesi içerir. Genellikle ilk sütun olarak kullanılır ve yalnızca bir sütunda expander="true" olmalıdır.

Örnek Managed Bean (Departman/Çalışan Yapısı):

public class Employee {
    private String name;
    private String title;
    private int salary;

    public Employee(String name, String title, int salary) {
        this.name = name;
        this.title = title;
        this.salary = salary;
    }
    // ... getter/setter'lar ...
}

@ManagedBean
@ViewScoped
public class TreeTableBean implements Serializable {
    private TreeNode root;
    private TreeNode selectedNode; // Tekli seçim için

    public TreeTableBean() {
        root = new DefaultTreeNode(new Employee("CEO", "Chief Executive Officer", 200000), null);

        TreeNode cto = new DefaultTreeNode(new Employee("Alice", "CTO", 150000), root);
        TreeNode devManager = new DefaultTreeNode(new Employee("Bob", "Development Manager", 100000), cto);
        new DefaultTreeNode(new Employee("Charlie", "Software Engineer", 80000), devManager);
        new DefaultTreeNode(new Employee("David", "Software Engineer", 85000), devManager);

        TreeNode hr = new DefaultTreeNode(new Employee("Eve", "HR Manager", 90000), root);
        new DefaultTreeNode(new Employee("Frank", "HR Specialist", 60000), hr);
    }

    public TreeNode getRoot() { return root; }
    public void setRoot(TreeNode root) { this.root = root; }
    public TreeNode getSelectedNode() { return selectedNode; }
    public void setSelectedNode(TreeNode selectedNode) { this.selectedNode = selectedNode; }

    public void onNodeSelect(NodeSelectEvent event) {
        Employee emp = (Employee) event.getTreeNode().getData();
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Seçilen Çalışan", emp.getName() + " - " + emp.getTitle());
        FacesContext.getCurrentInstance().addMessage(null, message);
    }
    // ... diğer olay metotları ...
}

Örnek XHTML Kodu:





Yukarıdaki örnekte, var="employee" değişkeni, her bir düğümün Employee nesnesine erişmek için kullanılır. sütunu, hiyerarşiyi genişletme/daraltma işlevselliğini sağlar.

Düğüm Seçimi ve Olay Yönetimi

‘da seçim, ‘ye benzer şekilde çalışır. selectionMode niteliği ("single", "multiple", "checkbox") ve selection niteliği (seçilen TreeNode veya TreeNode[]) kullanılır. nodeSelect, nodeUnselect gibi olaylar da aynı şekilde ile dinlenebilir.

Sıralama ve Filtreleme

, standart PrimeFaces DataTable gibi sıralama ve filtreleme özelliklerini de destekler. Ancak, bu özellikler hiyerarşik yapıyı koruyarak çalışır.

* sortBy ve sortOrder: Bir sütunu sıralamak için kullanılır.
* filterBy, filterMatchMode, filterEvent: Sütun bazında filtreleme yapmak için kullanılır.

Örnek Sıralama ve Filtreleme:


    
    
        
    

    
        
    

    
        
    

Sıralama ve filtreleme, yalnızca görünen (genişletilmiş) düğümler üzerinde uygulanır ve hiyerarşik yapıyı bozmadan sonuçları gösterir.

Genişletilmiş Özellikler: Lazy Loading

Çok büyük hiyerarşik veri setleriyle çalışırken, tüm ağacı başlangıçta belleğe yüklemek performans sorunlarına yol açabilir. PrimeFaces, bu durumu ele almak için “Lazy Loading” (Tembel Yükleme) mekanizmasını sunar.

Lazy Loading ile, bir düğüm yalnızca kullanıcı tarafından genişletildiğinde çocuk düğümleri yüklenir. Bu, özellikle veritabanından veya uzak bir servisten veri çekerken kaynak kullanımını optimize eder. Lazy loading için LazyTreeNode sınıfını kullanmanız veya kendi TreeNode uygulamanızda çocukları dinamik olarak yüklemeniz gerekir. Bu, genellikle TreeNode‘un getChildren() metodu çağrıldığında çocukları yükleyen bir mekanizma ile sağlanır.

Pratik Uygulama: Dosya Sistemi Gezgini ve Departman Yapısı

Şimdiye kadar öğrendiklerimizi pekiştirmek için hem hem de bileşenlerini kullanarak gerçek dünya senaryolarını simüle eden kapsamlı bir örnek oluşturalım.

Senaryo 1: Dosya Sistemi Gezgini ()
Basit bir dosya ve klasör yapısını göstereceğiz.

Senaryo 2: Departman ve Çalışan Hiyerarşisi ()
Bir şirketin departman ve çalışanlarını hiyerarşik bir tablo görünümünde sunacağız.

Backend Kodu (Managed Beans)

Önce veri modellerimizi ve Managed Bean’lerimizi oluşturalım.

FileNode.java (Dosya Sistemi Veri Modeli):

package com.example.model;

import java.io.Serializable;

public class FileNode implements Serializable {
    private String name;
    private String type; // folder, document, image, etc.
    private long size;
    private String lastModified;

    public FileNode(String name, String type, long size, String lastModified) {
        this.name = name;
        this.type = type;
        this.size = size;
        this.lastModified = lastModified;
    }

    // Getter ve Setter metotları
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getType() { return type; }
    public void setType(String type) { this.type = type; }
    public long getSize() { return size; }
    public void setSize(long size) { this.size = size; }
    public String getLastModified() { return lastModified; }
    public void setLastModified(String lastModified) { this.lastModified = lastModified; }

    @Override
    public String toString() {
        return name; // Tree'de gösterilecek değer
    }
}

DepartmentEmployee.java (Departman/Çalışan Veri Modeli):

package com.example.model;

import java.io.Serializable;

public class DepartmentEmployee implements Serializable {
    private String name;
    private String title;
    private String department;
    private double salary;

    public DepartmentEmployee(String name, String title, String department, double salary) {
        this.name = name;
        this.title = title;
        this.department = department;
        this.salary = salary;
    }

    // Getter ve Setter metotları
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getTitle() { return title; }
    public void setTitle(String title) { this.title = title; }
    public String getDepartment() { return department; }
    public void setDepartment(String department) { this.department = department; }
    public double getSalary() { return salary; }
    public void setSalary(double salary) { this.salary = salary; }
}

AppBeans.java (Managed Bean’ler):

package com.example.beans;

import com.example.model.DepartmentEmployee;
import com.example.model.FileNode;
import org.primefaces.event.NodeCollapseEvent;
import org.primefaces.event.NodeExpandEvent;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;

@Named("appBeans")
@ViewScoped
public class AppBeans implements Serializable {

    // --- p:tree için ---
    private TreeNode fileSystemRoot;
    private TreeNode selectedFileNode;
    private TreeNode[] selectedFileNodes; // Checkbox için

    // --- p:treeTable için ---
    private TreeNode departmentRoot;
    private TreeNode selectedDepartmentNode; // Tekli seçim için

    @PostConstruct
    public void init() {
        // Dosya Sistemi Ağacını Oluşturma
        fileSystemRoot = new DefaultTreeNode(new FileNode("Root", "root", 0, ""), null);

        TreeNode documents = new DefaultTreeNode("folder", new FileNode("Belgeler", "folder", 0, "2023-01-15"), fileSystemRoot);
        new DefaultTreeNode("document", new FileNode("Rapor.docx", "document", 12456, "2023-03-20"), documents);
        new DefaultTreeNode("document", new FileNode("Makale.pdf", "document", 89123, "2023-02-10"), documents);

        TreeNode projects = new DefaultTreeNode("folder", new FileNode("Projeler", "folder", 0, "2023-04-01"), documents);
        new DefaultTreeNode("document", new FileNode("ProjePlan.pptx", "document", 56789, "2023-04-05"), projects);
        new DefaultTreeNode("code", new FileNode("main.java", "code", 3456, "2023-04-10"), projects);

        TreeNode images = new DefaultTreeNode("folder", new FileNode("Resimler", "folder", 0, "2022-11-01"), fileSystemRoot);
        new DefaultTreeNode("image", new FileNode("Manzara.jpg", "image", 234567, "2022-12-01"), images);
        new DefaultTreeNode("image", new FileNode("Logo.png", "image", 12345, "2023-01-01"), images);

        // Departman Ağacını Oluşturma
        departmentRoot = new DefaultTreeNode(new DepartmentEmployee("Yönetim Kurulu", "CEO", "Yönetim", 500000), null);

        TreeNode ceoOffice = new DefaultTreeNode("department", new DepartmentEmployee("John Doe", "CEO", "Yönetim", 300000), departmentRoot);

        TreeNode itDept = new DefaultTreeNode("department", new DepartmentEmployee("Jane Smith", "IT Direktörü", "IT", 180000), ceoOffice);
        TreeNode devTeam = new DefaultTreeNode("team", new DepartmentEmployee("Bob Johnson", "Geliştirme Müdürü", "IT", 120000), itDept);
        new DefaultTreeNode("employee", new DepartmentEmployee("Alice Green", "Kıdemli Yazılım Geliştirici", "IT", 90000), devTeam);
        new DefaultTreeNode("employee", new DepartmentEmployee("Charlie Brown", "Yazılım Geliştirici", "IT", 75000), devTeam);
        TreeNode opsTeam = new DefaultTreeNode("team", new DepartmentEmployee("David White", "Operasyon Müdürü", "IT", 110000), itDept);
        new DefaultTreeNode("employee", new DepartmentEmployee("Eve Black", "Sistem Yöneticisi", "IT", 80000), opsTeam);

        TreeNode hrDept = new DefaultTreeNode("department", new DepartmentEmployee("Frank Blue", "İK Direktörü", "İnsan Kaynakları", 150000), ceoOffice);
        new DefaultTreeNode("employee", new DepartmentEmployee("Grace Red", "İK Uzmanı", "İnsan Kaynakları", 70000), hrDept);
    }

    // --- p:tree için getter/setter ve olay metotları ---
    public TreeNode getFileSystemRoot() { return fileSystemRoot; }
    public void setFileSystemRoot(TreeNode fileSystemRoot) { this.fileSystemRoot = fileSystemRoot; }
    public TreeNode getSelectedFileNode() { return selectedFileNode; }
    public void setSelectedFileNode(TreeNode selectedFileNode) { this.selectedFileNode = selectedFileNode; }
    public TreeNode[] getSelectedFileNodes() { return selectedFileNodes; }
    public void setSelectedFileNodes(TreeNode[] selectedFileNodes) { this.selectedFileNodes = selectedFileNodes; }

    public void onFileNodeSelect(NodeSelectEvent event) {
        FileNode file = (FileNode) event.getTreeNode().getData();
        addMessage(FacesMessage.SEVERITY_INFO, "Dosya Seçildi", file.getName() + " (" + file.getType() + ")");
    }

    public void onFileNodeUnselect(NodeSelectEvent event) {
        FileNode file = (FileNode) event.getTreeNode().getData();
        addMessage(FacesMessage.SEVERITY_INFO, "Dosya Seçimi Kaldırıldı", file.getName());
    }

    public void onFileNodeExpand(NodeExpandEvent event) {
        FileNode file = (FileNode) event.getTreeNode().getData();
        addMessage(FacesMessage.SEVERITY_INFO, "Klasör Genişletildi", file.getName());
    }

    public void onFileNodeCollapse(NodeCollapseEvent event) {
        FileNode file = (FileNode) event.getTreeNode().getData();
        addMessage(FacesMessage.SEVERITY_INFO, "Klasör Daraltıldı", file.getName());
    }

    public void displaySelectedFileNodes() {
        if (selectedFileNodes != null && selectedFileNodes.length > 0) {
            StringBuilder builder = new StringBuilder("Seçilen Dosyalar: ");
            for (TreeNode node : selectedFileNodes) {
                builder.append(((FileNode) node.getData()).getName()).append(", ");
            }
            addMessage(FacesMessage.SEVERITY_INFO, "Çoklu Dosya Seçimi", builder.toString());
        } else {
            addMessage(FacesMessage.SEVERITY_WARN, "Uyarı", "Hiçbir dosya seçilmedi.");
        }
    }

    // --- p:treeTable için getter/setter ve olay metotları ---
    public TreeNode getDepartmentRoot() { return departmentRoot; }
    public void setDepartmentRoot(TreeNode departmentRoot) { this.departmentRoot = departmentRoot; }
    public TreeNode getSelectedDepartmentNode() { return selectedDepartmentNode; }
    public void setSelectedDepartmentNode(TreeNode selectedDepartmentNode) { this.selectedDepartmentNode = selectedDepartmentNode; }

    public void onDepartmentNodeSelect(NodeSelectEvent event) {
        DepartmentEmployee emp = (DepartmentEmployee) event.getTreeNode().getData();
        addMessage(FacesMessage.SEVERITY_INFO, "Çalışan Seçildi", emp.getName() + " - " + emp.getTitle());
    }

    // Yardımcı metot
    private void addMessage(FacesMessage.Severity severity, String summary, String detail) {
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(severity, summary, detail));
    }
}

JSF (XHTML) Kodu

Şimdi bu Managed Bean’leri kullanarak iki farklı PrimeFaces bileşenini gösterelim.

index.xhtml:





Bu örnek, iki bileşenin de farklı senaryolarda nasıl kullanılabileceğini net bir şekilde göstermektedir. FileNode için toString() metodunu override ederek içinde sadece #{file} ile adını gösterebildik. DepartmentEmployee için ise içinde her özelliğe ayrı ayrı erişildi.

İleri Seviye Konular ve En İyi Uygulamalar

Büyük Veri Setlerinde Performans Optimizasyonu

Büyük hiyerarşilerde (binlerce düğüm), tüm ağacı başlangıçta yüklemek performansı düşürebilir.
* Lazy Loading: Daha önce bahsedildiği gibi, düğümleri yalnızca genişletildiklerinde yüklemek en etkili yöntemdir.

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Gönder

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.
Mobil sürümden çık