最近需要做树形选择,google了好久找到<<Richfaces复选框树(Checkbox tree)的权限分配的解决方案 >>一文,但觉得和自己的要求不太符合,它的缺点在于选择时用jquery来决定子项的状态,但不能决定父项的状态,因此自己在此思路上扩展了一些功能,在此记录一下.
效果图:
xhtml文件:
<a4j:region renderRegionOnly="true" selfRendered="true">
<h:panelGrid id="checkBoxTree" columns="1">
<a4j:form>
<rich:tree adviseNodeOpened="#{treeBean.adviseNodeOpened}" nodeFace="leaf" ajaxSubmitSelection="true"
switchType="client" value="#{treeBean.rootNode}" var="item" ajaxKeys="#{null}"
preserveModel="state" treeNodeVar="treeNode" ajaxSingle="true">
<rich:treeNode type="leaf">
<h:selectBooleanCheckbox value="#{item.selected}" id="boxselect">
<a4j:support reRender="checkBoxTree" event="onclick" ajaxSingle="true" actionListener="#{treeBean.processSelected}" />
</h:selectBooleanCheckbox>
<h:outputLabel value="#{item.name}" for="boxselect"/>
</rich:treeNode>
</rich:tree>
</a4j:form>
</h:panelGrid>
</a4j:region>
在些我用a4j:support 来实现Checkbox选中的触发事件,如果用Tree中的nodeSelectListener,单击CheckBox控件不会触发事件
Bean文件:
package com.test.bean;
import com.office.frames.tree.bean.CompanyTreeState;
import com.office.frames.tree.service.CompanyStructTreeService;
import org.richfaces.component.UITree;
import org.richfaces.component.state.TreeState;
import org.richfaces.model.TreeNode;
import org.richfaces.model.TreeRowKey;
import javax.faces.event.ActionEvent;
import java.util.Iterator;
import java.util.Map;
/**
* Created by IntelliJ IDEA.
* User: david
* Date: 11-2-15
* Time: 下午3:59
* To change this template use File | Settings | File Templates.
*/
public class TreeBean {
private CompanyStructTreeService companyStructTreeService;
private CompanyTreeState companyTreeState;
public CompanyTreeState getCompanyTreeState() {
return companyTreeState;
}
public void setCompanyTreeState(CompanyTreeState companyTreeState) {
this.companyTreeState = companyTreeState;
}
public CompanyStructTreeService getCompanyStructTreeService() {
return companyStructTreeService;
}
public void setCompanyStructTreeService(CompanyStructTreeService companyStructTreeService) {
this.companyStructTreeService = companyStructTreeService;
}
private TreeNode rootNode = null;
//取树数据
public TreeNode getRootNode() {
if (rootNode == null) {
try {
rootNode = companyStructTreeService.getCompanyExtendedTreeNode();
} catch (Exception e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
return rootNode;
}
public void setRootNode(TreeNode rootNode) {
this.rootNode = rootNode;
}
//因xhtml文件switchType="client",保持树打开形状,并且控制初始化时打开第一级
public Boolean adviseNodeOpened(UITree tree) {
if (tree.isExpanded()) {
return Boolean.TRUE;
}
TreeRowKey key = (TreeRowKey) tree.getRowKey();
if (key != null) {
TreeState state = (TreeState) tree.getComponentState();
if (companyTreeState.getSelectedMenuKey() == null) {
companyTreeState.setSelectedMenuKey(key);
}
TreeRowKey selectedKey = state.getSelectedNode();
if (selectedKey == null) {
selectedKey = companyTreeState.getSelectedMenuKey();
}
if (selectedKey != null && (key.isSubKey(selectedKey)))
return Boolean.TRUE;
}
return Boolean.FALSE;
}
// 点击checkbox处理
public void processSelected(ActionEvent event) {
if (rootNode != null) {
UITree tree = (UITree) event.getComponent().getParent().getParent().getParent();
TreeRowKey key = (TreeRowKey) tree.getRowKey();
companyTreeState.setSelectedMenuKey(key);
TreeNode currentNode = tree.getModelTreeNode(key);
//子项状态跟当前项一致
setSelectdNode(currentNode);
//修改父项状态
if (!((ExtendedTreeNode) (currentNode.getData())).isSelected()) {
setNodeUncheck(tree, key);
} else {
setNodecheck(tree, key);
}
}
}
//当有某个子项为uncheck状态,把父项的checkbox也设置成uncheck状态
private void setNodeUncheck(UITree tree, TreeRowKey key) {
while (!"".equals(key.getParentKey().toString())) {
TreeRowKey parentKey = key.getParentKey();
TreeNode parentNode = tree.getModelTreeNode(parentKey);
ExtendedTreeNode extendedTreeNode = ((ExtendedTreeNode) parentNode.getData());
key = parentKey;
extendedTreeNode.setSelected(Boolean.FALSE);
}
}
//当把有的子项为check状态,把父项的checkbox也设置成check状态
private void setNodecheck(UITree tree, TreeRowKey key) {
while (!"".equals(key.getParentKey().toString())) {
TreeRowKey parentKey = key.getParentKey();
TreeNode parentNode = tree.getModelTreeNode(parentKey);
ExtendedTreeNode extendedTreeNode = ((ExtendedTreeNode) parentNode.getData());
key = parentKey;
if (checkNodeCheck(parentNode)) {
extendedTreeNode.setSelected(Boolean.TRUE);
}
}
}
//检查所有子项check状态
private Boolean checkNodeCheck(TreeNode parentNode) {
Iterator itr = parentNode.getChildren();
while (itr.hasNext()) {
TreeNode childNode = (TreeNode) ((Map.Entry) itr.next()).getValue();
ExtendedTreeNode extendedTreeNode = ((ExtendedTreeNode) childNode.getData());
if (!extendedTreeNode.isSelected()) {
return Boolean.FALSE;
}
}
return Boolean.TRUE;
}
//设置选中项的子项状态
private void setSelectdNode(TreeNode currentNode) {
ExtendedTreeNode currentNodeData = ((ExtendedTreeNode) currentNode.getData());
boolean currentNodeIsChecked = currentNodeData.isSelected();
Iterator itr = currentNode.getChildren();
while (itr.hasNext()) {
TreeNode childNode = (TreeNode) ((Map.Entry) itr.next()).getValue();
ExtendedTreeNode extendedTreeNode = ((ExtendedTreeNode) childNode.getData());
extendedTreeNode.setSelected(currentNodeIsChecked);
setSelectdNode(childNode);
}
}
}
至此,在Rich Face 中的选择树的问题就解决了。。