001: /*
002: * $Id: PdfTable.java 2752 2007-05-15 14:58:33Z blowagie $
003: * $Name$
004: *
005: * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
006: *
007: * The contents of this file are subject to the Mozilla Public License Version 1.1
008: * (the "License"); you may not use this file except in compliance with the License.
009: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
010: *
011: * Software distributed under the License is distributed on an "AS IS" basis,
012: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
013: * for the specific language governing rights and limitations under the License.
014: *
015: * The Original Code is 'iText, a free JAVA-PDF library'.
016: *
017: * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
018: * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
019: * All Rights Reserved.
020: * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
021: * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
022: *
023: * Contributor(s): all the names of the contributors are added in the source code
024: * where applicable.
025: *
026: * Alternatively, the contents of this file may be used under the terms of the
027: * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
028: * provisions of LGPL are applicable instead of those above. If you wish to
029: * allow use of your version of this file only under the terms of the LGPL
030: * License and not to allow others to use your version of this file under
031: * the MPL, indicate your decision by deleting the provisions above and
032: * replace them with the notice and other provisions required by the LGPL.
033: * If you do not delete the provisions above, a recipient may use your version
034: * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
035: *
036: * This library is free software; you can redistribute it and/or modify it
037: * under the terms of the MPL as stated above or under the terms of the GNU
038: * Library General Public License as published by the Free Software Foundation;
039: * either version 2 of the License, or any later version.
040: *
041: * This library is distributed in the hope that it will be useful, but WITHOUT
042: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
043: * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
044: * details.
045: *
046: * If you didn't download this code from the following link, you should check if
047: * you aren't using an obsolete version:
048: * http://www.lowagie.com/iText/
049: */
050:
051: package com.lowagie.text.pdf;
052:
053: import java.util.ArrayList;
054: import java.util.Iterator;
055:
056: import com.lowagie.text.Cell;
057: import com.lowagie.text.Element;
058: import com.lowagie.text.Rectangle;
059: import com.lowagie.text.Row;
060: import com.lowagie.text.Table;
061:
062: /**
063: * <CODE>PdfTable</CODE> is an object that contains the graphics and text of a table.
064: *
065: * @see com.lowagie.text.Table
066: * @see com.lowagie.text.Row
067: * @see com.lowagie.text.Cell
068: * @see PdfCell
069: */
070:
071: public class PdfTable extends Rectangle {
072:
073: // membervariables
074:
075: /** this is the number of columns in the table. */
076: private int columns;
077:
078: /** this is the ArrayList with all the cell of the table header. */
079: private ArrayList headercells;
080:
081: /** this is the ArrayList with all the cells in the table. */
082: private ArrayList cells;
083:
084: /** Original table used to build this object*/
085: protected Table table;
086:
087: /** Cached column widths. */
088: protected float[] positions;
089:
090: // constructors
091:
092: /**
093: * Constructs a <CODE>PdfTable</CODE>-object.
094: *
095: * @param table a <CODE>Table</CODE>
096: * @param left the left border on the page
097: * @param right the right border on the page
098: * @param top the start position of the top of the table
099: * @param supportUpdateRowAdditions
100: * if true, table rows will be deleted after building the PdfTable table,
101: * in order to preserve memory and detect future row additions
102: */
103:
104: PdfTable(Table table, float left, float right, float top,
105: boolean supportUpdateRowAdditions) {
106: // constructs a Rectangle (the bottomvalue will be changed afterwards)
107: super (left, top, right, top);
108: this .table = table;
109: table.complete();
110:
111: // copying the attributes from class Table
112: cloneNonPositionParameters(table);
113:
114: this .columns = table.getColumns();
115: positions = table.getWidths(left, right - left);
116:
117: // initialisation of some parameters
118: setLeft(positions[0]);
119: setRight(positions[positions.length - 1]);
120:
121: headercells = new ArrayList();
122: cells = new ArrayList();
123:
124: updateRowAdditionsInternal();
125: if (supportUpdateRowAdditions) {
126: table.deleteAllRows();
127: }
128: }
129:
130: // methods
131:
132: /**
133: * Updates the table row additions in the underlying table object and deletes all table rows,
134: * in order to preserve memory and detect future row additions.
135: * <p><b>Pre-requisite</b>: the object must have been built with the parameter <code>supportUpdateRowAdditions</code> equals to true.
136: */
137:
138: void updateRowAdditions() {
139: table.complete();
140: updateRowAdditionsInternal();
141: table.deleteAllRows();
142: }
143:
144: /**
145: * Updates the table row additions in the underlying table object
146: */
147:
148: private void updateRowAdditionsInternal() {
149: // correct table : fill empty cells/ parse table in table
150: Row row;
151: int prevRows = rows();
152: int rowNumber = 0;
153: int groupNumber = 0;
154: boolean groupChange;
155: int firstDataRow = table.getLastHeaderRow() + 1;
156: Cell cell;
157: PdfCell currentCell;
158: ArrayList newCells = new ArrayList();
159: int rows = table.size() + 1;
160: float[] offsets = new float[rows];
161: for (int i = 0; i < rows; i++) {
162: offsets[i] = getBottom();
163: }
164:
165: // loop over all the rows
166: for (Iterator rowIterator = table.iterator(); rowIterator
167: .hasNext();) {
168: groupChange = false;
169: row = (Row) rowIterator.next();
170: if (row.isEmpty()) {
171: if (rowNumber < rows - 1
172: && offsets[rowNumber + 1] > offsets[rowNumber])
173: offsets[rowNumber + 1] = offsets[rowNumber];
174: } else {
175: for (int i = 0; i < row.getColumns(); i++) {
176: cell = (Cell) row.getCell(i);
177: if (cell != null) {
178: currentCell = new PdfCell(cell, rowNumber
179: + prevRows, positions[i], positions[i
180: + cell.getColspan()],
181: offsets[rowNumber], cellspacing(),
182: cellpadding());
183: try {
184: if (offsets[rowNumber]
185: - currentCell.getHeight()
186: - cellpadding() < offsets[rowNumber
187: + currentCell.rowspan()]) {
188: offsets[rowNumber
189: + currentCell.rowspan()] = offsets[rowNumber]
190: - currentCell.getHeight()
191: - cellpadding();
192: }
193: } catch (ArrayIndexOutOfBoundsException aioobe) {
194: if (offsets[rowNumber]
195: - currentCell.getHeight() < offsets[rows - 1]) {
196: offsets[rows - 1] = offsets[rowNumber]
197: - currentCell.getHeight();
198: }
199: }
200: if (rowNumber < firstDataRow) {
201: currentCell.setHeader();
202: headercells.add(currentCell);
203: }
204: currentCell.setGroupNumber(groupNumber);
205: groupChange |= cell.getGroupChange();
206: newCells.add(currentCell);
207: }
208: }
209: }
210: rowNumber++;
211: if (groupChange)
212: groupNumber++;
213: }
214:
215: // loop over all the cells
216: int n = newCells.size();
217: for (int i = 0; i < n; i++) {
218: currentCell = (PdfCell) newCells.get(i);
219: try {
220: currentCell.setBottom(offsets[currentCell.rownumber()
221: - prevRows + currentCell.rowspan()]);
222: } catch (ArrayIndexOutOfBoundsException aioobe) {
223: currentCell.setBottom(offsets[rows - 1]);
224: }
225: }
226: cells.addAll(newCells);
227: setBottom(offsets[rows - 1]);
228: }
229:
230: /**
231: * Get the number of rows
232: */
233:
234: int rows() {
235: return cells.isEmpty() ? 0 : ((PdfCell) cells
236: .get(cells.size() - 1)).rownumber() + 1;
237: }
238:
239: /** @see com.lowagie.text.Element#type() */
240: public int type() {
241: return Element.TABLE;
242: }
243:
244: /**
245: * Returns the arraylist with the cells of the table header.
246: *
247: * @return an <CODE>ArrayList</CODE>
248: */
249:
250: ArrayList getHeaderCells() {
251: return headercells;
252: }
253:
254: /**
255: * Checks if there is a table header.
256: *
257: * @return an <CODE>ArrayList</CODE>
258: */
259:
260: boolean hasHeader() {
261: return !headercells.isEmpty();
262: }
263:
264: /**
265: * Returns the arraylist with the cells of the table.
266: *
267: * @return an <CODE>ArrayList</CODE>
268: */
269:
270: ArrayList getCells() {
271: return cells;
272: }
273:
274: /**
275: * Returns the number of columns of the table.
276: *
277: * @return the number of columns
278: */
279:
280: int columns() {
281: return columns;
282: }
283:
284: /**
285: * Returns the cellpadding of the table.
286: *
287: * @return the cellpadding
288: */
289:
290: final float cellpadding() {
291: return table.getPadding();
292: }
293:
294: /**
295: * Returns the cellspacing of the table.
296: *
297: * @return the cellspacing
298: */
299:
300: final float cellspacing() {
301: return table.getSpacing();
302: }
303:
304: /**
305: * Checks if this <CODE>Table</CODE> has to fit a page.
306: *
307: * @return true if the table may not be split
308: */
309:
310: public final boolean hasToFitPageTable() {
311: return table.isTableFitsPage();
312: }
313:
314: /**
315: * Checks if the cells of this <CODE>Table</CODE> have to fit a page.
316: *
317: * @return true if the cells may not be split
318: */
319:
320: public final boolean hasToFitPageCells() {
321: return table.isCellsFitPage();
322: }
323:
324: /**
325: * Gets the offset of this table.
326: *
327: * @return the space between this table and the previous element.
328: */
329: public float getOffset() {
330: return table.getOffset();
331: }
332: }
|