Frames | No Frames |
1: /* =========================================================== 2: * JFreeChart : a free chart library for the Java(tm) platform 3: * =========================================================== 4: * 5: * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors. 6: * 7: * Project Info: http://www.jfree.org/jfreechart/index.html 8: * 9: * This library is free software; you can redistribute it and/or modify it 10: * under the terms of the GNU Lesser General Public License as published by 11: * the Free Software Foundation; either version 2.1 of the License, or 12: * (at your option) any later version. 13: * 14: * This library is distributed in the hope that it will be useful, but 15: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 17: * License for more details. 18: * 19: * You should have received a copy of the GNU Lesser General Public 20: * License along with this library; if not, write to the Free Software 21: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 22: * USA. 23: * 24: * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 25: * in the United States and other countries.] 26: * 27: * ------------------------ 28: * PeriodAxisLabelInfo.java 29: * ------------------------ 30: * (C) Copyright 2004, 2005, by Object Refinery Limited and Contributors. 31: * 32: * Original Author: David Gilbert (for Object Refinery Limited); 33: * Contributor(s): -; 34: * 35: * $Id: PeriodAxisLabelInfo.java,v 1.6.2.1 2005/10/25 20:37:34 mungady Exp $ 36: * 37: * Changes 38: * ------- 39: * 01-Jun-2004 : Version 1 (DG); 40: * 23-Feb-2005 : Replaced Spacer with RectangleInsets (DG); 41: * 01-Mar-2005 : Modified constructors to accept DateFormat (DG); 42: * 20-May-2005 : Added default constants and null argument checks in the 43: * constructor (DG); 44: * 45: */ 46: 47: package org.jfree.chart.axis; 48: 49: import java.awt.BasicStroke; 50: import java.awt.Color; 51: import java.awt.Font; 52: import java.awt.Paint; 53: import java.awt.Stroke; 54: import java.io.IOException; 55: import java.io.ObjectInputStream; 56: import java.io.ObjectOutputStream; 57: import java.io.Serializable; 58: import java.lang.reflect.Constructor; 59: import java.text.DateFormat; 60: import java.util.Date; 61: import java.util.TimeZone; 62: 63: import org.jfree.data.time.RegularTimePeriod; 64: import org.jfree.io.SerialUtilities; 65: import org.jfree.ui.RectangleInsets; 66: 67: /** 68: * A record that contains information for one "band" of date labels in 69: * a {@link PeriodAxis}. 70: */ 71: public class PeriodAxisLabelInfo implements Cloneable, Serializable { 72: 73: // TODO: this class is mostly immutable, so implementing Cloneable isn't 74: // really necessary. But there is still a hole in that you can get the 75: // dateFormat and modify it. We could return a copy, but that would slow 76: // things down. Needs resolving. 77: 78: /** For serialization. */ 79: private static final long serialVersionUID = 5710451740920277357L; 80: 81: /** The default insets. */ 82: public static final RectangleInsets DEFAULT_INSETS 83: = new RectangleInsets(2, 2, 2, 2); 84: 85: /** The default font. */ 86: public static final Font DEFAULT_FONT 87: = new Font("SansSerif", Font.PLAIN, 10); 88: 89: /** The default label paint. */ 90: public static final Paint DEFAULT_LABEL_PAINT = Color.black; 91: 92: /** The default divider stroke. */ 93: public static final Stroke DEFAULT_DIVIDER_STROKE = new BasicStroke(0.5f); 94: 95: /** The default divider paint. */ 96: public static final Paint DEFAULT_DIVIDER_PAINT = Color.gray; 97: 98: /** The subclass of {@link RegularTimePeriod} to use for this band. */ 99: private Class periodClass; 100: 101: /** Controls the gaps around the band. */ 102: private RectangleInsets padding; 103: 104: /** The date formatter. */ 105: private DateFormat dateFormat; 106: 107: /** The label font. */ 108: private Font labelFont; 109: 110: /** The label paint. */ 111: private transient Paint labelPaint; 112: 113: /** A flag that controls whether or not dividers are visible. */ 114: private boolean drawDividers; 115: 116: /** The stroke used to draw the dividers. */ 117: private transient Stroke dividerStroke; 118: 119: /** The paint used to draw the dividers. */ 120: private transient Paint dividerPaint; 121: 122: /** 123: * Creates a new instance. 124: * 125: * @param periodClass the subclass of {@link RegularTimePeriod} to use 126: * (<code>null</code> not permitted). 127: * @param dateFormat the date format (<code>null</code> not permitted). 128: */ 129: public PeriodAxisLabelInfo(Class periodClass, DateFormat dateFormat) { 130: this( 131: periodClass, dateFormat, DEFAULT_INSETS, DEFAULT_FONT, 132: DEFAULT_LABEL_PAINT, true, DEFAULT_DIVIDER_STROKE, 133: DEFAULT_DIVIDER_PAINT 134: ); 135: } 136: 137: /** 138: * Creates a new instance. 139: * 140: * @param periodClass the subclass of {@link RegularTimePeriod} to use 141: * (<code>null</code> not permitted). 142: * @param dateFormat the date format (<code>null</code> not permitted). 143: * @param padding controls the space around the band (<code>null</code> 144: * not permitted). 145: * @param labelFont the label font (<code>null</code> not permitted). 146: * @param labelPaint the label paint (<code>null</code> not permitted). 147: * @param drawDividers a flag that controls whether dividers are drawn. 148: * @param dividerStroke the stroke used to draw the dividers 149: * (<code>null</code> not permitted). 150: * @param dividerPaint the paint used to draw the dividers 151: * (<code>null</code> not permitted). 152: */ 153: public PeriodAxisLabelInfo(Class periodClass, DateFormat dateFormat, 154: RectangleInsets padding, 155: Font labelFont, Paint labelPaint, 156: boolean drawDividers, Stroke dividerStroke, 157: Paint dividerPaint) { 158: if (periodClass == null) { 159: throw new IllegalArgumentException("Null 'periodClass' argument."); 160: } 161: if (dateFormat == null) { 162: throw new IllegalArgumentException("Null 'dateFormat' argument."); 163: } 164: if (padding == null) { 165: throw new IllegalArgumentException("Null 'padding' argument."); 166: } 167: if (labelFont == null) { 168: throw new IllegalArgumentException("Null 'labelFont' argument."); 169: } 170: if (labelPaint == null) { 171: throw new IllegalArgumentException("Null 'labelPaint' argument."); 172: } 173: if (dividerStroke == null) { 174: throw new IllegalArgumentException("Null 'dividerStroke' argument."); 175: } 176: if (dividerPaint == null) { 177: throw new IllegalArgumentException("Null 'dividerPaint' argument."); 178: } 179: this.periodClass = periodClass; 180: this.dateFormat = dateFormat; 181: this.padding = padding; 182: this.labelFont = labelFont; 183: this.labelPaint = labelPaint; 184: this.drawDividers = drawDividers; 185: this.dividerStroke = dividerStroke; 186: this.dividerPaint = dividerPaint; 187: } 188: 189: /** 190: * Returns the subclass of {@link RegularTimePeriod} that should be used 191: * to generate the date labels. 192: * 193: * @return The class. 194: */ 195: public Class getPeriodClass() { 196: return this.periodClass; 197: } 198: 199: /** 200: * Returns the date formatter. 201: * 202: * @return The date formatter (never <code>null</code>). 203: */ 204: public DateFormat getDateFormat() { 205: return this.dateFormat; 206: } 207: 208: /** 209: * Returns the padding for the band. 210: * 211: * @return The padding. 212: */ 213: public RectangleInsets getPadding() { 214: return this.padding; 215: } 216: 217: /** 218: * Returns the label font. 219: * 220: * @return The label font (never <code>null</code>). 221: */ 222: public Font getLabelFont() { 223: return this.labelFont; 224: } 225: 226: /** 227: * Returns the label paint. 228: * 229: * @return The label paint. 230: */ 231: public Paint getLabelPaint() { 232: return this.labelPaint; 233: } 234: 235: /** 236: * Returns a flag that controls whether or not dividers are drawn. 237: * 238: * @return A flag. 239: */ 240: public boolean getDrawDividers() { 241: return this.drawDividers; 242: } 243: 244: /** 245: * Returns the stroke used to draw the dividers. 246: * 247: * @return The stroke. 248: */ 249: public Stroke getDividerStroke() { 250: return this.dividerStroke; 251: } 252: 253: /** 254: * Returns the paint used to draw the dividers. 255: * 256: * @return The paint. 257: */ 258: public Paint getDividerPaint() { 259: return this.dividerPaint; 260: } 261: 262: /** 263: * Creates a time period that includes the specified millisecond, assuming 264: * the given time zone. 265: * 266: * @param millisecond the time. 267: * @param zone the time zone. 268: * 269: * @return The time period. 270: */ 271: public RegularTimePeriod createInstance(Date millisecond, TimeZone zone) { 272: RegularTimePeriod result = null; 273: try { 274: Constructor c = this.periodClass.getDeclaredConstructor( 275: new Class[] {Date.class, TimeZone.class} 276: ); 277: result = (RegularTimePeriod) c.newInstance( 278: new Object[] {millisecond, zone} 279: ); 280: } 281: catch (Exception e) { 282: // do nothing 283: } 284: return result; 285: } 286: 287: /** 288: * Tests this object for equality with an arbitrary object. 289: * 290: * @param obj the object to test against (<code>null</code> permitted). 291: * 292: * @return A boolean. 293: */ 294: public boolean equals(Object obj) { 295: if (obj == this) { 296: return true; 297: } 298: if (obj instanceof PeriodAxisLabelInfo) { 299: PeriodAxisLabelInfo info = (PeriodAxisLabelInfo) obj; 300: if (!info.periodClass.equals(this.periodClass)) { 301: return false; 302: } 303: if (!info.dateFormat.equals(this.dateFormat)) { 304: return false; 305: } 306: if (!info.padding.equals(this.padding)) { 307: return false; 308: } 309: if (!info.labelFont.equals(this.labelFont)) { 310: return false; 311: } 312: if (!info.labelPaint.equals(this.labelPaint)) { 313: return false; 314: } 315: if (info.drawDividers != this.drawDividers) { 316: return false; 317: } 318: if (!info.dividerStroke.equals(this.dividerStroke)) { 319: return false; 320: } 321: if (!info.dividerPaint.equals(this.dividerPaint)) { 322: return false; 323: } 324: return true; 325: } 326: return false; 327: } 328: 329: /** 330: * Returns a hash code for this object. 331: * 332: * @return A hash code. 333: */ 334: public int hashCode() { 335: int result = 41; 336: result = 37 * this.periodClass.hashCode(); 337: result = 37 * this.dateFormat.hashCode(); 338: return result; 339: } 340: 341: /** 342: * Returns a clone of the object. 343: * 344: * @return A clone. 345: * 346: * @throws CloneNotSupportedException if cloning is not supported. 347: */ 348: public Object clone() throws CloneNotSupportedException { 349: Object clone = (PeriodAxisLabelInfo) super.clone(); 350: return clone; 351: } 352: 353: /** 354: * Provides serialization support. 355: * 356: * @param stream the output stream. 357: * 358: * @throws IOException if there is an I/O error. 359: */ 360: private void writeObject(ObjectOutputStream stream) throws IOException { 361: stream.defaultWriteObject(); 362: SerialUtilities.writePaint(this.labelPaint, stream); 363: SerialUtilities.writeStroke(this.dividerStroke, stream); 364: SerialUtilities.writePaint(this.dividerPaint, stream); 365: } 366: 367: /** 368: * Provides serialization support. 369: * 370: * @param stream the input stream. 371: * 372: * @throws IOException if there is an I/O error. 373: * @throws ClassNotFoundException if there is a classpath problem. 374: */ 375: private void readObject(ObjectInputStream stream) 376: throws IOException, ClassNotFoundException { 377: stream.defaultReadObject(); 378: this.labelPaint = SerialUtilities.readPaint(stream); 379: this.dividerStroke = SerialUtilities.readStroke(stream); 380: this.dividerPaint = SerialUtilities.readPaint(stream); 381: } 382: 383: }