    001/* ===========================================================
    002 * JFreeChart : a free chart library for the Java(tm) platform
    003 * ===========================================================
    004 *
    005 * (C) Copyright 2000-2011, 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 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    025 * Other names may be trademarks of their respective owners.]
    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
    044package org.jfree.data.xy;
    045
    046import java.io.Serializable;
    047import java.util.List;
    048
    049import org.jfree.data.general.DatasetChangeEvent;
    050import org.jfree.util.ObjectUtilities;
    051import org.jfree.util.PublicCloneable;
    052
    053/**
    054 * A collection of {@link XIntervalSeries} objects.
    055 *
    056 * @since 1.0.3
    057 *
    058 * @see XIntervalSeries
    059 */
    060public 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}