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