RichFaces - Cây phong phú
Trong chương này, chúng ta sẽ tìm hiểu về xử lý cây trong RichFaces. RichFaces cung cấp tất cả các thành phần cần thiết để tạo và thao tác trên một cây.
<rich: treeNode>
Thẻ này được sử dụng để tạo một cây phân cấp. Mỗi nút được cung cấp bên trong <treeNode> sẽ là một nút con của cây. Thẻ này sẽ được sử dụng với một thẻ khác có tên là <rich: tree>. Tất cả các biến cá thể mà chúng tôi đang sử dụng để tạo cây phải triển khai bất kỳ giao diện nào trong số ba giao diện này -org.richfaces.model.TreeNode, org.richfaces.model.TreeDataModel, và javax.swing.tree.TreeNode.
Trong ví dụ sau, chúng tôi sẽ điền một cây bằng cách sử dụng thẻ <rich: treeNode> từ phần phụ trợ.
<?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>
Sau đây là lớp java có liên quan sẽ triển khai “TreeNodeImpl” giao diện.
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;
}
}
Đoạn mã trên sẽ tạo ra kết quả sau trong trình duyệt.
<rich: treeModelAdaptor>
Thành phần này lấy Bản đồ làm đầu vào, lặp lại qua nó và tạo ra đầu ra cần thiết trong trình duyệt. Bất cứ khi nào chúng ta cần điền vào một bản đồ đệ quy, chúng ta có thể sử dụng một thẻ khác được gọi là<rich:recursiveTreeModelAdaptor>.
Ví dụ sau đây cho thấy cách hiển thị cấu trúc dự án trong trình duyệt. Trong RichFaces 3, hai thẻ này được sử dụng <rich: treeNodeAdaptor> và <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>
Chúng ta cần tạo hai đậu java mới cho ví dụ này. Sau đây là đoạn mã cho lớp bean "FileSystemBean.java", chứa tên thư mục bắt buộc.
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;
}
}
Sau đây là đoạn mã cho lớp bean “FileSystemNode.java”, chứa nút lá cần thiết của dự án.
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;
}
}
Ví dụ trên sẽ tạo ra kết quả sau trong trình duyệt.