KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > lowagie > text > pdf > PdfPTable


1 /*
2  * $Id: PdfPTable.java 2742 2007-05-08 13:04:56Z blowagie $
3  * $Name$
4  *
5  * Copyright 2001, 2002 Paulo Soares
6  *
7  * The contents of this file are subject to the Mozilla Public License Version 1.1
8  * (the "License"); you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the License.
14  *
15  * The Original Code is 'iText, a free JAVA-PDF library'.
16  *
17  * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
18  * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
19  * All Rights Reserved.
20  * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
21  * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
22  *
23  * Contributor(s): all the names of the contributors are added in the source code
24  * where applicable.
25  *
26  * Alternatively, the contents of this file may be used under the terms of the
27  * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
28  * provisions of LGPL are applicable instead of those above. If you wish to
29  * allow use of your version of this file only under the terms of the LGPL
30  * License and not to allow others to use your version of this file under
31  * the MPL, indicate your decision by deleting the provisions above and
32  * replace them with the notice and other provisions required by the LGPL.
33  * If you do not delete the provisions above, a recipient may use your version
34  * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
35  *
36  * This library is free software; you can redistribute it and/or modify it
37  * under the terms of the MPL as stated above or under the terms of the GNU
38  * Library General Public License as published by the Free Software Foundation;
39  * either version 2 of the License, or any later version.
40  *
41  * This library is distributed in the hope that it will be useful, but WITHOUT
42  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
43  * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
44  * details.
45  *
46  * If you didn't download this code from the following link, you should check if
47  * you aren't using an obsolete version:
48  * http://www.lowagie.com/iText/
49  */

50
51 package com.lowagie.text.pdf;
52
53 import java.util.ArrayList JavaDoc;
54
55 import com.lowagie.text.DocumentException;
56 import com.lowagie.text.Element;
57 import com.lowagie.text.ElementListener;
58 import com.lowagie.text.Image;
59 import com.lowagie.text.Phrase;
60 import com.lowagie.text.Rectangle;
61 import com.lowagie.text.pdf.events.PdfPTableEventForwarder;
62
63 /** This is a table that can be put at an absolute position but can also
64  * be added to the document as the class <CODE>Table</CODE>.
65  * In the last case when crossing pages the table always break at full rows; if a
66  * row is bigger than the page it is dropped silently to avoid infinite loops.
67  * <P>
68  * A PdfPTableEvent can be associated to the table to do custom drawing
69  * when the table is rendered.
70  * @author Paulo Soares (psoares@consiste.pt)
71  */

72
73 public class PdfPTable implements Element{
74     
75     /** The index of the original <CODE>PdfcontentByte</CODE>.
76      */

77     public static final int BASECANVAS = 0;
78     /** The index of the duplicate <CODE>PdfContentByte</CODE> where the background will be drawn.
79      */

80     public static final int BACKGROUNDCANVAS = 1;
81     /** The index of the duplicate <CODE>PdfContentByte</CODE> where the border lines will be drawn.
82      */

83     public static final int LINECANVAS = 2;
84     /** The index of the duplicate <CODE>PdfContentByte</CODE> where the text will be drawn.
85      */

86     public static final int TEXTCANVAS = 3;
87     
88     protected ArrayList JavaDoc rows = new ArrayList JavaDoc();
89     protected float totalHeight = 0;
90     protected PdfPCell currentRow[];
91     protected int currentRowIdx = 0;
92     protected PdfPCell defaultCell = new PdfPCell((Phrase)null);
93     protected float totalWidth = 0;
94     protected float relativeWidths[];
95     protected float absoluteWidths[];
96     protected PdfPTableEvent tableEvent;
97     
98 /** Holds value of property headerRows. */
99     protected int headerRows;
100     
101 /** Holds value of property widthPercentage. */
102     protected float widthPercentage = 80;
103     
104 /** Holds value of property horizontalAlignment. */
105     private int horizontalAlignment = Element.ALIGN_CENTER;
106     
107 /** Holds value of property skipFirstHeader. */
108     private boolean skipFirstHeader = false;
109
110     protected boolean isColspan = false;
111     
112     protected int runDirection = PdfWriter.RUN_DIRECTION_DEFAULT;
113
114     /**
115      * Holds value of property lockedWidth.
116      */

117     private boolean lockedWidth = false;
118     
119     /**
120      * Holds value of property splitRows.
121      */

122     private boolean splitRows = true;
123     
124 /** The spacing before the table. */
125     protected float spacingBefore;
126     
127 /** The spacing after the table. */
128     protected float spacingAfter;
129     
130     /**
131      * Holds value of property extendLastRow.
132      */

133     private boolean extendLastRow;
134     
135     /**
136      * Holds value of property headersInEvent.
137      */

138     private boolean headersInEvent;
139     
140     /**
141      * Holds value of property splitLate.
142      */

143     private boolean splitLate = true;
144     
145     /**
146      * Defines if the table should be kept
147      * on one page if possible
148      */

149     private boolean keepTogether;
150     
151     /**
152      * Holds value of property footerRows.
153      */

154     private int footerRows;
155     
156     protected PdfPTable() {
157     }
158     
159     /** Constructs a <CODE>PdfPTable</CODE> with the relative column widths.
160      * @param relativeWidths the relative column widths
161      */

162     public PdfPTable(float relativeWidths[]) {
163         if (relativeWidths == null)
164             throw new NullPointerException JavaDoc("The widths array in PdfPTable constructor can not be null.");
165         if (relativeWidths.length == 0)
166             throw new IllegalArgumentException JavaDoc("The widths array in PdfPTable constructor can not have zero length.");
167         this.relativeWidths = new float[relativeWidths.length];
168         System.arraycopy(relativeWidths, 0, this.relativeWidths, 0, relativeWidths.length);
169         absoluteWidths = new float[relativeWidths.length];
170         calculateWidths();
171         currentRow = new PdfPCell[absoluteWidths.length];
172         keepTogether = false;
173     }
174     
175     /** Constructs a <CODE>PdfPTable</CODE> with <CODE>numColumns</CODE> columns.
176      * @param numColumns the number of columns
177      */

178     public PdfPTable(int numColumns) {
179         if (numColumns <= 0)
180             throw new IllegalArgumentException JavaDoc("The number of columns in PdfPTable constructor must be greater than zero.");
181         relativeWidths = new float[numColumns];
182         for (int k = 0; k < numColumns; ++k)
183             relativeWidths[k] = 1;
184         absoluteWidths = new float[relativeWidths.length];
185         calculateWidths();
186         currentRow = new PdfPCell[absoluteWidths.length];
187         keepTogether = false;
188     }
189     
190     /** Constructs a copy of a <CODE>PdfPTable</CODE>.
191      * @param table the <CODE>PdfPTable</CODE> to be copied
192      */

193     public PdfPTable(PdfPTable table) {
194         copyFormat(table);
195         for (int k = 0; k < currentRow.length; ++k) {
196             if (table.currentRow[k] == null)
197                 break;
198             currentRow[k] = new PdfPCell(table.currentRow[k]);
199         }
200         for (int k = 0; k < table.rows.size(); ++k) {
201             PdfPRow row = (PdfPRow)(table.rows.get(k));
202             if (row != null)
203                 row = new PdfPRow(row);
204             rows.add(row);
205         }
206     }
207     
208     /**
209      * Makes a shallow copy of a table (format without content).
210      * @param table
211      * @return a shallow copy of the table
212      */

213     public static PdfPTable shallowCopy(PdfPTable table) {
214         PdfPTable nt = new PdfPTable();
215         nt.copyFormat(table);
216         return nt;
217     }
218
219     /**
220      * Copies the format of the sourceTable without copying the content.
221      * @param sourceTable
222      */

223     private void copyFormat(PdfPTable sourceTable) {
224         relativeWidths = new float[sourceTable.relativeWidths.length];
225         absoluteWidths = new float[sourceTable.relativeWidths.length];
226         System.arraycopy(sourceTable.relativeWidths, 0, relativeWidths, 0, relativeWidths.length);
227         System.arraycopy(sourceTable.absoluteWidths, 0, absoluteWidths, 0, relativeWidths.length);
228         totalWidth = sourceTable.totalWidth;
229         totalHeight = sourceTable.totalHeight;
230         currentRowIdx = 0;
231         tableEvent = sourceTable.tableEvent;
232         runDirection = sourceTable.runDirection;
233         defaultCell = new PdfPCell(sourceTable.defaultCell);
234         currentRow = new PdfPCell[sourceTable.currentRow.length];
235         isColspan = sourceTable.isColspan;
236         splitRows = sourceTable.splitRows;
237         spacingAfter = sourceTable.spacingAfter;
238         spacingBefore = sourceTable.spacingBefore;
239         headerRows = sourceTable.headerRows;
240         footerRows = sourceTable.footerRows;
241         lockedWidth = sourceTable.lockedWidth;
242         extendLastRow = sourceTable.extendLastRow;
243         headersInEvent = sourceTable.headersInEvent;
244         widthPercentage = sourceTable.widthPercentage;
245         splitLate = sourceTable.splitLate;
246         skipFirstHeader = sourceTable.skipFirstHeader;
247         horizontalAlignment = sourceTable.horizontalAlignment;
248         keepTogether = sourceTable.keepTogether;
249     }
250
251     /** Sets the relative widths of the table.
252      * @param relativeWidths the relative widths of the table.
253      * @throws DocumentException if the number of widths is different than the number
254      * of columns
255      */

256     public void setWidths(float relativeWidths[]) throws DocumentException {
257         if (relativeWidths.length != this.relativeWidths.length)
258             throw new DocumentException("Wrong number of columns.");
259         this.relativeWidths = new float[relativeWidths.length];
260         System.arraycopy(relativeWidths, 0, this.relativeWidths, 0, relativeWidths.length);
261         absoluteWidths = new float[relativeWidths.length];
262         totalHeight = 0;
263         calculateWidths();
264         calculateHeights();
265     }
266
267     /** Sets the relative widths of the table.
268      * @param relativeWidths the relative widths of the table.
269      * @throws DocumentException if the number of widths is different than the number
270      * of columns
271      */

272     public void setWidths(int relativeWidths[]) throws DocumentException {
273         float tb[] = new float[relativeWidths.length];
274         for (int k = 0; k < relativeWidths.length; ++k)
275             tb[k] = relativeWidths[k];
276         setWidths(tb);
277     }
278
279     private void calculateWidths() {
280         if (totalWidth <= 0)
281             return;
282         float total = 0;
283         for (int k = 0; k < absoluteWidths.length; ++k) {
284             total += relativeWidths[k];
285         }
286         for (int k = 0; k < absoluteWidths.length; ++k) {
287             absoluteWidths[k] = totalWidth * relativeWidths[k] / total;
288         }
289     }
290     
291     /** Sets the full width of the table.
292      * @param totalWidth the full width of the table.
293      */

294     public void setTotalWidth(float totalWidth) {
295         if (this.totalWidth == totalWidth)
296             return;
297         this.totalWidth = totalWidth;
298         totalHeight = 0;
299         calculateWidths();
300         calculateHeights();
301     }
302
303     /** Sets the full width of the table from the absolute column width.
304      * @param columnWidth the absolute width of each column
305      * @throws DocumentException if the number of widths is different than the number
306      * of columns
307      */

308     public void setTotalWidth(float columnWidth[]) throws DocumentException {
309         if (columnWidth.length != this.relativeWidths.length)
310             throw new DocumentException("Wrong number of columns.");
311         totalWidth = 0;
312         for (int k = 0; k < columnWidth.length; ++k)
313             totalWidth += columnWidth[k];
314         setWidths(columnWidth);
315     }
316
317     /** Sets the percentage width of the table from the absolute column width.
318      * @param columnWidth the absolute width of each column
319      * @param pageSize the page size
320      * @throws DocumentException
321      */

322     public void setWidthPercentage(float columnWidth[], Rectangle pageSize) throws DocumentException {
323         if (columnWidth.length != this.relativeWidths.length)
324             throw new IllegalArgumentException JavaDoc("Wrong number of columns.");
325         float totalWidth = 0;
326         for (int k = 0; k < columnWidth.length; ++k)
327             totalWidth += columnWidth[k];
328         widthPercentage = totalWidth / (pageSize.getRight() - pageSize.getLeft()) * 100f;
329         setWidths(columnWidth);
330     }
331
332     /** Gets the full width of the table.
333      * @return the full width of the table
334      */

335     public float getTotalWidth() {
336         return totalWidth;
337     }
338
339     void calculateHeights() {
340         if (totalWidth <= 0)
341             return;
342         totalHeight = 0;
343         for (int k = 0; k < rows.size(); ++k) {
344             PdfPRow row = (PdfPRow)rows.get(k);
345             if (row != null) {
346                 row.setWidths(absoluteWidths);
347                 totalHeight += row.getMaxHeights();
348             }
349         }
350     }
351     
352     /**
353      * Calculates the heights of the table.
354      */

355     public void calculateHeightsFast() {
356         if (totalWidth <= 0)
357             return;
358         totalHeight = 0;
359         for (int k = 0; k < rows.size(); ++k) {
360             PdfPRow row = (PdfPRow)rows.get(k);
361             if (row != null)
362                 totalHeight += row.getMaxHeights();
363         }
364     }
365     
366     /** Gets the default <CODE>PdfPCell</CODE> that will be used as
367      * reference for all the <CODE>addCell</CODE> methods except
368      * <CODE>addCell(PdfPCell)</CODE>.
369      * @return default <CODE>PdfPCell</CODE>
370      */

371     public PdfPCell getDefaultCell() {
372         return defaultCell;
373     }
374     
375     /** Adds a cell element.
376      * @param cell the cell element
377      */

378     public void addCell(PdfPCell cell) {
379         PdfPCell ncell = new PdfPCell(cell);
380         int colspan = ncell.getColspan();
381         colspan = Math.max(colspan, 1);
382         colspan = Math.min(colspan, currentRow.length - currentRowIdx);
383         ncell.setColspan(colspan);
384         if (colspan != 1)
385             isColspan = true;
386         int rdir = ncell.getRunDirection();
387         if (rdir == PdfWriter.RUN_DIRECTION_DEFAULT)
388             ncell.setRunDirection(runDirection);
389         currentRow[currentRowIdx] = ncell;
390         currentRowIdx += colspan;
391         if (currentRowIdx >= currentRow.length) {
392             if (runDirection == PdfWriter.RUN_DIRECTION_RTL) {
393                 PdfPCell rtlRow[] = new PdfPCell[absoluteWidths.length];
394                 int rev = currentRow.length;
395                 for (int k = 0; k < currentRow.length; ++k) {
396                     PdfPCell rcell = currentRow[k];
397                     int cspan = rcell.getColspan();
398                     rev -= cspan;
399                     rtlRow[rev] = rcell;
400                     k += cspan - 1;
401                 }
402                 currentRow = rtlRow;
403             }
404             PdfPRow row = new PdfPRow(currentRow);
405             if (totalWidth > 0) {
406                 row.setWidths(absoluteWidths);
407                 totalHeight += row.getMaxHeights();
408             }
409             rows.add(row);
410             currentRow = new PdfPCell[absoluteWidths.length];
411             currentRowIdx = 0;
412         }
413     }
414     
415     /** Adds a cell element.
416      * @param text the text for the cell
417      */

418     public void addCell(String JavaDoc text) {
419         addCell(new Phrase(text));
420     }
421     
422     /**
423      * Adds a nested table.
424      * @param table the table to be added to the cell
425      */

426     public void addCell(PdfPTable table) {
427         defaultCell.setTable(table);
428         addCell(defaultCell);
429         defaultCell.setTable(null);
430     }
431     
432     /**
433      * Adds an Image as Cell.
434      * @param image the <CODE>Image</CODE> to add to the table. This image will fit in the cell
435      */

436     public void addCell(Image image) {
437         defaultCell.setImage(image);
438         addCell(defaultCell);
439         defaultCell.setImage(null);
440     }
441     
442     /**
443      * Adds a cell element.
444      * @param phrase the <CODE>Phrase</CODE> to be added to the cell
445      */

446     public void addCell(Phrase phrase) {
447         defaultCell.setPhrase(phrase);
448         addCell(defaultCell);
449         defaultCell.setPhrase(null);
450     }
451     
452     /**
453      * Writes the selected rows to the document.
454      * <P>
455      * <CODE>canvases</CODE> is obtained from <CODE>beginWritingRows()</CODE>.
456      * @param rowStart the first row to be written, zero index
457      * @param rowEnd the last row to be written + 1. If it is -1 all the
458      * rows to the end are written
459      * @param xPos the x write coodinate
460      * @param yPos the y write coodinate
461      * @param canvases an array of 4 <CODE>PdfContentByte</CODE> obtained from
462      * <CODE>beginWrittingRows()</CODE>
463      * @return the y coordinate position of the bottom of the last row
464      * @see #beginWritingRows(com.lowagie.text.pdf.PdfContentByte)
465      */

466     public float writeSelectedRows(int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte[] canvases) {
467         return writeSelectedRows(0, -1, rowStart, rowEnd, xPos, yPos, canvases);
468     }
469     
470     /** Writes the selected rows and columns to the document.
471      * This method does not clip the columns; this is only important
472      * if there are columns with colspan at boundaries.
473      * <P>
474      * <CODE>canvases</CODE> is obtained from <CODE>beginWritingRows()</CODE>.
475      * <P>
476      * The table event is only fired for complete rows.
477      * @param colStart the first column to be written, zero index
478      * @param colEnd the last column to be written + 1. If it is -1 all the
479      * columns to the end are written
480      * @param rowStart the first row to be written, zero index
481      * @param rowEnd the last row to be written + 1. If it is -1 all the
482      * rows to the end are written
483      * @param xPos the x write coodinate
484      * @param yPos the y write coodinate
485      * @param canvases an array of 4 <CODE>PdfContentByte</CODE> obtained from
486      * <CODE>beginWrittingRows()</CODE>
487      * @return the y coordinate position of the bottom of the last row
488      * @see #beginWritingRows(com.lowagie.text.pdf.PdfContentByte)
489      */

490     public float writeSelectedRows(int colStart, int colEnd, int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte[] canvases) {
491         if (totalWidth <= 0)
492             throw new RuntimeException JavaDoc("The table width must be greater than zero.");
493         int size = rows.size();
494         if (rowEnd < 0)
495             rowEnd = size;
496         rowEnd = Math.min(rowEnd, size);
497         if (rowStart < 0)
498             rowStart = 0;
499         if (rowStart >= rowEnd)
500             return yPos;
501         if (colEnd < 0)
502             colEnd = absoluteWidths.length;
503         colEnd = Math.min(colEnd, absoluteWidths.length);
504         if (colStart < 0)
505             colStart = 0;
506         colStart = Math.min(colStart, absoluteWidths.length);
507         float yPosStart = yPos;
508         for (int k = rowStart; k < rowEnd; ++k) {
509             PdfPRow row = (PdfPRow)rows.get(k);
510             if (row != null) {
511                 row.writeCells(colStart, colEnd, xPos, yPos, canvases);
512                 yPos -= row.getMaxHeights();
513             }
514         }
515         if (tableEvent != null && colStart == 0 && colEnd == absoluteWidths.length) {
516             float heights[] = new float[rowEnd - rowStart + 1];
517             heights[0] = yPosStart;
518             for (int k = rowStart; k < rowEnd; ++k) {
519                 PdfPRow row = (PdfPRow)rows.get(k);
520                 float hr = 0;
521                 if (row != null)
522                     hr = row.getMaxHeights();
523                 heights[k - rowStart + 1] = heights[k - rowStart] - hr;
524             }
525             tableEvent.tableLayout(this, getEventWidths(xPos, rowStart, rowEnd, headersInEvent), heights, headersInEvent ? headerRows : 0, rowStart, canvases);
526         }
527         return yPos;
528     }
529     
530     /**
531      * Writes the selected rows to the document.
532      *
533      * @param rowStart the first row to be written, zero index
534      * @param rowEnd the last row to be written + 1. If it is -1 all the
535      * rows to the end are written
536      * @param xPos the x write coodinate
537      * @param yPos the y write coodinate
538      * @param canvas the <CODE>PdfContentByte</CODE> where the rows will
539      * be written to
540      * @return the y coordinate position of the bottom of the last row
541      */

542     public float writeSelectedRows(int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte canvas) {
543         return writeSelectedRows(0, -1, rowStart, rowEnd, xPos, yPos, canvas);
544     }
545     
546     /**
547      * Writes the selected rows to the document.
548      * This method clips the columns; this is only important
549      * if there are columns with colspan at boundaries.
550      * <P>
551      * The table event is only fired for complete rows.
552      *
553      * @param colStart the first column to be written, zero index
554      * @param colEnd the last column to be written + 1. If it is -1 all the
555      * @param rowStart the first row to be written, zero index
556      * @param rowEnd the last row to be written + 1. If it is -1 all the
557      * rows to the end are written
558      * @param xPos the x write coodinate
559      * @param yPos the y write coodinate
560      * @param canvas the <CODE>PdfContentByte</CODE> where the rows will
561      * be written to
562      * @return the y coordinate position of the bottom of the last row
563      */

564     public float writeSelectedRows(int colStart, int colEnd, int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte canvas) {
565         if (colEnd < 0)
566             colEnd = absoluteWidths.length;
567         colEnd = Math.min(colEnd, absoluteWidths.length);
568         if (colStart < 0)
569             colStart = 0;
570         colStart = Math.min(colStart, absoluteWidths.length);
571         if (colStart != 0 || colEnd != absoluteWidths.length) {
572             float w = 0;
573             for (int k = colStart; k < colEnd; ++k)
574                 w += absoluteWidths[k];
575             canvas.saveState();
576             float lx = 0;
577             float rx = 0;
578             if (colStart == 0)
579                 lx = 10000;
580             if (colEnd == absoluteWidths.length)
581                 rx = 10000;
582             canvas.rectangle(xPos - lx, -10000, w + lx + rx, 20000);
583             canvas.clip();
584             canvas.newPath();
585         }
586         PdfContentByte[] canvases = beginWritingRows(canvas);
587         float y = writeSelectedRows(colStart, colEnd, rowStart, rowEnd, xPos, yPos, canvases);
588         endWritingRows(canvases);
589         if (colStart != 0 || colEnd != absoluteWidths.length)
590             canvas.restoreState();
591         return y;
592     }
593     
594     /** Gets and initializes the 4 layers where the table is written to. The text or graphics are added to
595      * one of the 4 <CODE>PdfContentByte</CODE> returned with the following order:<p>
596      * <ul>
597      * <li><CODE>PdfPtable.BASECANVAS</CODE> - the original <CODE>PdfContentByte</CODE>. Anything placed here
598      * will be under the table.
599      * <li><CODE>PdfPtable.BACKGROUNDCANVAS</CODE> - the layer where the background goes to.
600      * <li><CODE>PdfPtable.LINECANVAS</CODE> - the layer where the lines go to.
601      * <li><CODE>PdfPtable.TEXTCANVAS</CODE> - the layer where the text go to. Anything placed here
602      * will be over the table.
603      * </ul><p>
604      * The layers are placed in sequence on top of each other.
605      * @param canvas the <CODE>PdfContentByte</CODE> where the rows will
606      * be written to
607      * @return an array of 4 <CODE>PdfContentByte</CODE>
608      * @see #writeSelectedRows(int, int, float, float, PdfContentByte[])
609      */

610     public static PdfContentByte[] beginWritingRows(PdfContentByte canvas) {
611         return new PdfContentByte[]{
612             canvas,
613             canvas.getDuplicate(),
614             canvas.getDuplicate(),
615             canvas.getDuplicate(),
616         };
617     }
618     
619     /** Finishes writing the table.
620      * @param canvases the array returned by <CODE>beginWritingRows()</CODE>
621      */

622     public static void endWritingRows(PdfContentByte[] canvases) {
623         PdfContentByte canvas = canvases[BASECANVAS];
624         canvas.saveState();
625         canvas.add(canvases[BACKGROUNDCANVAS]);
626         canvas.restoreState();
627         canvas.saveState();
628         canvas.setLineCap(2);
629         canvas.resetRGBColorStroke();
630         canvas.add(canvases[LINECANVAS]);
631         canvas.restoreState();
632         canvas.add(canvases[TEXTCANVAS]);
633     }
634     
635     /** Gets the number of rows in this table.
636      * @return the number of rows in this table
637      */

638     public int size() {
639         return rows.size();
640     }
641     
642     /** Gets the total height of the table.
643      * @return the total height of the table
644      */

645     public float getTotalHeight() {
646         return totalHeight;
647     }
648     
649     /** Gets the height of a particular row.
650      * @param idx the row index (starts at 0)
651      * @return the height of a particular row
652      */

653     public float getRowHeight(int idx) {
654         if (totalWidth <= 0 || idx < 0 || idx >= rows.size())
655             return 0;
656         PdfPRow row = (PdfPRow)rows.get(idx);
657         if (row == null)
658             return 0;
659         return row.getMaxHeights();
660     }
661     
662     /** Gets the height of the rows that constitute the header as defined by
663      * <CODE>setHeaderRows()</CODE>.
664      * @return the height of the rows that constitute the header
665      */

666     public float getHeaderHeight() {
667         float total = 0;
668         int size = Math.min(rows.size(), headerRows);
669         for (int k = 0; k < size; ++k) {
670             PdfPRow row = (PdfPRow)rows.get(k);
671             if (row != null)
672                 total += row.getMaxHeights();
673         }
674         return total;
675     }
676     
677     /** Deletes a row from the table.
678      * @param rowNumber the row to be deleted
679      * @return <CODE>true</CODE> if the row was deleted
680      */

681     public boolean deleteRow(int rowNumber) {
682         if (rowNumber < 0 || rowNumber >= rows.size()) {
683             return false;
684         }
685         if (totalWidth > 0) {
686             PdfPRow row = (PdfPRow)rows.get(rowNumber);
687             if (row != null)
688                 totalHeight -= row.getMaxHeights();
689         }
690         rows.remove(rowNumber);
691         return true;
692     }
693     
694     /** Deletes the last row in the table.
695      * @return <CODE>true</CODE> if the last row was deleted
696      */

697     public boolean deleteLastRow() {
698         return deleteRow(rows.size() - 1);
699     }
700     
701     /**
702      * Removes all of the rows except headers
703      */

704     public void deleteBodyRows() {
705         ArrayList JavaDoc rows2 = new ArrayList JavaDoc();
706         for (int k = 0; k < headerRows; ++k)
707             rows2.add(rows.get(k));
708         rows = rows2;
709         totalHeight = 0;
710         if (totalWidth > 0)
711             totalHeight = getHeaderHeight();
712     }
713
714     /** Gets the number of the rows that constitute the header.
715      * @return the number of the rows that constitute the header
716      */

717     public int getHeaderRows() {
718         return headerRows;
719     }
720     
721     /** Sets the number of the top rows that constitute the header.
722      * This header has only meaning if the table is added to <CODE>Document</CODE>
723      * and the table crosses pages.
724      * @param headerRows the number of the top rows that constitute the header
725      */

726     public void setHeaderRows(int headerRows) {
727         if (headerRows < 0)
728             headerRows = 0;
729         this.headerRows = headerRows;
730     }
731     
732     /**
733      * Gets all the chunks in this element.
734      *
735      * @return an <CODE>ArrayList</CODE>
736      */

737     public ArrayList JavaDoc getChunks() {
738         return new ArrayList JavaDoc();
739     }
740     
741     /**
742      * Gets the type of the text element.
743      *
744      * @return a type
745      */

746     public int type() {
747         return Element.PTABLE;
748     }
749     
750     /**
751      * Processes the element by adding it (or the different parts) to an
752      * <CODE>ElementListener</CODE>.
753      *
754      * @param listener an <CODE>ElementListener</CODE>
755      * @return <CODE>true</CODE> if the element was processed successfully
756      */

757     public boolean process(ElementListener listener) {
758         try {
759             return listener.add(this);
760         }
761         catch(DocumentException de) {
762             return false;
763         }
764     }
765     
766     /** Gets the width percentage that the table will occupy in the page.
767      * @return the width percentage that the table will occupy in the page
768      */

769     public float getWidthPercentage() {
770         return widthPercentage;
771     }
772     
773     /** Sets the width percentage that the table will occupy in the page.
774      * @param widthPercentage the width percentage that the table will occupy in the page
775      */

776     public void setWidthPercentage(float widthPercentage) {
777         this.widthPercentage = widthPercentage;
778     }
779     
780     /** Gets the horizontal alignment of the table relative to the page.
781      * @return the horizontal alignment of the table relative to the page
782      */

783     public int getHorizontalAlignment() {
784         return horizontalAlignment;
785     }
786     
787     /** Sets the horizontal alignment of the table relative to the page.
788      * It only has meaning if the width percentage is less than
789      * 100%.
790      * @param horizontalAlignment the horizontal alignment of the table relative to the page
791      */

792     public void setHorizontalAlignment(int horizontalAlignment) {
793         this.horizontalAlignment = horizontalAlignment;
794     }
795     
796     /**
797      * Gets a row with a given index
798      * (added by Jin-Hsia Yang).
799      * @param idx
800      * @return the row at position idx
801      */

802     public PdfPRow getRow(int idx) {
803         return (PdfPRow)rows.get(idx);
804     }
805
806     /**
807      * Gets an arraylist with all the rows in the table.
808      * @return an arraylist
809      */

810     public ArrayList JavaDoc getRows() {
811         return rows;
812     }
813
814     /** Sets the table event for this table.
815      * @param event the table event for this table
816      */

817     public void setTableEvent(PdfPTableEvent event) {
818         if (event == null) this.tableEvent = null;
819         else if (this.tableEvent == null) this.tableEvent = event;
820         else if (this.tableEvent instanceof PdfPTableEventForwarder) ((PdfPTableEventForwarder)this.tableEvent).addTableEvent(event);
821         else {
822             PdfPTableEventForwarder forward = new PdfPTableEventForwarder();
823             forward.addTableEvent(this.tableEvent);
824             forward.addTableEvent(event);
825             this.tableEvent = forward;
826         }
827     }
828     
829     /** Gets the table event for this page.
830      * @return the table event for this page
831      */

832     public PdfPTableEvent getTableEvent() {
833         return tableEvent;
834     }
835     
836     /** Gets the absolute sizes of each column width.
837      * @return he absolute sizes of each column width
838      */

839     public float[] getAbsoluteWidths() {
840         return absoluteWidths;
841     }
842     
843     float [][] getEventWidths(float xPos, int firstRow, int lastRow, boolean includeHeaders) {
844         if (includeHeaders) {
845             firstRow = Math.max(firstRow, headerRows);
846             lastRow = Math.max(lastRow, headerRows);
847         }
848         float widths[][] = new float[(includeHeaders ? headerRows : 0) + lastRow - firstRow][];
849         if (isColspan) {
850             int n = 0;
851             if (includeHeaders) {
852                 for (int k = 0; k < headerRows; ++k) {
853                     PdfPRow row = (PdfPRow)rows.get(k);
854                     if (row == null)
855                         ++n;
856                     else
857                         widths[n++] = row.getEventWidth(xPos);
858                 }
859             }
860             for (; firstRow < lastRow; ++firstRow) {
861                     PdfPRow row = (PdfPRow)rows.get(firstRow);
862                     if (row == null)
863                         ++n;
864                     else
865                         widths[n++] = row.getEventWidth(xPos);
866             }
867         }
868         else {
869             float width[] = new float[absoluteWidths.length + 1];
870             width[0] = xPos;
871             for (int k = 0; k < absoluteWidths.length; ++k)
872                 width[k + 1] = width[k] + absoluteWidths[k];
873             for (int k = 0; k < widths.length; ++k)
874                 widths[k] = width;
875         }
876         return widths;
877     }
878
879
880     /** Getter for property skipFirstHeader.
881      * @return Value of property skipFirstHeader.
882      */

883     public boolean isSkipFirstHeader() {
884         return skipFirstHeader;
885     }
886     
887     /** Skips the printing of the first header. Used when printing
888      * tables in succession belonging to the same printed table aspect.
889      * @param skipFirstHeader New value of property skipFirstHeader.
890      */

891     public void setSkipFirstHeader(boolean skipFirstHeader) {
892         this.skipFirstHeader = skipFirstHeader;
893     }
894
895     /**
896      * Sets the run direction of the contents of the table.
897      * @param runDirection
898      */

899     public void setRunDirection(int runDirection) {
900         if (runDirection < PdfWriter.RUN_DIRECTION_DEFAULT || runDirection > PdfWriter.RUN_DIRECTION_RTL)
901             throw new RuntimeException JavaDoc("Invalid run direction: " + runDirection);
902         this.runDirection = runDirection;
903     }
904     
905     /**
906      * Returns the run direction of the contents in the table.
907      * @return One of the following values: PdfWriter.RUN_DIRECTION_DEFAULT, PdfWriter.RUN_DIRECTION_NO_BIDI, PdfWriter.RUN_DIRECTION_LTR or PdfWriter.RUN_DIRECTION_RTL.
908      */

909     public int getRunDirection() {
910         return runDirection;
911     }
912     
913     /**
914      * Getter for property lockedWidth.
915      * @return Value of property lockedWidth.
916      */

917     public boolean isLockedWidth() {
918         return this.lockedWidth;
919     }
920     
921     /**
922      * Uses the value in <CODE>setTotalWidth()</CODE> in <CODE>Document.add()</CODE>.
923      * @param lockedWidth <CODE>true</CODE> to use the value in <CODE>setTotalWidth()</CODE> in <CODE>Document.add()</CODE>
924      */

925     public void setLockedWidth(boolean lockedWidth) {
926         this.lockedWidth = lockedWidth;
927     }
928     
929     /**
930      * Gets the split value.
931      * @return true to split; false otherwise
932      */

933     public boolean isSplitRows() {
934         return this.splitRows;
935     }
936     
937     /**
938      * When set the rows that won't fit in the page will be split.
939      * Note that it takes at least twice the memory to handle a split table row
940      * than a normal table. <CODE>true</CODE> by default.
941      * @param splitRows true to split; false otherwise
942      */

943     public void setSplitRows(boolean splitRows) {
944         this.splitRows = splitRows;
945     }
946     
947 /**
948  * Sets the spacing before this table.
949  *
950  * @param spacing the new spacing
951  */

952     
953     public void setSpacingBefore(float spacing) {
954         this.spacingBefore = spacing;
955     }
956     
957 /**
958  * Sets the spacing after this table.
959  *
960  * @param spacing the new spacing
961  */

962     
963     public void setSpacingAfter(float spacing) {
964         this.spacingAfter = spacing;
965     }
966
967 /**
968  * Gets the spacing before this table.
969  *
970  * @return the spacing
971  */

972     
973     public float spacingBefore() {
974         return spacingBefore;
975     }
976     
977 /**
978  * Gets the spacing before this table.
979  *
980  * @return the spacing
981  */

982     
983     public float spacingAfter() {
984         return spacingAfter;
985     }
986     
987     /**
988      * Gets the value of the last row extension.
989      * @return true if the last row will extend; false otherwise
990      */

991     public boolean isExtendLastRow() {
992         return this.extendLastRow;
993     }
994     
995     /**
996      * When set the last row will be extended to fill all the remaining space to the
997      * bottom boundary.
998      * @param extendLastRow true to extend the last row; false otherwise
999      */

1000    public void setExtendLastRow(boolean extendLastRow) {
1001        this.extendLastRow = extendLastRow;
1002    }
1003    
1004    /**
1005     * Gets the header status inclusion in PdfPTableEvent.
1006     * @return true if the headers are included; false otherwise
1007     */

1008    public boolean isHeadersInEvent() {
1009        return this.headersInEvent;
1010    }
1011    
1012    /**
1013     * When set the PdfPTableEvent will include the headers.
1014     * @param headersInEvent true to include the headers; false otherwise
1015     */

1016    public void setHeadersInEvent(boolean headersInEvent) {
1017        this.headersInEvent = headersInEvent;
1018    }
1019    
1020    /**
1021     * Gets the property splitLate.
1022     * @return the property splitLate
1023     */

1024    public boolean isSplitLate() {
1025        return this.splitLate;
1026    }
1027    
1028    /**
1029     * If true the row will only split if it's the first one in an empty page.
1030     * It's true by default.
1031     *<p>
1032     * It's only meaningful if setSplitRows(true).
1033     * @param splitLate the property value
1034     */

1035    public void setSplitLate(boolean splitLate) {
1036        this.splitLate = splitLate;
1037    }
1038    
1039    /**
1040     * If true the table will be kept on one page if it fits, by forcing a
1041     * new page if it doesn't fit on the current page. The default is to
1042     * split the table over multiple pages.
1043     *
1044     * @param p_KeepTogether whether to try to keep the table on one page
1045     */

1046    public void setKeepTogether(boolean p_KeepTogether) {
1047        keepTogether = p_KeepTogether;
1048    }
1049     
1050    public boolean getKeepTogether() {
1051        return keepTogether;
1052    }
1053    
1054    /**
1055     * Gets the number of rows in the footer.
1056     * @return the number of rows in the footer
1057     */

1058    public int getFooterRows() {
1059        return this.footerRows;
1060    }
1061    
1062    /**
1063     * Sets the number of rows to be used for the footer. The number
1064     * of footer rows are subtracted from the header rows. For
1065     * example, for a table with two header rows and one footer row the
1066     * code would be:
1067     * <p>
1068     * <PRE>
1069     * table.setHeaderRows(3);
1070     * table.setFooterRows(1);
1071     * </PRE>
1072     * <p>
1073     * Row 0 and 1 will be the header rows and row 2 will be the footer row.
1074     * @param footerRows the number of rows to be used for the footer
1075     */

1076    public void setFooterRows(int footerRows) {
1077        if (footerRows < 0)
1078            footerRows = 0;
1079        this.footerRows = footerRows;
1080    }
1081    
1082}
Popular Tags