<render-kit> <description>Some replacements for the standard renderers</description> <renderer> <description>Replacement renderer for h:outputLabel</description> <component-family>javax.faces.Output</component-family> <renderer-type>javax.faces.Label</renderer-type> <renderer-class>com.mycompany.app.webapp.jsf.LabelRenderer</renderer-class> </renderer> <renderer> <description>Replacement renderer for h:panelGrid that uses lists instead of tables</description> <component-family>javax.faces.Panel</component-family> <renderer-type>javax.faces.Grid</renderer-type> <renderer-class>com.mycompany.app.webapp.jsf.PanelGridRenderer</renderer-class> </renderer> </render-kit>
public class LabelRenderer extends Renderer { protected final Log log = LogFactory.getLog(LabelRenderer.class); public boolean getRendersChildren() { return false; } public void encodeBegin(FacesContext context, UIComponent component) throws java.io.IOException { ResponseWriter writer = context.getResponseWriter(); Map attrs = component.getAttributes(); String id = (String) attrs.get("for"); UIInput input = null; if (!StringUtils.isEmpty(id)) { input = (UIInput) component.findComponent(id); } writer.startElement("label", component); String styleClass = (String) component.getAttributes().get("styleClass"); boolean hasErrors = hasMessages(context, input); if (styleClass != null) { if (hasErrors) styleClass += " error"; writer.writeAttribute("class", styleClass, null); } else if (hasErrors) { writer.writeAttribute("class", "error", null); } String renderedId = (input != null) ? input.getClientId(context) : component.getClientId(context); writer.writeAttribute("for", renderedId, null); writer.write(attrs.get("value").toString()); } public void encodeEnd(FacesContext context, UIComponent component) throws java.io.IOException { ResponseWriter writer = context.getResponseWriter(); Map attrs = component.getAttributes(); String id = (String) attrs.get("for"); UIInput input = null; if (!StringUtils.isEmpty(id)) { input = (UIInput) component.findComponent(id); } if ((input != null) && input.isRequired()) { writer.write(" <span class=\"req\">*</span>"); } writer.endElement("label"); } private boolean hasMessages(FacesContext context, UIComponent component) { Iterator it = context.getClientIdsWithMessages(); boolean found = false; while (it.hasNext()) { String id = (String) it.next(); if ((component != null) && id.equals(component.getClientId(context))) { found = true; break; } } return found; }
public class PanelGridRenderer extends HtmlRenderer { private static final Log log = LogFactory.getLog(PanelGridRenderer.class); public boolean getRendersChildren() { return true; } public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException { // all work done in encodeEnd() } public void encodeChildren(FacesContext context, UIComponent component) throws IOException { // all work done in encodeEnd() } public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException { RendererUtils.checkParamValidity(facesContext, component, UIPanel.class); int columns; if (component instanceof HtmlPanelGrid) { columns = ((HtmlPanelGrid) component).getColumns(); } else { Integer i = (Integer) component.getAttributes().get(org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr.COLUMNS_ATTR); columns = i != null ? i.intValue() : 0; } if (columns <= 0) { if (log.isErrorEnabled()) { log.error("Wrong columns attribute for PanelGrid " + component.getClientId(facesContext) + ": " + columns); } columns = 1; } ResponseWriter writer = facesContext.getResponseWriter(); writer.startElement(HTML.UL_ELEM, component); HtmlRendererUtils.writeIdIfNecessary(writer, component, facesContext); HtmlRendererUtils.renderHTMLAttributes(writer, component, HTML.UL_PASSTHROUGH_ATTRIBUTES); writer.flush(); renderChildren(facesContext, writer, component, columns); writer.endElement(HTML.UL_ELEM); } protected void renderChildren(FacesContext context, ResponseWriter writer, UIComponent component, int columns) throws IOException { String rowClasses; if (component instanceof HtmlPanelGrid) { rowClasses = ((HtmlPanelGrid) component).getRowClasses(); } else { rowClasses = (String) component.getAttributes().get(JSFAttr.ROW_CLASSES_ATTR); } String[] rowClassesArray = (rowClasses == null) ? org.apache.myfaces.shared_tomahawk.util.ArrayUtils.EMPTY_STRING_ARRAY : StringUtils.trim(StringUtils.splitShortString(rowClasses, ',')); int rowClassesCount = rowClassesArray.length; int childCount = getChildCount(component); if (childCount > 0) { int columnIndex = 0; int rowClassIndex = 0; boolean rowStarted = false; for (Iterator it = getChildren(component).iterator(); it.hasNext();) { UIComponent child = (UIComponent) it.next(); if (child.isRendered()) { if (columnIndex == 0) { //start of new/next row if (rowStarted) { //do we have to close the last row? writer.endElement(HTML.LI_ELEM); HtmlRendererUtils.writePrettyLineSeparator(context); } writer.startElement(HTML.LI_ELEM, component); if (rowClassIndex < rowClassesCount) { writer.writeAttribute(HTML.CLASS_ATTR, rowClassesArray[rowClassIndex], null); } rowStarted = true; rowClassIndex++; if (rowClassIndex == rowClassesCount) { rowClassIndex = 0; } } RendererUtils.renderChild(context, child); columnIndex++; if (columnIndex >= columns) { columnIndex = 0; } } } if (rowStarted) { writer.endElement(HTML.LI_ELEM); HtmlRendererUtils.writePrettyLineSeparator(context); } } }