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