Podobnie jak kowertery czy walidatory, można też samemu pisać własne komponenty i renderery, choć zwykle nie ma takiej potrzeby. Można też oczywiście tworzyć też kombinacje nowy komponenttandardowy renderer i na odwrót. Zawsze jednak trzeba też oprogramować nowy znacznik.
public class UISimple extends UIInput {
public UISimple() {
public String getComponentType() { return "komponenty.Simple"; }
public String getRendererType() { return "komponenty.Simple"; }
setConverter(new IntegerConverter());
}
...
}
Być trzeba zaimplementować getFamily (rodzina komponentu używana jest przy
szukaniu rendererów do jego wyświetlania, tu bez zmian rodziną została
javax.faces.Input), napisać kod wyświetlający bądź, jak wyżej, zrzucić to na
renderera - no i zaimplementować zachowanie komponentu.
public class SimpleRenderer extends Renderer {
public void encodeBegin(FacesContext context, UIComponent simple)
throws IOException {
ResponseWriter writer = context.getResponseWriter();
String clientId = simple.getClientId(context);
writer.startElement("input", simple);
writer.writeAttribute("name", clientId + VAL, "clientId");
Object v = (UIInput) simple).getValue();
if (v != null)
writer.writeAttribute("value", v.toString(), "value");
writer.endElement("input");
}
}
Nie trzeba implementować wszystkich metod. ResponseWriter dostarcza przydatnych
metod
public void decode(FacesContext context, UIComponent component) {
EditableValueHolder simple = (EditableValueHolder) component;
Map requestMap = context.getExternalContext().getRequestParameterMap(
String clientId = component.getClientId(context);
if (requestMap.containsKey(clientId + VAL)) {
int submittedValue
= Integer.parseInt((String) requestMap.get(clientId + VAL));
simple.setSubmittedValue("" + submittedValue);
simple.setValid(true);
}
}
protected void setProperties(UIComponent component) {
super.setProperties(component);
MyComponent map = (MyComponent) component;
if (styleClass != null) {
if (isValueReference(styleClass)) {
ValueBinding vb =
FacesContext.getCurrentInstance().
getApplication().
createValueBinding(styleClass);
map.setValueBinding("styleClass", vb);
} else {
map.getAttributes().put("styleClass", styleClass);
}
}
}
<faces-config>
...
<component>
<component-type>komponenty.Simple</component-type>
<component-class>komponenty.UISimple</component-class>
</component>
<render-kit>
<renderer>
<component-family>javax.faces.Input</component-family>
<renderer-type>komponenty.Simple</renderer-type>
<renderer-class>komponenty.SimpleRenderer</renderer-class>
</renderer>
</render-kit>
</faces-config>