001/* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2007, 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 * AbstractCategoryItemLabelGenerator.java 029 * --------------------------------------- 030 * (C) Copyright 2005-2007, by Object Refinery Limited. 031 * 032 * Original Author: David Gilbert (for Object Refinery Limited); 033 * Contributor(s): -; 034 * 035 * Changes 036 * ------- 037 * 11-May-2004 : Version 1, distilled from StandardCategoryLabelGenerator (DG); 038 * 31-Jan-2005 : Added methods to return row and column labels (DG); 039 * 17-May-2005 : Added percentage to item array (DG); 040 * ------------- JFREECHART 1.0.x --------------------------------------------- 041 * 03-May-2006 : Added new constructor (DG); 042 */ 043 044package org.jfree.chart.labels; 045 046import java.io.Serializable; 047import java.text.DateFormat; 048import java.text.MessageFormat; 049import java.text.NumberFormat; 050 051import org.jfree.data.DataUtilities; 052import org.jfree.data.category.CategoryDataset; 053import org.jfree.util.ObjectUtilities; 054import org.jfree.util.PublicCloneable; 055 056/** 057 * A base class that can be used to create a label or tooltip generator that 058 * can be assigned to a 059 * {@link org.jfree.chart.renderer.category.CategoryItemRenderer}. 060 */ 061public abstract class AbstractCategoryItemLabelGenerator 062 implements PublicCloneable, Cloneable, Serializable { 063 064 /** For serialization. */ 065 private static final long serialVersionUID = -7108591260223293197L; 066 067 /** 068 * The label format string used by a <code>MessageFormat</code> object to 069 * combine the standard items: {0} = series name, {1} = category, 070 * {2} = value, {3} = value as a percentage of the column total. 071 */ 072 private String labelFormat; 073 074 /** The string used to represent a null value. */ 075 private String nullValueString; 076 077 /** 078 * A number formatter used to preformat the value before it is passed to 079 * the MessageFormat object. 080 */ 081 private NumberFormat numberFormat; 082 083 /** 084 * A date formatter used to preformat the value before it is passed to the 085 * MessageFormat object. 086 */ 087 private DateFormat dateFormat; 088 089 /** 090 * A number formatter used to preformat the percentage value before it is 091 * passed to the MessageFormat object. 092 */ 093 private NumberFormat percentFormat; 094 095 /** 096 * Creates a label generator with the specified number formatter. 097 * 098 * @param labelFormat the label format string (<code>null</code> not 099 * permitted). 100 * @param formatter the number formatter (<code>null</code> not permitted). 101 */ 102 protected AbstractCategoryItemLabelGenerator(String labelFormat, 103 NumberFormat formatter) { 104 this(labelFormat, formatter, NumberFormat.getPercentInstance()); 105 } 106 107 /** 108 * Creates a label generator with the specified number formatter. 109 * 110 * @param labelFormat the label format string (<code>null</code> not 111 * permitted). 112 * @param formatter the number formatter (<code>null</code> not permitted). 113 * @param percentFormatter the percent formatter (<code>null</code> not 114 * permitted). 115 * 116 * @since 1.0.2 117 */ 118 protected AbstractCategoryItemLabelGenerator(String labelFormat, 119 NumberFormat formatter, NumberFormat percentFormatter) { 120 if (labelFormat == null) { 121 throw new IllegalArgumentException("Null 'labelFormat' argument."); 122 } 123 if (formatter == null) { 124 throw new IllegalArgumentException("Null 'formatter' argument."); 125 } 126 if (percentFormatter == null) { 127 throw new IllegalArgumentException( 128 "Null 'percentFormatter' argument."); 129 } 130 this.labelFormat = labelFormat; 131 this.numberFormat = formatter; 132 this.percentFormat = percentFormatter; 133 this.dateFormat = null; 134 this.nullValueString = "-"; 135 } 136 137 /** 138 * Creates a label generator with the specified date formatter. 139 * 140 * @param labelFormat the label format string (<code>null</code> not 141 * permitted). 142 * @param formatter the date formatter (<code>null</code> not permitted). 143 */ 144 protected AbstractCategoryItemLabelGenerator(String labelFormat, 145 DateFormat formatter) { 146 if (labelFormat == null) { 147 throw new IllegalArgumentException("Null 'labelFormat' argument."); 148 } 149 if (formatter == null) { 150 throw new IllegalArgumentException("Null 'formatter' argument."); 151 } 152 this.labelFormat = labelFormat; 153 this.numberFormat = null; 154 this.percentFormat = NumberFormat.getPercentInstance(); 155 this.dateFormat = formatter; 156 this.nullValueString = "-"; 157 } 158 159 /** 160 * Generates a label for the specified row. 161 * 162 * @param dataset the dataset (<code>null</code> not permitted). 163 * @param row the row index (zero-based). 164 * 165 * @return The label. 166 */ 167 public String generateRowLabel(CategoryDataset dataset, int row) { 168 return dataset.getRowKey(row).toString(); 169 } 170 171 /** 172 * Generates a label for the specified row. 173 * 174 * @param dataset the dataset (<code>null</code> not permitted). 175 * @param column the column index (zero-based). 176 * 177 * @return The label. 178 */ 179 public String generateColumnLabel(CategoryDataset dataset, int column) { 180 return dataset.getColumnKey(column).toString(); 181 } 182 183 /** 184 * Returns the label format string. 185 * 186 * @return The label format string (never <code>null</code>). 187 */ 188 public String getLabelFormat() { 189 return this.labelFormat; 190 } 191 192 /** 193 * Returns the number formatter. 194 * 195 * @return The number formatter (possibly <code>null</code>). 196 */ 197 public NumberFormat getNumberFormat() { 198 return this.numberFormat; 199 } 200 201 /** 202 * Returns the date formatter. 203 * 204 * @return The date formatter (possibly <code>null</code>). 205 */ 206 public DateFormat getDateFormat() { 207 return this.dateFormat; 208 } 209 210 /** 211 * Generates a for the specified item. 212 * 213 * @param dataset the dataset (<code>null</code> not permitted). 214 * @param row the row index (zero-based). 215 * @param column the column index (zero-based). 216 * 217 * @return The label (possibly <code>null</code>). 218 */ 219 protected String generateLabelString(CategoryDataset dataset, 220 int row, int column) { 221 if (dataset == null) { 222 throw new IllegalArgumentException("Null 'dataset' argument."); 223 } 224 String result = null; 225 Object[] items = createItemArray(dataset, row, column); 226 result = MessageFormat.format(this.labelFormat, items); 227 return result; 228 229 } 230 231 /** 232 * Creates the array of items that can be passed to the 233 * {@link MessageFormat} class for creating labels. 234 * 235 * @param dataset the dataset (<code>null</code> not permitted). 236 * @param row the row index (zero-based). 237 * @param column the column index (zero-based). 238 * 239 * @return The items (never <code>null</code>). 240 */ 241 protected Object[] createItemArray(CategoryDataset dataset, 242 int row, int column) { 243 Object[] result = new Object[4]; 244 result[0] = dataset.getRowKey(row).toString(); 245 result[1] = dataset.getColumnKey(column).toString(); 246 Number value = dataset.getValue(row, column); 247 if (value != null) { 248 if (this.numberFormat != null) { 249 result[2] = this.numberFormat.format(value); 250 } 251 else if (this.dateFormat != null) { 252 result[2] = this.dateFormat.format(value); 253 } 254 } 255 else { 256 result[2] = this.nullValueString; 257 } 258 if (value != null) { 259 double total = DataUtilities.calculateColumnTotal(dataset, column); 260 double percent = value.doubleValue() / total; 261 result[3] = this.percentFormat.format(percent); 262 } 263 264 return result; 265 } 266 267 /** 268 * Tests this object for equality with an arbitrary object. 269 * 270 * @param obj the other object (<code>null</code> permitted). 271 * 272 * @return A boolean. 273 */ 274 public boolean equals(Object obj) { 275 if (obj == this) { 276 return true; 277 } 278 if (!(obj instanceof AbstractCategoryItemLabelGenerator)) { 279 return false; 280 } 281 282 AbstractCategoryItemLabelGenerator that 283 = (AbstractCategoryItemLabelGenerator) obj; 284 if (!this.labelFormat.equals(that.labelFormat)) { 285 return false; 286 } 287 if (!ObjectUtilities.equal(this.dateFormat, that.dateFormat)) { 288 return false; 289 } 290 if (!ObjectUtilities.equal(this.numberFormat, that.numberFormat)) { 291 return false; 292 } 293 return true; 294 } 295 296 /** 297 * Returns an independent copy of the generator. 298 * 299 * @return A clone. 300 * 301 * @throws CloneNotSupportedException should not happen. 302 */ 303 public Object clone() throws CloneNotSupportedException { 304 AbstractCategoryItemLabelGenerator clone 305 = (AbstractCategoryItemLabelGenerator) super.clone(); 306 if (this.numberFormat != null) { 307 clone.numberFormat = (NumberFormat) this.numberFormat.clone(); 308 } 309 if (this.dateFormat != null) { 310 clone.dateFormat = (DateFormat) this.dateFormat.clone(); 311 } 312 return clone; 313 } 314 315}