Component可以将解码、编码的动作交给Renderer,这让您的表现层技术可以轻易的抽换,我们可以将之前的自订元件的解码、编码动作移出至 Renderer,不过由于我们之前设计的Component是个很简单的元件,事实上,如果只是要新增一个Command在输入栏位旁边,我们并不需要大费周章的自订一个新的元件,我们可以直接为输入栏位更换一个自订的Renderer。
要自订一个Renderer,您要继承javax.faces.render.Renderer,我们的自订Renderer如下:
TextCmdRenderer.java
package onlyfun.caterpillar;
import java.io.IOException;
import java.util.Map;
import javax.faces.component.EditableValueHolder;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.Renderer;
public class TextCmdRenderer extends Renderer {
private static final String TEXT = ".text";
private static final String CMD = ".cmd";
public void encodeBegin(FacesContext context,
UIComponent component) throws IOException {
ResponseWriter writer = context.getResponseWriter();
String clientId = component.getClientId(context);
encodeTextField(component, writer, clientId);
encodeCommand(component, writer, clientId);
}
public void decode(FacesContext context,
UIComponent component) {
Map reqParaMap = context.getExternalContext().
getRequestParameterMap();
String clientId = component.getClientId(context);
String submittedValue =
(String) reqParaMap.get(clientId + TEXT);
((EditableValueHolder) component).setSubmittedValue(
submittedValue);
((EditableValueHolder) component).setValid(true);
}
private void encodeTextField(UIComponent component,
ResponseWriter writer, String clientId)
throws IOException {
writer.startElement("input", component);
writer.writeAttribute("name", clientId + TEXT, null);
Object value = ((UIInput) component).getValue();
if(value != null) {
writer.writeAttribute("value",
alue.toString(), null);
}
String size =
(String) component.getAttributes().get("size");
if(size != null) {
writer.writeAttribute("size", size, null);
}