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