001/* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2017, 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 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 025 * Other names may be trademarks of their respective owners.] 026 * 027 * ------------------------ 028 * PeriodAxisLabelInfo.java 029 * ------------------------ 030 * (C) Copyright 2004-2017, by Object Refinery Limited and Contributors. 031 * 032 * Original Author: David Gilbert (for Object Refinery Limited); 033 * Contributor(s): -; 034 * 035 * Changes 036 * ------- 037 * 01-Jun-2004 : Version 1 (DG); 038 * 23-Feb-2005 : Replaced Spacer with RectangleInsets (DG); 039 * 01-Mar-2005 : Modified constructors to accept DateFormat (DG); 040 * 20-May-2005 : Added default constants and null argument checks in the 041 * constructor (DG); 042 * 02-Mar-2009 : Updated createInstance to use locale (DG); 043 * 02-Jul-2013 : Use ParamChecks (DG); 044 * 045 */ 046 047package org.jfree.chart.axis; 048 049import java.awt.BasicStroke; 050import java.awt.Color; 051import java.awt.Font; 052import java.awt.Paint; 053import java.awt.Stroke; 054import java.io.IOException; 055import java.io.ObjectInputStream; 056import java.io.ObjectOutputStream; 057import java.io.Serializable; 058import java.lang.reflect.Constructor; 059import java.text.DateFormat; 060import java.util.Date; 061import java.util.Locale; 062import java.util.TimeZone; 063import org.jfree.chart.ui.RectangleInsets; 064import org.jfree.chart.util.Args; 065import org.jfree.chart.util.SerialUtils; 066 067import org.jfree.data.time.RegularTimePeriod; 068 069/** 070 * A record that contains information for one "band" of date labels in 071 * a {@link PeriodAxis}. 072 */ 073public class PeriodAxisLabelInfo implements Cloneable, Serializable { 074 075 /** For serialization. */ 076 private static final long serialVersionUID = 5710451740920277357L; 077 078 /** The default insets. */ 079 public static final RectangleInsets DEFAULT_INSETS 080 = new RectangleInsets(2, 2, 2, 2); 081 082 /** The default font. */ 083 public static final Font DEFAULT_FONT 084 = new Font("SansSerif", Font.PLAIN, 10); 085 086 /** The default label paint. */ 087 public static final Paint DEFAULT_LABEL_PAINT = Color.BLACK; 088 089 /** The default divider stroke. */ 090 public static final Stroke DEFAULT_DIVIDER_STROKE = new BasicStroke(0.5f); 091 092 /** The default divider paint. */ 093 public static final Paint DEFAULT_DIVIDER_PAINT = Color.GRAY; 094 095 /** The subclass of {@link RegularTimePeriod} to use for this band. */ 096 private Class periodClass; 097 098 /** Controls the gaps around the band. */ 099 private RectangleInsets padding; 100 101 /** The date formatter. */ 102 private DateFormat dateFormat; 103 104 /** The label font. */ 105 private Font labelFont; 106 107 /** The label paint. */ 108 private transient Paint labelPaint; 109 110 /** A flag that controls whether or not dividers are visible. */ 111 private boolean drawDividers; 112 113 /** The stroke used to draw the dividers. */ 114 private transient Stroke dividerStroke; 115 116 /** The paint used to draw the dividers. */ 117 private transient Paint dividerPaint; 118 119 /** 120 * Creates a new instance. 121 * 122 * @param periodClass the subclass of {@link RegularTimePeriod} to use 123 * ({@code null} not permitted). 124 * @param dateFormat the date format ({@code null} not permitted). 125 */ 126 public PeriodAxisLabelInfo(Class periodClass, DateFormat dateFormat) { 127 this(periodClass, dateFormat, DEFAULT_INSETS, DEFAULT_FONT, 128 DEFAULT_LABEL_PAINT, true, DEFAULT_DIVIDER_STROKE, 129 DEFAULT_DIVIDER_PAINT); 130 } 131 132 /** 133 * Creates a new instance. 134 * 135 * @param periodClass the subclass of {@link RegularTimePeriod} to use 136 * ({@code null} not permitted). 137 * @param dateFormat the date format ({@code null} not permitted). 138 * @param padding controls the space around the band ({@code null} 139 * not permitted). 140 * @param labelFont the label font ({@code null} not permitted). 141 * @param labelPaint the label paint ({@code null} not permitted). 142 * @param drawDividers a flag that controls whether dividers are drawn. 143 * @param dividerStroke the stroke used to draw the dividers 144 * ({@code null} not permitted). 145 * @param dividerPaint the paint used to draw the dividers 146 * ({@code null} not permitted). 147 */ 148 public PeriodAxisLabelInfo(Class periodClass, DateFormat dateFormat, 149 RectangleInsets padding, Font labelFont, Paint labelPaint, 150 boolean drawDividers, Stroke dividerStroke, Paint dividerPaint) { 151 Args.nullNotPermitted(periodClass, "periodClass"); 152 Args.nullNotPermitted(dateFormat, "dateFormat"); 153 Args.nullNotPermitted(padding, "padding"); 154 Args.nullNotPermitted(labelFont, "labelFont"); 155 Args.nullNotPermitted(labelPaint, "labelPaint"); 156 Args.nullNotPermitted(dividerStroke, "dividerStroke"); 157 Args.nullNotPermitted(dividerPaint, "dividerPaint"); 158 this.periodClass = periodClass; 159 this.dateFormat = (DateFormat) dateFormat.clone(); 160 this.padding = padding; 161 this.labelFont = labelFont; 162 this.labelPaint = labelPaint; 163 this.drawDividers = drawDividers; 164 this.dividerStroke = dividerStroke; 165 this.dividerPaint = dividerPaint; 166 } 167 168 /** 169 * Returns the subclass of {@link RegularTimePeriod} that should be used 170 * to generate the date labels. 171 * 172 * @return The class. 173 */ 174 public Class getPeriodClass() { 175 return this.periodClass; 176 } 177 178 /** 179 * Returns a copy of the date formatter. 180 * 181 * @return A copy of the date formatter (never {@code null}). 182 */ 183 public DateFormat getDateFormat() { 184 return (DateFormat) this.dateFormat.clone(); 185 } 186 187 /** 188 * Returns the padding for the band. 189 * 190 * @return The padding. 191 */ 192 public RectangleInsets getPadding() { 193 return this.padding; 194 } 195 196 /** 197 * Returns the label font. 198 * 199 * @return The label font (never {@code null}). 200 */ 201 public Font getLabelFont() { 202 return this.labelFont; 203 } 204 205 /** 206 * Returns the label paint. 207 * 208 * @return The label paint. 209 */ 210 public Paint getLabelPaint() { 211 return this.labelPaint; 212 } 213 214 /** 215 * Returns a flag that controls whether or not dividers are drawn. 216 * 217 * @return A flag. 218 */ 219 public boolean getDrawDividers() { 220 return this.drawDividers; 221 } 222 223 /** 224 * Returns the stroke used to draw the dividers. 225 * 226 * @return The stroke. 227 */ 228 public Stroke getDividerStroke() { 229 return this.dividerStroke; 230 } 231 232 /** 233 * Returns the paint used to draw the dividers. 234 * 235 * @return The paint. 236 */ 237 public Paint getDividerPaint() { 238 return this.dividerPaint; 239 } 240 241 /** 242 * Creates a time period that includes the specified millisecond, assuming 243 * the given time zone. 244 * 245 * @param millisecond the time. 246 * @param zone the time zone. 247 * @param locale the locale. 248 * 249 * @return The time period. 250 * 251 * @since 1.0.13. 252 */ 253 public RegularTimePeriod createInstance(Date millisecond, TimeZone zone, 254 Locale locale) { 255 RegularTimePeriod result = null; 256 try { 257 Constructor c = this.periodClass.getDeclaredConstructor( 258 new Class[] {Date.class, TimeZone.class, Locale.class}); 259 result = (RegularTimePeriod) c.newInstance(new Object[] { 260 millisecond, zone, locale}); 261 } 262 catch (Exception e) { 263 // do nothing 264 } 265 return result; 266 } 267 268 /** 269 * Tests this object for equality with an arbitrary object. 270 * 271 * @param obj the object to test against ({@code null} permitted). 272 * 273 * @return A boolean. 274 */ 275 @Override 276 public boolean equals(Object obj) { 277 if (obj == this) { 278 return true; 279 } 280 if (obj instanceof PeriodAxisLabelInfo) { 281 PeriodAxisLabelInfo info = (PeriodAxisLabelInfo) obj; 282 if (!info.periodClass.equals(this.periodClass)) { 283 return false; 284 } 285 if (!info.dateFormat.equals(this.dateFormat)) { 286 return false; 287 } 288 if (!info.padding.equals(this.padding)) { 289 return false; 290 } 291 if (!info.labelFont.equals(this.labelFont)) { 292 return false; 293 } 294 if (!info.labelPaint.equals(this.labelPaint)) { 295 return false; 296 } 297 if (info.drawDividers != this.drawDividers) { 298 return false; 299 } 300 if (!info.dividerStroke.equals(this.dividerStroke)) { 301 return false; 302 } 303 if (!info.dividerPaint.equals(this.dividerPaint)) { 304 return false; 305 } 306 return true; 307 } 308 return false; 309 } 310 311 /** 312 * Returns a hash code for this object. 313 * 314 * @return A hash code. 315 */ 316 @Override 317 public int hashCode() { 318 int result = 41; 319 result = result + 37 * this.periodClass.hashCode(); 320 result = result + 37 * this.dateFormat.hashCode(); 321 return result; 322 } 323 324 /** 325 * Returns a clone of the object. 326 * 327 * @return A clone. 328 * 329 * @throws CloneNotSupportedException if cloning is not supported. 330 */ 331 @Override 332 public Object clone() throws CloneNotSupportedException { 333 PeriodAxisLabelInfo clone = (PeriodAxisLabelInfo) super.clone(); 334 return clone; 335 } 336 337 /** 338 * Provides serialization support. 339 * 340 * @param stream the output stream. 341 * 342 * @throws IOException if there is an I/O error. 343 */ 344 private void writeObject(ObjectOutputStream stream) throws IOException { 345 stream.defaultWriteObject(); 346 SerialUtils.writePaint(this.labelPaint, stream); 347 SerialUtils.writeStroke(this.dividerStroke, stream); 348 SerialUtils.writePaint(this.dividerPaint, stream); 349 } 350 351 /** 352 * Provides serialization support. 353 * 354 * @param stream the input stream. 355 * 356 * @throws IOException if there is an I/O error. 357 * @throws ClassNotFoundException if there is a classpath problem. 358 */ 359 private void readObject(ObjectInputStream stream) 360 throws IOException, ClassNotFoundException { 361 stream.defaultReadObject(); 362 this.labelPaint = SerialUtils.readPaint(stream); 363 this.dividerStroke = SerialUtils.readStroke(stream); 364 this.dividerPaint = SerialUtils.readPaint(stream); 365 } 366 367}