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>