KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > data > xy > XYSeriesCollection


1 /* ===========================================================
2  * JFreeChart : a free chart library for the Java(tm) platform
3  * ===========================================================
4  *
5  * (C) Copyright 2000-2006, by Object Refinery Limited and Contributors.
6  *
7  * Project Info: http://www.jfree.org/jfreechart/index.html
8  *
9  * This library is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22  * USA.
23  *
24  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
25  * in the United States and other countries.]
26  *
27  * -----------------------
28  * XYSeriesCollection.java
29  * -----------------------
30  * (C) Copyright 2001-2006, by Object Refinery Limited and Contributors.
31  *
32  * Original Author: David Gilbert (for Object Refinery Limited);
33  * Contributor(s): Aaron Metzger;
34  *
35  * $Id: XYSeriesCollection.java,v 1.12.2.3 2006/08/03 16:22:40 mungady Exp $
36  *
37  * Changes
38  * -------
39  * 15-Nov-2001 : Version 1 (DG);
40  * 03-Apr-2002 : Added change listener code (DG);
41  * 29-Apr-2002 : Added removeSeries, removeAllSeries methods (ARM);
42  * 07-Oct-2002 : Fixed errors reported by Checkstyle (DG);
43  * 26-Mar-2003 : Implemented Serializable (DG);
44  * 04-Aug-2003 : Added getSeries() method (DG);
45  * 31-Mar-2004 : Modified to use an XYIntervalDelegate.
46  * 05-May-2004 : Now extends AbstractIntervalXYDataset (DG);
47  * 18-Aug-2004 : Moved from org.jfree.data --> org.jfree.data.xy (DG);
48  * 17-Nov-2004 : Updated for changes to DomainInfo interface (DG);
49  * 11-Jan-2005 : Removed deprecated code in preparation for 1.0.0 release (DG);
50  * 28-Mar-2005 : Fixed bug in getSeries(int) method (1170825) (DG);
51  * 05-Oct-2005 : Made the interval delegate a dataset listener (DG);
52  *
53  */

54
55 package org.jfree.data.xy;
56
57 import java.io.Serializable JavaDoc;
58 import java.util.Collections JavaDoc;
59 import java.util.List JavaDoc;
60
61 import org.jfree.data.DomainInfo;
62 import org.jfree.data.Range;
63 import org.jfree.data.general.DatasetChangeEvent;
64 import org.jfree.data.general.DatasetUtilities;
65 import org.jfree.util.ObjectUtilities;
66
67 /**
68  * Represents a collection of {@link XYSeries} objects that can be used as a
69  * dataset.
70  */

71 public class XYSeriesCollection extends AbstractIntervalXYDataset
72                                 implements IntervalXYDataset, DomainInfo,
73                                            Serializable JavaDoc {
74
75     /** For serialization. */
76     private static final long serialVersionUID = -7590013825931496766L;
77     
78     /** The series that are included in the collection. */
79     private List JavaDoc data;
80     
81     /** The interval delegate (used to calculate the start and end x-values). */
82     private IntervalXYDelegate intervalDelegate;
83     
84     /**
85      * Constructs an empty dataset.
86      */

87     public XYSeriesCollection() {
88         this(null);
89     }
90
91     /**
92      * Constructs a dataset and populates it with a single series.
93      *
94      * @param series the series (<code>null</code> ignored).
95      */

96     public XYSeriesCollection(XYSeries series) {
97         this.data = new java.util.ArrayList JavaDoc();
98         this.intervalDelegate = new IntervalXYDelegate(this, false);
99         addChangeListener(this.intervalDelegate);
100         if (series != null) {
101             this.data.add(series);
102             series.addChangeListener(this);
103         }
104     }
105     
106     /**
107      * Adds a series to the collection and sends a {@link DatasetChangeEvent}
108      * to all registered listeners.
109      *
110      * @param series the series (<code>null</code> not permitted).
111      */

112     public void addSeries(XYSeries series) {
113
114         if (series == null) {
115             throw new IllegalArgumentException JavaDoc("Null 'series' argument.");
116         }
117         this.data.add(series);
118         series.addChangeListener(this);
119         fireDatasetChanged();
120
121     }
122
123     /**
124      * Removes a series from the collection and sends a
125      * {@link DatasetChangeEvent} to all registered listeners.
126      *
127      * @param series the series index (zero-based).
128      */

129     public void removeSeries(int series) {
130
131         if ((series < 0) || (series > getSeriesCount())) {
132             throw new IllegalArgumentException JavaDoc("Series index out of bounds.");
133         }
134
135         // fetch the series, remove the change listener, then remove the series.
136
XYSeries ts = (XYSeries) this.data.get(series);
137         ts.removeChangeListener(this);
138         this.data.remove(series);
139         fireDatasetChanged();
140
141     }
142
143     /**
144      * Removes a series from the collection and sends a
145      * {@link DatasetChangeEvent} to all registered listeners.
146      *
147      * @param series the series (<code>null</code> not permitted).
148      */

149     public void removeSeries(XYSeries series) {
150
151         if (series == null) {
152             throw new IllegalArgumentException JavaDoc("Null 'series' argument.");
153         }
154         if (this.data.contains(series)) {
155             series.removeChangeListener(this);
156             this.data.remove(series);
157             fireDatasetChanged();
158         }
159
160     }
161     
162     /**
163      * Removes all the series from the collection and sends a
164      * {@link DatasetChangeEvent} to all registered listeners.
165      */

166     public void removeAllSeries() {
167         // Unregister the collection as a change listener to each series in
168
// the collection.
169
for (int i = 0; i < this.data.size(); i++) {
170           XYSeries series = (XYSeries) this.data.get(i);
171           series.removeChangeListener(this);
172         }
173
174         // Remove all the series from the collection and notify listeners.
175
this.data.clear();
176         fireDatasetChanged();
177     }
178
179     /**
180      * Returns the number of series in the collection.
181      *
182      * @return The series count.
183      */

184     public int getSeriesCount() {
185         return this.data.size();
186     }
187
188     /**
189      * Returns a list of all the series in the collection.
190      *
191      * @return The list (which is unmodifiable).
192      */

193     public List JavaDoc getSeries() {
194         return Collections.unmodifiableList(this.data);
195     }
196
197     /**
198      * Returns a series from the collection.
199      *
200      * @param series the series index (zero-based).
201      *
202      * @return The series.
203      *
204      * @throws IllegalArgumentException if <code>series</code> is not in the
205      * range <code>0</code> to <code>getSeriesCount() - 1</code>.
206      */

207     public XYSeries getSeries(int series) {
208         if ((series < 0) || (series >= getSeriesCount())) {
209             throw new IllegalArgumentException JavaDoc("Series index out of bounds");
210         }
211         return (XYSeries) this.data.get(series);
212     }
213
214     /**
215      * Returns the key for a series.
216      *
217      * @param series the series index (in the range <code>0</code> to
218      * <code>getSeriesCount() - 1</code>).
219      *
220      * @return The key for a series.
221      *
222      * @throws IllegalArgumentException if <code>series</code> is not in the
223      * specified range.
224      */

225     public Comparable JavaDoc getSeriesKey(int series) {
226         // defer argument checking
227
return getSeries(series).getKey();
228     }
229
230     /**
231      * Returns the number of items in the specified series.
232      *
233      * @param series the series (zero-based index).
234      *
235      * @return The item count.
236      *
237      * @throws IllegalArgumentException if <code>series</code> is not in the
238      * range <code>0</code> to <code>getSeriesCount() - 1</code>.
239      */

240     public int getItemCount(int series) {
241         // defer argument checking
242
return getSeries(series).getItemCount();
243     }
244
245     /**
246      * Returns the x-value for the specified series and item.
247      *
248      * @param series the series (zero-based index).
249      * @param item the item (zero-based index).
250      *
251      * @return The value.
252      */

253     public Number JavaDoc getX(int series, int item) {
254         XYSeries ts = (XYSeries) this.data.get(series);
255         XYDataItem xyItem = ts.getDataItem(item);
256         return xyItem.getX();
257     }
258
259     /**
260      * Returns the starting X value for the specified series and item.
261      *
262      * @param series the series (zero-based index).
263      * @param item the item (zero-based index).
264      *
265      * @return The starting X value.
266      */

267     public Number JavaDoc getStartX(int series, int item) {
268         return this.intervalDelegate.getStartX(series, item);
269     }
270
271     /**
272      * Returns the ending X value for the specified series and item.
273      *
274      * @param series the series (zero-based index).
275      * @param item the item (zero-based index).
276      *
277      * @return The ending X value.
278      */

279     public Number JavaDoc getEndX(int series, int item) {
280         return this.intervalDelegate.getEndX(series, item);
281     }
282
283     /**
284      * Returns the y-value for the specified series and item.
285      *
286      * @param series the series (zero-based index).
287      * @param index the index of the item of interest (zero-based).
288      *
289      * @return The value (possibly <code>null</code>).
290      */

291     public Number JavaDoc getY(int series, int index) {
292
293         XYSeries ts = (XYSeries) this.data.get(series);
294         XYDataItem xyItem = ts.getDataItem(index);
295         return xyItem.getY();
296
297     }
298
299     /**
300      * Returns the starting Y value for the specified series and item.
301      *
302      * @param series the series (zero-based index).
303      * @param item the item (zero-based index).
304      *
305      * @return The starting Y value.
306      */

307     public Number JavaDoc getStartY(int series, int item) {
308         return getY(series, item);
309     }
310
311     /**
312      * Returns the ending Y value for the specified series and item.
313      *
314      * @param series the series (zero-based index).
315      * @param item the item (zero-based index).
316      *
317      * @return The ending Y value.
318      */

319     public Number JavaDoc getEndY(int series, int item) {
320         return getY(series, item);
321     }
322
323     /**
324      * Tests this collection 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 JavaDoc obj) {
331         /*
332          * XXX
333          *
334          * what about the interval delegate...?
335          * The interval width etc wasn't considered
336          * before, hence i did not add it here (AS)
337          *
338          */

339
340         if (obj == this) {
341             return true;
342         }
343         if (!(obj instanceof XYSeriesCollection)) {
344             return false;
345         }
346         XYSeriesCollection that = (XYSeriesCollection) obj;
347         return ObjectUtilities.equal(this.data, that.data);
348     }
349
350     /**
351      * Returns a hash code.
352      *
353      * @return A hash code.
354      */

355     public int hashCode() {
356         // Same question as for equals (AS)
357
return (this.data != null ? this.data.hashCode() : 0);
358     }
359        
360     /**
361      * Returns the minimum x-value in the dataset.
362      *
363      * @param includeInterval a flag that determines whether or not the
364      * x-interval is taken into account.
365      *
366      * @return The minimum value.
367      */

368     public double getDomainLowerBound(boolean includeInterval) {
369         return this.intervalDelegate.getDomainLowerBound(includeInterval);
370     }
371
372     /**
373      * Returns the maximum x-value in the dataset.
374      *
375      * @param includeInterval a flag that determines whether or not the
376      * x-interval is taken into account.
377      *
378      * @return The maximum value.
379      */

380     public double getDomainUpperBound(boolean includeInterval) {
381         return this.intervalDelegate.getDomainUpperBound(includeInterval);
382     }
383
384     /**
385      * Returns the range of the values in this dataset's domain.
386      *
387      * @param includeInterval a flag that determines whether or not the
388      * x-interval is taken into account.
389      *
390      * @return The range.
391      */

392     public Range getDomainBounds(boolean includeInterval) {
393         if (includeInterval) {
394             return this.intervalDelegate.getDomainBounds(includeInterval);
395         }
396         else {
397             return DatasetUtilities.iterateDomainBounds(this, includeInterval);
398         }
399             
400     }
401     
402     /**
403      * Returns the interval width. This is used to calculate the start and end
404      * x-values, if/when the dataset is used as an {@link IntervalXYDataset}.
405      *
406      * @return The interval width.
407      */

408     public double getIntervalWidth() {
409         return this.intervalDelegate.getIntervalWidth();
410     }
411     
412     /**
413      * Sets the interval width and sends a {@link DatasetChangeEvent} to all
414      * registered listeners.
415      *
416      * @param width the width (negative values not permitted).
417      */

418     public void setIntervalWidth(double width) {
419         if (width < 0.0) {
420             throw new IllegalArgumentException JavaDoc("Negative 'width' argument.");
421         }
422         this.intervalDelegate.setFixedIntervalWidth(width);
423         fireDatasetChanged();
424     }
425
426     /**
427      * Returns the interval position factor.
428      *
429      * @return The interval position factor.
430      */

431     public double getIntervalPositionFactor() {
432         return this.intervalDelegate.getIntervalPositionFactor();
433     }
434     
435     /**
436      * Sets the interval position factor. This controls where the x-value is in
437      * relation to the interval surrounding the x-value (0.0 means the x-value
438      * will be positioned at the start, 0.5 in the middle, and 1.0 at the end).
439      *
440      * @param factor the factor.
441      */

442     public void setIntervalPositionFactor(double factor) {
443         this.intervalDelegate.setIntervalPositionFactor(factor);
444         fireDatasetChanged();
445     }
446     
447     /**
448      * Returns whether the interval width is automatically calculated or not.
449      *
450      * @return Whether the width is automatically calculated or not.
451      */

452     public boolean isAutoWidth() {
453         return this.intervalDelegate.isAutoWidth();
454     }
455
456     /**
457      * Sets the flag that indicates wether the interval width is automatically
458      * calculated or not.
459      *
460      * @param b a boolean.
461      */

462     public void setAutoWidth(boolean b) {
463         this.intervalDelegate.setAutoWidth(b);
464         fireDatasetChanged();
465     }
466     
467 }
468
Popular Tags