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 * VectorSeriesCollection.java 029 * --------------------------- 030 * (C) Copyright 2007, by Object Refinery Limited. 031 * 032 * Original Author: David Gilbert (for Object Refinery Limited); 033 * Contributor(s): -; 034 * 035 * Changes 036 * ------- 037 * 30-Jan-2007 : Version 1 (DG); 038 * 24-May-2007 : Added indexOf(), removeSeries() and removeAllSeries() 039 * methods (DG); 040 * 25-May-2007 : Moved from experimental to the main source tree (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 052 /** 053 * A collection of {@link VectorSeries} objects. 054 * 055 * @since 1.0.6 056 */ 057 public class VectorSeriesCollection extends AbstractXYDataset 058 implements VectorXYDataset, Serializable { 059 060 /** Storage for the data series. */ 061 private List data; 062 063 /** 064 * Creates a new instance of <code>VectorSeriesCollection</code>. 065 */ 066 public VectorSeriesCollection() { 067 this.data = new java.util.ArrayList(); 068 } 069 070 /** 071 * Adds a series to the collection and sends a {@link DatasetChangeEvent} 072 * to all registered listeners. 073 * 074 * @param series the series (<code>null</code> not permitted). 075 */ 076 public void addSeries(VectorSeries series) { 077 if (series == null) { 078 throw new IllegalArgumentException("Null 'series' argument."); 079 } 080 this.data.add(series); 081 series.addChangeListener(this); 082 fireDatasetChanged(); 083 } 084 085 /** 086 * Removes the specified series from the collection and sends a 087 * {@link DatasetChangeEvent} to all registered listeners. 088 * 089 * @param series the series (<code>null</code> not permitted). 090 * 091 * @return A boolean indicating whether the series has actually been 092 * removed. 093 */ 094 public boolean removeSeries(VectorSeries series) { 095 if (series == null) { 096 throw new IllegalArgumentException("Null 'series' argument."); 097 } 098 boolean removed = this.data.remove(series); 099 if (removed) { 100 series.removeChangeListener(this); 101 fireDatasetChanged(); 102 } 103 return removed; 104 } 105 106 /** 107 * Removes all the series from the collection and sends a 108 * {@link DatasetChangeEvent} to all registered listeners. 109 */ 110 public void removeAllSeries() { 111 112 // deregister the collection as a change listener to each series in the 113 // collection 114 for (int i = 0; i < this.data.size(); i++) { 115 VectorSeries series = (VectorSeries) this.data.get(i); 116 series.removeChangeListener(this); 117 } 118 119 // remove all the series from the collection and notify listeners. 120 this.data.clear(); 121 fireDatasetChanged(); 122 123 } 124 125 /** 126 * Returns the number of series in the collection. 127 * 128 * @return The series count. 129 */ 130 public int getSeriesCount() { 131 return this.data.size(); 132 } 133 134 /** 135 * Returns a series from the collection. 136 * 137 * @param series the series index (zero-based). 138 * 139 * @return The series. 140 * 141 * @throws IllegalArgumentException if <code>series</code> is not in the 142 * range <code>0</code> to <code>getSeriesCount() - 1</code>. 143 */ 144 public VectorSeries getSeries(int series) { 145 if ((series < 0) || (series >= getSeriesCount())) { 146 throw new IllegalArgumentException("Series index out of bounds"); 147 } 148 return (VectorSeries) this.data.get(series); 149 } 150 151 /** 152 * Returns the key for a series. 153 * 154 * @param series the series index (in the range <code>0</code> to 155 * <code>getSeriesCount() - 1</code>). 156 * 157 * @return The key for a series. 158 * 159 * @throws IllegalArgumentException if <code>series</code> is not in the 160 * specified range. 161 */ 162 public Comparable getSeriesKey(int series) { 163 // defer argument checking 164 return getSeries(series).getKey(); 165 } 166 167 /** 168 * Returns the index of the specified series, or -1 if that series is not 169 * present in the dataset. 170 * 171 * @param series the series (<code>null</code> not permitted). 172 * 173 * @return The series index. 174 */ 175 public int indexOf(VectorSeries series) { 176 if (series == null) { 177 throw new IllegalArgumentException("Null 'series' argument."); 178 } 179 return this.data.indexOf(series); 180 } 181 182 /** 183 * Returns the number of items in the specified series. 184 * 185 * @param series the series (zero-based index). 186 * 187 * @return The item count. 188 * 189 * @throws IllegalArgumentException if <code>series</code> is not in the 190 * range <code>0</code> to <code>getSeriesCount() - 1</code>. 191 */ 192 public int getItemCount(int series) { 193 // defer argument checking 194 return getSeries(series).getItemCount(); 195 } 196 197 /** 198 * Returns the x-value for an item within a series. 199 * 200 * @param series the series index. 201 * @param item the item index. 202 * 203 * @return The x-value. 204 */ 205 public double getXValue(int series, int item) { 206 VectorSeries s = (VectorSeries) this.data.get(series); 207 VectorDataItem di = (VectorDataItem) s.getDataItem(item); 208 return di.getXValue(); 209 } 210 211 /** 212 * Returns the x-value for an item within a series. Note that this method 213 * creates a new {@link Double} instance every time it is called---use 214 * {@link #getXValue(int, int)} instead, if possible. 215 * 216 * @param series the series index. 217 * @param item the item index. 218 * 219 * @return The x-value. 220 */ 221 public Number getX(int series, int item) { 222 return new Double(getXValue(series, item)); 223 } 224 225 /** 226 * Returns the y-value for an item within a series. 227 * 228 * @param series the series index. 229 * @param item the item index. 230 * 231 * @return The y-value. 232 */ 233 public double getYValue(int series, int item) { 234 VectorSeries s = (VectorSeries) this.data.get(series); 235 VectorDataItem di = (VectorDataItem) s.getDataItem(item); 236 return di.getYValue(); 237 } 238 239 /** 240 * Returns the y-value for an item within a series. Note that this method 241 * creates a new {@link Double} instance every time it is called---use 242 * {@link #getYValue(int, int)} instead, if possible. 243 * 244 * @param series the series index. 245 * @param item the item index. 246 * 247 * @return The y-value. 248 */ 249 public Number getY(int series, int item) { 250 return new Double(getYValue(series, item)); 251 } 252 253 /** 254 * Returns the vector for an item in a series. 255 * 256 * @param series the series index. 257 * @param item the item index. 258 * 259 * @return The vector (possibly <code>null</code>). 260 */ 261 public Vector getVector(int series, int item) { 262 VectorSeries s = (VectorSeries) this.data.get(series); 263 VectorDataItem di = (VectorDataItem) s.getDataItem(item); 264 return di.getVector(); 265 } 266 267 /** 268 * Returns the x-component of the vector for an item in a series. 269 * 270 * @param series the series index. 271 * @param item the item index. 272 * 273 * @return The x-component of the vector. 274 */ 275 public double getVectorXValue(int series, int item) { 276 VectorSeries s = (VectorSeries) this.data.get(series); 277 VectorDataItem di = (VectorDataItem) s.getDataItem(item); 278 return di.getVectorX(); 279 } 280 281 /** 282 * Returns the y-component of the vector for an item in a series. 283 * 284 * @param series the series index. 285 * @param item the item index. 286 * 287 * @return The y-component of the vector. 288 */ 289 public double getVectorYValue(int series, int item) { 290 VectorSeries s = (VectorSeries) this.data.get(series); 291 VectorDataItem di = (VectorDataItem) s.getDataItem(item); 292 return di.getVectorY(); 293 } 294 295 /** 296 * Tests this instance for equality with an arbitrary object. 297 * 298 * @param obj the object (<code>null</code> permitted). 299 * 300 * @return A boolean. 301 */ 302 public boolean equals(Object obj) { 303 if (obj == this) { 304 return true; 305 } 306 if (!(obj instanceof VectorSeriesCollection)) { 307 return false; 308 } 309 VectorSeriesCollection that = (VectorSeriesCollection) obj; 310 return ObjectUtilities.equal(this.data, that.data); 311 } 312 313 /** 314 * Returns a clone of this instance. 315 * 316 * @return A clone. 317 * 318 * @throws CloneNotSupportedException if there is a problem. 319 */ 320 public Object clone() throws CloneNotSupportedException { 321 VectorSeriesCollection clone 322 = (VectorSeriesCollection) super.clone(); 323 clone.data = (List) ObjectUtilities.deepClone(this.data); 324 return clone; 325 } 326 327 }