001: // ========================================================================
002: // $Id: Table.java,v 1.3 2004/05/09 20:31:28 gregwilkins Exp $
003: // Copyright 1996-2004 Mort Bay Consulting Pty. Ltd.
004: // ------------------------------------------------------------------------
005: // Licensed under the Apache License, Version 2.0 (the "License");
006: // you may not use this file except in compliance with the License.
007: // You may obtain a copy of the License at
008: // http://www.apache.org/licenses/LICENSE-2.0
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014: // ========================================================================
015:
016: package org.mortbay.html;
017:
018: import java.util.Hashtable;
019:
020: /* --------------------------------------------------------------------- */
021: /** A HTML Table element.
022: * <p> The Table Element works by calling newRow and then adding cells or
023: * headings.
024: * <p>Notes<br>
025: * Tables are implemented by nesting a cell Block within a row Block
026: * within the table which is also a Block (see nest() on class Composite).
027: * Once a row and cell have been created, calling add or attributes on
028: * the table actually calls the cell.
029: *
030: * @see org.mortbay.html.Element
031: */
032: public class Table extends Block {
033: /* ----------------------------------------------------------------- */
034: private Block row = null;
035: private Block cell = null;
036: private static Hashtable threadNestingMap = null;
037: private CompositeFactory cellNestFactory = null;
038: private Block _defaultHead = null;
039: private Block _defaultCell = null;
040: private Block _defaultRow = null;
041:
042: /* ----------------------------------------------------------------- */
043: /** Construct Table.
044: */
045: public Table() {
046: super ("table");
047: if (threadNestingMap != null)
048: cellNestFactory = (CompositeFactory) threadNestingMap
049: .get(Thread.currentThread());
050: }
051:
052: /* ----------------------------------------------------------------- */
053: /** Construct Table.
054: */
055: public Table(int border) {
056: super ("table");
057: attribute("border", border);
058: if (threadNestingMap != null)
059: cellNestFactory = (CompositeFactory) threadNestingMap
060: .get(Thread.currentThread());
061: }
062:
063: /* ----------------------------------------------------------------- */
064: /** Construct Table with attributes.
065: */
066: public Table(int border, String attributes) {
067: this (border);
068: attribute(attributes);
069: }
070:
071: /* ----------------------------------------------------------------- */
072: /** Create new table row.
073: * Attributes set after this call and before a call to newCell or
074: * newHeader are considered row attributes.
075: */
076: public Table newRow() {
077: unnest();
078: nest(row = new Block("tr"));
079: if (_defaultRow != null) {
080: row.setAttributesFrom(_defaultRow);
081: if (_defaultRow.size() > 0)
082: row.add(_defaultRow.contents());
083: }
084: cell = null;
085: return this ;
086: }
087:
088: /* ----------------------------------------------------------------- */
089: /** Create new table row with attributes.
090: * Attributes set after this call and before a call to newCell or
091: * newHeader are considered row attributes.
092: */
093: public Table newRow(String attributes) {
094: newRow();
095: row.attribute(attributes);
096: return this ;
097: }
098:
099: /* ----------------------------------------------------------------- */
100: /* Create a new Cell in the current row.
101: * Adds to the table after this call and before next call to newRow,
102: * newCell or newHeader are added to the cell.
103: */
104: private void newBlock(String m) {
105: if (row == null)
106: newRow();
107: else
108: row.unnest();
109: row.nest(cell = new Block(m));
110:
111: if (cellNestFactory != null)
112: cell.nest(cellNestFactory.newComposite());
113: }
114:
115: /* ----------------------------------------------------------------- */
116: /* Create a new Cell in the current row.
117: * Adds to the table after this call and before next call to newRow,
118: * newCell or newHeader are added to the cell.
119: */
120: public Table newCell() {
121: newBlock("td");
122: if (_defaultCell != null) {
123: cell.setAttributesFrom(_defaultCell);
124: if (_defaultCell.size() > 0)
125: cell.add(_defaultCell.contents());
126: }
127: return this ;
128: }
129:
130: /* ----------------------------------------------------------------- */
131: /* Create a new Cell in the current row.
132: * Adds to the table after this call and before next call to newRow,
133: * newCell or newHeader are added to the cell.
134: * @return This table for call chaining
135: */
136: public Table newCell(String attributes) {
137: newCell();
138: cell.attribute(attributes);
139: return this ;
140: }
141:
142: /* ----------------------------------------------------------------- */
143: /* Add a new Cell in the current row.
144: * Adds to the table after this call and before next call to newRow,
145: * newCell or newHeader are added to the cell.
146: * @return This table for call chaining
147: */
148: public Table addCell(Object o) {
149: newCell();
150: cell.add(o);
151: return this ;
152: }
153:
154: /* ----------------------------------------------------------------- */
155: /* Add a new Cell in the current row.
156: * Adds to the table after this call and before next call to newRow,
157: * newCell or newHeader are added to the cell.
158: * @return This table for call chaining
159: */
160: public Table addCell(Object o, String attributes) {
161: addCell(o);
162: cell.attribute(attributes);
163: return this ;
164: }
165:
166: /* ----------------------------------------------------------------- */
167: /* Create a new Heading in the current row.
168: * Adds to the table after this call and before next call to newRow,
169: * newCell or newHeader are added to the cell.
170: */
171: public Table newHeading() {
172: newBlock("th");
173: if (_defaultHead != null) {
174: cell.setAttributesFrom(_defaultHead);
175: if (_defaultHead.size() > 0)
176: cell.add(_defaultHead.contents());
177: }
178: return this ;
179: }
180:
181: /* ----------------------------------------------------------------- */
182: /* Add a new heading Cell in the current row.
183: * Adds to the table after this call and before next call to newRow,
184: * newCell or newHeader are added to the cell.
185: * @return This table for call chaining
186: */
187: public Table addHeading(Object o) {
188: newHeading();
189: cell.add(o);
190: return this ;
191: }
192:
193: /* ----------------------------------------------------------------- */
194: /* Add a new heading Cell in the current row.
195: * Adds to the table after this call and before next call to newRow,
196: * newCell or newHeader are added to the cell.
197: * @return This table for call chaining
198: */
199: public Table addHeading(Object o, String attributes) {
200: addHeading(o);
201: cell.attribute(attributes);
202: return this ;
203: }
204:
205: /* ------------------------------------------------------------ */
206: /** Set the table cell spacing.
207: * @param s spacing in pixels
208: * @return This table for call chaining
209: */
210: public Table cellSpacing(int s) {
211: attribute("cellspacing", s);
212: return this ;
213: }
214:
215: /* ------------------------------------------------------------ */
216: /** Set the table cell padding.
217: * @param padding the cell padding in pixels
218: * @return This table for call chaining
219: */
220: public Table cellPadding(int padding) {
221: attribute("cellpadding", padding);
222: return this ;
223: }
224:
225: /* ------------------------------------------------------------ */
226: /** Set horizontal and vertical spacing.
227: * @param h horizontal spacing
228: * @param v vertical spacing
229: * @return This table for call chaining
230: */
231: public Table spacing(int h, int v) {
232: if (h >= 0)
233: attribute("hspace", h);
234: if (v >= 0)
235: attribute("vspace", v);
236: return this ;
237: }
238:
239: /* ----------------------------------------------------------------- */
240: /** Get the current row Block element.
241: * Use this call for setting row attributes.
242: * @return The Block instance which has been nested in the table as
243: * the row
244: */
245: public Block row() {
246: return row;
247: }
248:
249: /* ----------------------------------------------------------------- */
250: /** Get the current cell Block element.
251: * Use this call for setting cell attributes.
252: * @return The Block instance which has been nested in the row as
253: * the cell
254: */
255: public Block cell() {
256: return cell;
257: }
258:
259: /* ----------------------------------------------------------------- */
260: /** Add cell nesting factory.
261: * Set the CompositeFactory for this thread. Each new cell in the
262: * table added by this thread will have a new Composite from this
263: * factory nested in the Cell.
264: * @param factory The factory for this Thread. If null clear this
265: * threads factory.
266: * @deprecated Use setNestingFactory or setThreadNestingFactory
267: */
268: public static void setCellNestingFactory(CompositeFactory factory) {
269: if (threadNestingMap == null)
270: threadNestingMap = new Hashtable();
271:
272: if (factory == null)
273: threadNestingMap.remove(Thread.currentThread());
274: else
275: threadNestingMap.put(Thread.currentThread(), factory);
276: }
277:
278: /* ----------------------------------------------------------------- */
279: /** Add cell nesting factory for thread.
280: * Set the CompositeFactory for this thread. Each new cell in the
281: * table added by this thread will have a new Composite from this
282: * factory nested in the Cell.
283: * @param factory The factory for this Thread. If null clear this
284: * threads factory.
285: */
286: public static void setThreadNestingFactory(CompositeFactory factory) {
287: if (threadNestingMap == null)
288: threadNestingMap = new Hashtable();
289:
290: if (factory == null)
291: threadNestingMap.remove(Thread.currentThread());
292: else
293: threadNestingMap.put(Thread.currentThread(), factory);
294: }
295:
296: /* ----------------------------------------------------------------- */
297: /** Add cell nesting factory for table.
298: * Set the CompositeFactory for this thread. Each new cell in the
299: * table added by this thread will have a new Composite from this
300: * factory nested in the Cell.
301: * @param factory The factory for this Thread. If null clear this
302: * threads factory.
303: */
304: public void setNestingFactory(CompositeFactory factory) {
305: cellNestFactory = factory;
306: }
307:
308: /* ------------------------------------------------------------ */
309: /** Access the default row template.
310: * The Block returned is used as a template for all new rows added
311: * to the table. Thus if attributes or content are added to the
312: * default row, the these are added to each new row in the table.
313: * @return The default row template
314: */
315: public Block defaultRow() {
316: if (_defaultRow == null)
317: _defaultRow = new Block("tr");
318: return _defaultRow;
319: }
320:
321: /* ------------------------------------------------------------ */
322: /** Access the default header cell template.
323: * The Block returned is used as a template for all new header cells added
324: * to the table. Thus if attributes or content are added to the
325: * default cell, the these are added to each new cell in the table.
326: * @return The default head cell template
327: */
328: public Block defaultHead() {
329: if (_defaultHead == null)
330: _defaultHead = new Block("th");
331: return _defaultHead;
332: }
333:
334: /* ------------------------------------------------------------ */
335: /** Access the default cell template.
336: * The Block returned is used as a template for all new cells added
337: * to the table. Thus if attributes or content are added to the
338: * default cell, the these are added to each new cell in the table.
339: * @return The default cell template
340: */
341: public Block defaultCell() {
342: if (_defaultCell == null)
343: _defaultCell = new Block("td");
344: return _defaultCell;
345: }
346: }
|