有关JSF 2.0自定义组件和Primefaces的帮助

时间:2011-09-07 05:04:50

标签: java jsf jsf-2 primefaces

我需要使用jsf 2.0自定义组件动态创建面板。面板中的控件将从xml中动态读取并在相应对象的选择上呈现(例如:如果选择了Person,我应该渲染一个面板,该面板将具有与人相关的控件:Person age field(inputtext),人DOB(日历)等)。

我试图从扩展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;
  }

我这样做了。但我得到一个空指针异常。如何动态呈现具有已定义控件的面板?

这就是我得到的 -

====将开始渲染==== 在面板内获取方法------ 2011年9月7日10:01:42 com.sun.faces.context.PartialViewContextImpl $ PhaseAwareVisitCallback访问 严重:java.lang.NullPointerException

1 个答案:

答案 0 :(得分:2)

myPrimePanel为空。您需要为它分配一个实例,使其不为空。

但是,我认为你正在以错误的方式开展这项任务。您不应该在渲染阶段向树中添加组件。据推测,您希望在某个时间读取,验证并将数据输入到模型中。

encodeBegin中发出您的开始元素。在encodeEnd中发送您的结尾元素。请勿覆盖encodeChildren并确保getRendersChildren返回false(这是默认设置)。

使用binding属性在Restore View阶段配置动态组件。使用类型为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&amp; JSF 1.1。