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