在本章中,我们将了解RichFaces中的树处理. RichFaces提供了创建和操作树所需的所有组件.
此标记用于创建分层树.在< treeNode>内提供的每个节点将是树的子节点.此标记将与另一个名为< rich:tree>的标记一起使用.我们用于创建树的所有实例变量必须实现这三个接口中的任何一个 - org.richfaces.model.TreeNode,org.richfaces.model.TreeDataModel,和 javax.swing. tree.TreeNode .
在下面的示例中,我们将使用< rich:treeNode>填充树.来自后端的标记.
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE html> <html 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:head> <title>TreeNode Example</title> <meta name = "viewport" content = "width = device-width, initial-scale = 1.0"/> </h:head> <h:body> <h:form> <rich:tree value = "#{tree.populateNode}" var = "tree"> <rich:treeNode> <rich:treeModelRecursiveAdaptor> </rich:treeModelRecursiveAdaptor> <h:outputText value = "#{tree.data}" /> </rich:treeNode> </rich:tree> </h:form> </h:body> </html>
以下是实现"TreeNodeImpl"接口的相关java类.
import javax.faces.bean.ManagedBean; import javax.faces.bean.RequestScoped; import org.richfaces.model.TreeNodeImpl; @ManagedBean @RequestScoped public class Tree extends TreeNodeImpl { private Tree stationRoot; private Tree populateNode; private Object data; public Tree() { super(); } public Tree(boolean leaf, Object data) { super(leaf); this.data = data; } public Object getData() { return data; } public Tree getPopulateNode() { if (populateNode == null) { String[] List_OF_Node = { "Frist Node", "Second Node", "Third Node", "Fourth Node", "Fifth Node"}; stationRoot = new Tree(false, "Example Of Tree"); for (int i = 0; i < List_OF_Node.length; i++) { Tree child = new Tree(true, List_OF_Node[i]); stationRoot.addChild(i, child); } populateNode = new Tree(); populateNode.addChild(0, stationRoot); } return populateNode; } }
以上代码将在浏览器中生成以下输出.
这component将Map作为输入,遍历它,并在浏览器中生成所需的输出.每当我们需要填充递归映射时,我们可以使用另一个名为< rich:recursiveTreeModelAdaptor> 的标记.
以下示例显示了如何呈现项目结构在浏览器中.在RichFaces 3中,使用这两个标签< rich:treeNodeAdaptor>和< rich:recursiveTreeNodeAdaptor>.
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE html> <html 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:head> <title>Tree Model and Recursive Model Example</title> </h:head> <h:body> <h:form id = "form"> <rich:tree toggleType = "AJAX" var = "item" style = "max-width: 400px"> <rich:treeModelRecursiveAdaptor roots = "#{fileSystemBean.sourceRoots}" nodes = "#{item.directories}"> <rich:treeNode> #{item.shortPath} </rich:treeNode> <rich:treeModelAdaptor nodes = "#{item.files}"> <rich:treeNode>#{item}</rich:treeNode> </rich:treeModelAdaptor> </rich:treeModelRecursiveAdaptor> </rich:tree> </h:form> </h:body> </html>
我们需要为这个例子创建两个新的java bean.以下是bean类"FileSystemBean.java"的代码片段,它包含所需的文件夹名称.
import java.util.List; import javax.faces.bean.ManagedBean; import javax.faces.bean.RequestScoped; @ManagedBean @RequestScoped public class FileSystemBean { private static final String SRC_PATH = "/WEB-INF"; private List<FileSystemNode> srcRoots; public synchronized List<FileSystemNode> getSourceRoots() { if (srcRoots == null) { srcRoots = new FileSystemNode(SRC_PATH).getDirectories(); } return srcRoots; } }
以下是bean类"FileSystemNode.java"的代码片段,它包含所需的叶子节点该项目.
import static com.google.common.base.Predicates.containsPattern; import static com.google.common.base.Predicates.not; import static com.google.common.collect.Iterables.filter; import static com.google.common.collect.Iterables.transform; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import com.google.common.base.Function; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; public class FileSystemNode { private static final Function<String, FileSystemNode> FACTORY = new Function<String, FileSystemNode>() { public FileSystemNode apply(String from) { return new FileSystemNode(from.substring(0, from.length() - 1)); }; }; private static final Function<String, String> TO_SHORT_PATH = new Function<String, String>() { public String apply(String from) { int idx = from.lastIndexOf('/'); if (idx < 0) { return from; } return from.substring(idx + 1); }; }; private String path; private List<FileSystemNode> directories; private List<String> files; private String shortPath; public FileSystemNode(String path) { this.path = path; int idx = path.lastIndexOf('/'); if (idx != -1) { shortPath = path.substring(idx + 1); } else { shortPath = path; } } public synchronized List<FileSystemNode> getDirectories() { if (directories == null) { directories = Lists.newArrayList(); Iterables.addAll(directories, transform(filter( getResourcePaths(), containsPattern("/$")), FACTORY)); } return directories; } public synchronized List<String> getFiles() { if (files == null) { files = new ArrayList<String>(); Iterables.addAll(files, transform(filter( getResourcePaths(), not(containsPattern("/$"))), TO_SHORT_PATH)); } return files; } private Iterable<String> getResourcePaths() { FacesContext facesContext = FacesContext.getCurrentInstance(); ExternalContext externalContext = facesContext.getExternalContext(); Set<String> resourcePaths = externalContext.getResourcePaths(this.path); if (resourcePaths == null) { resourcePaths = Collections.emptySet(); } return resourcePaths; } public String getShortPath() { return shortPath; } }
以上示例将在浏览器中生成以下输出.