关于 JSF 2.0 自定义组件和 Primefaces 的帮助
Posted
技术标签:
【中文标题】关于 JSF 2.0 自定义组件和 Primefaces 的帮助【英文标题】:Help on JSF 2.0 Custom Components and Primefaces 【发布时间】:2011-11-11 20:17:45 【问题描述】:我需要使用 jsf 2.0 自定义组件动态创建面板。面板中的控件将从 xml 动态读取并在选择相应对象时呈现(例如:如果选择了 Person,我应该呈现一个面板,该面板将具有与 person 相关的控件,例如:Person age field(inputtext),人出生日期(日历)等)。
我正在尝试从扩展 UIComponentBase 的组件类中呈现它。
ResponseWriter writer = Util.getResponseWriter(context);
//start the <table> tag
writer.startElement(Constants.STR_TABLE, this);
//start the <tr> tag
writer.startElement(Constants.STR_TR, this);
//start the <td> tag
writer.startElement(Constants.STR_TD, this);
//encode the button 1 component inside this <td>
encodeAllComponent(context, getMyPrimePanel());
// end the <td> tag
writer.endElement(Constants.STR_TD);
//end the <tr> tag
writer.endElement(Constants.STR_TR);
//end the <table> tag
writer.endElement(Constants.STR_TABLE);
//private variable to render a panel
private Panel myPrimePanel;
/**
* @return the myPrimePanel
*/
public Panel getMyPrimePanel()
System.out.println("inside the panel get method------");
if (myPrimePanel.getChildCount() <= 1)
System.out.println("inside the panel creation function");
InputText input = new InputText();
myPrimePanel.getChildren().add(input);
System.out.println("inside the panel get method-------------");
return myPrimePanel;
/**
* @param myPrimePanel the myPrimePanel to set
*/
public void setMyPrimePanel(Panel myPrimePanel)
System.out.println("inside the panel get method-------------");
//initialize the button 1 component
this.myPrimePanel = myPrimePanel;
我就是这样做的。但我得到一个空指针异常。如何动态呈现具有定义控件的面板?
这就是我得到的 -
====将开始渲染==== 面板里面的get方法------ 2011 年 9 月 7 日上午 10:01:42 com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback 访问 严重:java.lang.NullPointerException
【问题讨论】:
检查异常的堆栈跟踪(在服务器日志中)。 NPE 必须有一个行号,例如“NullPointerException at line xy”。告诉我们它在您的代码中的哪一行。这将使我们更容易为您提供帮助。 感谢您的回复。但它没有显示任何行号。 【参考方案1】:myPrimePanel
为空。您需要为其分配一个实例才能使其不为空。
但是,我认为您执行此任务的方式错误。您不应该在渲染阶段向树中添加组件。据推测,您想在某个时候读取、验证并将输入数据输入到模型中。
在encodeBegin 中发出您的开始元素。在encodeEnd 中发出你的结束元素。不要覆盖 encodeChildren 并确保 getRendersChildren 返回 false(这是默认值)。
在恢复视图阶段使用绑定属性来配置动态组件。添加具有UIComponent 类型属性的请求范围托管bean,并使用EL 将其绑定到视图中的元素。在 getter 中,如果属性为 null,则创建自定义控件的新实例并添加任何 children。
考虑这个观点:
<h:form>
<h:panelGroup id="myPanel" binding="#componentMakerBean.panel" />
<h:commandButton value="go" action="#componentMakerBean.dumpValuesAction" />
</h:form>
面板在 bean 中创建和填充:
/** Request scope bean defined in faces-config.xml */
public class ComponentMakerBean
private UIPanel panel;
public UIPanel getPanel()
if(panel == null)
panel = new htmlPanelGroup();
for(int i=0; i<3; i++)
panel.getChildren().add(new HtmlInputText());
return panel;
public void setPanel(UIPanel panel) this.panel = panel;
public String dumpValuesAction()
for(Object kid : panel.getChildren())
if(kid instanceof ValueHolder)
ValueHolder valueHolder = (ValueHolder) kid;
System.out.println(valueHolder.getValue());
return null; //no navigation
在运行时,这将发出三个可编辑的文本字段,其值将在单击按钮时打印到日志中。
此代码已在使用 Java 5 和 JSF 1.1 的 JSP 中进行了测试。
【讨论】:
感谢您的回复。你能更清楚地告诉我如何创作吗?我对自定义组件很陌生。我应该创建另一个扩展 UIComponentTag 类的类吗?在 setProperties 中我应该使用 EL 进行 valueBinding 是吗?你能提供一个相同的样本sn-p吗? @Deepika - 使用我概述的方法,您不需要任何额外的标签;您只需要使用组件绑定功能。有关行为的详细信息,请参阅 JSF 规范。我添加了一些示例代码。 是的,这是正确的。但是这里没有使用自定义组件是它。但我的要求是使用自定义组件。 :( 我能够以您指定的方式呈现控件,但我应该使用自定义组件来做同样的事情。在 jsf 2.0 中,它不允许我包含 tld 文件,因为它只允许 facelets。(.xhtml)页面 @Deepika - 我认为这很明显,但是将绑定属性与您的自定义控件一起使用。如何在 Facelets 中定义标签在 JSF 规范中有详细说明。 Facelets 有自己的标签库描述符格式 - 见example @Deepika - 我不知道你的错误是什么;发布的代码在 Mojarra 2.x(在 Glassfish 3.1 上运行)和 MyFaces 2.x(在 Jetty 7 上运行)上按原样工作以上是关于关于 JSF 2.0 自定义组件和 Primefaces 的帮助的主要内容,如果未能解决你的问题,请参考以下文章
向 JSF 2.0 UIInput 组件添加自定义属性 (HTML5) 支持
JSF 2.0 复合组件 - ajax 渲染参数 OUTSIDE 组件定义
JSF 2.0 AJAX:使用 jsf.ajax.request(或其他方式)从 javascript 调用 bean 方法