A quick way to create a custom JSF component

I know two ways to create custom JSF components: 1. Native JSF way: create JSF component class, tag, etc. 2. Facelets way: defining the component in the xhtml file and then creating the corresponding decrption in the facelets taglets.

I am currently working on a project in which, unfortunately, this cannot be said. On the other hand, creating custom components in the standard JSF way seems like a pain in the ass.

Maybe there is a third party library that allows you to create custom components in the same way as facelets, but doesn't entail the need for custom rendering?

+2


a source to share


1 answer


You can use a limited number of templates using (for example) jsp: include and f: subview .

Alternatively, you can extend the UIComponent by overriding the selected methods and then expose it via an existing tag and managed bean using binding

. This still requires a fairly detailed understanding of component design (and the implications of that choice), but can significantly reduce the number of files / code footprint.

This approach is a bit hacky, but might be fine for short term things. You would not do this for component libraries that you want to distribute or components that require long-term maintenance.

New component:

public class QuickComponent extends HtmlOutputText {
  @Override public void encodeAll(FacesContext context) throws IOException {
    ResponseWriter writer = context.getResponseWriter();
    writer.writeText("I'm not really a HtmlOutputText", null);
    for (UIComponent kid : getChildren()) {
      if (kid instanceof UIParameter) {
        UIParameter param = (UIParameter) kid;
        writer.startElement("br", this);
        writer.endElement("br");
        writer.writeText(param.getName() + "=" + param.getValue(), null);
      }
    }
  }
}

      

bean providing an instance:



/**Request-scope managed bean defined in faces-config.xml*/
public class QuickComponentProviderBean {
  private QuickComponent quick;

  public void setQuick(QuickComponent quick) {
    this.quick = quick;
  }

  public QuickComponent getQuick() {
    if (quick == null) {
      quick = new QuickComponent();
    }
    return quick;
  }
}

      

Note. Don't reuse the same bean property for multiple tags in your views, or they will refer to the same object instance.

Adding a new view to a view:

<h:outputText binding="#{quickComponentProviderBean.quick}">
  <f:param name="Hello" value="World" />
</h:outputText>

      

Note. The attributes that can be defined have not changed. They are captured by the TLD.

+2


a source







All Articles