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: * DefaultPieDataset.java
029: * ----------------------
030: * (C) Copyright 2001-2007, by Object Refinery Limited.
031: *
032: * Original Author: David Gilbert (for Object Refinery Limited);
033: * Contributor(s): Sam (oldman);
034: *
035: * $Id: DefaultPieDataset.java,v 1.6.2.6 2007/04/30 16:16:50 mungady Exp $
036: *
037: * Changes
038: * -------
039: * 17-Nov-2001 : Version 1 (DG);
040: * 22-Jan-2002 : Removed legend methods from dataset implementations (DG);
041: * 07-Apr-2002 : Modified implementation to guarantee data sequence to remain
042: * in the order categories are added (oldman);
043: * 23-Oct-2002 : Added getCategory(int) method and getItemCount() method, in
044: * line with changes to the PieDataset interface (DG);
045: * 04-Feb-2003 : Changed underlying data storage to DefaultKeyedValues (DG);
046: * 04-Mar-2003 : Inserted DefaultKeyedValuesDataset class into hierarchy (DG);
047: * 24-Apr-2003 : Switched places with DefaultKeyedValuesDataset (DG);
048: * 18-Aug-2003 : Implemented Cloneable (DG);
049: * 03-Mar-2005 : Implemented PublicCloneable (DG);
050: * 29-Jun-2005 : Added remove() method (DG);
051: * ------------- JFREECHART 1.0.0 ---------------------------------------------
052: * 31-Jul-2006 : Added a clear() method to clear all values from the
053: * dataset (DG);
054: * 28-Sep-2006 : Added sortByKeys() and sortByValues() methods (DG);
055: * 30-Apr-2007 : Added new insertValues() methods (DG);
056: *
057: */
058:
059: package org.jfree.data.general;
060:
061: import java.io.Serializable;
062: import java.util.Collections;
063: import java.util.List;
064:
065: import org.jfree.data.DefaultKeyedValues;
066: import org.jfree.data.KeyedValues;
067: import org.jfree.data.UnknownKeyException;
068: import org.jfree.util.PublicCloneable;
069: import org.jfree.util.SortOrder;
070:
071: /**
072: * A default implementation of the {@link PieDataset} interface.
073: */
074: public class DefaultPieDataset extends AbstractDataset implements
075: PieDataset, Cloneable, PublicCloneable, Serializable {
076:
077: /** For serialization. */
078: private static final long serialVersionUID = 2904745139106540618L;
079:
080: /** Storage for the data. */
081: private DefaultKeyedValues data;
082:
083: /**
084: * Constructs a new dataset, initially empty.
085: */
086: public DefaultPieDataset() {
087: this .data = new DefaultKeyedValues();
088: }
089:
090: /**
091: * Creates a new dataset by copying data from a {@link KeyedValues}
092: * instance.
093: *
094: * @param data the data (<code>null</code> not permitted).
095: */
096: public DefaultPieDataset(KeyedValues data) {
097: if (data == null) {
098: throw new IllegalArgumentException("Null 'data' argument.");
099: }
100: this .data = new DefaultKeyedValues();
101: for (int i = 0; i < data.getItemCount(); i++) {
102: this .data.addValue(data.getKey(i), data.getValue(i));
103: }
104: }
105:
106: /**
107: * Returns the number of items in the dataset.
108: *
109: * @return The item count.
110: */
111: public int getItemCount() {
112: return this .data.getItemCount();
113: }
114:
115: /**
116: * Returns the categories in the dataset. The returned list is
117: * unmodifiable.
118: *
119: * @return The categories in the dataset.
120: */
121: public List getKeys() {
122: return Collections.unmodifiableList(this .data.getKeys());
123: }
124:
125: /**
126: * Returns the key for the specified item, or <code>null</code>.
127: *
128: * @param item the item index (in the range <code>0</code> to
129: * <code>getItemCount() - 1</code>).
130: *
131: * @return The key, or <code>null</code>.
132: *
133: * @throws IndexOutOfBoundsException if <code>item</code> is not in the
134: * specified range.
135: */
136: public Comparable getKey(int item) {
137: return this .data.getKey(item);
138: }
139:
140: /**
141: * Returns the index for a key, or -1 if the key is not recognised.
142: *
143: * @param key the key (<code>null</code> not permitted).
144: *
145: * @return The index, or <code>-1</code> if the key is unrecognised.
146: *
147: * @throws IllegalArgumentException if <code>key</code> is
148: * <code>null</code>.
149: */
150: public int getIndex(Comparable key) {
151: return this .data.getIndex(key);
152: }
153:
154: /**
155: * Returns a value.
156: *
157: * @param item the value index.
158: *
159: * @return The value (possibly <code>null</code>).
160: */
161: public Number getValue(int item) {
162:
163: Number result = null;
164: if (getItemCount() > item) {
165: result = this .data.getValue(item);
166: }
167: return result;
168:
169: }
170:
171: /**
172: * Returns the data value associated with a key.
173: *
174: * @param key the key (<code>null</code> not permitted).
175: *
176: * @return The value (possibly <code>null</code>).
177: *
178: * @throws UnknownKeyException if the key is not recognised.
179: */
180: public Number getValue(Comparable key) {
181: if (key == null) {
182: throw new IllegalArgumentException("Null 'key' argument.");
183: }
184: return this .data.getValue(key);
185: }
186:
187: /**
188: * Sets the data value for a key and sends a {@link DatasetChangeEvent} to
189: * all registered listeners.
190: *
191: * @param key the key (<code>null</code> not permitted).
192: * @param value the value.
193: *
194: * @throws IllegalArgumentException if <code>key</code> is
195: * <code>null</code>.
196: */
197: public void setValue(Comparable key, Number value) {
198: this .data.setValue(key, value);
199: fireDatasetChanged();
200: }
201:
202: /**
203: * Sets the data value for a key and sends a {@link DatasetChangeEvent} to
204: * all registered listeners.
205: *
206: * @param key the key (<code>null</code> not permitted).
207: * @param value the value.
208: *
209: * @throws IllegalArgumentException if <code>key</code> is
210: * <code>null</code>.
211: */
212: public void setValue(Comparable key, double value) {
213: setValue(key, new Double(value));
214: }
215:
216: /**
217: * Inserts a new value at the specified position in the dataset or, if
218: * there is an existing item with the specified key, updates the value
219: * for that item and moves it to the specified position. After the change
220: * is made, this methods sends a {@link DatasetChangeEvent} to all
221: * registered listeners.
222: *
223: * @param position the position (in the range 0 to getItemCount()).
224: * @param key the key (<code>null</code> not permitted).
225: * @param value the value (<code>null</code> permitted).
226: *
227: * @since 1.0.6
228: */
229: public void insertValue(int position, Comparable key, double value) {
230: insertValue(position, key, new Double(value));
231: }
232:
233: /**
234: * Inserts a new value at the specified position in the dataset or, if
235: * there is an existing item with the specified key, updates the value
236: * for that item and moves it to the specified position. After the change
237: * is made, this methods sends a {@link DatasetChangeEvent} to all
238: * registered listeners.
239: *
240: * @param position the position (in the range 0 to getItemCount()).
241: * @param key the key (<code>null</code> not permitted).
242: * @param value the value (<code>null</code> permitted).
243: *
244: * @since 1.0.6
245: */
246: public void insertValue(int position, Comparable key, Number value) {
247: this .data.insertValue(position, key, value);
248: fireDatasetChanged();
249: }
250:
251: /**
252: * Removes an item from the dataset and sends a {@link DatasetChangeEvent}
253: * to all registered listeners.
254: *
255: * @param key the key (<code>null</code> not permitted).
256: *
257: * @throws IllegalArgumentException if <code>key</code> is
258: * <code>null</code>.
259: */
260: public void remove(Comparable key) {
261: this .data.removeValue(key);
262: fireDatasetChanged();
263: }
264:
265: /**
266: * Clears all data from this dataset and sends a {@link DatasetChangeEvent}
267: * to all registered listeners (unless the dataset was already empty).
268: *
269: * @since 1.0.2
270: */
271: public void clear() {
272: if (getItemCount() > 0) {
273: this .data.clear();
274: fireDatasetChanged();
275: }
276: }
277:
278: /**
279: * Sorts the dataset's items by key and sends a {@link DatasetChangeEvent}
280: * to all registered listeners.
281: *
282: * @param order the sort order (<code>null</code> not permitted).
283: *
284: * @since 1.0.3
285: */
286: public void sortByKeys(SortOrder order) {
287: this .data.sortByKeys(order);
288: fireDatasetChanged();
289: }
290:
291: /**
292: * Sorts the dataset's items by value and sends a {@link DatasetChangeEvent}
293: * to all registered listeners.
294: *
295: * @param order the sort order (<code>null</code> not permitted).
296: *
297: * @since 1.0.3
298: */
299: public void sortByValues(SortOrder order) {
300: this .data.sortByValues(order);
301: fireDatasetChanged();
302: }
303:
304: /**
305: * Tests if this object is equal to another.
306: *
307: * @param obj the other object.
308: *
309: * @return A boolean.
310: */
311: public boolean equals(Object obj) {
312: if (obj == this ) {
313: return true;
314: }
315:
316: if (!(obj instanceof PieDataset)) {
317: return false;
318: }
319: PieDataset that = (PieDataset) obj;
320: int count = getItemCount();
321: if (that.getItemCount() != count) {
322: return false;
323: }
324:
325: for (int i = 0; i < count; i++) {
326: Comparable k1 = getKey(i);
327: Comparable k2 = that.getKey(i);
328: if (!k1.equals(k2)) {
329: return false;
330: }
331:
332: Number v1 = getValue(i);
333: Number v2 = that.getValue(i);
334: if (v1 == null) {
335: if (v2 != null) {
336: return false;
337: }
338: } else {
339: if (!v1.equals(v2)) {
340: return false;
341: }
342: }
343: }
344: return true;
345:
346: }
347:
348: /**
349: * Returns a hash code.
350: *
351: * @return A hash code.
352: */
353: public int hashCode() {
354: return this .data.hashCode();
355: }
356:
357: /**
358: * Returns a clone of the dataset.
359: *
360: * @return A clone.
361: *
362: * @throws CloneNotSupportedException This class will not throw this
363: * exception, but subclasses (if any) might.
364: */
365: public Object clone() throws CloneNotSupportedException {
366: DefaultPieDataset clone = (DefaultPieDataset) super .clone();
367: clone.data = (DefaultKeyedValues) this.data.clone();
368: return clone;
369: }
370:
371: }
|