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