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