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 * DefaultCategoryDataset.java 029 * --------------------------- 030 * (C) Copyright 2002-2007, by Object Refinery Limited. 031 * 032 * Original Author: David Gilbert (for Object Refinery Limited); 033 * Contributor(s): -; 034 * 035 * $Id: DefaultCategoryDataset.java,v 1.5.2.4 2007/03/08 11:12:08 mungady Exp $ 036 * 037 * Changes 038 * ------- 039 * 21-Jan-2003 : Added standard header, and renamed DefaultCategoryDataset (DG); 040 * 13-Mar-2003 : Inserted DefaultKeyedValues2DDataset into class hierarchy (DG); 041 * 06-Oct-2003 : Added incrementValue() method (DG); 042 * 05-Apr-2004 : Added clear() method (DG); 043 * 18-Aug-2004 : Moved from org.jfree.data --> org.jfree.data.category (DG); 044 * ------------- JFREECHART 1.0.x --------------------------------------------- 045 * 26-Feb-2007 : Updated API docs (DG); 046 * 08-Mar-2007 : Implemented clone() (DG); 047 * 048 */ 049 050 package org.jfree.data.category; 051 052 import java.io.Serializable; 053 import java.util.List; 054 055 import org.jfree.data.DefaultKeyedValues2D; 056 import org.jfree.data.UnknownKeyException; 057 import org.jfree.data.general.AbstractDataset; 058 import org.jfree.data.general.DatasetChangeEvent; 059 060 /** 061 * A default implementation of the {@link CategoryDataset} interface. 062 */ 063 public class DefaultCategoryDataset extends AbstractDataset 064 implements CategoryDataset, Serializable { 065 066 /** For serialization. */ 067 private static final long serialVersionUID = -8168173757291644622L; 068 069 /** A storage structure for the data. */ 070 private DefaultKeyedValues2D data; 071 072 /** 073 * Creates a new (empty) dataset. 074 */ 075 public DefaultCategoryDataset() { 076 this.data = new DefaultKeyedValues2D(); 077 } 078 079 /** 080 * Returns the number of rows in the table. 081 * 082 * @return The row count. 083 * 084 * @see #getColumnCount() 085 */ 086 public int getRowCount() { 087 return this.data.getRowCount(); 088 } 089 090 /** 091 * Returns the number of columns in the table. 092 * 093 * @return The column count. 094 * 095 * @see #getRowCount() 096 */ 097 public int getColumnCount() { 098 return this.data.getColumnCount(); 099 } 100 101 /** 102 * Returns a value from the table. 103 * 104 * @param row the row index (zero-based). 105 * @param column the column index (zero-based). 106 * 107 * @return The value (possibly <code>null</code>). 108 * 109 * @see #addValue(Number, Comparable, Comparable) 110 */ 111 public Number getValue(int row, int column) { 112 return this.data.getValue(row, column); 113 } 114 115 /** 116 * Returns a row key. 117 * 118 * @param row the row index (zero-based). 119 * 120 * @return The row key. 121 * 122 * @see #getRowIndex(Comparable) 123 * @see #getRowKeys() 124 */ 125 public Comparable getRowKey(int row) { 126 return this.data.getRowKey(row); 127 } 128 129 /** 130 * Returns the row index for a given key. 131 * 132 * @param key the row key. 133 * 134 * @return The row index. 135 * 136 * @see #getRowKey(int) 137 */ 138 public int getRowIndex(Comparable key) { 139 return this.data.getRowIndex(key); 140 } 141 142 /** 143 * Returns the row keys. 144 * 145 * @return The keys. 146 * 147 * @see #getRowKey(int) 148 */ 149 public List getRowKeys() { 150 return this.data.getRowKeys(); 151 } 152 153 /** 154 * Returns a column key. 155 * 156 * @param column the column index (zero-based). 157 * 158 * @return The column key. 159 * 160 * @see #getColumnIndex(Comparable) 161 */ 162 public Comparable getColumnKey(int column) { 163 return this.data.getColumnKey(column); 164 } 165 166 /** 167 * Returns the column index for a given key. 168 * 169 * @param key the column key. 170 * 171 * @return The column index. 172 * 173 * @see #getColumnKey(int) 174 */ 175 public int getColumnIndex(Comparable key) { 176 return this.data.getColumnIndex(key); 177 } 178 179 /** 180 * Returns the column keys. 181 * 182 * @return The keys. 183 * 184 * @see #getColumnKey(int) 185 */ 186 public List getColumnKeys() { 187 return this.data.getColumnKeys(); 188 } 189 190 /** 191 * Returns the value for a pair of keys. 192 * 193 * @param rowKey the row key (<code>null</code> not permitted). 194 * @param columnKey the column key (<code>null</code> not permitted). 195 * 196 * @return The value (possibly <code>null</code>). 197 * 198 * @throws UnknownKeyException if either key is not defined in the dataset. 199 * 200 * @see #addValue(Number, Comparable, Comparable) 201 */ 202 public Number getValue(Comparable rowKey, Comparable columnKey) { 203 return this.data.getValue(rowKey, columnKey); 204 } 205 206 /** 207 * Adds a value to the table. Performs the same function as setValue(). 208 * 209 * @param value the value. 210 * @param rowKey the row key. 211 * @param columnKey the column key. 212 * 213 * @see #getValue(Comparable, Comparable) 214 * @see #removeValue(Comparable, Comparable) 215 */ 216 public void addValue(Number value, Comparable rowKey, 217 Comparable columnKey) { 218 this.data.addValue(value, rowKey, columnKey); 219 fireDatasetChanged(); 220 } 221 222 /** 223 * Adds a value to the table. 224 * 225 * @param value the value. 226 * @param rowKey the row key. 227 * @param columnKey the column key. 228 * 229 * @see #getValue(Comparable, Comparable) 230 */ 231 public void addValue(double value, Comparable rowKey, 232 Comparable columnKey) { 233 addValue(new Double(value), rowKey, columnKey); 234 } 235 236 /** 237 * Adds or updates a value in the table and sends a 238 * {@link DatasetChangeEvent} to all registered listeners. 239 * 240 * @param value the value (<code>null</code> permitted). 241 * @param rowKey the row key (<code>null</code> not permitted). 242 * @param columnKey the column key (<code>null</code> not permitted). 243 * 244 * @see #getValue(Comparable, Comparable) 245 */ 246 public void setValue(Number value, Comparable rowKey, 247 Comparable columnKey) { 248 this.data.setValue(value, rowKey, columnKey); 249 fireDatasetChanged(); 250 } 251 252 /** 253 * Adds or updates a value in the table and sends a 254 * {@link DatasetChangeEvent} to all registered listeners. 255 * 256 * @param value the value. 257 * @param rowKey the row key (<code>null</code> not permitted). 258 * @param columnKey the column key (<code>null</code> not permitted). 259 * 260 * @see #getValue(Comparable, Comparable) 261 */ 262 public void setValue(double value, Comparable rowKey, 263 Comparable columnKey) { 264 setValue(new Double(value), rowKey, columnKey); 265 } 266 267 /** 268 * Adds the specified value to an existing value in the dataset (if the 269 * existing value is <code>null</code>, it is treated as if it were 0.0). 270 * 271 * @param value the value. 272 * @param rowKey the row key (<code>null</code> not permitted). 273 * @param columnKey the column key (<code>null</code> not permitted). 274 * 275 * @throws UnknownKeyException if either key is not defined in the dataset. 276 */ 277 public void incrementValue(double value, 278 Comparable rowKey, 279 Comparable columnKey) { 280 double existing = 0.0; 281 Number n = getValue(rowKey, columnKey); 282 if (n != null) { 283 existing = n.doubleValue(); 284 } 285 setValue(existing + value, rowKey, columnKey); 286 } 287 288 /** 289 * Removes a value from the dataset and sends a {@link DatasetChangeEvent} 290 * to all registered listeners. 291 * 292 * @param rowKey the row key. 293 * @param columnKey the column key. 294 * 295 * @see #addValue(Number, Comparable, Comparable) 296 */ 297 public void removeValue(Comparable rowKey, Comparable columnKey) { 298 this.data.removeValue(rowKey, columnKey); 299 fireDatasetChanged(); 300 } 301 302 /** 303 * Removes a row from the dataset and sends a {@link DatasetChangeEvent} 304 * to all registered listeners. 305 * 306 * @param rowIndex the row index. 307 * 308 * @see #removeColumn(int) 309 */ 310 public void removeRow(int rowIndex) { 311 this.data.removeRow(rowIndex); 312 fireDatasetChanged(); 313 } 314 315 /** 316 * Removes a row from the dataset and sends a {@link DatasetChangeEvent} 317 * to all registered listeners. 318 * 319 * @param rowKey the row key. 320 * 321 * @see #removeColumn(Comparable) 322 */ 323 public void removeRow(Comparable rowKey) { 324 this.data.removeRow(rowKey); 325 fireDatasetChanged(); 326 } 327 328 /** 329 * Removes a column from the dataset and sends a {@link DatasetChangeEvent} 330 * to all registered listeners. 331 * 332 * @param columnIndex the column index. 333 * 334 * @see #removeRow(int) 335 */ 336 public void removeColumn(int columnIndex) { 337 this.data.removeColumn(columnIndex); 338 fireDatasetChanged(); 339 } 340 341 /** 342 * Removes a column from the dataset and sends a {@link DatasetChangeEvent} 343 * to all registered listeners. 344 * 345 * @param columnKey the column key. 346 * 347 * @see #removeRow(Comparable) 348 */ 349 public void removeColumn(Comparable columnKey) { 350 this.data.removeColumn(columnKey); 351 fireDatasetChanged(); 352 } 353 354 /** 355 * Clears all data from the dataset and sends a {@link DatasetChangeEvent} 356 * to all registered listeners. 357 */ 358 public void clear() { 359 this.data.clear(); 360 fireDatasetChanged(); 361 } 362 363 /** 364 * Tests this dataset for equality with an arbitrary object. 365 * 366 * @param obj the object (<code>null</code> permitted). 367 * 368 * @return A boolean. 369 */ 370 public boolean equals(Object obj) { 371 372 if (obj == this) { 373 return true; 374 } 375 376 if (!(obj instanceof CategoryDataset)) { 377 return false; 378 } 379 380 CategoryDataset that = (CategoryDataset) obj; 381 if (!getRowKeys().equals(that.getRowKeys())) { 382 return false; 383 } 384 385 if (!getColumnKeys().equals(that.getColumnKeys())) { 386 return false; 387 } 388 389 int rowCount = getRowCount(); 390 int colCount = getColumnCount(); 391 for (int r = 0; r < rowCount; r++) { 392 for (int c = 0; c < colCount; c++) { 393 Number v1 = getValue(r, c); 394 Number v2 = that.getValue(r, c); 395 if (v1 == null) { 396 if (v2 != null) { 397 return false; 398 } 399 } 400 else if (!v1.equals(v2)) { 401 return false; 402 } 403 } 404 } 405 return true; 406 } 407 408 /** 409 * Returns a hash code for the dataset. 410 * 411 * @return A hash code. 412 */ 413 public int hashCode() { 414 return this.data.hashCode(); 415 } 416 417 /** 418 * Returns a clone of the dataset. 419 * 420 * @return A clone. 421 * 422 * @throws CloneNotSupportedException if there is a problem cloning the 423 * dataset. 424 */ 425 public Object clone() throws CloneNotSupportedException { 426 DefaultCategoryDataset clone = (DefaultCategoryDataset) super.clone(); 427 clone.data = (DefaultKeyedValues2D) this.data.clone(); 428 return clone; 429 } 430 431 }