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 }