PrimeFaces树形组件深度教程:Tree、TreeNode与TreeTable实战指南
这是文章《PrimeFaces 树(Tree)、树节点(TreeNode)、树表(TreeTable) 示例教程》的第1部分(共13部分)。
为了有效展示层次结构数据并构建网站导航,PrimeFaces 提供了强大的树和树表组件。然而,充分利用这些组件并非易事,它们涉及大量的技术细节。互联网上现有的技术文档对这些问题仅有零散的提及,甚至有些关键部分完全缺失。本教程旨在为您提供一份全面的指南,帮助您深入理解并充分发挥这些组件的强大功能。
PrimeFaces 树形组件基础信息
| 信息 | 树 (Tree) | 
|---|---|
| 组件类 | org.primefaces.component.tree.Tree | 
| 组件类型 | org.primefaces.component.Tree | 
| 组件家族 | org.primefaces.component | 
| 渲染器类型 | org.primefaces.component.TreeRenderer | 
| 渲染器类 | org.primefaces.component.tree.TreeRenderer | 
PrimeFaces 树的属性
| 名称 | 默认值 | 类型 | 描述 | 
|---|---|---|---|
id | 
null | 
String | 
组件的唯一标识符。 | 
rendered | 
true | 
Boolean | 
布尔值,用于指定组件是否渲染。设置为 false 时,组件将不被渲染。 | 
binding | 
null | 
Object | 
一个 EL 表达式,映射到后端 Bean 中的服务器端 UIComponent 实例。 | 
widgetVar | 
null | 
String | 
客户端小部件的名称。 | 
value | 
null | 
Object | 
作为后端模型的 TreeNode 实例。 | 
var | 
null | 
String | 
请求作用域变量的名称,用于引用每个树节点的数据。 | 
dynamic | 
false | 
Boolean | 
指定 Ajax/客户端切换模式。 | 
cache | 
true | 
Boolean | 
指定动态加载节点的缓存。设置为 true 时,展开的节点将保留在内存中。 | 
onNodeClick | 
null | 
String | 
当树节点被点击时要处理的 JavaScript 事件。 | 
selection | 
null | 
Object | 
用于引用选定节点的 TreeNode 数组。 | 
style | 
null | 
String | 
树主容器元素的样式。 | 
styleClass | 
null | 
String | 
树主容器元素的样式类。 | 
selectionMode | 
null | 
String | 
定义选择模式。 | 
highlight | 
true | 
Boolean | 
启用选择时,鼠标悬停在节点上是否高亮显示。 | 
datakey | 
null | 
Object | 
节点表示的数据的唯一键。 | 
animate | 
false | 
Boolean | 
启用时,切换时显示滑动效果。 | 
orientation | 
vertical | 
String | 
布局方向,可选值:vertical(垂直)或 horizontal(水平)。 | 
propagateSelectionUp | 
true | 
Boolean | 
在复选框模式下,定义向上选择传播。 | 
propagateSelectionDown | 
true | 
Boolean | 
在复选框模式下,定义向下选择传播。 | 
dir | 
ltr | 
String | 
定义文本方向,有效值:ltr(从左到右)和 rtl(从右到左)。 | 
draggable | 
false | 
Boolean | 
使树节点可拖动。 | 
droppable | 
false | 
Boolean | 
使树可放置。 | 
dragdropScope | 
null | 
String | 
作用域键,用于将一组树组件分组,以便通过拖放传输节点。 | 
dragMode | 
self | 
String | 
定义节点被拖动时的父子关系,有效值:self(默认)、parent 和 ancestor。 | 
dropRestrict | 
none | 
String | 
定义节点被放置时的父子限制,有效值:none(默认)和 sibling。 | 
required | 
false | 
Boolean | 
选择的验证约束。 | 
requiredMessage | 
null | 
String | 
必选选择验证的消息。 | 
开始使用 PrimeFaces Tree
这是文章《Primefaces 树(Tree)、树节点(TreeNode)、树表(TreeTable) 示例教程》的第2部分(共13部分)。
内容片段:该树由一个org.primefaces.model.TreeNode实例填充,该实例对应于根节点。以下是一个简单的示例,展示了如何使用Tree组件。
index.xhtml 代码:
<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
<h:head>
	<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>
	<p:tree value="#{treeManagedBean.root}" var="node">
		<p:treeNode>
			<h:outputText value="#{node}"/>
		</p:treeNode>
	</p:tree>
</h:form>
</html>
package com.Olivia.prime.faces.beans;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
@ManagedBean
@SessionScoped
public class TreeManagedBean {
	// TreeNode 实例
	private TreeNode root;
	public TreeManagedBean(){
		// 这是根节点,其数据为“Root Node”,父节点为 null
		this.root = new DefaultTreeNode("Root Node", null);
		// 创建子节点
		TreeNode child = new DefaultTreeNode("Child Node", this.root);
		// 引用子节点的父节点
		child.setParent(this.root);
		// 创建后代节点
		TreeNode descendent = new DefaultTreeNode("Descendent Node", child);
		// 引用后代节点的父节点
		descendent.setParent(child);
	}
	public TreeNode getRoot() {
		return root;
	}
	public void setRoot(TreeNode root) {
		this.root = root;
	}
}
以下是对上述代码的进一步解释:
- Tree组件与一个名为
root的TreeNode实例关联。 root实例也有一个作为TreeNode实例的子节点,该子节点也引用其子节点。- 这种层级视图通过直接使用
value属性引用根节点来显示。 var属性由Tree组件用于引用请求作用域变量,该变量将用于引用每个树节点的数据。- 每个
TreeNode都是通过传递两个参数创建的:封装的数据对象实例和父节点引用。 - 每个
TreeNode的属性包括:类型(type)、数据(data)、子节点(children)、父节点(parent)和展开布尔指示器(expanded boolean indicator)。所有这些属性将在接下来的章节中详细探讨。 
Primefaces 动态树
树形组件默认情况下不是动态的。动态模式使用Ajax从服务器端按需获取树节点。当节点展开时,树会加载特定展开节点的子节点并发送给客户端进行显示。与将切换设置为客户端时(模型中的所有树节点都会渲染到客户端并创建树)不同,对于大规模数据,动态模式比使用默认行为更合适。以下是识别动态属性的方法。
index.xhtml 代码:
<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
<h:head>
	<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>
	<p:tree value="#{treeManagedBean.root}" var="node" dynamic="true">
		<p:treeNode>
			<h:outputText value="#{node}"/>
		</p:treeNode>
	</p:tree>
</h:form>
</html>
Primefaces支持多种树节点类型。
一个常见的需求是在层级结构中拥有不同类型的TreeNode和对应的图标。为了实现这一点,您应该遵循以下简单步骤:
- 定义/放置多个组件,每个组件具有不同的类型。
 - 使用已定义的类型来绑定模型中的
TreeNode。 
以下是一个简单示例,演示了如何使用不同的TreeNode来展示类型多样性。受影响的文件是index.xhtml视图文件和TreeManagedBean.java文件。index.xhtml的代码如下:
<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
<h:head>
	<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>
	<p:tree value="#{treeManagedBean.root}" var="node" dynamic="true">
		<p:treeNode expandedIcon="ui-icon ui-icon-folder-open"
						collapsedIcon="ui-icon ui-icon-folder-collapsed">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="document" icon="ui-icon ui-icon-document">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="image" icon="ui-icon ui-icon-image">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="video" icon="ui-icon ui-icon-video">
			<h:outputText value="#{node}"/>
		</p:treeNode>
	</p:tree>
</h:form>
</html>
package com.Olivia.prime.faces.beans;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
@ManagedBean
@SessionScoped
public class TreeManagedBean {
	// TreeNode 实例
	private TreeNode root;
	public TreeManagedBean(){
		// 这是根节点,因此其数据为“Root Node”,父节点为 null
		this.root = new DefaultTreeNode("Root Node", null);
		// 创建文档节点
		TreeNode documents = new DefaultTreeNode("Documents", this.root);
		// 创建单个文档节点
		TreeNode document01 = new DefaultTreeNode("document","Expenses.doc", documents);
		// 创建图片节点
		TreeNode images = new DefaultTreeNode("Images", this.root);
		// 创建单个图片节点
		TreeNode image01 = new DefaultTreeNode("image","Travel.gif", images);
		// 创建视频节点
		TreeNode videos = new DefaultTreeNode("Videos", this.root);
		// 创建单个视频节点
		TreeNode video01 = new DefaultTreeNode("video","Play.avi", videos);
	}
	public TreeNode getRoot() {
		return root;
	}
	public void setRoot(TreeNode root) {
		this.root = root;
	}
}
从提供的演示中可以明显看出,TreeNode实例和p:treeNode组件之间的集成是通过type属性实现的。
PrimeFaces 树状图的 Ajax 行为事件
树形控件提供了多种不同的 Ajax 行为事件:
| 事件 (Event) | 监听器参数 (Listener Parameter) | 触发时机 (Fired) | 
|---|---|---|
expand | 
org.primefaces.event.NodeExpandEvent | 
当节点展开时触发。 | 
collapse | 
org.primefaces.event.NodeCollapseEvent | 
当节点折叠时触发。 | 
select | 
org.primefaces.event.NodeSelectEvent | 
当节点被选中时触发。 | 
unselect | 
org.primefaces.event.NodeUnselectEvent | 
当节点被取消选中时触发。 | 
PrimeFaces 树组件事件监听器示例:index2.xhtml 代码解析
以下 PrimeFaces 树组件配置了四个事件监听器:
<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
<h:head>
	<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>
	<p:tree value="#{treeManagedBean.root}" var="node" dynamic="true">
		<p:treeNode expandedIcon="ui-icon ui-icon-folder-open"
						collapsedIcon="ui-icon ui-icon-folder-collapsed">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="document" icon="ui-icon ui-icon-document">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="image" icon="ui-icon ui-icon-image">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="video" icon="ui-icon ui-icon-video">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:ajax event="select" listener="#{treeManagedBean.onNodeSelect}"></p:ajax>
		<p:ajax event="unselect" listener="#{treeManagedBean.onNodeUnSelect}"></p:ajax>
		<p:ajax event="expand" listener="#{treeManagedBean.onNodeExpand}"></p:ajax>
		<p:ajax event="collapse" listener="#{treeManagedBean.onNodeCollapse}"></p:ajax>
	</p:tree>
</h:form>
</html>
package com.Olivia.prime.faces.beans;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.primefaces.event.NodeCollapseEvent;
import org.primefaces.event.NodeExpandEvent;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.event.NodeUnselectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
@ManagedBean
@SessionScoped
public class TreeManagedBean {
	// TreeNode 实例
	private TreeNode root;
	public TreeManagedBean(){
		// 这是根节点,其数据为“Root Node”,父节点为 null
		this.root = new DefaultTreeNode("Root Node", null);
		// 创建文档节点
		TreeNode documents = new DefaultTreeNode("Documents", this.root);
		// 创建单个文档节点
		TreeNode document01 = new DefaultTreeNode("document","Expenses.doc", documents);
		// 创建图片节点
		TreeNode images = new DefaultTreeNode("Images", this.root);
		// 创建单个图片节点
		TreeNode image01 = new DefaultTreeNode("image","Travel.gif", images);
		// 创建视频节点
		TreeNode videos = new DefaultTreeNode("Videos", this.root);
		// 创建单个视频节点
		TreeNode video01 = new DefaultTreeNode("video","Play.avi", videos);
	}
	public TreeNode getRoot() {
		return root;
	}
	public void setRoot(TreeNode root) {
		this.root = root;
	}
	public void onNodeSelect(NodeSelectEvent event){
		System.out.println("节点数据 ::"+event.getTreeNode().getData()+" :: 已选中");
	}
	public void onNodeUnSelect(NodeUnselectEvent event){
		System.out.println("节点数据 ::"+event.getTreeNode().getData()+" :: 已取消选中");
	}
	public void onNodeExpand(NodeExpandEvent event){
		System.out.println("节点数据 ::"+event.getTreeNode().getData()+" :: 已展开");
	}
	public void onNodeCollapse(NodeCollapseEvent event){
		System.out.println("节点数据 ::"+event.getTreeNode().getData()+" :: 已折叠");
	}
}
PrimeFaces 树组件事件监听器说明
- 当您展开或折叠树节点(TreeNode)时,会触发相应的 Ajax 事件。
 - 对于每个触发的事件,都定义了一个 Ajax 监听器方法(listener method)来处理。
 - 事件监听器在处理大量数据时也特别有用。通过为树提供根节点和子节点,可以使用事件监听器在运行时获取选定的节点并向该特定树添加新节点。
 - 请注意,本示例中“选择”(select)和“取消选择”(unselect)事件目前不会触发,要触发这些事件需要设置树的 
selectionMode属性。 
PrimeFaces 树组件:节点选择与事件处理详解
这是文章《PrimeFaces 树(Tree)、树节点(TreeNode)、树表(TreeTable) 示例教程》的第5部分(共13部分)。
PrimeFaces 树组件内置了强大的节点选择功能,帮助您轻松识别用户选中的节点。节点选择机制支持三种模式,每种模式都对应着不同的选择引用类型:
- 单选模式 (Single Mode): 每次只能选择一个树节点。选中的节点将作为单个 
TreeNode实例进行引用。 - 多选模式 (Multiple Mode): 可以同时选择多个节点。选中的节点将作为 
TreeNode数组进行引用。 - 复选框模式 (Checkbox Mode): 通过复选框用户界面选择多个节点。选中的节点同样作为 
TreeNode数组进行引用。 
index1.xhtml 代码示例:
<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
<h:head>
	<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>
	<!-- 单选模式示例 -->
	<p:tree value="#{treeManagedBean.root}" var="node" dynamic="true"
			selectionMode="single" selection="#{treeManagedBean.singleSelectedTreeNode}">
		<p:treeNode expandedIcon="ui-icon ui-icon-folder-open"
						collapsedIcon="ui-icon ui-icon-folder-collapsed">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="document" icon="ui-icon ui-icon-document">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="image" icon="ui-icon ui-icon-image">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="video" icon="ui-icon ui-icon-video">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:ajax event="select" listener="#{treeManagedBean.onNodeSelect}"></p:ajax>
		<p:ajax event="unselect" listener="#{treeManagedBean.onNodeUnSelect}"></p:ajax>
		<p:ajax event="expand" listener="#{treeManagedBean.onNodeExpand}"></p:ajax>
		<p:ajax event="collapse" listener="#{treeManagedBean.onNodeCollapse}"></p:ajax>
	</p:tree>
	<!-- 多选模式示例 -->
	<p:tree value="#{treeManagedBean.root}" var="node" dynamic="true"
			selectionMode="multiple" selection="#{treeManagedBean.multipleSelectedTreeNodes}">
		<p:treeNode expandedIcon="ui-icon ui-icon-folder-open"
						collapsedIcon="ui-icon ui-icon-folder-collapsed">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="document" icon="ui-icon ui-icon-document">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="image" icon="ui-icon ui-icon-image">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="video" icon="ui-icon ui-icon-video">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:ajax event="select" listener="#{treeManagedBean.onNodeSelect}"></p:ajax>
		<p:ajax event="unselect" listener="#{treeManagedBean.onNodeUnSelect}"></p:ajax>
		<p:ajax event="expand" listener="#{treeManagedBean.onNodeExpand}"></p:ajax>
		<p:ajax event="collapse" listener="#{treeManagedBean.onNodeCollapse}"></p:ajax>
	</p:tree>
	<!-- 复选框模式示例 -->
	<p:tree value="#{treeManagedBean.root}" var="node" dynamic="true"
			selectionMode="checkbox" selection="#{treeManagedBean.checkboxSelectedTreeNodes}">
		<p:treeNode expandedIcon="ui-icon ui-icon-folder-open"
						collapsedIcon="ui-icon ui-icon-folder-collapsed">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="document" icon="ui-icon ui-icon-document">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="image" icon="ui-icon ui-icon-image">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="video" icon="ui-icon ui-icon-video">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:ajax event="select" listener="#{treeManagedBean.onNodeSelect}"></p:ajax>
		<p:ajax event="unselect" listener="#{treeManagedBean.onNodeUnSelect}"></p:ajax>
		<p:ajax event="expand" listener="#{treeManagedBean.onNodeExpand}"></p:ajax>
		<p:ajax event="collapse" listener="#{treeManagedBean.onNodeCollapse}"></p:ajax>
	</p:tree>
	<h:commandButton value="打印选定节点" action="#{treeManagedBean.printSelectedNodes}"></h:commandButton>
</h:form>
</html>
package com.Olivia.prime.faces.beans;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.primefaces.event.NodeCollapseEvent;
import org.primefaces.event.NodeExpandEvent;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.event.NodeUnselectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
@ManagedBean
@SessionScoped
public class TreeManagedBean {
	// TreeNode 实例
	private TreeNode root;
	private TreeNode singleSelectedTreeNode;
	private TreeNode [] multipleSelectedTreeNodes;
	private TreeNode [] checkboxSelectedTreeNodes;
	public TreeManagedBean(){
		// 这是根节点,其数据为“Root Node”,父节点为 null
		this.root = new DefaultTreeNode("Root Node", null);
		// 创建“文档”节点
		TreeNode documents = new DefaultTreeNode("Documents", this.root);
		// 创建文档子节点
		TreeNode document01 = new DefaultTreeNode("document","Expenses.doc", documents);
		// 创建“图片”节点
		TreeNode images = new DefaultTreeNode("Images", this.root);
		// 创建图片子节点
		TreeNode image01 = new DefaultTreeNode("image","Travel.gif", images);
		// 创建“视频”节点
		TreeNode videos = new DefaultTreeNode("Videos", this.root);
		// 创建视频子节点
		TreeNode video01 = new DefaultTreeNode("video","Play.avi", videos);
	}
	public TreeNode getRoot() {
		return root;
	}
	public void setRoot(TreeNode root) {
		this.root = root;
	}
	public TreeNode getSingleSelectedTreeNode() {
		return singleSelectedTreeNode;
	}
	public void setSingleSelectedTreeNode(TreeNode singleSelectedTreeNode) {
		this.singleSelectedTreeNode = singleSelectedTreeNode;
	}
	public TreeNode[] getMultipleSelectedTreeNodes() {
		return multipleSelectedTreeNodes;
	}
	public void setMultipleSelectedTreeNodes(TreeNode[] multipleSelectedTreeNodes) {
		this.multipleSelectedTreeNodes = multipleSelectedTreeNodes;
	}
	public TreeNode[] getCheckboxSelectedTreeNodes() {
		return checkboxSelectedTreeNodes;
	}
	public void setCheckboxSelectedTreeNodes(TreeNode[] checkboxSelectedTreeNodes) {
		this.checkboxSelectedTreeNodes = checkboxSelectedTreeNodes;
	}
	public void onNodeSelect(NodeSelectEvent event){
		System.out.println("节点数据 ::"+event.getTreeNode().getData()+" :: 已选择");
	}
	public void onNodeUnSelect(NodeUnselectEvent event){
		System.out.println("节点数据 ::"+event.getTreeNode().getData()+" :: 已取消选择");
	}
	public void onNodeExpand(NodeExpandEvent event){
		System.out.println("节点数据 ::"+event.getTreeNode().getData()+" :: 已展开");
	}
	public void onNodeCollapse(NodeCollapseEvent event){
		System.out.println("节点数据 ::"+event.getTreeNode().getData()+" :: 已折叠");
	}
	public String printSelectedNodes(){
		System.out.println("单选节点为 :: "+this.singleSelectedTreeNode.getData());
		for(TreeNode n : this.multipleSelectedTreeNodes){
			System.out.println("多选节点为 :: "+n.getData());
		}
		for(TreeNode n : this.checkboxSelectedTreeNodes){
			System.out.println("复选框选择节点为 :: "+n.getData());
		}
		return "";
	}
}
PrimeFaces 节点图标与事件处理
在 PrimeFaces 的 TreeNode 组件中,还有一些重要的属性和事件值得关注:
TreeNode组件提供了expandedIcon和collapsedIcon属性,用于指定节点展开和折叠状态下的图标。TreeNode组件还具有icon属性,用于指定节点自身的图标。
PrimeFaces 树组件:缓存、动态加载与节点点击事件处理
在 PrimeFaces 树组件中,默认情况下,缓存属性是启用的。这意味着动态加载的节点会保留在内存中,因此当您重新展开一个节点时,不会再次触发服务器端请求,从而提升用户体验和性能。如果您将此缓存属性设置为 false,那么折叠节点时其子节点将被移除。当您稍后再次展开该节点时,系统将不得不重新从服务器获取子节点数据。
此外,PrimeFaces 树组件还允许您在节点被点击时执行自定义的 JavaScript 代码。通过使用 onNodeClick 属性,您可以指定一个 JavaScript 方法。该方法在被调用时,会接收到两个参数:被点击的 HTML 节点元素和相关的事件对象。下面的示例展示了如何在 onNodeClick 方法中打印一些日志消息,以便在节点被点击时进行调试或执行其他操作。
index3.xhtml 代码示例:
<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
<h:head>
	<script name="jquery/jquery.js" library="primefaces"></script>
	<script>
		function onNodeClick(node, event) {
			console.log("节点参数 :: " + node);
			console.log("事件参数 :: " + event);
		}
	</script>
</h:head>
<h:form>
	<p:tree value="#{treeManagedBean.root}" var="node" dynamic="true"
				onNodeClick="onNodeClick(node,event)"
				selectionMode="single" selection="#{treeManagedBean.singleSelectedTreeNode}">
		<p:treeNode expandedIcon="ui-icon ui-icon-folder-open"
						collapsedIcon="ui-icon ui-icon-folder-collapsed">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="document" icon="ui-icon ui-icon-document">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="image" icon="ui-icon ui-icon-image">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="video" icon="ui-icon ui-icon-video">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:ajax event="select" listener="#{treeManagedBean.onNodeSelect}"></p:ajax>
		<p:ajax event="unselect" listener="#{treeManagedBean.onNodeUnSelect}"></p:ajax>
		<p:ajax event="expand" listener="#{treeManagedBean.onNodeExpand}"></p:ajax>
		<p:ajax event="collapse" listener="#{treeManagedBean.onNodeCollapse}"></p:ajax>
	</p:tree>
</h:form>
</html>
PrimeFaces 拖放功能
这是文章《Primefaces 树(Tree)、树节点(TreeNode)、树表(TreeTable) 示例教程》的第7部分(共13部分)。
内容片段: 单个树结构中的树节点可以重新排序,甚至可以使用拖放功能在多个树之间进行转移。以下示例向您展示如何使单个树具有可拖放功能。index4.xhtml 代码如下:
<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
<h:head>
	<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>
	<p:tree value="#{treeManagedBean.root}" var="node" dynamic="true" droppable="true" draggable="true"
				selectionMode="single" selection="#{treeManagedBean.singleSelectedTreeNode}">
		<p:treeNode expandedIcon="ui-icon ui-icon-folder-open"
						collapsedIcon="ui-icon ui-icon-folder-collapsed">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="document" icon="ui-icon ui-icon-document">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="image" icon="ui-icon ui-icon-image">
			<h:outputText value="#{node}"/>
		</p:treeNode>					
		<p:treeNode type="video" icon="ui-icon ui-icon-video">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:ajax event="select" listener="#{treeManagedBean.onNodeSelect}"></p:ajax>
		<p:ajax event="unselect" listener="#{treeManagedBean.onNodeUnSelect}"></p:ajax>
		<p:ajax event="expand" listener="#{treeManagedBean.onNodeExpand}"></p:ajax>
		<p:ajax event="collapse" listener="#{treeManagedBean.onNodeCollapse}"></p:ajax>								
	</p:tree>
</h:form>
</html>
应用拖放概念对单个树进行操作非常简单,而当涉及到多个树组件的拖放时,会出现更复杂的示例。以下示例为您展示了一个简单的多树拖放示例。这次需要使用一个新属性 dragdropScope 来使树的节点能够在彼此之间进行拖放。index5.xhtml 代码如下:
<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
<h:head>
	<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>
	<p:tree value="#{treeManagedBean.root}" var="node" dynamic="true" droppable="true" draggable="true"
				selectionMode="single" selection="#{treeManagedBean.singleSelectedTreeNode}"
				dragdropScope="myScope">
		<p:treeNode expandedIcon="ui-icon ui-icon-folder-open"
						collapsedIcon="ui-icon ui-icon-folder-collapsed">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="document" icon="ui-icon ui-icon-document">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="image" icon="ui-icon ui-icon-image">
			<h:outputText value="#{node}"/>
		</p:treeNode>					
		<p:treeNode type="video" icon="ui-icon ui-icon-video">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:ajax event="select" listener="#{treeManagedBean.onNodeSelect}"></p:ajax>
		<p:ajax event="unselect" listener="#{treeManagedBean.onNodeUnSelect}"></p:ajax>
		<p:ajax event="expand" listener="#{treeManagedBean.onNodeExpand}"></p:ajax>
		<p:ajax event="collapse" listener="#{treeManagedBean.onNodeCollapse}"></p:ajax>								
	</p:tree>
	
	<p:tree value="#{treeManagedBean.root}" var="node" dynamic="true" droppable="true" draggable="true"
				selectionMode="single" selection="#{treeManagedBean.singleSelectedTreeNode}"
				dragdropScope="myScope">
		<p:treeNode expandedIcon="ui-icon ui-icon-folder-open"
						collapsedIcon="ui-icon ui-icon-folder-collapsed">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="document" icon="ui-icon ui-icon-document">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="image" icon="ui-icon ui-icon-image">
			<h:outputText value="#{node}"/>
		</p:treeNode>					
		<p:treeNode type="video" icon="ui-icon ui-icon-video">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:ajax event="select" listener="#{treeManagedBean.onNodeSelect}"></p:ajax>
		<p:ajax event="unselect" listener="#{treeManagedBean.onNodeUnSelect}"></p:ajax>
		<p:ajax event="expand" listener="#{treeManagedBean.onNodeExpand}"></p:ajax>
		<p:ajax event="collapse" listener="#{treeManagedBean.onNodeCollapse}"></p:ajax>								
	</p:tree>	
</h:form>
</html>
PrimeFaces 树组件:拖放功能详解与示例
这是文章《Primefaces 树(Tree)、树节点(TreeNode)、树表(TreeTable) 示例教程》的第8部分(共13部分)。
PrimeFaces 树组件默认方向为垂直。通过设置 orientation 属性为 horizontal,可以将树节点以水平布局显示。除了拖放功能外,垂直树的所有特性在水平树上同样可用。
以下是 index6.xhtml 的代码示例:
<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
<h:head>
	<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>
	<p:tree value="#{treeManagedBean.root}" var="node" dynamic="true" orientation="horizontal" 
				selectionMode="single" selection="#{treeManagedBean.singleSelectedTreeNode}">
		<p:treeNode expandedIcon="ui-icon ui-icon-folder-open"
						collapsedIcon="ui-icon ui-icon-folder-collapsed">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="document" icon="ui-icon ui-icon-document">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="image" icon="ui-icon ui-icon-image">
			<h:outputText value="#{node}"/>
		</p:treeNode>					
		<p:treeNode type="video" icon="ui-icon ui-icon-video">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:ajax event="select" listener="#{treeManagedBean.onNodeSelect}"></p:ajax>
		<p:ajax event="unselect" listener="#{treeManagedBean.onNodeUnSelect}"></p:ajax>
		<p:ajax event="expand" listener="#{treeManagedBean.onNodeExpand}"></p:ajax>
		<p:ajax event="collapse" listener="#{treeManagedBean.onNodeCollapse}"></p:ajax>							
	</p:tree>
</h:form>
</html>
PrimeFaces 上下文菜单 (ContextMenu)
PrimeFaces 树形表格:上下文菜单集成示例
PrimeFaces 提供了一个特殊的组件,用于实现上下文操作。ContextMenu 组件正是为此目的而设计,并且 Tree 组件甚至可以与上下文菜单无缝集成,以便对选定的节点或多个选择的节点应用排序操作。
要实现此功能,应使用 ContextMenu 的 for 属性来引用 Tree 组件的 id 属性。这样,每当在 Tree 组件内选择特定节点时,就会显示预定义的菜单。通过右键单击即可显示上下文菜单组件。
index6.xhtml 代码示例:
<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
<h:head>
	<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>
	<p:contextMenu for="tree">
		<p:menuitem value="查看" actionListener="#{treeManagedBean.view}" icon="ui-icon-search"></p:menuitem>
	</p:contextMenu>
	<p:tree id="tree" value="#{treeManagedBean.root}" var="node" dynamic="true" orientation="horizontal" 
				selectionMode="single" selection="#{treeManagedBean.singleSelectedTreeNode}">
		<p:treeNode expandedIcon="ui-icon ui-icon-folder-open"
						collapsedIcon="ui-icon ui-icon-folder-collapsed">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="document" icon="ui-icon ui-icon-document">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:treeNode type="image" icon="ui-icon ui-icon-image">
			<h:outputText value="#{node}"/>
		</p:treeNode>					
		<p:treeNode type="video" icon="ui-icon ui-icon-video">
			<h:outputText value="#{node}"/>
		</p:treeNode>
		<p:ajax event="select" listener="#{treeManagedBean.onNodeSelect}"></p:ajax>
		<p:ajax event="unselect" listener="#{treeManagedBean.onNodeUnSelect}"></p:ajax>
		<p:ajax event="expand" listener="#{treeManagedBean.onNodeExpand}"></p:ajax>
		<p:ajax event="collapse" listener="#{treeManagedBean.onNodeCollapse}"></p:ajax>							
	</p:tree>
</h:form>
</html>
TreeManagedBean.java 代码示例:
package com.Olivia.prime.faces.beans;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ActionEvent;
import org.primefaces.event.NodeCollapseEvent;
import org.primefaces.event.NodeExpandEvent;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.event.NodeUnselectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
@ManagedBean
@SessionScoped
public class TreeManagedBean {
	// 树节点实例
	private TreeNode root;
	private TreeNode singleSelectedTreeNode;
	private TreeNode [] multipleSelectedTreeNodes;
	private TreeNode [] checkboxSelectedTreeNodes;
	
	public TreeManagedBean(){
		// 这是根节点,其数据为“Root Node”,父节点为 null
		this.root = new DefaultTreeNode("Root Node", null);
		// 创建文档节点
		TreeNode documents = new DefaultTreeNode("Documents", this.root);
		// 创建文档子节点
		TreeNode document01 = new DefaultTreeNode("document","Expenses.doc", documents);
		// 创建图片节点
		TreeNode images = new DefaultTreeNode("Images", this.root);
		// 创建图片子节点
		TreeNode image01 = new DefaultTreeNode("image","Travel.gif", images);
		// 创建视频节点
		TreeNode videos = new DefaultTreeNode("Videos", this.root);
		// 创建视频子节点
		TreeNode video01 = new DefaultTreeNode("video","Play.avi", videos);
	}
	public TreeNode getRoot() {
		return root;
	}
	public void setRoot(TreeNode root) {
		this.root = root;
	}
	
	public TreeNode getSingleSelectedTreeNode() {
		return singleSelectedTreeNode;
	}
	public void setSingleSelectedTreeNode(TreeNode singleSelectedTreeNode) {
		this.singleSelectedTreeNode = singleSelectedTreeNode;
	}
	public TreeNode[] getMultipleSelectedTreeNodes() {
		return multipleSelectedTreeNodes;
	}
	public void setMultipleSelectedTreeNodes(TreeNode[] multipleSelectedTreeNodes) {
		this.multipleSelectedTreeNodes = multipleSelectedTreeNodes;
	}
	public TreeNode[] getCheckboxSelectedTreeNodes() {
		return checkboxSelectedTreeNodes;
	}
	public void setCheckboxSelectedTreeNodes(TreeNode[] checkboxSelectedTreeNodes) {
		this.checkboxSelectedTreeNodes = checkboxSelectedTreeNodes;
	}
	public void onNodeSelect(NodeSelectEvent event){
		System.out.println("节点数据 ::"+event.getTreeNode().getData()+" :: 已选中");
	}
	
	public void onNodeUnSelect(NodeUnselectEvent event){
		System.out.println("节点数据 ::"+event.getTreeNode().getData()+" :: 已取消选中");
	}
	
	public void onNodeExpand(NodeExpandEvent event){
		System.out.println("节点数据 ::"+event.getTreeNode().getData()+" :: 已展开");
	}
	
	public void onNodeCollapse(NodeCollapseEvent event){
		System.out.println("节点数据 ::"+event.getTreeNode().getData()+" :: 已折叠");
	}
	
	public String printSelectedNodes(){
		System.out.println("单选结果为 :: "+this.singleSelectedTreeNode.getData());
		for(TreeNode n : this.multipleSelectedTreeNodes){
			System.out.println("多选结果为 :: "+n.getData());	
		}
		for(TreeNode n : this.checkboxSelectedTreeNodes){
			System.out.println("复选框选择结果为 :: "+n.getData());	
		}		
		return "";
	}
	
	public void view(ActionEvent e){
		System.out.println("针对节点 :: "+this.singleSelectedTreeNode.getData()+" :: 已调用查看操作");
	}	
}
TreeTable 用于以表格形式显示分层数据。
开始使用 PrimeFaces TreeTable
在探索 TreeTable 组件之前,了解其基本信息和属性非常重要。
| 信息 | TreeTable | 
|---|---|
| 组件类 | org.primefaces.component.treetable.TreeTable | 
| 组件类型 | org.primefaces.component.TreeTable | 
| 组件家族 | org.primefaces.component | 
| 渲染器类型 | org.primefaces.component.TreeTableRenderer | 
| 渲染器类 | org.primefaces.component.treetable.TreeTableRenderer | 
| 名称 | 默认值 | 类型 | 描述 | 
|---|---|---|---|
id | 
null | 
String | 
组件的唯一标识符。 | 
rendered | 
true | 
Boolean | 
指定组件是否渲染的布尔值,设置为 false 时组件将不被渲染。 | 
binding | 
null | 
Object | 
一个 EL 表达式,映射到后台 Bean 中的服务器端 UIComponent 实例。 | 
value | 
null | 
Object | 
作为后台模型的 TreeNode 实例。 | 
var | 
null | 
String | 
用于引用每个树节点的请求作用域变量的名称。 | 
widgetVar | 
null | 
String | 
客户端小部件的名称。 | 
style | 
null | 
String | 
容器元素的内联样式。 | 
styleClass | 
null | 
String | 
容器元素的样式类。 | 
selection | 
null | 
Object | 
选择引用。 | 
selectionMode | 
null | 
String | 
选择模式的类型。 | 
scrollable | 
false | 
Boolean | 
数据是否可滚动。 | 
scrollHeight | 
null | 
Integer | 
可滚动数据的高度。 | 
scrollWidth | 
null | 
Integer | 
可滚动数据的宽度。 | 
tableStyle | 
null | 
String | 
表格元素的内联样式。 | 
tableStyleClass | 
null | 
String | 
表格元素的样式类。 | 
emptyMessage | 
No records found | 
String | 
没有数据显示时要显示的文本。 | 
resizableColumns | 
false | 
Boolean | 
定义列是否可以调整大小。 | 
rowStyleClass | 
null | 
String | 
每行的样式类。 | 
liveResize | 
false | 
Boolean | 
在此模式下,列会实时调整大小,无需使用调整大小辅助工具。 | 
required | 
false | 
Boolean | 
选择的验证约束。 | 
requiredMessage | 
null | 
String | 
必选选择验证的消息。 | 
sortBy | 
null | 
ValueExpr | 
默认排序的表达式。 | 
sortOrder | 
ascending | 
String | 
定义默认排序顺序。 | 
sortFunction | 
null | 
MethodExpr | 
用于默认排序的自定义可插拔排序函数。 | 
nativeElements | 
false | 
Boolean | 
在原生模式下,TreeTable 使用原生复选框。 | 
dataLocale | 
null | 
Object | 
用于排序等功能的区域设置,默认为视图区域设置。 | 
caseSensitiveSort | 
false | 
Boolean | 
排序是否区分大小写,默认不区分。 | 
Primefaces TreeTable 示例教程:数据绑定与选择
本教程是《Primefaces 树(Tree)、树节点(TreeNode)、树表(TreeTable) 示例教程》的第11部分,将深入探讨如何使用Primefaces TreeTable组件展示数据,并介绍其选择功能。
与Primefaces Tree组件类似,TreeTable通过TreeNode实例进行数据填充,每个实例都代表一个节点,并与根节点关联。TreeNode API提供了一种分层的数据结构,用于表示要在树表中显示的数据。以下示例将展示如何使用TreeTable组件来显示普通的Java对象(POJO)文档实例。
index7.xhtml 代码示例:
<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
<h:head>
	<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>						
	<p:treeTable value="#{treeTableManagedBean.root}" var="node">
		<p:column>
			<f:facet name="header">
				名称
			</f:facet>
			<h:outputText value="#{node.name}"></h:outputText>
		</p:column>
		<p:column>
			<f:facet name="header">
				作者
			</f:facet>
			<h:outputText value="#{node.author}"></h:outputText>
		</p:column>
		<p:column>
			<f:facet name="header">
				ID
			</f:facet>
			<h:outputText value="#{node.id}"></h:outputText>
		</p:column>				
	</p:treeTable>
</h:form>
</html>
Document.java 代码示例:
package com.Olivia.prime.faces.data;
public class Document {
	private String name;
	private String id;
	private String author;
	
	public Document(String name, String id,String author){
		this.name = name;
		this.id = id;
		this.author = author;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
}
TreeTableManagedBean.java 代码示例:
package com.Olivia.prime.faces.beans;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
import com.Olivia.prime.faces.data.Document;
@ManagedBean
@SessionScoped
public class TreeTableManagedBean {
	
	private TreeNode root = new DefaultTreeNode("根节点", null);
	public TreeTableManagedBean(){
		// 填充文档实例
		Document doc01 = new Document("Primefaces 教程","1","Primefaces 公司");
		
		Document doc02 = new Document("Hibernate 教程","2","JournalDev");
		
		// 创建文档 TreeNode
		TreeNode documents = new DefaultTreeNode(new Document("文档","0","文档"), this.root);
		// 创建具体文档 TreeNode
		TreeNode document01 = new DefaultTreeNode(doc01, documents);
		TreeNode document02 = new DefaultTreeNode(doc02, documents);
	}
	
	public TreeNode getRoot() {
		return root;
	}
	public void setRoot(TreeNode root) {
		this.root = root;
	}
}
Primefaces TreeTable – 选择功能
与树组件类似,节点选择是PrimeFaces内置的功能,您可以通过它来确定选择的类型。可选值包括:Single(单选)、Multiple(多选)和Checkbox(复选框)。单选模式下,选定的节点将绑定到一个TreeNode实例;而多选和复选框模式下,则会使用TreeNode数组来存储选定的节点。以下示例展示了如何通过显示Growl消息来封装用户选择。此示例使用了PrimeFaces提供的p:commandButton组件,其具体用法将在后续讨论。index8.xhtml代码如下:
<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
<h:head>
	<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>			
	<p:growl id="message" />				
	<p:treeTable value="#{treeTableManagedBean.root}" var="node" selectionMode="single"
		selection="#{treeTableManagedBean.singleSelectedNode}">
		<p:column>
			<f:facet name="header">
				名称
			</f:facet>
			<h:outputText value="#{node.name}" />
		</p:column>
		<p:column>
			<f:facet name="header">
				作者
			</f:facet>
			<h:outputText value="#{node.author}" />
		</p:column>
		<p:column>
			<f:facet name="header">
				ID
			</f:facet>
			<h:outputText value="#{node.id}" />
		</p:column>				
	</p:treeTable>
	<p:treeTable value="#{treeTableManagedBean.root}" var="node" selectionMode="multiple"
		selection="#{treeTableManagedBean.multipleSelectedNodes}">
		<p:column>
			<f:facet name="header">
				名称
			</f:facet>
			<h:outputText value="#{node.name}" />
		</p:column>
		<p:column>
			<f:facet name="header">
				作者
			</f:facet>
			<h:outputText value="#{node.author}" />
		</p:column>
		<p:column>
			<f:facet name="header">
				ID
			</f:facet>
			<h:outputText value="#{node.id}" />
		</p:column>				
	</p:treeTable>
	<p:treeTable value="#{treeTableManagedBean.root}" var="node" selectionMode="checkbox"
		selection="#{treeTableManagedBean.checkboxSelectedNodes}">
		<p:column>
			<f:facet name="header">
				名称
			</f:facet>
			<h:outputText value="#{node.name}" />
		</p:column>
		<p:column>
			<f:facet name="header">
				作者
			</f:facet>
			<h:outputText value="#{node.author}" />
		</p:column>
		<p:column>
			<f:facet name="header">
				ID
			</f:facet>
			<h:outputText value="#{node.id}" />
		</p:column>				
	</p:treeTable>	
	<p:commandButton value="显示选定文档" action="#{treeTableManagedBean.viewSelectedNodes}" process="@form" update="message" />	
</h:form>
</html>
package com.Olivia.prime.faces.beans;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
import com.Olivia.prime.faces.data.Document;
@ManagedBean
@SessionScoped
public class TreeTableManagedBean {
	
	private TreeNode root = new DefaultTreeNode("根节点", null);
	private TreeNode singleSelectedNode;
	private TreeNode [] multipleSelectedNodes;
	private TreeNode [] checkboxSelectedNodes;
	public TreeTableManagedBean(){
		// 填充文档实例
		Document doc01 = new Document("Primefaces 教程","1","Primefaces 公司");	
		Document doc02 = new Document("Hibernate 教程","2","JournalDev");
		// 创建文档树节点
		TreeNode documents = new DefaultTreeNode(new Document("文档","0","文档"), this.root);
		// 创建文档树节点
		TreeNode document01 = new DefaultTreeNode(doc01, documents);
		TreeNode document02 = new DefaultTreeNode(doc02, documents);
	}
	
	public TreeNode getRoot() {
		return root;
	}
	public void setRoot(TreeNode root) {
		this.root = root;
	}
	public TreeNode getSingleSelectedNode() {
		return singleSelectedNode;
	}
	public void setSingleSelectedNode(TreeNode singleSelectedNode) {
		this.singleSelectedNode = singleSelectedNode;
	}
	public TreeNode[] getMultipleSelectedNodes() {
		return multipleSelectedNodes;
	}
	public void setMultipleSelectedNodes(TreeNode[] multipleSelectedNodes) {
		this.multipleSelectedNodes = multipleSelectedNodes;
	}
	public TreeNode[] getCheckboxSelectedNodes() {
		return checkboxSelectedNodes;
	}
	public void setCheckboxSelectedNodes(TreeNode[] checkboxSelectedNodes) {
		this.checkboxSelectedNodes = checkboxSelectedNodes;
	}
	
	public String viewSelectedNodes(){
		String message = "您已选择的文档:";
		if (this.singleSelectedNode != null) {
		    message += "- " + ((Document)this.singleSelectedNode.getData()).getName() + "\n";
		}
		if (this.multipleSelectedNodes != null) {
		    for(TreeNode node : this.multipleSelectedNodes){
			    message += "- " + ((Document)node.getData()).getName() + "\n";	
		    }
		}
		if (this.checkboxSelectedNodes != null) {
		    for(TreeNode node : this.checkboxSelectedNodes){
			    message += "- " + ((Document)node.getData()).getName() + "\n";	
		    }
		}
		FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(message));
		return "";
	}
}
PrimeFaces TreeTable – Ajax行为事件和上下文菜单
这是文章《Primefaces 树(Tree)、树节点(TreeNode)、树表(TreeTable) 示例教程》的第13部分(共13部分)。
TreeTable Ajax事件与列宽调整
TreeTable 组件已支持与 Tree 组件相同的 Ajax 行为事件。唯一的例外是 colResize 事件,该事件在调整列宽时触发。ContextMenu 的使用方式与 Tree 组件中没有区别。不幸的是,我们目前使用的 PrimeFaces 5.0 免费版本存在一个严重问题,无法确定是否支持列宽调整事件的监听。但是,为了了解如何监听此类事件,下面提供了一个简单的示例:
index9.xhtml 代码:
<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
<h:head>
	<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>						
	<p:treeTable value="#{treeTableManagedBean.root}" var="node" resizableColumns="true">
		<p:column>
			<f:facet name="header">
				名称
			</f:facet>
			<h:outputText value="#{node.name}"></h:outputText>
		</p:column>
		<p:column>
			<f:facet name="header">
				作者
			</f:facet>
			<h:outputText value="#{node.author}"></h:outputText>
		</p:column>
		<p:column>
			<f:facet name="header">
				ID
			</f:facet>
			<h:outputText value="#{node.id}"></h:outputText>
		</p:column>				
		<p:ajax event="colResize" listener="#{treeTableManagedBean.colResizeListener}"></p:ajax>
	</p:treeTable>
</h:form>
</html>
// .. 部分所需代码
	public void colResizeListener(ColumnResizeEvent e){
		String message ="列宽调整事件已触发";
		FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(message));
	}
Primefaces TreeTable – 排序
通过在列级别设置 sortBy 表达式可以启用排序。
index10.xhtml 代码:
<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
<h:head>
	<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>						
	<p:treeTable value="#{treeTableManagedBean.root}" var="node">
		<p:column sortBy="#{node.name}">
			<f:facet name="header">
				名称
			</f:facet>
			<h:outputText value="#{node.name}"></h:outputText>
		</p:column>
		<p:column sortBy="#{node.author}">
			<f:facet name="header">
				作者
			</f:facet>
			<h:outputText value="#{node.author}"></h:outputText>
		</p:column>
		<p:column sortBy="#{node.id}">
			<f:facet name="header">
				ID
			</f:facet>
			<h:outputText value="#{node.id}"></h:outputText>
		</p:column>				
	</p:treeTable>
</h:form>
</html>
如果你希望页面加载时以排序方式显示 TreeTable,请使用 TreeTable 的 sortBy 属性,可选的 sortOrder 和 sortFunction 属性用于定义默认排序顺序(升序或降序)和实际排序的 Java 方法。
Primefaces 树组件、TreeNode 和 TreeTable 总结
树状和树表格组件被广泛用于展示结构化的层级数据。我们学习了如何正确使用这些组件以及所需的主要属性。请在下方评论中向我们提供贡献,并可下载下方的源代码以供使用。
下载 PrimeFaces Tree 项目
要求:
- Java Development Kit (JDK) 8 或更高版本
 - Apache Maven 3.x
 - 集成开发环境 (IDE),如 Eclipse 或 IntelliJ IDEA