001: /*
002: * Copyright 2005 jWic group (http://www.jwic.de)
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: *
016: * de.jwic.controls.layout.TableLayoutContainer
017: * Created on 05.06.2005
018: * $Id: TableLayoutContainer.java,v 1.6 2007/05/02 20:21:02 cosote Exp $
019: */
020:
021: package de.jwic.controls.layout;
022:
023: import java.util.ArrayList;
024: import java.util.HashMap;
025: import java.util.Iterator;
026: import java.util.List;
027: import java.util.Map;
028:
029: import de.jwic.base.Control;
030: import de.jwic.base.ControlContainer;
031: import de.jwic.base.IControlContainer;
032: import de.jwic.base.JWicException;
033:
034: /**
035: * The TableLayoutContainer is a special form of a IControlContainer. <p>
036: *
037: * This Container follows a simple layoutstructure in form of a table. <br>
038: * The Controls are added in sequence and are displayed in the given columns partition.
039: * The columns can be set through constructor or setter. <br>
040: * TableLayoutContainer.vtl is the template for this container. <br>
041: * The template simply uses table tags to form the layout of the control.
042: * <br><br>
043: * This container also has its own layoutdata like alignment, width, height and border.
044: *
045: * @author Ronny Pfretzschner
046: * @author Florian Lippisch
047: *
048: */
049: public class TableLayoutContainer extends ControlContainer {
050:
051: private static final long serialVersionUID = 1L;
052:
053: public final static String ALIGN_DEFAULT = "";
054: public final static String ALIGN_LEFT = "left";
055: public final static String ALIGN_CENTER = "center";
056: public final static String ALIGN_RIGHT = "right";
057:
058: // layout properties
059: private String align = ALIGN_DEFAULT;
060: private int borderSize = -1; // -1 == default
061: private int cellSpacing = -1; // -1 == default
062: private int cellPadding = -1; // -1 == default
063: private String sCSSClass = "";
064:
065: // size settings
066: private String height = "";
067: private String width = "";
068:
069: private Map allLayoutInfos = new HashMap();
070: private List childNames = new ArrayList();
071:
072: private int columnCount = 1;
073: private int[] colWidths = new int[1];
074: private Cell[][] cells = null;
075: private Row[] rows = null;
076: private int rowCount = -1; // will be calculated if required.
077:
078: /**
079: * Constructs a new TableLayoutContainer with a default name.
080: *
081: */
082: public TableLayoutContainer(IControlContainer container) {
083: this (container, null);
084: }
085:
086: /**
087: * Constructs a new TableLayoutContainer with the specified name.
088: *
089: */
090: public TableLayoutContainer(IControlContainer container, String name) {
091: super (container, name);
092: }
093:
094: /**
095: * Constructor. <p>
096: *
097: * @param cols Amount of columns, which the Container will be devided in.
098: */
099: public TableLayoutContainer(IControlContainer container,
100: String name, int columnCount) {
101: super (container, name);
102: if (columnCount < 1) {
103: throw new IllegalArgumentException("Argument wrong in "
104: + getClass().getName()
105: + " constructor: Set column amount not negative!");
106: }
107: this .columnCount = columnCount;
108: this .colWidths = new int[columnCount];
109: }
110:
111: /**
112: * @return Returns the align.
113: */
114: public String getAlign() {
115: return align;
116: }
117:
118: /**
119: * Returns the list of childs.
120: * @return
121: */
122: public List getChildNames() {
123: return childNames;
124: }
125:
126: /**
127: * Returns the cols amount as an int. <p>
128: *
129: * @return int The amount of columns
130: */
131: public int getColumnCount() {
132: return columnCount;
133: }
134:
135: /**
136: * @return Returns the height.
137: */
138: public String getHeight() {
139: return height;
140: }
141:
142: /**
143: * Get the TableData of a specific name of a control. <p>
144: *
145: * null is only returned, if the controls name is belonging to a GridLayoutContainer. <p>
146: *
147: * @param controlName
148: * @return GridData
149: */
150: public TableData getLayoutData(String controlName) {
151: TableData test = (TableData) allLayoutInfos.get(controlName);
152: return test;
153: }
154:
155: /**
156: * Returns the rows required to render this table.
157: * @return
158: */
159: public Row[] getRows() {
160:
161: if (rows == null) {
162: layout();
163: }
164: return rows;
165: }
166:
167: /**
168: * Returns the cells to the specified row.
169: * @param row
170: * @return
171: */
172: public Cell[] getCells(Row row) {
173:
174: if (cells == null) {
175: layout();
176: }
177: return cells[row.getNum()];
178: }
179:
180: /**
181: * @return Returns the width.
182: */
183: public String getWidth() {
184: return width;
185: }
186:
187: /**
188: * Calculates the layout of the table.
189: */
190: public void layout() {
191:
192: if (childNames.size() == 0) { // no controls added
193: rows = new Row[0];
194: cells = new Cell[0][0];
195: } else {
196:
197: // step #1: calculate the number of rows
198: int column = 0;
199: int rowNum = 0;
200: int[] spawn = new int[columnCount];
201:
202: for (Iterator it = childNames.iterator(); it.hasNext();) {
203: if (spawn[column] > 1) {
204: spawn[column]--;
205: column++;
206: } else {
207: String name = (String) it.next();
208: TableData td = getLayoutData(name);
209: spawn[column] = td.getRowSpan();
210: column += td.getColSpan();
211: }
212: if (column >= columnCount) {
213: column = 0;
214: if (it.hasNext()) {
215: rowNum++;
216: }
217: }
218: }
219: rowCount = rowNum + 1;
220:
221: // step #2: setup the cells
222: column = 0;
223: rowNum = 0;
224: int colIdx = 0;
225: spawn = new int[columnCount];
226: cells = new Cell[rowCount][columnCount];
227: Row[] rowData = new Row[rowCount]; // create a max size row data
228: rowData[rowNum] = new Row(rowNum);
229:
230: for (Iterator it = childNames.iterator(); it.hasNext();) {
231: if (spawn[column] > 1) {
232: spawn[column]--;
233: column++;
234: } else {
235: String name = (String) it.next();
236: TableData td = getLayoutData(name);
237: spawn[column] = td.getRowSpan();
238: Cell cell = new Cell(rowNum, column, td);
239: cells[rowNum][colIdx] = cell;
240: cell.setControlName(name);
241: if (colWidths[column] != 0) {
242: cell.setWidth(Integer
243: .toString(colWidths[column]));
244: }
245: column += td.getColSpan();
246: if (column > this .columnCount) {
247: column = columnCount;
248: }
249: colIdx++;
250: }
251:
252: if (colIdx < column) { // fill 'empty' cells
253: for (int c = colIdx; c < column; c++) {
254: cells[rowNum][c] = new Cell(rowNum, c);
255: cells[rowNum][c].setRender(false);
256: }
257: colIdx = column;
258: }
259:
260: if (column >= columnCount) {
261: if (it.hasNext()) {
262: column = 0;
263: colIdx = 0;
264: rowNum++;
265: rowData[rowNum] = new Row(rowNum);
266: }
267: }
268: }
269:
270: if (colIdx < columnCount) {
271: for (int c = colIdx; c < columnCount; c++) {
272: cells[rowNum][c] = new Cell(rowNum, c);
273: cells[rowNum][c].setRender(false);
274: }
275: }
276:
277: rows = rowData;
278:
279: }
280:
281: }
282:
283: /* (non-Javadoc)
284: * @see de.jwic.base.ControlContainer#registerControl(de.jwic.base.Control, java.lang.String)
285: */
286: public void registerControl(Control control, String name)
287: throws JWicException {
288: super .registerControl(control, name);
289: childNames.add(control.getName());
290: // add default GridData
291: allLayoutInfos.put(control.getName(), new TableData());
292: cells = null; // --> forces re-layout on next rendering
293: }
294:
295: /**
296: * Removes a control from the container with the given controlName. <p>
297: *
298: * @param String controlName
299: */
300: public void removeControl(String controlName) {
301: allLayoutInfos.remove(controlName);
302: childNames.remove(controlName);
303: cells = null; // --> forces re-layout on next rendering
304: super .removeControl(controlName);
305: }
306:
307: /* (non-Javadoc)
308: * @see de.jwic.base.ControlContainer#unregisterControl(de.jwic.base.Control)
309: */
310: public void unregisterControl(Control control) {
311: allLayoutInfos.remove(control.getName());
312: childNames.remove(control.getName());
313: cells = null; // --> forces re-layout on next rendering
314: super .unregisterControl(control);
315: }
316:
317: /**
318: * @param align The align to set.
319: */
320: public void setAlign(String align) {
321: this .align = align;
322: requireRedraw();
323: }
324:
325: /**
326: * Sets the amount of available columns of the GridLayoutContainer. <p>
327: *
328: * The default value is 1. Do not use negative values. An IllegalArgumentException<br>
329: * is thrown in that case.
330: *
331: * @param cols The amount of columns of the GridLayoutContainer
332: */
333: public void setColumnCount(int cols) {
334: if (cols < 1) {
335: throw new IllegalArgumentException(
336: "Argument wrong: Set column amount not 0 and not negative!");
337: }
338: this .columnCount = cols;
339: cells = null;
340: if (colWidths == null) {
341: colWidths = new int[cols];
342: } else {
343: int[] newCols = new int[cols];
344: System.arraycopy(colWidths, 0, newCols, 0,
345: colWidths.length > cols ? cols : colWidths.length);
346: colWidths = newCols;
347: }
348: requireRedraw();
349: }
350:
351: /**
352: * Set the width of a specified column. Set a column width to -1 if you do not want
353: * to specify a size.
354: * @param col
355: * @param width
356: */
357: public void setColWidth(int col, int width) {
358: colWidths[col] = width;
359: cells = null;
360: requireRedraw();
361: }
362:
363: /**
364: * @param height The height to set.
365: */
366: public void setHeight(String height) {
367: this .height = height;
368: requireRedraw();
369: }
370:
371: /**
372: * Set the layout of a control inside of this container.
373: *
374: * If null is used for the GridData and the Control is NOT a GridLayoutContainer, <br>
375: * a default GridData is set with left alignment. <br><br>
376: * GridLayoutContainers can also be added. In this case, use null for layoutData.<br>
377: * This is anyway the only possible setting, if you do not use null, null will be set automatically. <br>
378: * GridLayoutContainers should use their own layoutproperties.
379: *
380: * @param IControl control The control, which will be added in proper sequence to the LayoutContainer
381: * @param TableData layoutData The layoutData of the specific control. null, if it is a GridLayoutContainer
382: */
383: public void setLayoutData(Control control, TableData layoutData) {
384:
385: if (control.getContainer() != this ) {
386: throw new IllegalArgumentException(
387: "The specified control is not member of this container.");
388: }
389:
390: if (control instanceof TableLayoutContainer) {
391: allLayoutInfos.put(control.getName(), null);
392: } else {
393: allLayoutInfos.put(control.getName(),
394: layoutData != null ? layoutData : new TableData());
395: }
396: requireRedraw();
397: cells = null;
398: }
399:
400: /**
401: * @param width The width to set.
402: */
403: public void setWidth(String width) {
404: this .width = width;
405: requireRedraw();
406: }
407:
408: /**
409: * @return Returns the borderSize.
410: */
411: public int getBorderSize() {
412: return borderSize;
413: }
414:
415: /**
416: * The size of the border. If set to -1, the border property will
417: * not be specified on the table.
418: * @param borderSize The borderSize to set.
419: */
420: public void setBorderSize(int borderSize) {
421: this .borderSize = borderSize;
422: requireRedraw();
423: }
424:
425: /**
426: * @return Returns the cellPadding.
427: */
428: public int getCellPadding() {
429: return cellPadding;
430: }
431:
432: /**
433: * Set the cellpadding property. If set to -1, the cellpadding
434: * will not be specified on the table. (default)
435: * @param cellPadding The cellPadding to set.
436: */
437: public void setCellPadding(int cellPadding) {
438: this .cellPadding = cellPadding;
439: requireRedraw();
440: }
441:
442: /**
443: * @return Returns the cellSpacing.
444: */
445: public int getCellSpacing() {
446: return cellSpacing;
447: }
448:
449: /**
450: * Set the cellspacing property. If set to -1, the cellspacing
451: * will not be specified on the table. (default)
452: * @param cellSpacing The cellSpacing to set.
453: */
454: public void setCellSpacing(int cellSpacing) {
455: this .cellSpacing = cellSpacing;
456: requireRedraw();
457: }
458:
459: /**
460: * @return Returns the sCSSClass.
461: */
462: public String getCSSClass() {
463: return sCSSClass;
464: }
465:
466: /**
467: * @param class1 The sCSSClass to set.
468: */
469: public void setCSSClass(String cssClass) {
470: sCSSClass = cssClass;
471: requireRedraw();
472: }
473:
474: }
|