Справка по пользовательским компонентам JSF 2.0 и основным лицам - PullRequest
2 голосов
/ 07 сентября 2011

У меня есть требование для динамического создания панели с использованием пользовательских компонентов jsf 2.0.Элементы управления на панели будут динамически считываться из xml и визуализироваться при выделении соответствующего объекта (например, если выбран Person, я должен отобразить панель, которая будет иметь элементы управления, связанные с таким человеком, как: поле возраста человека (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 метод ------ 7 сентября 2011 г. 10:01:42:00 com.sun.faces.context.PartialViewContextImpl $ PhaseAwareVisitОбратная связь ОБРАТНАЯ СВЯЗЬ

1 Ответ

2 голосов
/ 07 сентября 2011

myPrimePanel - ноль. Вам нужно будет присвоить его экземпляр, чтобы он не был нулевым.

Тем не менее, я думаю, что вы решаете эту задачу неправильно. Вы не должны добавлять компоненты в дерево на этапе рендеринга. Предположительно, вы хотите прочитать, проверить и ввести эти данные в модель некоторое время.

Создайте стартовые элементы в encodeBegin . Создайте свои конечные элементы в encodeEnd . Не переопределяйте encodeChildren и убедитесь, что getRendersChildren возвращает false (это значение по умолчанию).

Используйте атрибут связывания для предоставления динамического компонента на этапе восстановления представления. Добавьте управляемый компонент области запроса со свойством типа UIComponent и привяжите его к элементу в вашем представлении, используя EL. В получателе, если свойство имеет значение 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
  }
}

Во время выполнения будут выдаваться три редактируемых текстовых поля, значения которых будут напечатаны в журнале при нажатии кнопки.

Этот код был протестирован в JSP с использованием Java 5 и JSF 1.1.

...