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