001: /**
002: * ===========================================
003: * JFreeReport : a free Java reporting library
004: * ===========================================
005: *
006: * Project Info: http://reporting.pentaho.org/
007: *
008: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
009: *
010: * This library is free software; you can redistribute it and/or modify it under the terms
011: * of the GNU Lesser General Public License as published by the Free Software Foundation;
012: * either version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015: * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016: * See the GNU Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public License along with this
019: * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: *
022: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023: * in the United States and other countries.]
024: *
025: * ------------
026: * CustomPageDefinition.java
027: * ------------
028: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029: */package org.jfree.report;
030:
031: import java.awt.geom.Rectangle2D;
032: import java.awt.print.PageFormat;
033: import java.io.IOException;
034: import java.io.ObjectInputStream;
035: import java.io.ObjectOutputStream;
036: import java.util.ArrayList;
037: import java.util.Iterator;
038:
039: import org.jfree.report.util.PageFormatFactory;
040: import org.jfree.serializer.SerializerHelper;
041:
042: /**
043: * A page definition, that consists of one or many pages. The pages are allowed to
044: * overlapp or to leave areas of the page uncovered.
045: *
046: * @author Thomas Morgner
047: * @see PageDefinition
048: */
049: public class CustomPageDefinition implements PageDefinition {
050: /**
051: * The page bounds, the imageable area on the global virtual page.
052: */
053: private transient ArrayList pageBoundsList;
054: /**
055: * The page format list.
056: */
057: private transient ArrayList pageFormatList;
058: /**
059: * The total width of the page.
060: */
061: private float width;
062: /**
063: * The total height of the page.
064: */
065: private float height;
066:
067: /**
068: * Creates a new (initialy empty and therefore invalid) page definition.
069: */
070: public CustomPageDefinition() {
071: pageBoundsList = new ArrayList();
072: pageFormatList = new ArrayList();
073: }
074:
075: /**
076: * Adds a new page format to the page definition.
077: *
078: * @param format the page format
079: * @param x the x-position to where the imageable-x of the pageformat is mapped.
080: * @param y the y-position to where the imageable-y of the pageformat is mapped.
081: */
082: public void addPageFormat(final PageFormat format, final float x,
083: final float y) {
084: if (format == null) {
085: throw new NullPointerException(
086: "The given pageformat must not be null.");
087: }
088: width = Math.max(width,
089: (float) (format.getImageableWidth() + x));
090: height = Math.max(height,
091: (float) (format.getImageableHeight() + y));
092: final Rectangle2D bounds = new Rectangle2D.Double(x, y, format
093: .getImageableWidth(), format.getImageableHeight());
094: pageBoundsList.add(bounds);
095: pageFormatList.add(format.clone());
096: }
097:
098: /**
099: * Returns the number of physical pages in the logical page definition.
100: *
101: * @return the number of physical pages.
102: */
103: public int getPageCount() {
104: return pageBoundsList.size();
105: }
106:
107: /**
108: * Returns the page format for the given page number. The page format contains local
109: * coordinates - that means that the point (0,0) denotes the upper left corner of this
110: * returned page format and not global coordinates.
111: *
112: * @param pos the position of the pageformat within the page
113: * @return the given pageformat.
114: */
115: public PageFormat getPageFormat(final int pos) {
116: final PageFormat fmt = (PageFormat) pageFormatList.get(pos);
117: return (PageFormat) fmt.clone();
118: }
119:
120: /**
121: * Describes the internal position of the given page within the logical page. The
122: * logical page does not include any page margins, the printable area for a page starts
123: * at (0,0).
124: *
125: * @param index the index of the page.
126: * @return the position of the page (within the global page).
127: */
128: public Rectangle2D getPagePosition(final int index) {
129: final Rectangle2D rec = (Rectangle2D) pageBoundsList.get(index);
130: return rec.getBounds2D();
131: }
132:
133: /**
134: * Returns all page positions as array.
135: *
136: * @return the collected page positions
137: * @see PageDefinition#getPagePosition(int)
138: */
139: public Rectangle2D[] getPagePositions() {
140: final Rectangle2D[] rects = new Rectangle2D[pageBoundsList
141: .size()];
142: for (int i = 0; i < pageBoundsList.size(); i++) {
143: final Rectangle2D rec = (Rectangle2D) pageBoundsList.get(i);
144: rects[i] = rec.getBounds2D();
145: }
146: return rects;
147: }
148:
149: /**
150: * Returns the total width of the page definition.
151: *
152: * @return the total width of the page definition.
153: */
154: public float getWidth() {
155: return width;
156: }
157:
158: /**
159: * Returns the total height of the page definition.
160: *
161: * @return the total height of the page definition.
162: */
163: public float getHeight() {
164: return height;
165: }
166:
167: /**
168: * Clones the given page definition object.
169: *
170: * @return a clone of this page definition.
171: *
172: * @throws CloneNotSupportedException if an error occured.
173: */
174: public Object clone() throws CloneNotSupportedException {
175: final CustomPageDefinition def = (CustomPageDefinition) super
176: .clone();
177: def.pageBoundsList = (ArrayList) pageBoundsList.clone();
178: def.pageFormatList = (ArrayList) pageFormatList.clone();
179: return def;
180: }
181:
182: /**
183: * Deserizalize the report and restore the pageformat.
184: *
185: * @param out the objectoutput stream
186: * @throws java.io.IOException if errors occur
187: */
188: private void writeObject(final ObjectOutputStream out)
189: throws IOException {
190: out.defaultWriteObject();
191: final SerializerHelper instance = SerializerHelper
192: .getInstance();
193: final Iterator pageBoundsIterator = pageBoundsList.iterator();
194: while (pageBoundsIterator.hasNext()) {
195: instance.writeObject(pageBoundsIterator.next(), out);
196: }
197: instance.writeObject(null, out);
198: final Iterator pageFormatIterator = pageFormatList.iterator();
199: while (pageFormatIterator.hasNext()) {
200: instance.writeObject(pageFormatIterator.next(), out);
201: }
202: instance.writeObject(null, out);
203: }
204:
205: /**
206: * Resolve the pageformat, as PageFormat is not serializable.
207: *
208: * @param in the input stream.
209: * @throws java.io.IOException if there is an IO problem.
210: * @throws ClassNotFoundException if there is a class problem.
211: */
212: private void readObject(final ObjectInputStream in)
213: throws IOException, ClassNotFoundException {
214: in.defaultReadObject();
215: final SerializerHelper instance = SerializerHelper
216: .getInstance();
217: pageBoundsList = new ArrayList();
218: pageFormatList = new ArrayList();
219:
220: Object o = instance.readObject(in);
221: while (o != null) {
222: final Rectangle2D rect = (Rectangle2D) o;
223: pageBoundsList.add(rect);
224: o = instance.readObject(in);
225: }
226:
227: o = instance.readObject(in);
228: while (o != null) {
229: final PageFormat format = (PageFormat) o;
230: pageFormatList.add(format);
231: o = instance.readObject(in);
232: }
233: }
234:
235: /**
236: * Checks, whether the given object is equal to this one.
237: *
238: * @param obj the other object.
239: * @return true, if the other object is equal, false otherwise.
240: */
241: public boolean equals(final Object obj) {
242: if (this == obj) {
243: return true;
244: }
245: if (!(obj instanceof CustomPageDefinition)) {
246: return false;
247: }
248:
249: final CustomPageDefinition customPageDefinition = (CustomPageDefinition) obj;
250:
251: if (height != customPageDefinition.height) {
252: return false;
253: }
254: if (width != customPageDefinition.width) {
255: return false;
256: }
257: if (!pageBoundsList.equals(customPageDefinition.pageBoundsList)) {
258: return false;
259: }
260:
261: if (pageFormatList.size() != customPageDefinition.pageFormatList
262: .size()) {
263: return false;
264: }
265:
266: for (int i = 0; i < pageFormatList.size(); i++) {
267: final PageFormat pf = (PageFormat) pageFormatList.get(i);
268: final PageFormat cpf = (PageFormat) customPageDefinition.pageFormatList
269: .get(i);
270: if (PageFormatFactory.isEqual(pf, cpf) == false) {
271: return false;
272: }
273: }
274:
275: return true;
276: }
277:
278: /**
279: * Computes the hashcode of this page definition.
280: *
281: * @return the hashcode.
282: */
283: public int hashCode() {
284: int result = pageBoundsList.hashCode();
285: result = 29 * result + pageFormatList.hashCode();
286: result = 29 * result + width == 0.0f ? 0 : Float
287: .floatToIntBits(width);
288: result = 29 * result + height == 0.0f ? 0 : Float
289: .floatToIntBits(height);
290: return result;
291: }
292: }
|