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: * SimplePageDefinition.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.Arrays;
037:
038: import org.jfree.report.util.PageFormatFactory;
039: import org.jfree.serializer.SerializerHelper;
040:
041: /**
042: * A simple page definition defines a logical page, for which all physical pages have the same size.
043: * <p/>
044: * The page area is a rectangle.
045: *
046: * @author Thomas Morgner
047: */
048: public class SimplePageDefinition implements PageDefinition {
049: /**
050: * The page format.
051: */
052: private transient PageFormat format;
053: /**
054: * The page positions of the physical pages.
055: */
056: private transient Rectangle2D[] pagePositions;
057: /**
058: * The number of columns in the page grid.
059: */
060: private int pageCountHorizontal;
061: /**
062: * The number of rows in the page grid.
063: */
064: private int pageCountVertical;
065:
066: /**
067: * Creates a new SimplePageDefinition object.
068: *
069: * @param format the pageformat used as base.
070: * @param x the number of physical pages in a row.
071: * @param y the number of physical pages in a column.
072: */
073: public SimplePageDefinition(final PageFormat format, final int x,
074: final int y) {
075: if (format == null) {
076: throw new NullPointerException("Format must not be null");
077: }
078: if (x < 1) {
079: throw new IllegalArgumentException(
080: "PageCount must be greater or equal to 1");
081: }
082: if (y < 1) {
083: throw new IllegalArgumentException(
084: "PageCount must be greater or equal to 1");
085: }
086: this .format = (PageFormat) format.clone();
087: this .pageCountHorizontal = x;
088: this .pageCountVertical = y;
089: this .pagePositions = new Rectangle2D[pageCountHorizontal
090: * pageCountVertical];
091:
092: final float width = (float) format.getImageableWidth();
093: final float height = (float) format.getImageableHeight();
094: float pageStartY = 0;
095: for (int vert = 0; vert < pageCountVertical; vert++) {
096: float pageStartX = 0;
097: for (int hor = 0; hor < pageCountHorizontal; hor++) {
098: final Rectangle2D rect = new Rectangle2D.Float(
099: pageStartX, pageStartY, width, height);
100: pagePositions[vert * pageCountHorizontal + hor] = rect;
101: pageStartX += width;
102: }
103: pageStartY += height;
104: }
105: }
106:
107: /**
108: * Creates a 1x1 page defintion. The physical page size is equal to the logical page size.
109: *
110: * @param format the pageformat.
111: */
112: public SimplePageDefinition(final PageFormat format) {
113: this (format, 1, 1);
114: }
115:
116: /**
117: * Returns the number of physical pages in this page definition.
118: *
119: * @return the number of pages.
120: */
121: public int getPageCount() {
122: return pageCountHorizontal * pageCountVertical;
123: }
124:
125: /**
126: * Returns the physical page format for the given position.
127: *
128: * @param pos the position in the page grid.
129: * @return a clone of the pageformat at the specified positon.
130: */
131: public PageFormat getPageFormat(final int pos) {
132: if (pos < 0 || pos > getPageCount()) {
133: throw new IndexOutOfBoundsException("Index is invalid");
134: }
135: return (PageFormat) format.clone();
136: }
137:
138: /**
139: * Returns the printable area within the logical page area covered by the physical page at the given position.
140: *
141: * @param index the positon.
142: * @return the printable area for the page.
143: */
144: public Rectangle2D getPagePosition(final int index) {
145: if (index < 0 || index > getPageCount()) {
146: throw new IndexOutOfBoundsException("Index is invalid");
147: }
148: return pagePositions[index].getBounds2D();
149: }
150:
151: /**
152: * Returns all page position known to this page definition.
153: *
154: * @return the page positions.
155: */
156: public Rectangle2D[] getPagePositions() {
157: final int length = pagePositions.length;
158: final Rectangle2D[] rects = new Rectangle2D[length];
159: for (int i = 0; i < length; i++) {
160: rects[i] = pagePositions[i].getBounds2D();
161: }
162: return rects;
163: }
164:
165: /**
166: * Returns the total height of the logical page.
167: *
168: * @return the height of the page.
169: */
170: public float getHeight() {
171: return (float) (format.getImageableHeight() * pageCountVertical);
172: }
173:
174: /**
175: * Returns the total width of the logical page.
176: *
177: * @return the width of the page.
178: */
179: public float getWidth() {
180: return (float) (format.getImageableWidth() * pageCountHorizontal);
181: }
182:
183: /**
184: * Deserizalize the report and restore the pageformat.
185: *
186: * @param out the objectoutput stream
187: * @throws java.io.IOException if errors occur
188: */
189: private void writeObject(final ObjectOutputStream out)
190: throws IOException {
191: out.defaultWriteObject();
192: final SerializerHelper instance = SerializerHelper
193: .getInstance();
194: instance.writeObject(format, out);
195: final int length = pagePositions.length;
196: out.writeInt(length);
197: for (int i = 0; i < length; i++) {
198: instance.writeObject(pagePositions[i], out);
199: }
200: }
201:
202: /**
203: * Resolve the pageformat, as PageFormat is not serializable.
204: *
205: * @param in the input stream.
206: * @throws java.io.IOException if there is an IO problem.
207: * @throws ClassNotFoundException if there is a class problem.
208: */
209: private void readObject(final ObjectInputStream in)
210: throws IOException, ClassNotFoundException {
211: in.defaultReadObject();
212: final SerializerHelper instance = SerializerHelper
213: .getInstance();
214: format = (PageFormat) instance.readObject(in);
215: final int length = in.readInt();
216: pagePositions = new Rectangle2D[length];
217: for (int i = 0; i < length; i++) {
218: pagePositions[i] = (Rectangle2D) instance.readObject(in);
219: }
220: }
221:
222: /**
223: * Creates a copy of this page definition.
224: *
225: * @return a clone of this page definition object.
226: * @throws CloneNotSupportedException
227: */
228: public Object clone() throws CloneNotSupportedException {
229: final SimplePageDefinition pdef = (SimplePageDefinition) super
230: .clone();
231: pdef.format = (PageFormat) format.clone();
232: return pdef;
233: }
234:
235: /**
236: * Checks, whether this page definition object is equal to the given object.
237: *
238: * @param obj the other object.
239: * @return true, if that object is the same as this object, false otherwise.
240: */
241: public boolean equals(final Object obj) {
242: if (this == obj) {
243: return true;
244: }
245: if (!(obj instanceof SimplePageDefinition)) {
246: return false;
247: }
248:
249: final SimplePageDefinition simplePageDefinition = (SimplePageDefinition) obj;
250:
251: if (pageCountHorizontal != simplePageDefinition.pageCountHorizontal) {
252: return false;
253: }
254: if (pageCountVertical != simplePageDefinition.pageCountVertical) {
255: return false;
256: }
257: if (!PageFormatFactory.isEqual(format,
258: simplePageDefinition.format)) {
259: return false;
260: }
261: if (!Arrays.equals(pagePositions,
262: simplePageDefinition.pagePositions)) {
263: return false;
264: }
265:
266: return true;
267: }
268:
269: /**
270: * Returns the number of horizontal pages in this page definition. That number is always greater than zero.
271: *
272: * @return the horizontal page count.
273: */
274: public int getPageCountHorizontal() {
275: return pageCountHorizontal;
276: }
277:
278: /**
279: * Returns the number of vertical pages in this page definition. That number is always greater than zero.
280: *
281: * @return the vertical page count.
282: */
283: public int getPageCountVertical() {
284: return pageCountVertical;
285: }
286:
287: /**
288: * Computes a hashcode for this page definition.
289: *
290: * @return the hashcode.
291: */
292: public int hashCode() {
293: int result = format.hashCode();
294: result = 29 * result + pageCountHorizontal;
295: result = 29 * result + pageCountVertical;
296: return result;
297: }
298: }
|