The rich:tree component renders a tree control on the page. The most important tree features include the following:
This demonstration also includes a simple selection-handling example. When you select a node, its name is shown. When you select a leaf, the full album details will be populated.
<!DOCTYPE html> <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich"> <h:outputStylesheet> .top{ vertical-align: top; width: 50%; } .bold{ font-weight: bold; } </h:outputStylesheet> <h:panelGrid columns="2" columnClasses="top,top" width="60%"> <h:form id="form"> <rich:tree id="tree" nodeType="#{node.type}" var="node" value="#{treeBean.rootNodes}" toggleType="client" selectionType="ajax" selectionChangeListener="#{treeBean.selectionChanged}"> <rich:treeNode type="country"> #{node.name} </rich:treeNode> <rich:treeNode type="company" iconExpanded="/images/tree/disc.gif" iconCollapsed="/images/tree/disc.gif"> #{node.name} </rich:treeNode> <rich:treeNode type="cd" iconLeaf="/images/tree/song.gif"> #{node.artist} - #{node.name} - #{node.year} </rich:treeNode> </rich:tree> </h:form> <a4j:outputPanel ajaxRendered="true" layout="block"> <rich:panel header="Current Selection" rendered="#{not empty treeBean.currentSelection}"> <h:outputText value="Name:" /> <h:outputText value="#{treeBean.currentSelection.name}" /> <h:panelGroup rendered="#{treeBean.currentSelection.leaf}"> <fieldset> <legend>Details</legend> <h:panelGrid columnClasses="bold" columns="2"> <h:outputText value="Country:" /> <h:outputText value="#{treeBean.currentSelection.company.country}" /> <h:outputText value="Company:" /> <h:outputText value="#{treeBean.currentSelection.company}" /> <h:outputText value="Artist:" /> <h:outputText value="#{treeBean.currentSelection.artist}" /> <h:outputText value="Price:" /> <h:outputText value="#{treeBean.currentSelection.price}"> <f:convertNumber type="currency" currencyCode="USD" /> </h:outputText> <h:outputText value="Year:" /> <h:outputText value="#{treeBean.currentSelection.year}" /> </h:panelGrid> </fieldset> </h:panelGroup> </rich:panel> </a4j:outputPanel> </h:panelGrid> </ui:composition>
package org.richfaces.demo.tree; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; import javax.faces.bean.ManagedBean; import javax.faces.bean.ManagedProperty; import javax.faces.bean.ViewScoped; import javax.swing.tree.TreeNode; import org.richfaces.component.AbstractTree; import org.richfaces.demo.tree.model.CD; import org.richfaces.demo.tree.model.Company; import org.richfaces.demo.tree.model.Country; import org.richfaces.event.TreeSelectionChangeEvent; /** * @author Ilya Shaikovsky */ @ManagedBean @ViewScoped public class TreeBean implements Serializable { private static final long serialVersionUID = 1L; @ManagedProperty(value = "#{cdsParser.cdsList}") private List<CDXmlDescriptor> cdXmlDescriptors; private List<TreeNode> rootNodes = new ArrayList<TreeNode>(); private Map<String, Country> countriesCache = new HashMap<String, Country>(); private Map<String, Company> companiesCache = new HashMap<String, Company>(); private TreeNode currentSelection = null; @PostConstruct public void init() { for (CDXmlDescriptor current : cdXmlDescriptors) { String countryName = current.getCountry(); String companyName = current.getCompany(); Country country = getCountryByName(current); Company company = getCompanyByName(current, country); CD cd = new CD(current.getTitle(), current.getArtist(), company, current.getPrice(), current.getYear()); company.getCds().add(cd); } } public void selectionChanged(TreeSelectionChangeEvent selectionChangeEvent) { // considering only single selection List<Object> selection = new ArrayList<Object>(selectionChangeEvent.getNewSelection()); Object currentSelectionKey = selection.get(0); AbstractTree tree = (AbstractTree) selectionChangeEvent.getSource(); Object storedKey = tree.getRowKey(); tree.setRowKey(currentSelectionKey); currentSelection = (TreeNode) tree.getRowData(); tree.setRowKey(storedKey); } private Country getCountryByName(CDXmlDescriptor descriptor) { String countryName = descriptor.getCountry(); Country country = countriesCache.get(countryName); if (country == null) { country = new Country(); country.setName(countryName); countriesCache.put(countryName, country); rootNodes.add(country); } return country; } private Company getCompanyByName(CDXmlDescriptor descriptor, Country country) { String companyName = descriptor.getCompany(); Company company = companiesCache.get(companyName); if (company == null) { company = new Company(); company.setName(companyName); company.setParent(country); country.getCompanies().add(company); companiesCache.put(companyName, company); } return company; } public List<CDXmlDescriptor> getCdXmlDescriptors() { return cdXmlDescriptors; } public void setCdXmlDescriptors(List<CDXmlDescriptor> cdXmlDescriptors) { this.cdXmlDescriptors = cdXmlDescriptors; } public List<TreeNode> getRootNodes() { return rootNodes; } public void setRootNodes(List<TreeNode> rootNodes) { this.rootNodes = rootNodes; } public TreeNode getCurrentSelection() { return currentSelection; } public void setCurrentSelection(TreeNode currentSelection) { this.currentSelection = currentSelection; } }
package org.richfaces.demo.tree.model; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import javax.swing.tree.TreeNode; import com.google.common.collect.Iterators; public class Country extends NamedNode implements TreeNode { private List<Company> companies = new ArrayList<Company>(); public Country() { this.setType("country"); } public TreeNode getChildAt(int childIndex) { return companies.get(childIndex); } public int getChildCount() { return companies.size(); } public TreeNode getParent() { return null; } public int getIndex(TreeNode node) { return companies.indexOf(node); } public boolean getAllowsChildren() { return true; } public boolean isLeaf() { return companies.isEmpty(); } public Enumeration<Company> children() { return Iterators.asEnumeration(companies.iterator()); } public List<Company> getCompanies() { return companies; } }
package org.richfaces.demo.tree.model; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import javax.swing.tree.TreeNode; import com.google.common.collect.Iterators; public class Company extends NamedNode implements TreeNode { private List<CD> cds = new ArrayList<CD>(); private Country country; public Company() { this.setType("company"); } public TreeNode getChildAt(int childIndex) { return cds.get(childIndex); } public int getChildCount() { return cds.size(); } public TreeNode getParent() { return country; } public void setParent(Country country) { this.country = country; } public int getIndex(TreeNode node) { return cds.indexOf(node); } public boolean getAllowsChildren() { return true; } public boolean isLeaf() { return cds.isEmpty(); } public Enumeration children() { return Iterators.asEnumeration(cds.iterator()); } public Country getCountry() { return country; } public void setCountry(Country country) { this.country = country; } public List<CD> getCds() { return cds; } }
package org.richfaces.demo.tree.model; import java.util.Enumeration; import javax.swing.tree.TreeNode; public class CD extends NamedNode implements TreeNode { private Company company; private String artist; private float price; private int year; public CD() { this.setType("cd"); } public CD(String name, String artist, Company company, float price, int year) { super(); this.setType("cd"); this.company = company; this.artist = artist; this.name = name; this.price = price; this.year = year; } public Company getCompany() { return company; } public void setCompany(Company company) { this.company = company; } public TreeNode getChildAt(int childIndex) { return null; } public int getChildCount() { return 0; } public TreeNode getParent() { return company; } public int getIndex(TreeNode node) { return 0; } public boolean getAllowsChildren() { return false; } public boolean isLeaf() { return true; } public Enumeration<TreeNode> children() { return new Enumeration<TreeNode>() { public boolean hasMoreElements() { return false; } public TreeNode nextElement() { return null; } }; } public String getArtist() { return artist; } public void setArtist(String artist) { this.artist = artist; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } }
package org.richfaces.demo.tree.model; import java.io.Serializable; public class NamedNode implements Serializable { protected String type; protected String name; 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; } @Override public String toString() { return this.name; } }