001/* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2013, 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 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 025 * Other names may be trademarks of their respective owners.] 026 * 027 * ------------------------------- 028 * XYIntervalSeriesCollection.java 029 * ------------------------------- 030 * (C) Copyright 2006-2013, by Object Refinery Limited. 031 * 032 * Original Author: David Gilbert (for Object Refinery Limited); 033 * Contributor(s): -; 034 * 035 * Changes 036 * ------- 037 * 20-Oct-2006 : Version 1 (DG); 038 * 13-Feb-2007 : Provided a number of method overrides that enhance 039 * performance, and added a proper clone() 040 * implementation (DG); 041 * 18-Jan-2008 : Added removeSeries() and removeAllSeries() methods (DG); 042 * 22-Apr-2008 : Implemented PublicCloneable (DG); 043 * 02-Jul-2013 : Use ParamChecks (DG); 044 * 045 */ 046 047package org.jfree.data.xy; 048 049import java.io.Serializable; 050import java.util.List; 051import org.jfree.chart.util.ParamChecks; 052 053import org.jfree.data.general.DatasetChangeEvent; 054import org.jfree.util.ObjectUtilities; 055import org.jfree.util.PublicCloneable; 056 057/** 058 * A collection of {@link XYIntervalSeries} objects. 059 * 060 * @since 1.0.3 061 * 062 * @see XYIntervalSeries 063 */ 064public class XYIntervalSeriesCollection extends AbstractIntervalXYDataset 065 implements IntervalXYDataset, PublicCloneable, Serializable { 066 067 /** Storage for the data series. */ 068 private List data; 069 070 /** 071 * Creates a new instance of <code>XIntervalSeriesCollection</code>. 072 */ 073 public XYIntervalSeriesCollection() { 074 this.data = new java.util.ArrayList(); 075 } 076 077 /** 078 * Adds a series to the collection and sends a {@link DatasetChangeEvent} 079 * to all registered listeners. 080 * 081 * @param series the series (<code>null</code> not permitted). 082 */ 083 public void addSeries(XYIntervalSeries series) { 084 ParamChecks.nullNotPermitted(series, "series"); 085 this.data.add(series); 086 series.addChangeListener(this); 087 fireDatasetChanged(); 088 } 089 090 /** 091 * Returns the number of series in the collection. 092 * 093 * @return The series count. 094 */ 095 @Override 096 public int getSeriesCount() { 097 return this.data.size(); 098 } 099 100 /** 101 * Returns a series from the collection. 102 * 103 * @param series the series index (zero-based). 104 * 105 * @return The series. 106 * 107 * @throws IllegalArgumentException if <code>series</code> is not in the 108 * range <code>0</code> to <code>getSeriesCount() - 1</code>. 109 */ 110 public XYIntervalSeries getSeries(int series) { 111 if ((series < 0) || (series >= getSeriesCount())) { 112 throw new IllegalArgumentException("Series index out of bounds"); 113 } 114 return (XYIntervalSeries) this.data.get(series); 115 } 116 117 /** 118 * Returns the key for a series. 119 * 120 * @param series the series index (in the range <code>0</code> to 121 * <code>getSeriesCount() - 1</code>). 122 * 123 * @return The key for a series. 124 * 125 * @throws IllegalArgumentException if <code>series</code> is not in the 126 * specified range. 127 */ 128 @Override 129 public Comparable getSeriesKey(int series) { 130 // defer argument checking 131 return getSeries(series).getKey(); 132 } 133 134 /** 135 * Returns the number of items in the specified series. 136 * 137 * @param series the series (zero-based index). 138 * 139 * @return The item count. 140 * 141 * @throws IllegalArgumentException if <code>series</code> is not in the 142 * range <code>0</code> to <code>getSeriesCount() - 1</code>. 143 */ 144 @Override 145 public int getItemCount(int series) { 146 // defer argument checking 147 return getSeries(series).getItemCount(); 148 } 149 150 /** 151 * Returns the x-value for an item within a series. 152 * 153 * @param series the series index. 154 * @param item the item index. 155 * 156 * @return The x-value. 157 */ 158 @Override 159 public Number getX(int series, int item) { 160 XYIntervalSeries s = (XYIntervalSeries) this.data.get(series); 161 return s.getX(item); 162 } 163 164 /** 165 * Returns the start x-value (as a double primitive) for an item within a 166 * series. 167 * 168 * @param series the series index (zero-based). 169 * @param item the item index (zero-based). 170 * 171 * @return The value. 172 */ 173 @Override 174 public double getStartXValue(int series, int item) { 175 XYIntervalSeries s = (XYIntervalSeries) this.data.get(series); 176 return s.getXLowValue(item); 177 } 178 179 /** 180 * Returns the end x-value (as a double primitive) for an item within a 181 * series. 182 * 183 * @param series the series index (zero-based). 184 * @param item the item index (zero-based). 185 * 186 * @return The value. 187 */ 188 @Override 189 public double getEndXValue(int series, int item) { 190 XYIntervalSeries s = (XYIntervalSeries) this.data.get(series); 191 return s.getXHighValue(item); 192 } 193 194 /** 195 * Returns the y-value (as a double primitive) for an item within a 196 * series. 197 * 198 * @param series the series index (zero-based). 199 * @param item the item index (zero-based). 200 * 201 * @return The value. 202 */ 203 @Override 204 public double getYValue(int series, int item) { 205 XYIntervalSeries s = (XYIntervalSeries) this.data.get(series); 206 return s.getYValue(item); 207 } 208 209 /** 210 * Returns the start y-value (as a double primitive) for an item within a 211 * series. 212 * 213 * @param series the series index (zero-based). 214 * @param item the item index (zero-based). 215 * 216 * @return The value. 217 */ 218 @Override 219 public double getStartYValue(int series, int item) { 220 XYIntervalSeries s = (XYIntervalSeries) this.data.get(series); 221 return s.getYLowValue(item); 222 } 223 224 /** 225 * Returns the end y-value (as a double primitive) for an item within a 226 * series. 227 * 228 * @param series the series (zero-based index). 229 * @param item the item (zero-based index). 230 * 231 * @return The value. 232 */ 233 @Override 234 public double getEndYValue(int series, int item) { 235 XYIntervalSeries s = (XYIntervalSeries) this.data.get(series); 236 return s.getYHighValue(item); 237 } 238 239 /** 240 * Returns the y-value for an item within a series. 241 * 242 * @param series the series index. 243 * @param item the item index. 244 * 245 * @return The y-value. 246 */ 247 @Override 248 public Number getY(int series, int item) { 249 return new Double(getYValue(series, item)); 250 } 251 252 /** 253 * Returns the start x-value for an item within a series. 254 * 255 * @param series the series index. 256 * @param item the item index. 257 * 258 * @return The x-value. 259 */ 260 @Override 261 public Number getStartX(int series, int item) { 262 return new Double(getStartXValue(series, item)); 263 } 264 265 /** 266 * Returns the end x-value for an item within a series. 267 * 268 * @param series the series index. 269 * @param item the item index. 270 * 271 * @return The x-value. 272 */ 273 @Override 274 public Number getEndX(int series, int item) { 275 return new Double(getEndXValue(series, item)); 276 } 277 278 /** 279 * Returns the start y-value for an item within a series. This method 280 * maps directly to {@link #getY(int, int)}. 281 * 282 * @param series the series index. 283 * @param item the item index. 284 * 285 * @return The start y-value. 286 */ 287 @Override 288 public Number getStartY(int series, int item) { 289 return new Double(getStartYValue(series, item)); 290 } 291 292 /** 293 * Returns the end y-value for an item within a series. This method 294 * maps directly to {@link #getY(int, int)}. 295 * 296 * @param series the series index. 297 * @param item the item index. 298 * 299 * @return The end y-value. 300 */ 301 @Override 302 public Number getEndY(int series, int item) { 303 return new Double(getEndYValue(series, item)); 304 } 305 306 /** 307 * Removes a series from the collection and sends a 308 * {@link DatasetChangeEvent} to all registered listeners. 309 * 310 * @param series the series index (zero-based). 311 * 312 * @since 1.0.10 313 */ 314 public void removeSeries(int series) { 315 if ((series < 0) || (series >= getSeriesCount())) { 316 throw new IllegalArgumentException("Series index out of bounds."); 317 } 318 XYIntervalSeries ts = (XYIntervalSeries) this.data.get(series); 319 ts.removeChangeListener(this); 320 this.data.remove(series); 321 fireDatasetChanged(); 322 } 323 324 /** 325 * Removes a series from the collection and sends a 326 * {@link DatasetChangeEvent} to all registered listeners. 327 * 328 * @param series the series (<code>null</code> not permitted). 329 * 330 * @since 1.0.10 331 */ 332 public void removeSeries(XYIntervalSeries series) { 333 ParamChecks.nullNotPermitted(series, "series"); 334 if (this.data.contains(series)) { 335 series.removeChangeListener(this); 336 this.data.remove(series); 337 fireDatasetChanged(); 338 } 339 } 340 341 /** 342 * Removes all the series from the collection and sends a 343 * {@link DatasetChangeEvent} to all registered listeners. 344 * 345 * @since 1.0.10 346 */ 347 public void removeAllSeries() { 348 // Unregister the collection as a change listener to each series in 349 // the collection. 350 for (int i = 0; i < this.data.size(); i++) { 351 XYIntervalSeries series = (XYIntervalSeries) this.data.get(i); 352 series.removeChangeListener(this); 353 } 354 this.data.clear(); 355 fireDatasetChanged(); 356 } 357 358 /** 359 * Tests this instance for equality with an arbitrary object. 360 * 361 * @param obj the object (<code>null</code> permitted). 362 * 363 * @return A boolean. 364 */ 365 @Override 366 public boolean equals(Object obj) { 367 if (obj == this) { 368 return true; 369 } 370 if (!(obj instanceof XYIntervalSeriesCollection)) { 371 return false; 372 } 373 XYIntervalSeriesCollection that = (XYIntervalSeriesCollection) obj; 374 return ObjectUtilities.equal(this.data, that.data); 375 } 376 377 /** 378 * Returns a clone of this dataset. 379 * 380 * @return A clone of this dataset. 381 * 382 * @throws CloneNotSupportedException if there is a problem cloning. 383 */ 384 @Override 385 public Object clone() throws CloneNotSupportedException { 386 XYIntervalSeriesCollection clone 387 = (XYIntervalSeriesCollection) super.clone(); 388 int seriesCount = getSeriesCount(); 389 clone.data = new java.util.ArrayList(seriesCount); 390 for (int i = 0; i < this.data.size(); i++) { 391 clone.data.set(i, getSeries(i).clone()); 392 } 393 return clone; 394 } 395 396}