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: * AbstractXYItemLabelGenerator.java 29: * --------------------------------- 30: * (C) Copyright 2004-2007, by Object Refinery Limited. 31: * 32: * Original Author: David Gilbert (for Object Refinery Limited); 33: * Contributor(s): -; 34: * 35: * Changes 36: * ------- 37: * 27-Feb-2004 : Version 1 (DG); 38: * 12-May-2004 : Moved default tool tip format to 39: * StandardXYToolTipGenerator (DG); 40: * 15-Jul-2004 : Switched getX() with getXValue() and getY() with 41: * getYValue() (DG); 42: * 08-Oct-2004 : Modified createItemArray() method to handle null values (DG); 43: * 10-Jan-2005 : Updated createItemArray() to use x, y primitives if 44: * possible (DG); 45: * ------------- JFREECHART 1.0.x -------------------------------------------- 46: * 26-Jan-2006 : Minor API doc update (DG); 47: * 25-Jan-2007 : Added new constructor and fixed bug in clone() method (DG); 48: * 16-Oct-2007 : Removed redundant code (DG); 49: * 50: */ 51: 52: package org.jfree.chart.labels; 53: 54: import java.io.Serializable; 55: import java.text.DateFormat; 56: import java.text.MessageFormat; 57: import java.text.NumberFormat; 58: import java.util.Date; 59: 60: import org.jfree.data.xy.XYDataset; 61: import org.jfree.util.ObjectUtilities; 62: 63: /** 64: * A base class for creating item label generators. 65: */ 66: public class AbstractXYItemLabelGenerator implements Cloneable, Serializable { 67: 68: /** For serialization. */ 69: private static final long serialVersionUID = 5869744396278660636L; 70: 71: /** The item label format string. */ 72: private String formatString; 73: 74: /** A number formatter for the x value. */ 75: private NumberFormat xFormat; 76: 77: /** A date formatter for the x value. */ 78: private DateFormat xDateFormat; 79: 80: /** A formatter for the y value. */ 81: private NumberFormat yFormat; 82: 83: /** A date formatter for the y value. */ 84: private DateFormat yDateFormat; 85: 86: /** The string used to represent 'null' for the y-value. */ 87: private String nullYString = "null"; 88: 89: /** 90: * Creates an item label generator using default number formatters. 91: */ 92: protected AbstractXYItemLabelGenerator() { 93: this("{2}", NumberFormat.getNumberInstance(), 94: NumberFormat.getNumberInstance()); 95: } 96: 97: /** 98: * Creates an item label generator using the specified number formatters. 99: * 100: * @param formatString the item label format string (<code>null</code> 101: * not permitted). 102: * @param xFormat the format object for the x values (<code>null</code> 103: * not permitted). 104: * @param yFormat the format object for the y values (<code>null</code> 105: * not permitted). 106: */ 107: protected AbstractXYItemLabelGenerator(String formatString, 108: NumberFormat xFormat, 109: NumberFormat yFormat) { 110: 111: if (formatString == null) { 112: throw new IllegalArgumentException("Null 'formatString' argument."); 113: } 114: if (xFormat == null) { 115: throw new IllegalArgumentException("Null 'xFormat' argument."); 116: } 117: if (yFormat == null) { 118: throw new IllegalArgumentException("Null 'yFormat' argument."); 119: } 120: this.formatString = formatString; 121: this.xFormat = xFormat; 122: this.yFormat = yFormat; 123: 124: } 125: 126: /** 127: * Creates an item label generator using the specified number formatters. 128: * 129: * @param formatString the item label format string (<code>null</code> 130: * not permitted). 131: * @param xFormat the format object for the x values (<code>null</code> 132: * permitted). 133: * @param yFormat the format object for the y values (<code>null</code> 134: * not permitted). 135: */ 136: protected AbstractXYItemLabelGenerator(String formatString, 137: DateFormat xFormat, 138: NumberFormat yFormat) { 139: 140: this(formatString, NumberFormat.getInstance(), yFormat); 141: this.xDateFormat = xFormat; 142: 143: } 144: 145: /** 146: * Creates an item label generator using the specified formatters (a 147: * number formatter for the x-values and a date formatter for the 148: * y-values). 149: * 150: * @param formatString the item label format string (<code>null</code> 151: * not permitted). 152: * @param xFormat the format object for the x values (<code>null</code> 153: * permitted). 154: * @param yFormat the format object for the y values (<code>null</code> 155: * not permitted). 156: * 157: * @since 1.0.4 158: */ 159: protected AbstractXYItemLabelGenerator(String formatString, 160: NumberFormat xFormat, DateFormat yFormat) { 161: 162: this(formatString, xFormat, NumberFormat.getInstance()); 163: this.yDateFormat = yFormat; 164: } 165: 166: /** 167: * Creates an item label generator using the specified number formatters. 168: * 169: * @param formatString the item label format string (<code>null</code> 170: * not permitted). 171: * @param xFormat the format object for the x values (<code>null</code> 172: * permitted). 173: * @param yFormat the format object for the y values (<code>null</code> 174: * not permitted). 175: */ 176: protected AbstractXYItemLabelGenerator(String formatString, 177: DateFormat xFormat, 178: DateFormat yFormat) { 179: 180: this(formatString, NumberFormat.getInstance(), 181: NumberFormat.getInstance()); 182: this.xDateFormat = xFormat; 183: this.yDateFormat = yFormat; 184: 185: } 186: 187: /** 188: * Returns the format string (this controls the overall structure of the 189: * label). 190: * 191: * @return The format string (never <code>null</code>). 192: */ 193: public String getFormatString() { 194: return this.formatString; 195: } 196: 197: /** 198: * Returns the number formatter for the x-values. 199: * 200: * @return The number formatter (possibly <code>null</code>). 201: */ 202: public NumberFormat getXFormat() { 203: return this.xFormat; 204: } 205: 206: /** 207: * Returns the date formatter for the x-values. 208: * 209: * @return The date formatter (possibly <code>null</code>). 210: */ 211: public DateFormat getXDateFormat() { 212: return this.xDateFormat; 213: } 214: 215: /** 216: * Returns the number formatter for the y-values. 217: * 218: * @return The number formatter (possibly <code>null</code>). 219: */ 220: public NumberFormat getYFormat() { 221: return this.yFormat; 222: } 223: 224: /** 225: * Returns the date formatter for the y-values. 226: * 227: * @return The date formatter (possibly <code>null</code>). 228: */ 229: public DateFormat getYDateFormat() { 230: return this.yDateFormat; 231: } 232: 233: /** 234: * Generates a label string for an item in the dataset. 235: * 236: * @param dataset the dataset (<code>null</code> not permitted). 237: * @param series the series (zero-based index). 238: * @param item the item (zero-based index). 239: * 240: * @return The label (possibly <code>null</code>). 241: */ 242: public String generateLabelString(XYDataset dataset, int series, int item) { 243: String result = null; 244: Object[] items = createItemArray(dataset, series, item); 245: result = MessageFormat.format(this.formatString, items); 246: return result; 247: } 248: 249: /** 250: * Creates the array of items that can be passed to the 251: * {@link MessageFormat} class for creating labels. 252: * 253: * @param dataset the dataset (<code>null</code> not permitted). 254: * @param series the series (zero-based index). 255: * @param item the item (zero-based index). 256: * 257: * @return An array of three items from the dataset formatted as 258: * <code>String</code> objects (never <code>null</code>). 259: */ 260: protected Object[] createItemArray(XYDataset dataset, int series, 261: int item) { 262: Object[] result = new Object[3]; 263: result[0] = dataset.getSeriesKey(series).toString(); 264: 265: double x = dataset.getXValue(series, item); 266: if (this.xDateFormat != null) { 267: result[1] = this.xDateFormat.format(new Date((long) x)); 268: } 269: else { 270: result[1] = this.xFormat.format(x); 271: } 272: 273: double y = dataset.getYValue(series, item); 274: if (Double.isNaN(y) && dataset.getY(series, item) == null) { 275: result[2] = this.nullYString; 276: } 277: else { 278: if (this.yDateFormat != null) { 279: result[2] = this.yDateFormat.format(new Date((long) y)); 280: } 281: else { 282: result[2] = this.yFormat.format(y); 283: } 284: } 285: return result; 286: } 287: 288: /** 289: * Tests this object for equality with an arbitrary object. 290: * 291: * @param obj the other object (<code>null</code> permitted). 292: * 293: * @return A boolean. 294: */ 295: public boolean equals(Object obj) { 296: if (obj == this) { 297: return true; 298: } 299: if (!(obj instanceof AbstractXYItemLabelGenerator)) { 300: return false; 301: } 302: AbstractXYItemLabelGenerator that = (AbstractXYItemLabelGenerator) obj; 303: if (!this.formatString.equals(that.formatString)) { 304: return false; 305: } 306: if (!ObjectUtilities.equal(this.xFormat, that.xFormat)) { 307: return false; 308: } 309: if (!ObjectUtilities.equal(this.xDateFormat, that.xDateFormat)) { 310: return false; 311: } 312: if (!ObjectUtilities.equal(this.yFormat, that.yFormat)) { 313: return false; 314: } 315: if (!ObjectUtilities.equal(this.yDateFormat, that.yDateFormat)) { 316: return false; 317: } 318: return true; 319: } 320: 321: /** 322: * Returns an independent copy of the generator. 323: * 324: * @return A clone. 325: * 326: * @throws CloneNotSupportedException if cloning is not supported. 327: */ 328: public Object clone() throws CloneNotSupportedException { 329: AbstractXYItemLabelGenerator clone 330: = (AbstractXYItemLabelGenerator) super.clone(); 331: if (this.xFormat != null) { 332: clone.xFormat = (NumberFormat) this.xFormat.clone(); 333: } 334: if (this.yFormat != null) { 335: clone.yFormat = (NumberFormat) this.yFormat.clone(); 336: } 337: if (this.xDateFormat != null) { 338: clone.xDateFormat = (DateFormat) this.xDateFormat.clone(); 339: } 340: if (this.yDateFormat != null) { 341: clone.yDateFormat = (DateFormat) this.yDateFormat.clone(); 342: } 343: return clone; 344: } 345: 346: }