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 * MatrixSeriesCollection.java
029 * ---------------------------
030 * (C) Copyright 2003-2008, by Barak Naveh and Contributors.
031 *
032 * Original Author: Barak Naveh;
033 * Contributor(s): David Gilbert (for Object Refinery Limited);
034 *
035 * Changes
036 * -------
037 * 10-Jul-2003 : Version 1 contributed by Barak Naveh (DG);
038 * 05-May-2004 : Now extends AbstractXYZDataset (DG);
039 * 15-Jul-2004 : Switched getZ() and getZValue() methods (DG);
040 * ------------- JFREECHART 1.0.x ---------------------------------------------
041 * 27-Nov-2006 : Added clone() override (DG);
042 * 02-Feb-2007 : Removed author tags all over JFreeChart sources (DG);
043 * 22-Apr-2008 : Implemented PublicCloneable (DG);
044 */
045
046 package org.jfree.data.xy;
047
048 import java.io.Serializable;
049 import java.util.List;
050
051 import org.jfree.util.ObjectUtilities;
052 import org.jfree.util.PublicCloneable;
053
054 /**
055 * Represents a collection of {@link MatrixSeries} that can be used as a
056 * dataset.
057 *
058 * @see org.jfree.data.xy.MatrixSeries
059 */
060 public class MatrixSeriesCollection extends AbstractXYZDataset
061 implements XYZDataset, PublicCloneable, Serializable {
062
063 /** For serialization. */
064 private static final long serialVersionUID = -3197705779242543945L;
065
066 /** The series that are included in the collection. */
067 private List seriesList;
068
069 /**
070 * Constructs an empty dataset.
071 */
072 public MatrixSeriesCollection() {
073 this(null);
074 }
075
076
077 /**
078 * Constructs a dataset and populates it with a single matrix series.
079 *
080 * @param series the time series.
081 */
082 public MatrixSeriesCollection(MatrixSeries series) {
083 this.seriesList = new java.util.ArrayList();
084
085 if (series != null) {
086 this.seriesList.add(series);
087 series.addChangeListener(this);
088 }
089 }
090
091 /**
092 * Returns the number of items in the specified series.
093 *
094 * @param seriesIndex zero-based series index.
095 *
096 * @return The number of items in the specified series.
097 */
098 public int getItemCount(int seriesIndex) {
099 return getSeries(seriesIndex).getItemCount();
100 }
101
102
103 /**
104 * Returns the series having the specified index.
105 *
106 * @param seriesIndex zero-based series index.
107 *
108 * @return The series.
109 *
110 * @throws IllegalArgumentException
111 */
112 public MatrixSeries getSeries(int seriesIndex) {
113 if ((seriesIndex < 0) || (seriesIndex > getSeriesCount())) {
114 throw new IllegalArgumentException("Index outside valid range.");
115 }
116
117 MatrixSeries series = (MatrixSeries) this.seriesList.get(seriesIndex);
118
119 return series;
120 }
121
122
123 /**
124 * Returns the number of series in the collection.
125 *
126 * @return The number of series in the collection.
127 */
128 public int getSeriesCount() {
129 return this.seriesList.size();
130 }
131
132
133 /**
134 * Returns the key for a series.
135 *
136 * @param seriesIndex zero-based series index.
137 *
138 * @return The key for a series.
139 */
140 public Comparable getSeriesKey(int seriesIndex) {
141 return getSeries(seriesIndex).getKey();
142 }
143
144
145 /**
146 * Returns the j index value of the specified Mij matrix item in the
147 * specified matrix series.
148 *
149 * @param seriesIndex zero-based series index.
150 * @param itemIndex zero-based item index.
151 *
152 * @return The j index value for the specified matrix item.
153 *
154 * @see org.jfree.data.xy.XYDataset#getXValue(int, int)
155 */
156 public Number getX(int seriesIndex, int itemIndex) {
157 MatrixSeries series = (MatrixSeries) this.seriesList.get(seriesIndex);
158 int x = series.getItemColumn(itemIndex);
159
160 return new Integer(x); // I know it's bad to create object. better idea?
161 }
162
163
164 /**
165 * Returns the i index value of the specified Mij matrix item in the
166 * specified matrix series.
167 *
168 * @param seriesIndex zero-based series index.
169 * @param itemIndex zero-based item index.
170 *
171 * @return The i index value for the specified matrix item.
172 *
173 * @see org.jfree.data.xy.XYDataset#getYValue(int, int)
174 */
175 public Number getY(int seriesIndex, int itemIndex) {
176 MatrixSeries series = (MatrixSeries) this.seriesList.get(seriesIndex);
177 int y = series.getItemRow(itemIndex);
178
179 return new Integer(y); // I know it's bad to create object. better idea?
180 }
181
182
183 /**
184 * Returns the Mij item value of the specified Mij matrix item in the
185 * specified matrix series.
186 *
187 * @param seriesIndex the series (zero-based index).
188 * @param itemIndex zero-based item index.
189 *
190 * @return The Mij item value for the specified matrix item.
191 *
192 * @see org.jfree.data.xy.XYZDataset#getZValue(int, int)
193 */
194 public Number getZ(int seriesIndex, int itemIndex) {
195 MatrixSeries series = (MatrixSeries) this.seriesList.get(seriesIndex);
196 Number z = series.getItem(itemIndex);
197 return z;
198 }
199
200
201 /**
202 * Adds a series to the collection.
203 * <P>
204 * Notifies all registered listeners that the dataset has changed.
205 * </p>
206 *
207 * @param series the series.
208 *
209 * @throws IllegalArgumentException
210 */
211 public void addSeries(MatrixSeries series) {
212 // check arguments...
213 if (series == null) {
214 throw new IllegalArgumentException("Cannot add null series.");
215 }
216 // FIXME: Check that there isn't already a series with the same key
217
218 // add the series...
219 this.seriesList.add(series);
220 series.addChangeListener(this);
221 fireDatasetChanged();
222 }
223
224
225 /**
226 * Tests this collection for equality with an arbitrary object.
227 *
228 * @param obj the object.
229 *
230 * @return A boolean.
231 */
232 public boolean equals(Object obj) {
233 if (obj == null) {
234 return false;
235 }
236
237 if (obj == this) {
238 return true;
239 }
240
241 if (obj instanceof MatrixSeriesCollection) {
242 MatrixSeriesCollection c = (MatrixSeriesCollection) obj;
243
244 return ObjectUtilities.equal(this.seriesList, c.seriesList);
245 }
246
247 return false;
248 }
249
250 /**
251 * Returns a hash code.
252 *
253 * @return A hash code.
254 */
255 public int hashCode() {
256 return (this.seriesList != null ? this.seriesList.hashCode() : 0);
257 }
258
259 /**
260 * Returns a clone of this instance.
261 *
262 * @return A clone.
263 *
264 * @throws CloneNotSupportedException if there is a problem.
265 */
266 public Object clone() throws CloneNotSupportedException {
267 MatrixSeriesCollection clone = (MatrixSeriesCollection) super.clone();
268 clone.seriesList = (List) ObjectUtilities.deepClone(this.seriesList);
269 return clone;
270 }
271
272 /**
273 * Removes all the series from the collection.
274 * <P>
275 * Notifies all registered listeners that the dataset has changed.
276 * </p>
277 */
278 public void removeAllSeries() {
279 // Unregister the collection as a change listener to each series in
280 // the collection.
281 for (int i = 0; i < this.seriesList.size(); i++) {
282 MatrixSeries series = (MatrixSeries) this.seriesList.get(i);
283 series.removeChangeListener(this);
284 }
285
286 // Remove all the series from the collection and notify listeners.
287 this.seriesList.clear();
288 fireDatasetChanged();
289 }
290
291
292 /**
293 * Removes a series from the collection.
294 * <P>
295 * Notifies all registered listeners that the dataset has changed.
296 * </p>
297 *
298 * @param series the series.
299 *
300 * @throws IllegalArgumentException
301 */
302 public void removeSeries(MatrixSeries series) {
303 // check arguments...
304 if (series == null) {
305 throw new IllegalArgumentException("Cannot remove null series.");
306 }
307
308 // remove the series...
309 if (this.seriesList.contains(series)) {
310 series.removeChangeListener(this);
311 this.seriesList.remove(series);
312 fireDatasetChanged();
313 }
314 }
315
316
317 /**
318 * Removes a series from the collection.
319 * <P>
320 * Notifies all registered listeners that the dataset has changed.
321 *
322 * @param seriesIndex the series (zero based index).
323 *
324 * @throws IllegalArgumentException
325 */
326 public void removeSeries(int seriesIndex) {
327 // check arguments...
328 if ((seriesIndex < 0) || (seriesIndex > getSeriesCount())) {
329 throw new IllegalArgumentException("Index outside valid range.");
330 }
331
332 // fetch the series, remove the change listener, then remove the series.
333 MatrixSeries series = (MatrixSeries) this.seriesList.get(seriesIndex);
334 series.removeChangeListener(this);
335 this.seriesList.remove(seriesIndex);
336 fireDatasetChanged();
337 }
338
339 }