关于 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 生命周期和自定义组件

JSF 2.0 复合组件 - ajax 渲染参数 OUTSIDE 组件定义

如何在 JSF 2.0 中创建自定义 404 消息?

JSF 2.0 AJAX:使用 jsf.ajax.request(或其他方式)从 javascript 调用 bean 方法

在哪里放置组合组件?(JSF 2.0)