Source for org.jfree.chart.axis.PeriodAxisLabelInfo

   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: }