代码创建和呈现JSF组件树的成功意味着,可以在页面动态的呈现各种JSF组件,如在用户交互后,根据用户需求产生界面.,或者用户自定义页面发布
好了,废话不多,直接进入正题
l JSF组件树创建与呈现
² 创建或者获取根
//从当前上下文获取
UIViewRoot root = facesContext.getViewRoot();
² 创建树
======在现有的根上创建======
用下行方法把组件对象组合起来
parentUIComponent.getChildrern
().add(child
UIComponent);
例子:
//***树***:根
UIViewRoot root = facesContext.getViewRoot();
//***树***:根/ scriptCollector1
UIComponent uic0 = (UIComponent) root.getChildren().iterator().next();
// uic0获得页面上已有的scriptCollector1,将在这之下创建自己的组件
//***树***:根/ scriptCollector1/ myTable1
HtmlDataTable myTable1 = new HtmlDataTable();
myTable1.setId("myTable1");
uic0.getChildren().add(myTable1); //组合到树上去
//table的Column1
UIColumn myColumn1 = new UIColumn();
myColumn1.setId("myColumn1");
myTable1.getChildren().add(myColumn1);
//Column1的Output
UIOutput myText1 = new UIOutput();
myText1.setId("myText1");
myColumn1.getChildren().add(myText1);
//table的Column2
UIColumn myColumn2 = new UIColumn();
myColumn2.setId("myColumn2");
myTable1.getChildren().add(myColumn2);
//Column2的Output
UIOutput myText2 = new UIOutput();
myText2.setId("myText2");
myColumn2.getChildren().add(myText2);
(例子 完)
² 呈现
组件的Encode()方法,自呈现
renderResponse(facesContext, root ) ; //呈现整个组件树
private void renderResponse(FacesContext context, UIComponent component) {
try {
component.encodeBegin(context); // encodeBegin
component.encodeChildren(context); // encodeChildren
Iterator kids = component.getChildren().iterator();
while (kids.hasNext()) {
UIComponent child = (UIComponent) kids.next();
renderResponse(context, child); //递归调用
}
component.encodeEnd(context); // encodeEnd
} catch (IOException e) {
e.printStackTrace();
}
}
² 字段数据绑定(表达式,绑定方法)
在数据表中,字段绑定值应为当前行的这个字段的值,不能固定为某个固定的值。
( 代码中不能调用setValue()来绑定数据,
这与页面标记内使用value="#{vardd3.GROUPTYPE}"绑定数据容易混淆 )
表达式创建使用ValueBinding对象
例子:
HtmlDataTable myTable1 = new HtmlDataTable();
myTable1.setId("myTable1");
myTable1.setValue(getDd3()); //获取SDO的数据源: getDd3()
myTable1.setVar("vardd33"); //产生了一个包含当前行数据的一个内部对象
//vardd33,在request域,取值的方法只可以内部组件
//之间完成 [内部当前行,重要的一个对象]
...... ......
...... ......
...... ......
//创建ValueBinding对象,放入表达式
ApplicationFactory factory = (ApplicationFactory) FactoryFinder
.getFactory(FactoryFinder.APPLICATION_FACTORY);
Application app = factory.getApplication();
ValueBinding binding1 = app.createValueBinding("#{vardd33.GROUPKEY}");
//表达式中把前面定义的内部当前行vardd33纳入计算
...... ......
...... ......
...... ......
//绑定数据到字段
UIColumn myColumn1 = new UIColumn();
myColumn1.setId("myColumn1");
myTable1.getChildren().add(myColumn1);
UIOutput myText1 = new UIOutput();
myText1.setId("myText1");
myText1.setValueBinding("value",binding1); //最关键的一句, value 是UIOutput
//隐藏的一个属性字段,这句话的意
//思是动态设置myText1
//的value为binding1的表达式
//#{vardd33.GROUPKEY}计算出的
//当前行vardd33的字段GROUPKEY
//的值
myColumn1.getChildren().add(myText1);
//注意: myText1.setValue(binding1),或者myText1.setValue(binding1.getValue(facesContext))都不能实现setValueBinding的功能。setValue始终是设定一个固定值。
页面上value="#{vardd3.GROUPTYPE}"这样写,肯定faces框架在后台遇到表达式就调用了setValueBinding方法,遇到值,就调用setValue方法。
//探讨ValueBinding对象
比如:
ValueBinding binding = application.createValueBinding("#{newvar}");
binding.setValue( facesContext, map );
(注释:假设这个map对象为{id=”test 001” , name=”testName”}
ValueBinding binding1 = application.createValueBinding("#{newvar.id}");
ValueBinding binding2 = application.createValueBinding("#{newvar. name }");
那么
binding1.getValue(facesContext) 就是 ”test 001”
binding2.getValue(facesContext) 就是 ” testName”
ValueBinding对象不仅可以引用已有的bean、bean的属性值,等 ……
还可以创建出新的属性对象newvar,供其他使用。
还有就是UIComponent setValueBinding(“newName”,binding)这个的“newName”如果不是属性字段的名称,就会创建这样的属性名称,getValueBinding(“newName” )也可以取出来
setValueBinding
public abstract void setValueBinding(java.lang.String name,
javax.faces.el.ValueBinding binding)
Set the ValueBinding used to calculate the value for the specified attribute or property name, if any.
Parameters:
name - Name of the attribute or property for which to set a ValueBinding
binding - The ValueBinding to set, or null to remove any currently set ValueBinding
Throws:
java.lang.IllegalArgumentException - if name is one of id or parent
java.lang.NullPointerException - if name is null
============================
如何在页面中调用呢?我的理解可能有严重错误,请指教谢谢
======jsp======
<f:view>
<h:form id="regularMeetingDataForm">
<h:panelGrid columns="10" id="regularMeetingDataPanel"></h:panelGrid>
<h:commandButton value="TEST"
styleClass="button1" actionListener="#{testPage.getPage}">
</h:commandButton>
</h:form>
</f:view>
=====java========
public void getPage(){
FacesContext facesContext = FacesContext.getCurrentInstance();
UIViewRoot root = facesContext.getViewRoot();
UIPanel panel = (UIPanel) root.findComponent("regularMeetingDataForm").findComponent("regularMeetingDataPanel");
UIOutput myText2 = new UIOutput();
myText2.setId("myText2");
myText2.setValue("Hello");
panel.getChildren().add(myText2);
renderResponse(facesContext, root) ; //呈现整个组件树
}
====================================
这一点我没有讲清楚,因为我以为大家应该都明白的,所以没有提
=========================================
我是这样做的,jsp页面对应一个request域的bean
在bean里创建一个pageLoad()的方法,实现组件树组织与呈现
在jsp页面这样调用:
<f:view>
先写一个faces output组件,引用一个""值显示,否则后面那一句不可用
//现在可写这句了:pc_First_page为页面faces受管的bean名字,pagecode.First_page为bean类名,配置文件里定义的.
<% ((pagecode.First_page)request.getAttribut("pc_First_page")).pageLoad() %>
</f:view>
===========================
java.lang.IllegalArgumentException - if name is one of id or parent好像没有其效果,这里name我试了很多名字,包括组件的id,parent,都没有出现异常。
原网址:http://www.cnblogs.com/ou_xiang001/archive/2006/09/01/492151.html
原作者:
网名:灵石
QQ:36774162
MSN:ou_xiang@sohu.com