JSF ResponseWriter自定义组件

时间:2009-03-16 15:11:20

标签: jsf uicomponents

我知道ResponseWriter上的startElement,endElement和writeAttribute方法。我的问题是,我想通过声明HtmlCommandLink link = new HtmlCommandLink();来输出h:commandLink。

如何在我自己的组件中输出这样的其他UIComponent?我可能想在我的组件中使用一些RichFaces ajax的东西,所以希望我可以避免全部用它来制作。

编辑:我要做的是使用以下标记<myTags:commentTree>创建我自己的标记库。每个评论都有一个回复按钮,当点击回复按钮时,我会在评论下面呈现回复表单。渲染完成后,我想输出richfaces <a4j:commandButton>组件。这必须在我自己的java标记文件中完成,我已经调用了CommentsTreeUI.java

通常我输出所有显示表单和按钮writer.startElement("input", myComponent); writer.writeAttribute("type", "button", null);的元素,但是如果我可以代替startElement("a4j:commandbutton", myComponent)来帮助我的ALOT,因为它具有所有内置的ajax功能等。

任何线索?

3 个答案:

答案 0 :(得分:2)

通过使用

添加新组件解决了此问题
HtmlCommandButton button = new HtmlCommandButton();
button.encodeAll(context);

答案 1 :(得分:1)

您可以这样做:

HtmlCommandLink link = new HtmlCommandLink();
getChildren().add(link);

这取决于你想要对子组件做什么,例如,如果你希望它们被自定义HTML包围(例如在HTML列表中),你将需要更复杂的东西。

答案 2 :(得分:0)

制作复合控件的一种方法是使用绑定属性将标记与您自己的代码相关联:

<f:view>
    <h:form>
        <h:panelGroup binding="#{compositeControlBean.panelGrid}" />
    </h:form>
</f:view>

faces-config.xml 中的bean配置:

<managed-bean>
    <managed-bean-name>compositeControlBean</managed-bean-name>
    <managed-bean-class>
        composite.CompositeControlBean
    </managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

bean代码:

/**
 * Configure this bean in request scope as "compositeControlBean".
 */
public class CompositeControlBean {

  private transient UIComponent panelGrid;

  public UIComponent getPanelGrid() {
    if (panelGrid == null) {
      panelGrid = createCompositePanel();
    }
    return panelGrid;
  }

  public void setPanelGrid(UIComponent panelGrid) {
    this.panelGrid = panelGrid;
  }

  private UIComponent createCompositePanel() {
    initContextMemebers();

    UIComponent commandLink = createCommandLink();

    String id = view.createUniqueId();
    UIComponent panelGrid = application
        .createComponent("javax.faces.HtmlPanelGroup");
    panelGrid.setId(id);
    panelGrid.setRendererType("javax.faces.Group");

    panelGrid.getChildren().add(commandLink);

    return panelGrid;
  }

  private UIComponent createCommandLink() {
    // create control
    String id = view.createUniqueId();
    UIComponent commandLink = application
        .createComponent("javax.faces.HtmlCommandLink");
    commandLink.setId(id);
    commandLink.setRendererType("javax.faces.Link");
    // set attributes (bind to printHello method)
    Map<String, Object> attributes = commandLink
        .getAttributes();
    MethodExpression action = expressionFactory
        .createMethodExpression(elContext,
            "#{compositeControlBean.printHello}",
            String.class, new Class<?>[0]);
    attributes.put("value", "print hello");
    attributes.put("actionExpression", action);
    return commandLink;
  }

  private transient FacesContext context;
  private transient Application application;
  private transient ELContext elContext;
  private transient ExpressionFactory expressionFactory;
  private transient UIViewRoot view;

  private void initContextMemebers() {
    context = FacesContext.getCurrentInstance();
    application = context.getApplication();
    elContext = context.getELContext();
    expressionFactory = application.getExpressionFactory();
    view = context.getViewRoot();
  }

  public String printHello() {
    System.out.println("Hello");
    return null;
  }

}