001 /* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2005, 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 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 025 * in the United States and other countries.] 026 * 027 * --------------------------------- 028 * AbstractXYItemLabelGenerator.java 029 * --------------------------------- 030 * (C) Copyright 2004, 2005, by Object Refinery Limited. 031 * 032 * Original Author: David Gilbert (for Object Refinery Limited); 033 * Contributor(s): -; 034 * 035 * $Id: AbstractXYItemLabelGenerator.java,v 1.9.2.1 2005/10/25 20:49:02 mungady Exp $ 036 * 037 * Changes 038 * ------- 039 * 27-Feb-2004 : Version 1 (DG); 040 * 12-May-2004 : Moved default tool tip format to 041 * StandardXYToolTipGenerator (DG); 042 * 15-Jul-2004 : Switched getX() with getXValue() and getY() with 043 * getYValue() (DG); 044 * 08-Oct-2004 : Modified createItemArray() method to handle null values (DG); 045 * 10-Jan-2005 : Updated createItemArray() to use x, y primitives if 046 * possible (DG); 047 * 048 */ 049 050 package org.jfree.chart.labels; 051 052 import java.io.Serializable; 053 import java.text.DateFormat; 054 import java.text.MessageFormat; 055 import java.text.NumberFormat; 056 import java.util.Date; 057 058 import org.jfree.data.xy.XYDataset; 059 import org.jfree.util.ObjectUtilities; 060 061 /** 062 * A base class for creating item label generators. 063 */ 064 public class AbstractXYItemLabelGenerator implements Cloneable, Serializable { 065 066 /** For serialization. */ 067 private static final long serialVersionUID = 5869744396278660636L; 068 069 /** The item label format string. */ 070 private String formatString; 071 072 /** A number formatter for the x value. */ 073 private NumberFormat xFormat; 074 075 /** A date formatter for the x value. */ 076 private DateFormat xDateFormat; 077 078 /** A formatter for the y value. */ 079 private NumberFormat yFormat; 080 081 /** A date formatter for the y value. */ 082 private DateFormat yDateFormat; 083 084 /** The string used to represent 'null' for the x-value. */ 085 private String nullXString = "null"; 086 087 /** The string used to represent 'null' for the y-value. */ 088 private String nullYString = "null"; 089 090 /** 091 * Creates an item label generator using default number formatters. 092 */ 093 protected AbstractXYItemLabelGenerator() { 094 this( 095 "{2}", NumberFormat.getNumberInstance(), 096 NumberFormat.getNumberInstance() 097 ); 098 } 099 100 /** 101 * Creates an item label generator using the specified number formatters. 102 * 103 * @param formatString the item label format string (<code>null</code> 104 * not permitted). 105 * @param xFormat the format object for the x values (<code>null</code> 106 * not permitted). 107 * @param yFormat the format object for the y values (<code>null</code> 108 * not permitted). 109 */ 110 protected AbstractXYItemLabelGenerator(String formatString, 111 NumberFormat xFormat, 112 NumberFormat yFormat) { 113 114 if (formatString == null) { 115 throw new IllegalArgumentException("Null 'formatString' argument."); 116 } 117 if (xFormat == null) { 118 throw new IllegalArgumentException("Null 'xFormat' argument."); 119 } 120 if (yFormat == null) { 121 throw new IllegalArgumentException("Null 'yFormat' argument."); 122 } 123 this.formatString = formatString; 124 this.xFormat = xFormat; 125 this.yFormat = yFormat; 126 127 } 128 129 /** 130 * Creates an item label generator using the specified number formatters. 131 * 132 * @param formatString the item label format string (<code>null</code> 133 * not permitted). 134 * @param xFormat the format object for the x values (<code>null</code> 135 * permitted). 136 * @param yFormat the format object for the y values (<code>null</code> 137 * not permitted). 138 */ 139 protected AbstractXYItemLabelGenerator(String formatString, 140 DateFormat xFormat, 141 NumberFormat yFormat) { 142 143 this(formatString, NumberFormat.getInstance(), yFormat); 144 this.xDateFormat = xFormat; 145 146 } 147 148 /** 149 * Creates an item label generator using the specified number formatters. 150 * 151 * @param formatString the item label format string (<code>null</code> 152 * not permitted). 153 * @param xFormat the format object for the x values (<code>null</code> 154 * permitted). 155 * @param yFormat the format object for the y values (<code>null</code> 156 * not permitted). 157 */ 158 protected AbstractXYItemLabelGenerator(String formatString, 159 DateFormat xFormat, 160 DateFormat yFormat) { 161 162 this( 163 formatString, NumberFormat.getInstance(), 164 NumberFormat.getInstance() 165 ); 166 this.xDateFormat = xFormat; 167 this.yDateFormat = yFormat; 168 169 } 170 171 /** 172 * Returns the format string (this controls the overall structure of the 173 * label). 174 * 175 * @return The format string (never <code>null</code>). 176 */ 177 public String getFormatString() { 178 return this.formatString; 179 } 180 181 /** 182 * Returns the number formatter for the x-values. 183 * 184 * @return The number formatter (possibly <code>null</code>). 185 */ 186 public NumberFormat getXFormat() { 187 return this.xFormat; 188 } 189 190 /** 191 * Returns the date formatter for the x-values. 192 * 193 * @return The date formatter (possibly <code>null</code>). 194 */ 195 public DateFormat getXDateFormat() { 196 return this.xDateFormat; 197 } 198 199 /** 200 * Returns the number formatter for the y-values. 201 * 202 * @return The number formatter (possibly <code>null</code>). 203 */ 204 public NumberFormat getYFormat() { 205 return this.yFormat; 206 } 207 208 /** 209 * Returns the date formatter for the y-values. 210 * 211 * @return The date formatter (possibly <code>null</code>). 212 */ 213 public DateFormat getYDateFormat() { 214 return this.yDateFormat; 215 } 216 217 /** 218 * Generates a label string for an item in the dataset. 219 * 220 * @param dataset the dataset (<code>null</code> not permitted). 221 * @param series the series (zero-based index). 222 * @param item the item (zero-based index). 223 * 224 * @return The label (possibly <code>null</code>). 225 */ 226 public String generateLabelString(XYDataset dataset, int series, int item) { 227 String result = null; 228 Object[] items = createItemArray(dataset, series, item); 229 result = MessageFormat.format(this.formatString, items); 230 return result; 231 } 232 233 /** 234 * Creates the array of items that can be passed to the 235 * {@link MessageFormat} class for creating labels. 236 * 237 * @param dataset the dataset (<code>null</code> not permitted). 238 * @param series the series (zero-based index). 239 * @param item the item (zero-based index). 240 * 241 * @return The items (never <code>null</code>). 242 */ 243 protected Object[] createItemArray(XYDataset dataset, int series, 244 int item) { 245 Object[] result = new Object[3]; 246 result[0] = dataset.getSeriesKey(series).toString(); 247 248 double x = dataset.getXValue(series, item); 249 if (Double.isNaN(x) && dataset.getX(series, item) == null) { 250 result[1] = this.nullXString; 251 } 252 else { 253 if (this.xDateFormat != null) { 254 result[1] = this.xDateFormat.format(new Date((long) x)); 255 } 256 else { 257 result[1] = this.xFormat.format(x); 258 } 259 } 260 261 double y = dataset.getYValue(series, item); 262 if (Double.isNaN(y) && dataset.getY(series, item) == null) { 263 result[2] = this.nullYString; 264 } 265 else { 266 if (this.yDateFormat != null) { 267 result[2] = this.yDateFormat.format(new Date((long) y)); 268 } 269 else { 270 result[2] = this.yFormat.format(y); 271 } 272 } 273 return result; 274 } 275 276 /** 277 * Tests this object for equality with an arbitrary object. 278 * 279 * @param obj the other object (<code>null</code> permitted). 280 * 281 * @return A boolean. 282 */ 283 public boolean equals(Object obj) { 284 if (obj == this) { 285 return true; 286 } 287 if (!(obj instanceof AbstractXYItemLabelGenerator)) { 288 return false; 289 } 290 AbstractXYItemLabelGenerator that = (AbstractXYItemLabelGenerator) obj; 291 if (!this.formatString.equals(that.formatString)) { 292 return false; 293 } 294 if (!ObjectUtilities.equal(this.xFormat, that.xFormat)) { 295 return false; 296 } 297 if (!ObjectUtilities.equal(this.xDateFormat, that.xDateFormat)) { 298 return false; 299 } 300 if (!ObjectUtilities.equal(this.yFormat, that.yFormat)) { 301 return false; 302 } 303 if (!ObjectUtilities.equal(this.yDateFormat, that.yDateFormat)) { 304 return false; 305 } 306 return true; 307 308 } 309 310 /** 311 * Returns an independent copy of the generator. 312 * 313 * @return A clone. 314 * 315 * @throws CloneNotSupportedException if cloning is not supported. 316 */ 317 public Object clone() throws CloneNotSupportedException { 318 319 AbstractXYItemLabelGenerator clone 320 = (AbstractXYItemLabelGenerator) super.clone(); 321 322 if (this.xFormat != null) { 323 clone.xFormat = (NumberFormat) this.xFormat.clone(); 324 } 325 326 if (this.yFormat != null) { 327 clone.yFormat = (NumberFormat) this.yFormat.clone(); 328 } 329 330 return clone; 331 332 } 333 334 }