001: /* ===========================================================
002: * JFreeChart : a free chart library for the Java(tm) platform
003: * ===========================================================
004: *
005: * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
006: *
007: * Project Info: http://www.jfree.org/jfreechart/index.html
008: *
009: * This library is free software; you can redistribute it and/or modify it
010: * under the terms of the GNU Lesser General Public License as published by
011: * the Free Software Foundation; either version 2.1 of the License, or
012: * (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but
015: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
016: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
017: * License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
022: * USA.
023: *
024: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
025: * in the United States and other countries.]
026: *
027: * ------------------------
028: * PeriodAxisLabelInfo.java
029: * ------------------------
030: * (C) Copyright 2004, 2005, by Object Refinery Limited and Contributors.
031: *
032: * Original Author: David Gilbert (for Object Refinery Limited);
033: * Contributor(s): -;
034: *
035: * $Id: PeriodAxisLabelInfo.java,v 1.6.2.1 2005/10/25 20:37:34 mungady Exp $
036: *
037: * Changes
038: * -------
039: * 01-Jun-2004 : Version 1 (DG);
040: * 23-Feb-2005 : Replaced Spacer with RectangleInsets (DG);
041: * 01-Mar-2005 : Modified constructors to accept DateFormat (DG);
042: * 20-May-2005 : Added default constants and null argument checks in the
043: * constructor (DG);
044: *
045: */
046:
047: package org.jfree.chart.axis;
048:
049: import java.awt.BasicStroke;
050: import java.awt.Color;
051: import java.awt.Font;
052: import java.awt.Paint;
053: import java.awt.Stroke;
054: import java.io.IOException;
055: import java.io.ObjectInputStream;
056: import java.io.ObjectOutputStream;
057: import java.io.Serializable;
058: import java.lang.reflect.Constructor;
059: import java.text.DateFormat;
060: import java.util.Date;
061: import java.util.TimeZone;
062:
063: import org.jfree.data.time.RegularTimePeriod;
064: import org.jfree.io.SerialUtilities;
065: import org.jfree.ui.RectangleInsets;
066:
067: /**
068: * A record that contains information for one "band" of date labels in
069: * a {@link PeriodAxis}.
070: */
071: public class PeriodAxisLabelInfo implements Cloneable, Serializable {
072:
073: // TODO: this class is mostly immutable, so implementing Cloneable isn't
074: // really necessary. But there is still a hole in that you can get the
075: // dateFormat and modify it. We could return a copy, but that would slow
076: // things down. Needs resolving.
077:
078: /** For serialization. */
079: private static final long serialVersionUID = 5710451740920277357L;
080:
081: /** The default insets. */
082: public static final RectangleInsets DEFAULT_INSETS = new RectangleInsets(
083: 2, 2, 2, 2);
084:
085: /** The default font. */
086: public static final Font DEFAULT_FONT = new Font("SansSerif",
087: Font.PLAIN, 10);
088:
089: /** The default label paint. */
090: public static final Paint DEFAULT_LABEL_PAINT = Color.black;
091:
092: /** The default divider stroke. */
093: public static final Stroke DEFAULT_DIVIDER_STROKE = new BasicStroke(
094: 0.5f);
095:
096: /** The default divider paint. */
097: public static final Paint DEFAULT_DIVIDER_PAINT = Color.gray;
098:
099: /** The subclass of {@link RegularTimePeriod} to use for this band. */
100: private Class periodClass;
101:
102: /** Controls the gaps around the band. */
103: private RectangleInsets padding;
104:
105: /** The date formatter. */
106: private DateFormat dateFormat;
107:
108: /** The label font. */
109: private Font labelFont;
110:
111: /** The label paint. */
112: private transient Paint labelPaint;
113:
114: /** A flag that controls whether or not dividers are visible. */
115: private boolean drawDividers;
116:
117: /** The stroke used to draw the dividers. */
118: private transient Stroke dividerStroke;
119:
120: /** The paint used to draw the dividers. */
121: private transient Paint dividerPaint;
122:
123: /**
124: * Creates a new instance.
125: *
126: * @param periodClass the subclass of {@link RegularTimePeriod} to use
127: * (<code>null</code> not permitted).
128: * @param dateFormat the date format (<code>null</code> not permitted).
129: */
130: public PeriodAxisLabelInfo(Class periodClass, DateFormat dateFormat) {
131: this (periodClass, dateFormat, DEFAULT_INSETS, DEFAULT_FONT,
132: DEFAULT_LABEL_PAINT, true, DEFAULT_DIVIDER_STROKE,
133: DEFAULT_DIVIDER_PAINT);
134: }
135:
136: /**
137: * Creates a new instance.
138: *
139: * @param periodClass the subclass of {@link RegularTimePeriod} to use
140: * (<code>null</code> not permitted).
141: * @param dateFormat the date format (<code>null</code> not permitted).
142: * @param padding controls the space around the band (<code>null</code>
143: * not permitted).
144: * @param labelFont the label font (<code>null</code> not permitted).
145: * @param labelPaint the label paint (<code>null</code> not permitted).
146: * @param drawDividers a flag that controls whether dividers are drawn.
147: * @param dividerStroke the stroke used to draw the dividers
148: * (<code>null</code> not permitted).
149: * @param dividerPaint the paint used to draw the dividers
150: * (<code>null</code> not permitted).
151: */
152: public PeriodAxisLabelInfo(Class periodClass,
153: DateFormat dateFormat, RectangleInsets padding,
154: Font labelFont, Paint labelPaint, boolean drawDividers,
155: Stroke dividerStroke, Paint dividerPaint) {
156: if (periodClass == null) {
157: throw new IllegalArgumentException(
158: "Null 'periodClass' argument.");
159: }
160: if (dateFormat == null) {
161: throw new IllegalArgumentException(
162: "Null 'dateFormat' argument.");
163: }
164: if (padding == null) {
165: throw new IllegalArgumentException(
166: "Null 'padding' argument.");
167: }
168: if (labelFont == null) {
169: throw new IllegalArgumentException(
170: "Null 'labelFont' argument.");
171: }
172: if (labelPaint == null) {
173: throw new IllegalArgumentException(
174: "Null 'labelPaint' argument.");
175: }
176: if (dividerStroke == null) {
177: throw new IllegalArgumentException(
178: "Null 'dividerStroke' argument.");
179: }
180: if (dividerPaint == null) {
181: throw new IllegalArgumentException(
182: "Null 'dividerPaint' argument.");
183: }
184: this .periodClass = periodClass;
185: this .dateFormat = dateFormat;
186: this .padding = padding;
187: this .labelFont = labelFont;
188: this .labelPaint = labelPaint;
189: this .drawDividers = drawDividers;
190: this .dividerStroke = dividerStroke;
191: this .dividerPaint = dividerPaint;
192: }
193:
194: /**
195: * Returns the subclass of {@link RegularTimePeriod} that should be used
196: * to generate the date labels.
197: *
198: * @return The class.
199: */
200: public Class getPeriodClass() {
201: return this .periodClass;
202: }
203:
204: /**
205: * Returns the date formatter.
206: *
207: * @return The date formatter (never <code>null</code>).
208: */
209: public DateFormat getDateFormat() {
210: return this .dateFormat;
211: }
212:
213: /**
214: * Returns the padding for the band.
215: *
216: * @return The padding.
217: */
218: public RectangleInsets getPadding() {
219: return this .padding;
220: }
221:
222: /**
223: * Returns the label font.
224: *
225: * @return The label font (never <code>null</code>).
226: */
227: public Font getLabelFont() {
228: return this .labelFont;
229: }
230:
231: /**
232: * Returns the label paint.
233: *
234: * @return The label paint.
235: */
236: public Paint getLabelPaint() {
237: return this .labelPaint;
238: }
239:
240: /**
241: * Returns a flag that controls whether or not dividers are drawn.
242: *
243: * @return A flag.
244: */
245: public boolean getDrawDividers() {
246: return this .drawDividers;
247: }
248:
249: /**
250: * Returns the stroke used to draw the dividers.
251: *
252: * @return The stroke.
253: */
254: public Stroke getDividerStroke() {
255: return this .dividerStroke;
256: }
257:
258: /**
259: * Returns the paint used to draw the dividers.
260: *
261: * @return The paint.
262: */
263: public Paint getDividerPaint() {
264: return this .dividerPaint;
265: }
266:
267: /**
268: * Creates a time period that includes the specified millisecond, assuming
269: * the given time zone.
270: *
271: * @param millisecond the time.
272: * @param zone the time zone.
273: *
274: * @return The time period.
275: */
276: public RegularTimePeriod createInstance(Date millisecond,
277: TimeZone zone) {
278: RegularTimePeriod result = null;
279: try {
280: Constructor c = this .periodClass
281: .getDeclaredConstructor(new Class[] { Date.class,
282: TimeZone.class });
283: result = (RegularTimePeriod) c.newInstance(new Object[] {
284: millisecond, zone });
285: } catch (Exception e) {
286: // do nothing
287: }
288: return result;
289: }
290:
291: /**
292: * Tests this object for equality with an arbitrary object.
293: *
294: * @param obj the object to test against (<code>null</code> permitted).
295: *
296: * @return A boolean.
297: */
298: public boolean equals(Object obj) {
299: if (obj == this ) {
300: return true;
301: }
302: if (obj instanceof PeriodAxisLabelInfo) {
303: PeriodAxisLabelInfo info = (PeriodAxisLabelInfo) obj;
304: if (!info.periodClass.equals(this .periodClass)) {
305: return false;
306: }
307: if (!info.dateFormat.equals(this .dateFormat)) {
308: return false;
309: }
310: if (!info.padding.equals(this .padding)) {
311: return false;
312: }
313: if (!info.labelFont.equals(this .labelFont)) {
314: return false;
315: }
316: if (!info.labelPaint.equals(this .labelPaint)) {
317: return false;
318: }
319: if (info.drawDividers != this .drawDividers) {
320: return false;
321: }
322: if (!info.dividerStroke.equals(this .dividerStroke)) {
323: return false;
324: }
325: if (!info.dividerPaint.equals(this .dividerPaint)) {
326: return false;
327: }
328: return true;
329: }
330: return false;
331: }
332:
333: /**
334: * Returns a hash code for this object.
335: *
336: * @return A hash code.
337: */
338: public int hashCode() {
339: int result = 41;
340: result = 37 * this .periodClass.hashCode();
341: result = 37 * this .dateFormat.hashCode();
342: return result;
343: }
344:
345: /**
346: * Returns a clone of the object.
347: *
348: * @return A clone.
349: *
350: * @throws CloneNotSupportedException if cloning is not supported.
351: */
352: public Object clone() throws CloneNotSupportedException {
353: Object clone = (PeriodAxisLabelInfo) super .clone();
354: return clone;
355: }
356:
357: /**
358: * Provides serialization support.
359: *
360: * @param stream the output stream.
361: *
362: * @throws IOException if there is an I/O error.
363: */
364: private void writeObject(ObjectOutputStream stream)
365: throws IOException {
366: stream.defaultWriteObject();
367: SerialUtilities.writePaint(this .labelPaint, stream);
368: SerialUtilities.writeStroke(this .dividerStroke, stream);
369: SerialUtilities.writePaint(this .dividerPaint, stream);
370: }
371:
372: /**
373: * Provides serialization support.
374: *
375: * @param stream the input stream.
376: *
377: * @throws IOException if there is an I/O error.
378: * @throws ClassNotFoundException if there is a classpath problem.
379: */
380: private void readObject(ObjectInputStream stream)
381: throws IOException, ClassNotFoundException {
382: stream.defaultReadObject();
383: this.labelPaint = SerialUtilities.readPaint(stream);
384: this.dividerStroke = SerialUtilities.readStroke(stream);
385: this.dividerPaint = SerialUtilities.readPaint(stream);
386: }
387:
388: }
|