001 /* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2008, 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 * DefaultIntervalCategoryDataset.java 029 * ----------------------------------- 030 * (C) Copyright 2002-2008, by Jeremy Bowman and Contributors. 031 * 032 * Original Author: Jeremy Bowman; 033 * Contributor(s): David Gilbert (for Object Refinery Limited); 034 * 035 * Changes 036 * ------- 037 * 29-Apr-2002 : Version 1, contributed by Jeremy Bowman (DG); 038 * 24-Oct-2002 : Amendments for changes made to the dataset interface (DG); 039 * ------------- JFREECHART 1.0.x --------------------------------------------- 040 * 08-Mar-2007 : Added equals() and clone() overrides (DG); 041 * 25-Feb-2008 : Fix for the special case where the dataset is empty, see bug 042 * 1897580 (DG) 043 * 18-Dec-2008 : Use ResourceBundleWrapper - see patch 1607918 by 044 * Jess Thrysoee (DG); 045 * 046 */ 047 048 package org.jfree.data.category; 049 050 import java.util.ArrayList; 051 import java.util.Arrays; 052 import java.util.Collections; 053 import java.util.List; 054 import java.util.ResourceBundle; 055 056 import org.jfree.chart.util.ResourceBundleWrapper; 057 import org.jfree.data.DataUtilities; 058 import org.jfree.data.UnknownKeyException; 059 import org.jfree.data.general.AbstractSeriesDataset; 060 061 /** 062 * A convenience class that provides a default implementation of the 063 * {@link IntervalCategoryDataset} interface. 064 * <p> 065 * The standard constructor accepts data in a two dimensional array where the 066 * first dimension is the series, and the second dimension is the category. 067 */ 068 public class DefaultIntervalCategoryDataset extends AbstractSeriesDataset 069 implements IntervalCategoryDataset { 070 071 /** The series keys. */ 072 private Comparable[] seriesKeys; 073 074 /** The category keys. */ 075 private Comparable[] categoryKeys; 076 077 /** Storage for the start value data. */ 078 private Number[][] startData; 079 080 /** Storage for the end value data. */ 081 private Number[][] endData; 082 083 /** 084 * Creates a new dataset using the specified data values and automatically 085 * generated series and category keys. 086 * 087 * @param starts the starting values for the intervals (<code>null</code> 088 * not permitted). 089 * @param ends the ending values for the intervals (<code>null</code> not 090 * permitted). 091 */ 092 public DefaultIntervalCategoryDataset(double[][] starts, double[][] ends) { 093 this(DataUtilities.createNumberArray2D(starts), 094 DataUtilities.createNumberArray2D(ends)); 095 } 096 097 /** 098 * Constructs a dataset and populates it with data from the array. 099 * <p> 100 * The arrays are indexed as data[series][category]. Series and category 101 * names are automatically generated - you can change them using the 102 * {@link #setSeriesKeys(Comparable[])} and 103 * {@link #setCategoryKeys(Comparable[])} methods. 104 * 105 * @param starts the start values data. 106 * @param ends the end values data. 107 */ 108 public DefaultIntervalCategoryDataset(Number[][] starts, Number[][] ends) { 109 this(null, null, starts, ends); 110 } 111 112 /** 113 * Constructs a DefaultIntervalCategoryDataset, populates it with data 114 * from the arrays, and uses the supplied names for the series. 115 * <p> 116 * Category names are generated automatically ("Category 1", "Category 2", 117 * etc). 118 * 119 * @param seriesNames the series names (if <code>null</code>, series names 120 * will be generated automatically). 121 * @param starts the start values data, indexed as data[series][category]. 122 * @param ends the end values data, indexed as data[series][category]. 123 */ 124 public DefaultIntervalCategoryDataset(String[] seriesNames, 125 Number[][] starts, 126 Number[][] ends) { 127 128 this(seriesNames, null, starts, ends); 129 130 } 131 132 /** 133 * Constructs a DefaultIntervalCategoryDataset, populates it with data 134 * from the arrays, and uses the supplied names for the series and the 135 * supplied objects for the categories. 136 * 137 * @param seriesKeys the series keys (if <code>null</code>, series keys 138 * will be generated automatically). 139 * @param categoryKeys the category keys (if <code>null</code>, category 140 * keys will be generated automatically). 141 * @param starts the start values data, indexed as data[series][category]. 142 * @param ends the end values data, indexed as data[series][category]. 143 */ 144 public DefaultIntervalCategoryDataset(Comparable[] seriesKeys, 145 Comparable[] categoryKeys, 146 Number[][] starts, 147 Number[][] ends) { 148 149 this.startData = starts; 150 this.endData = ends; 151 152 if (starts != null && ends != null) { 153 154 String baseName = "org.jfree.data.resources.DataPackageResources"; 155 ResourceBundle resources = ResourceBundleWrapper.getBundle( 156 baseName); 157 158 int seriesCount = starts.length; 159 if (seriesCount != ends.length) { 160 String errMsg = "DefaultIntervalCategoryDataset: the number " 161 + "of series in the start value dataset does " 162 + "not match the number of series in the end " 163 + "value dataset."; 164 throw new IllegalArgumentException(errMsg); 165 } 166 if (seriesCount > 0) { 167 168 // set up the series names... 169 if (seriesKeys != null) { 170 171 if (seriesKeys.length != seriesCount) { 172 throw new IllegalArgumentException( 173 "The number of series keys does not " 174 + "match the number of series in the data."); 175 } 176 177 this.seriesKeys = seriesKeys; 178 } 179 else { 180 String prefix = resources.getString( 181 "series.default-prefix") + " "; 182 this.seriesKeys = generateKeys(seriesCount, prefix); 183 } 184 185 // set up the category names... 186 int categoryCount = starts[0].length; 187 if (categoryCount != ends[0].length) { 188 String errMsg = "DefaultIntervalCategoryDataset: the " 189 + "number of categories in the start value " 190 + "dataset does not match the number of " 191 + "categories in the end value dataset."; 192 throw new IllegalArgumentException(errMsg); 193 } 194 if (categoryKeys != null) { 195 if (categoryKeys.length != categoryCount) { 196 throw new IllegalArgumentException( 197 "The number of category keys does not match " 198 + "the number of categories in the data."); 199 } 200 this.categoryKeys = categoryKeys; 201 } 202 else { 203 String prefix = resources.getString( 204 "categories.default-prefix") + " "; 205 this.categoryKeys = generateKeys(categoryCount, prefix); 206 } 207 208 } 209 else { 210 this.seriesKeys = new Comparable[0]; 211 this.categoryKeys = new Comparable[0]; 212 } 213 } 214 215 } 216 217 /** 218 * Returns the number of series in the dataset (possibly zero). 219 * 220 * @return The number of series in the dataset. 221 * 222 * @see #getRowCount() 223 * @see #getCategoryCount() 224 */ 225 public int getSeriesCount() { 226 int result = 0; 227 if (this.startData != null) { 228 result = this.startData.length; 229 } 230 return result; 231 } 232 233 /** 234 * Returns a series index. 235 * 236 * @param seriesKey the series key. 237 * 238 * @return The series index. 239 * 240 * @see #getRowIndex(Comparable) 241 * @see #getSeriesKey(int) 242 */ 243 public int getSeriesIndex(Comparable seriesKey) { 244 int result = -1; 245 for (int i = 0; i < this.seriesKeys.length; i++) { 246 if (seriesKey.equals(this.seriesKeys[i])) { 247 result = i; 248 break; 249 } 250 } 251 return result; 252 } 253 254 /** 255 * Returns the name of the specified series. 256 * 257 * @param series the index of the required series (zero-based). 258 * 259 * @return The name of the specified series. 260 * 261 * @see #getSeriesIndex(Comparable) 262 */ 263 public Comparable getSeriesKey(int series) { 264 if ((series >= getSeriesCount()) || (series < 0)) { 265 throw new IllegalArgumentException("No such series : " + series); 266 } 267 return this.seriesKeys[series]; 268 } 269 270 /** 271 * Sets the names of the series in the dataset. 272 * 273 * @param seriesKeys the new keys (<code>null</code> not permitted, the 274 * length of the array must match the number of series in the 275 * dataset). 276 * 277 * @see #setCategoryKeys(Comparable[]) 278 */ 279 public void setSeriesKeys(Comparable[] seriesKeys) { 280 if (seriesKeys == null) { 281 throw new IllegalArgumentException("Null 'seriesKeys' argument."); 282 } 283 if (seriesKeys.length != getSeriesCount()) { 284 throw new IllegalArgumentException( 285 "The number of series keys does not match the data."); 286 } 287 this.seriesKeys = seriesKeys; 288 fireDatasetChanged(); 289 } 290 291 /** 292 * Returns the number of categories in the dataset. 293 * 294 * @return The number of categories in the dataset. 295 * 296 * @see #getColumnCount() 297 */ 298 public int getCategoryCount() { 299 int result = 0; 300 if (this.startData != null) { 301 if (getSeriesCount() > 0) { 302 result = this.startData[0].length; 303 } 304 } 305 return result; 306 } 307 308 /** 309 * Returns a list of the categories in the dataset. This method supports 310 * the {@link CategoryDataset} interface. 311 * 312 * @return A list of the categories in the dataset. 313 * 314 * @see #getRowKeys() 315 */ 316 public List getColumnKeys() { 317 // the CategoryDataset interface expects a list of categories, but 318 // we've stored them in an array... 319 if (this.categoryKeys == null) { 320 return new ArrayList(); 321 } 322 else { 323 return Collections.unmodifiableList(Arrays.asList( 324 this.categoryKeys)); 325 } 326 } 327 328 /** 329 * Sets the categories for the dataset. 330 * 331 * @param categoryKeys an array of objects representing the categories in 332 * the dataset. 333 * 334 * @see #getRowKeys() 335 * @see #setSeriesKeys(Comparable[]) 336 */ 337 public void setCategoryKeys(Comparable[] categoryKeys) { 338 if (categoryKeys == null) { 339 throw new IllegalArgumentException("Null 'categoryKeys' argument."); 340 } 341 if (categoryKeys.length != getCategoryCount()) { 342 throw new IllegalArgumentException( 343 "The number of categories does not match the data."); 344 } 345 for (int i = 0; i < categoryKeys.length; i++) { 346 if (categoryKeys[i] == null) { 347 throw new IllegalArgumentException( 348 "DefaultIntervalCategoryDataset.setCategoryKeys(): " 349 + "null category not permitted."); 350 } 351 } 352 this.categoryKeys = categoryKeys; 353 fireDatasetChanged(); 354 } 355 356 /** 357 * Returns the data value for one category in a series. 358 * <P> 359 * This method is part of the CategoryDataset interface. Not particularly 360 * meaningful for this class...returns the end value. 361 * 362 * @param series The required series (zero based index). 363 * @param category The required category. 364 * 365 * @return The data value for one category in a series (null possible). 366 * 367 * @see #getEndValue(Comparable, Comparable) 368 */ 369 public Number getValue(Comparable series, Comparable category) { 370 int seriesIndex = getSeriesIndex(series); 371 if (seriesIndex < 0) { 372 throw new UnknownKeyException("Unknown 'series' key."); 373 } 374 int itemIndex = getColumnIndex(category); 375 if (itemIndex < 0) { 376 throw new UnknownKeyException("Unknown 'category' key."); 377 } 378 return getValue(seriesIndex, itemIndex); 379 } 380 381 /** 382 * Returns the data value for one category in a series. 383 * <P> 384 * This method is part of the CategoryDataset interface. Not particularly 385 * meaningful for this class...returns the end value. 386 * 387 * @param series the required series (zero based index). 388 * @param category the required category. 389 * 390 * @return The data value for one category in a series (null possible). 391 * 392 * @see #getEndValue(int, int) 393 */ 394 public Number getValue(int series, int category) { 395 return getEndValue(series, category); 396 } 397 398 /** 399 * Returns the start data value for one category in a series. 400 * 401 * @param series the required series. 402 * @param category the required category. 403 * 404 * @return The start data value for one category in a series 405 * (possibly <code>null</code>). 406 * 407 * @see #getStartValue(int, int) 408 */ 409 public Number getStartValue(Comparable series, Comparable category) { 410 int seriesIndex = getSeriesIndex(series); 411 if (seriesIndex < 0) { 412 throw new UnknownKeyException("Unknown 'series' key."); 413 } 414 int itemIndex = getColumnIndex(category); 415 if (itemIndex < 0) { 416 throw new UnknownKeyException("Unknown 'category' key."); 417 } 418 return getStartValue(seriesIndex, itemIndex); 419 } 420 421 /** 422 * Returns the start data value for one category in a series. 423 * 424 * @param series the required series (zero based index). 425 * @param category the required category. 426 * 427 * @return The start data value for one category in a series 428 * (possibly <code>null</code>). 429 * 430 * @see #getStartValue(Comparable, Comparable) 431 */ 432 public Number getStartValue(int series, int category) { 433 434 // check arguments... 435 if ((series < 0) || (series >= getSeriesCount())) { 436 throw new IllegalArgumentException( 437 "DefaultIntervalCategoryDataset.getValue(): " 438 + "series index out of range."); 439 } 440 441 if ((category < 0) || (category >= getCategoryCount())) { 442 throw new IllegalArgumentException( 443 "DefaultIntervalCategoryDataset.getValue(): " 444 + "category index out of range."); 445 } 446 447 // fetch the value... 448 return this.startData[series][category]; 449 450 } 451 452 /** 453 * Returns the end data value for one category in a series. 454 * 455 * @param series the required series. 456 * @param category the required category. 457 * 458 * @return The end data value for one category in a series (null possible). 459 * 460 * @see #getEndValue(int, int) 461 */ 462 public Number getEndValue(Comparable series, Comparable category) { 463 int seriesIndex = getSeriesIndex(series); 464 if (seriesIndex < 0) { 465 throw new UnknownKeyException("Unknown 'series' key."); 466 } 467 int itemIndex = getColumnIndex(category); 468 if (itemIndex < 0) { 469 throw new UnknownKeyException("Unknown 'category' key."); 470 } 471 return getEndValue(seriesIndex, itemIndex); 472 } 473 474 /** 475 * Returns the end data value for one category in a series. 476 * 477 * @param series the required series (zero based index). 478 * @param category the required category. 479 * 480 * @return The end data value for one category in a series (null possible). 481 * 482 * @see #getEndValue(Comparable, Comparable) 483 */ 484 public Number getEndValue(int series, int category) { 485 if ((series < 0) || (series >= getSeriesCount())) { 486 throw new IllegalArgumentException( 487 "DefaultIntervalCategoryDataset.getValue(): " 488 + "series index out of range."); 489 } 490 491 if ((category < 0) || (category >= getCategoryCount())) { 492 throw new IllegalArgumentException( 493 "DefaultIntervalCategoryDataset.getValue(): " 494 + "category index out of range."); 495 } 496 497 return this.endData[series][category]; 498 } 499 500 /** 501 * Sets the start data value for one category in a series. 502 * 503 * @param series the series (zero-based index). 504 * @param category the category. 505 * 506 * @param value The value. 507 * 508 * @see #setEndValue(int, Comparable, Number) 509 */ 510 public void setStartValue(int series, Comparable category, Number value) { 511 512 // does the series exist? 513 if ((series < 0) || (series > getSeriesCount() - 1)) { 514 throw new IllegalArgumentException( 515 "DefaultIntervalCategoryDataset.setValue: " 516 + "series outside valid range."); 517 } 518 519 // is the category valid? 520 int categoryIndex = getCategoryIndex(category); 521 if (categoryIndex < 0) { 522 throw new IllegalArgumentException( 523 "DefaultIntervalCategoryDataset.setValue: " 524 + "unrecognised category."); 525 } 526 527 // update the data... 528 this.startData[series][categoryIndex] = value; 529 fireDatasetChanged(); 530 531 } 532 533 /** 534 * Sets the end data value for one category in a series. 535 * 536 * @param series the series (zero-based index). 537 * @param category the category. 538 * 539 * @param value the value. 540 * 541 * @see #setStartValue(int, Comparable, Number) 542 */ 543 public void setEndValue(int series, Comparable category, Number value) { 544 545 // does the series exist? 546 if ((series < 0) || (series > getSeriesCount() - 1)) { 547 throw new IllegalArgumentException( 548 "DefaultIntervalCategoryDataset.setValue: " 549 + "series outside valid range."); 550 } 551 552 // is the category valid? 553 int categoryIndex = getCategoryIndex(category); 554 if (categoryIndex < 0) { 555 throw new IllegalArgumentException( 556 "DefaultIntervalCategoryDataset.setValue: " 557 + "unrecognised category."); 558 } 559 560 // update the data... 561 this.endData[series][categoryIndex] = value; 562 fireDatasetChanged(); 563 564 } 565 566 /** 567 * Returns the index for the given category. 568 * 569 * @param category the category (<code>null</code> not permitted). 570 * 571 * @return The index. 572 * 573 * @see #getColumnIndex(Comparable) 574 */ 575 public int getCategoryIndex(Comparable category) { 576 int result = -1; 577 for (int i = 0; i < this.categoryKeys.length; i++) { 578 if (category.equals(this.categoryKeys[i])) { 579 result = i; 580 break; 581 } 582 } 583 return result; 584 } 585 586 /** 587 * Generates an array of keys, by appending a space plus an integer 588 * (starting with 1) to the supplied prefix string. 589 * 590 * @param count the number of keys required. 591 * @param prefix the name prefix. 592 * 593 * @return An array of <i>prefixN</i> with N = { 1 .. count}. 594 */ 595 private Comparable[] generateKeys(int count, String prefix) { 596 Comparable[] result = new Comparable[count]; 597 String name; 598 for (int i = 0; i < count; i++) { 599 name = prefix + (i + 1); 600 result[i] = name; 601 } 602 return result; 603 } 604 605 /** 606 * Returns a column key. 607 * 608 * @param column the column index. 609 * 610 * @return The column key. 611 * 612 * @see #getRowKey(int) 613 */ 614 public Comparable getColumnKey(int column) { 615 return this.categoryKeys[column]; 616 } 617 618 /** 619 * Returns a column index. 620 * 621 * @param columnKey the column key (<code>null</code> not permitted). 622 * 623 * @return The column index. 624 * 625 * @see #getCategoryIndex(Comparable) 626 */ 627 public int getColumnIndex(Comparable columnKey) { 628 if (columnKey == null) { 629 throw new IllegalArgumentException("Null 'columnKey' argument."); 630 } 631 return getCategoryIndex(columnKey); 632 } 633 634 /** 635 * Returns a row index. 636 * 637 * @param rowKey the row key. 638 * 639 * @return The row index. 640 * 641 * @see #getSeriesIndex(Comparable) 642 */ 643 public int getRowIndex(Comparable rowKey) { 644 return getSeriesIndex(rowKey); 645 } 646 647 /** 648 * Returns a list of the series in the dataset. This method supports the 649 * {@link CategoryDataset} interface. 650 * 651 * @return A list of the series in the dataset. 652 * 653 * @see #getColumnKeys() 654 */ 655 public List getRowKeys() { 656 // the CategoryDataset interface expects a list of series, but 657 // we've stored them in an array... 658 if (this.seriesKeys == null) { 659 return new java.util.ArrayList(); 660 } 661 else { 662 return Collections.unmodifiableList(Arrays.asList(this.seriesKeys)); 663 } 664 } 665 666 /** 667 * Returns the name of the specified series. 668 * 669 * @param row the index of the required row/series (zero-based). 670 * 671 * @return The name of the specified series. 672 * 673 * @see #getColumnKey(int) 674 */ 675 public Comparable getRowKey(int row) { 676 if ((row >= getRowCount()) || (row < 0)) { 677 throw new IllegalArgumentException( 678 "The 'row' argument is out of bounds."); 679 } 680 return this.seriesKeys[row]; 681 } 682 683 /** 684 * Returns the number of categories in the dataset. This method is part of 685 * the {@link CategoryDataset} interface. 686 * 687 * @return The number of categories in the dataset. 688 * 689 * @see #getCategoryCount() 690 * @see #getRowCount() 691 */ 692 public int getColumnCount() { 693 return this.categoryKeys.length; 694 } 695 696 /** 697 * Returns the number of series in the dataset (possibly zero). 698 * 699 * @return The number of series in the dataset. 700 * 701 * @see #getSeriesCount() 702 * @see #getColumnCount() 703 */ 704 public int getRowCount() { 705 return this.seriesKeys.length; 706 } 707 708 /** 709 * Tests this dataset for equality with an arbitrary object. 710 * 711 * @param obj the object (<code>null</code> permitted). 712 * 713 * @return A boolean. 714 */ 715 public boolean equals(Object obj) { 716 if (obj == this) { 717 return true; 718 } 719 if (!(obj instanceof DefaultIntervalCategoryDataset)) { 720 return false; 721 } 722 DefaultIntervalCategoryDataset that 723 = (DefaultIntervalCategoryDataset) obj; 724 if (!Arrays.equals(this.seriesKeys, that.seriesKeys)) { 725 return false; 726 } 727 if (!Arrays.equals(this.categoryKeys, that.categoryKeys)) { 728 return false; 729 } 730 if (!equal(this.startData, that.startData)) { 731 return false; 732 } 733 if (!equal(this.endData, that.endData)) { 734 return false; 735 } 736 // seem to be the same... 737 return true; 738 } 739 740 /** 741 * Returns a clone of this dataset. 742 * 743 * @return A clone. 744 * 745 * @throws CloneNotSupportedException if there is a problem cloning the 746 * dataset. 747 */ 748 public Object clone() throws CloneNotSupportedException { 749 DefaultIntervalCategoryDataset clone 750 = (DefaultIntervalCategoryDataset) super.clone(); 751 clone.categoryKeys = (Comparable[]) this.categoryKeys.clone(); 752 clone.seriesKeys = (Comparable[]) this.seriesKeys.clone(); 753 clone.startData = clone(this.startData); 754 clone.endData = clone(this.endData); 755 return clone; 756 } 757 758 /** 759 * Tests two double[][] arrays for equality. 760 * 761 * @param array1 the first array (<code>null</code> permitted). 762 * @param array2 the second arrray (<code>null</code> permitted). 763 * 764 * @return A boolean. 765 */ 766 private static boolean equal(Number[][] array1, Number[][] array2) { 767 if (array1 == null) { 768 return (array2 == null); 769 } 770 if (array2 == null) { 771 return false; 772 } 773 if (array1.length != array2.length) { 774 return false; 775 } 776 for (int i = 0; i < array1.length; i++) { 777 if (!Arrays.equals(array1[i], array2[i])) { 778 return false; 779 } 780 } 781 return true; 782 } 783 784 /** 785 * Clones a two dimensional array of <code>Number</code> objects. 786 * 787 * @param array the array (<code>null</code> not permitted). 788 * 789 * @return A clone of the array. 790 */ 791 private static Number[][] clone(Number[][] array) { 792 if (array == null) { 793 throw new IllegalArgumentException("Null 'array' argument."); 794 } 795 Number[][] result = new Number[array.length][]; 796 for (int i = 0; i < array.length; i++) { 797 Number[] child = array[i]; 798 Number[] copychild = new Number[child.length]; 799 System.arraycopy(child, 0, copychild, 0, child.length); 800 result[i] = copychild; 801 } 802 return result; 803 } 804 805 /** 806 * Returns a list of the series in the dataset. 807 * 808 * @return A list of the series in the dataset. 809 * 810 * @deprecated Use {@link #getRowKeys()} instead. 811 */ 812 public List getSeries() { 813 if (this.seriesKeys == null) { 814 return new java.util.ArrayList(); 815 } 816 else { 817 return Collections.unmodifiableList(Arrays.asList(this.seriesKeys)); 818 } 819 } 820 821 /** 822 * Returns a list of the categories in the dataset. 823 * 824 * @return A list of the categories in the dataset. 825 * 826 * @deprecated Use {@link #getColumnKeys()} instead. 827 */ 828 public List getCategories() { 829 return getColumnKeys(); 830 } 831 832 /** 833 * Returns the item count. 834 * 835 * @return The item count. 836 * 837 * @deprecated Use {@link #getCategoryCount()} instead. 838 */ 839 public int getItemCount() { 840 return this.categoryKeys.length; 841 } 842 843 }