001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package com.sun.rave.web.ui.renderer;
042:
043: import java.io.IOException;
044:
045: import javax.faces.component.UIComponent;
046: import javax.faces.context.FacesContext;
047: import javax.faces.context.ResponseWriter;
048:
049: import com.sun.rave.web.ui.theme.Theme;
050: import com.sun.rave.web.ui.util.RenderingUtilities;
051:
052: /**
053: * RowColumnRenderer renders a HTML table.
054: * The contents are rendered by a subclass during the
055: * renderCellContent method, implemented in a subclass.
056: * An example of the HTML produced when the subclass renderer
057: * is a {@link RadionButtonGroup}.
058: * <p>
059: * <table class=" RbGrp" style="">
060: * <tbody>
061: * <tr class="RbGrpRwOd">
062: * <td class="RbGrpCpt">
063: * <label class="RbGrpLbl" for="form1:_id1_0_input"
064: * title="rbgrp-tooltip"
065: * id="form1:_id1_caption">Radio Button Group</label>
066: * </td>
067: * <td class="RbGrpClEv">
068: * <input tabindex="1" class="Rb"
069: * value="Server" name="form1:_id1"
070: * id="form1:_id1_0_input" type="radio">
071: * <img class="RbImg" src="tree_server.gif" id="form1:_id1_0_image">
072: * <label class="RbLbl LblLev3Txt" for="form1:_id1_0_input"
073: * id="form1:_id1_0_label">Server</label>
074: * </td>
075: * <td class="RbGrpClOd">
076: * <input tabindex="1" class="Rb"
077: * value="Volume" name="form1:_id1"
078: * id="form1:_id1_1_input" type="radio">
079: * <img class="RbImg" src="volumegroup_tree.gif"
080: * id="form1:_id1_1_image">
081: * <label
082: * class="RbLbl LblLev3Txt" for="form1:_id1_1_input"
083: * id="form1:_id1_1_label">Volume</label>
084: * </td>
085: * </tr>
086: * <tr class="RbGrpRwEv">
087: * <td>
088: * </td>
089: * <td class="RbGrpClEv">
090: * <input tabindex="1" class="Rb"
091: * checked="checked" value="Pool" name="form1:_id1"
092: * id="form1:_id1_2_input" type="radio">
093: * <img class="RbImg" src="pool_tree.gif" id="form1:_id1_2_image">
094: * <label class="RbLbl LblLev3Txt" for="form1:_id1_2_input"
095: * id="form1:_id1_2_label">Pool</label>
096: * </td>
097: * <td class="RbGrpClEv">
098: * </td>
099: * </tr>
100: * </tbody>
101: * </table>
102: * </p>
103: * The style class selectors are not output by <code>RowColumnRenderer</code>
104: * but by a subclass.
105: */
106: abstract class RowColumnRenderer extends AbstractRenderer {
107:
108: private final static String TABLE_ELEMENT = "table"; //NOI18N
109: private final static String CAPTION_ELEMENT = "td"; //NOI18N
110: private final static String ROW_ELEMENT = "tr"; //NOI18N
111: private final static String CELL_ELEMENT = "td"; //NOI18N
112:
113: /**
114: * Constant indicating a TABLE element style selector is desired.
115: */
116: protected final static int TABLE_STYLE = 0;
117: /**
118: * Constant indicating a TD element stlye is desired.
119: * This selector is used for the TD element that contains
120: * the group label.
121: */
122: protected final static int CAPTION_STYLE = 1;
123: /**
124: * Constant indicating a TR element style selector is desired.
125: * The selector is applied to an odd row.
126: */
127: protected final static int ROWEVEN_STYLE = 2;
128: /**
129: * Constant indicating a TR element style selector is desired.
130: * The selector is applied to an even row.
131: */
132: protected final static int ROWODD_STYLE = 3;
133: /**
134: * Constant indicating a TD element style selector is desired.
135: * The selector is applied to an even column.
136: */
137: protected final static int CELLEVEN_STYLE = 4;
138: /**
139: * Constant indicating a TD element style selector is desired.
140: * The selector is applied to an odd column.
141: */
142: protected final static int CELLODD_STYLE = 5;
143:
144: /**
145: * Create a RowColumnRenderer instance.
146: */
147: public RowColumnRenderer() {
148: super ();
149: }
150:
151: /**
152: * Called from a subclass when rendering is to begin
153: *
154: * @param context <code>FacesContext</code> for the current request
155: * @param component <code>RadioButtonGroup</code> component rendered
156: * @param writer <code>ResponseWriter</code> to which the HTML is rendered
157: * @param rows the number of rows to render
158: * @param columns the number of columns to render
159: */
160: protected void renderRowColumnLayout(FacesContext context,
161: UIComponent component, Theme theme, ResponseWriter writer,
162: int rows, int columns) throws IOException {
163:
164: writer.startElement(TABLE_ELEMENT, component);
165:
166: // Set the CSS table style
167: //
168: writeStyleAttribute(component, writer, null);
169:
170: // Set the class attribute.
171: // Include the hidden attribute
172: //
173: String styles = RenderingUtilities.getStyleClasses(context,
174: component, getRowColumnStyle(theme, TABLE_STYLE));
175: if (styles != null) {
176: writer.writeAttribute("class", styles, null); //NOI18N
177: }
178:
179: // Assume contained elements inherit from these
180: // span attributes
181: //
182: addStringAttributes(context, component, writer, I18N_ATTRIBUTES);
183:
184: //<RAVE>
185: //mbohm 6300361,6300362
186: //commenting out this call to addStringAttributes
187: //see RadioButtonGroupRenderer.getSelectorComponent and
188: //CheckboxGroupRenderer.getSelectorComponent
189: //addStringAttributes(context, component, writer,
190: //EVENTS_ATTRIBUTES);
191: //</RAVE>
192:
193: renderRows(context, component, theme, writer, rows, columns);
194:
195: writer.endElement(TABLE_ELEMENT);
196:
197: }
198:
199: /**
200: * Render the rows of the table
201: */
202: private void renderRows(FacesContext context,
203: UIComponent component, Theme theme, ResponseWriter writer,
204: int rows, int columns) throws IOException {
205:
206: // Create a cell for the caption
207: //
208: int row = 0;
209: writer.startElement(ROW_ELEMENT, component);
210: writer.writeAttribute("class", //NOI18N
211: getRowColumnStyle(theme, ROWODD_STYLE), null);
212:
213: writer.startElement(CELL_ELEMENT, component);
214: String style = getRowColumnStyle(theme, CAPTION_STYLE);
215: if (style != null) {
216: writer.writeAttribute("class", style, null); //NOI18N
217: }
218: renderCaption(context, component, theme, writer);
219: writer.endElement(CELL_ELEMENT);
220:
221: int itemN = 0;
222: for (row = 1; row <= rows; ++row) {
223:
224: for (int column = 0; column < columns; ++column) {
225:
226: writer.startElement(CELL_ELEMENT, component);
227:
228: // Use "1" based cells so that the first cell is odd
229: // vs. "0th" cell which would be even
230: //
231: // Don't inlcude the hidden attribute
232: String styles = getRowColumnStyle(theme,
233: (column & 0x00000001) == 0 ? CELLEVEN_STYLE
234: : CELLODD_STYLE);
235: if (styles != null) {
236: writer.writeAttribute("class", styles, null); //NOI18N
237: }
238:
239: renderCellContent(context, component, theme, writer,
240: itemN);
241: ++itemN;
242:
243: writer.endElement(CELL_ELEMENT);
244:
245: }
246: writer.endElement(ROW_ELEMENT);
247:
248: // Don't start any more rows if the loop is ending
249: //
250: if (row + 1 <= rows) {
251: writer.startElement(ROW_ELEMENT, component);
252: // Use "1" based rows so that the first row is odd
253: // vs. "0th" row which would be even
254: //
255: String styles = getRowColumnStyle(theme,
256: (row & 0x00000001) == 0 ? ROWODD_STYLE
257: : ROWEVEN_STYLE);
258: if (styles != null) {
259: writer.writeAttribute("class", styles, null); //NOI18N
260: }
261:
262: writer.startElement(CELL_ELEMENT, component);
263: writer.endElement(CELL_ELEMENT);
264: }
265:
266: }
267:
268: // FIXME
269: // Need to know if rows can ever be zero.
270: // If rows is 0 then this is the only time this
271: // row needs to be terminated.
272: //
273: if (rows == 0) {
274: // End the row started outside the loop
275: //
276: writer.endElement(ROW_ELEMENT);
277: }
278: }
279:
280: /**
281: * Implemented by a subclass.
282: * Called when subclass should render the contents of the cell for the
283: * <code>itemN</code>'th renderer cell.
284: *
285: * @param context <code>FacesContext</code> for the current request
286: * @param component component being rendered
287: * @param writer <code>ResponseWriter</code> to which the HTML is rendered
288: * @param itemN the nth cell to be rendered.
289: */
290: protected abstract void renderCellContent(FacesContext context,
291: UIComponent component, Theme theme, ResponseWriter writer,
292: int itemN) throws IOException;
293:
294: /**
295: * Implemented by a subclass.
296: * Called when the subclass should render the CAPTION element for
297: * the table.
298: *
299: * @param context <code>FacesContext</code> for the current request
300: * @param component component being rendered
301: * @param writer <code>ResponseWriter</code> to which the HTML is rendered
302: */
303: protected abstract void renderCaption(FacesContext context,
304: UIComponent component, Theme theme, ResponseWriter writer)
305: throws IOException;
306:
307: /**
308: * Get the style class for a structural element of the table.
309: * <code>styleCode</code> is one of.
310: * <p>
311: * <lo>
312: * <li><code>TABLE_STYLE</code></li>
313: * <li><code>CAPTION_STYLE</code></li>
314: * <li><code>ROWEVEN_STYLE</code></li>
315: * <li><code>ROWODD_STYLE</code></li>
316: * <li><code>CELLEVEN_STYLE</code></li>
317: * <li><code>CELLODD_STYLE</code></li>
318: * </lo>
319: * </p>
320: *
321: * @param context <code>FacesContext</code> for the current request
322: * @param styleCode one the predefined constants.
323: */
324: protected abstract String getRowColumnStyle(Theme theme,
325: int styleCode);
326:
327: private void writeStyleAttribute(UIComponent component,
328: ResponseWriter writer, String style) throws IOException {
329:
330: StringBuffer styleBuf = new StringBuffer();
331: String compStyle = (String) component.getAttributes().get(
332: "style"); //NOI18N
333: if (compStyle != null) {
334: styleBuf.append(compStyle);
335: }
336: if (style != null) {
337: if (styleBuf.length() != 0) {
338: styleBuf.append(" "); //NOI18N
339: }
340: styleBuf.append(style);
341: }
342: if (styleBuf.length() != 0) {
343: writer.writeAttribute("style", styleBuf.toString(), null); //NOI18N
344: }
345: }
346: }
|