Richfacse rich:tree +rich:treeNode
在seam中使用Richfaces使得前台的页面对于后台开发人员来讲变得十分简单,而且在Richfacse的Demo网站上有相当详细的例子,所有的demo源文件也可以下载到。但是也有很多需要注意的地方。如用到rich:tree时, 难免在需要在自己的code中加入org.richfaces.TreeNodeImp或者实现org.richfaces.TreeNode接口,code非常简单,可在运行的时候就没那么容易了,对于jar包的位置要求相对严格了许多。
运行环境:
1. Jboss-4.2.3GA
2. Jboss-seam-2.2.0GA
3. Richfaces-3.3.0.GA.
java文件:
2
3 import java.util.List;
4
5 import org.jboss.seam.ScopeType;
6 import org.jboss.seam.annotations.AutoCreate;
7 import org.jboss.seam.annotations.In;
8 import org.jboss.seam.annotations.Name;
9 import org.jboss.seam.annotations.Scope;
10 import org.richfaces.model.TreeNode;
11 import org.richfaces.model.TreeNodeImpl;
12
13 import com.logile.elm.ta.common.TACommonQueryDAO;
14 import com.logile.elm.ta.workbench.model.AttributeParameter;
15 import com.logile.elm.ta.workbench.model.AttributeType;
16 import com.logile.elm.ta.workbench.model.Fact;
17 import com.logile.elm.ta.workbench.model.RuleHelpNode;
18
19 @Name("xmlManger")
20 @Scope(ScopeType.CONVERSATION)
21 @AutoCreate
22 public class XmlManger {
23 @In(create = true)
24 private TACommonQueryDAO taCommonQueryDao;
25
26 private TreeNode<RuleHelpNode> helpNode;
27
28
29
30 public void setupHelp()
31 {
32 if(helpNode == null){
33 helpNode = new TreeNodeImpl<RuleHelpNode>();
34 RuleHelpNode help = new RuleHelpNode();
35 helpNode.setData(help);
36 List<Fact> facts = taCommonQueryDao.getFact();
37 for(Fact fact : facts){
38 helpNode.addChild(fact.getDisplayName(), getNodeFromFact(fact));
39 }
40 }
41 }
42
43 private TreeNode<RuleHelpNode> getNodeFromFact(Fact fact)
44 {
45 RuleHelpNode factHelp = new RuleHelpNode();
46 factHelp.setId(fact.getId());
47 factHelp.setType(RuleHelpNode.NODE_TYPE_FACT);
48 factHelp.setIcon(RuleHelpNode.NODE_ICON_FACT);
49 factHelp.setName(fact.getDisplayName());
50 TreeNode<RuleHelpNode> factNode = new TreeNodeImpl<RuleHelpNode>();
51 factNode.setData(factHelp);
52 for(AttributeType attribute : fact.getAttributeSet()){
53 factNode.addChild(attribute.getDisplayName(), getNodeFromAttribute(attribute));
54 }
55 return factNode;
56 }
57
58 private TreeNode<RuleHelpNode> getNodeFromAttribute(AttributeType attribute){
59 RuleHelpNode attributeHelp = new RuleHelpNode();
60 attributeHelp.setId(attribute.getId());
61 attributeHelp.setName(attribute.getDisplayName());
62 attributeHelp.setType(RuleHelpNode.NODE_TYPE_ATTRIBUTE);
63 if(attribute.getMethodFlag()){
64 attributeHelp.setIcon(RuleHelpNode.NODE_ICON_METHOD);
65 }else {
66 attributeHelp.setIcon(RuleHelpNode.NODE_ICON_FIELD);
67 }
68 TreeNode<RuleHelpNode> attributeNode = new TreeNodeImpl<RuleHelpNode>();
69 attributeNode.setData(attributeHelp);
70 for(AttributeParameter parameter : attribute.getParameters()){
71 attributeNode.addChild(parameter.getDisplayName(), getNodeFromParameter(parameter));
72 }
73 return attributeNode;
74 }
75
76 private TreeNode<RuleHelpNode> getNodeFromParameter(AttributeParameter parameter){
77 RuleHelpNode paramHelp = new RuleHelpNode();
78 paramHelp.setId(parameter.getId());
79 paramHelp.setName(parameter.getDisplayName());
80 paramHelp.setType(RuleHelpNode.NODE_TYPE_PARAMETER);
81 paramHelp.setIcon(RuleHelpNode.NODE_ICON_PARAMETER);
82 TreeNode<RuleHelpNode> paramNode = new TreeNodeImpl<RuleHelpNode>();
83 paramNode.setData(paramHelp);
84 return paramNode;
85 }
86
87 public void setHelpNode(TreeNode<RuleHelpNode> helpNode) {
88 this.helpNode = helpNode;
89 }
90
91 public TreeNode<RuleHelpNode> getHelpNode() {
92 return helpNode;
93 }
94
95 }
96
2
3 public class RuleHelpNode {
4
5 private static final long serialVersionUID = 1L;
6
7 public static final String NODE_TYPE_FACT = "FACT";
8 public static final String NODE_TYPE_ATTRIBUTE = "ATTRIBUTE";
9 public static final String NODE_TYPE_PARAMETER = "PARAMETER";
10
11 public static final String NODE_ICON_FACT = "/img/workbench/node_fact.png";
12 public static final String NODE_ICON_FIELD = "/img/workbench/node_field.png";
13 public static final String NODE_ICON_METHOD = "/img/workbench/node_method.png";
14 public static final String NODE_ICON_PARAMETER = "/img/workbench/node_parameter.png";
15
16 private Long id;
17 private String type;
18 private String icon;
19 private String name;
20
21 public Long getId() {
22 return id;
23 }
24
25 public void setId(Long id) {
26 this.id = id;
27 }
28
29 public String getType() {
30 return type;
31 }
32
33 public void setType(String type) {
34 this.type = type;
35 }
36
37 public String getIcon() {
38 return icon;
39 }
40
41 public void setIcon(String icon) {
42 this.icon = icon;
43 }
44
45 public String getName() {
46 return name;
47 }
48
49 public void setName(String name) {
50 this.name = name;
51 }
52
53 }
54
Xhtml code:
2 value="#{xmlManger.helpNode}" id="tree" var="item"
3 nodeFace="#{item.type}" rendered="#{xmlManger.helpNode != null}" >
4 <rich:treeNode type="FACT" iconLeaf="#{item.icon}" icon="#{item.icon}">
5 <h:outputText value="#{item.name}"/>
6 </rich:treeNode>
7 <rich:treeNode type="ATTRIBUTE" iconLeaf="#{item.icon}" icon="#{item.icon}">
8 <h:outputText value="#{item.name}"/>
9 </rich:treeNode>
10 <rich:treeNode type="PARAMETER" iconLeaf="#{item.icon}" icon="#{item.icon}">
11 <h:outputText value="#{item.name}"/>
12 </rich:treeNode>
13 </rich:tree>
代码就是这么简单,可已发布问题就来了。
第一个问题:java.lang.NoClassDefFoundError: org/richfaces/model/TreeNode,jboss直接无法启动。
说 明: 在EAR和WAR的WEB-INF/lib下面都已经有richfaces-api.jar、richfaces-impl.jar、richfaces-ui.jar了。
解决方法:尝试着将richfaces-*.jar复制到/server/defaut/lib中,问题貌似解决,结果高兴早了。
第二问题: org.richfaces.model.TreeNodeImpl cannot be cast to javax.swing.tree.TreeNode,正常启动,但是前台页面无法显示。
说明:在程序中从未使用过javax.swing.tree.TreeNode。
解决方法:1. /server/defaut/lib中只保留richfaces-api.jar;2. EAR下面只保留richfaces-api.jar; 3. WAR的WEB-INF/lib下面只保留richfaces-impl.jar、richfaces-ui.jar。发布,重启jboss ,一切正常。
问题总结:
1. 在用到rich:tree或者说在自己的code里面需要引用Richfaces,需要特别的注意richfaces-*.jar的位置。
2. 问题解决了,问题的根源是什么,为什么一定要按上面的位置来放jar包?
猜想:问题1--jboss启动时依赖的jar包在/server/defaut/lib中;
问题2--EAR工程中,JAR和WAR貌似使用了不同的classLoader,但是都受EAR的控制。
至于真正的原因,希望看到这篇文章的人能给予指出,不胜感激。