ca.odell.glazedlists.jfreechart.EventListPieDataset Maven / Gradle / Ivy
Show all versions of glazedlists_java15 Show documentation
/* Glazed Lists (c) 2003-2006 */
/* http://publicobject.com/glazedlists/ publicobject.com,*/
/* O'Dell Engineering Ltd.*/
package ca.odell.glazedlists.jfreechart;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.FunctionList;
import ca.odell.glazedlists.GroupingList;
import ca.odell.glazedlists.event.ListEvent;
import ca.odell.glazedlists.event.ListEventListener;
import org.jfree.data.general.AbstractDataset;
import org.jfree.data.general.DatasetChangeEvent;
import org.jfree.data.general.PieDataset;
import java.util.Comparator;
import java.util.List;
/**
* This class adapts an {@link EventList} to the JFreeChart PieDataset
* interface. Changes to the backing {@link EventList} are rebroadcast as
* changes to this PieDataset.
*
*
* Extension: JFreeChart
* This Glazed Lists extension requires the third party library JFreeChart.
* Tested Version: 1.0.0
* Home page: http://www.jfree.org/jfreechart/
* License: LGPL
*
*
*
* Note: The DataEvents broadcasted by this class occur on the Thread the
* ListEvents arrive on. If this PieDataset is attached to a swing component,
* like a {@link org.jfree.chart.ChartPanel}, it is the responsibility of the
* client to ensure that the ListEvents are arriving on the Swing Event
* Dispatch Thread, perhaps by using the
* {@link ca.odell.glazedlists.impl.swing.SwingThreadProxyEventList}.
*
* @see ca.odell.glazedlists.impl.swing.SwingThreadProxyEventList
*
* @author James Lemieux
*/
public class EventListPieDataset extends AbstractDataset implements PieDataset {
/** The single immutable DatasetChangeEvent we fire each time this Dataset is changed. */
private final DatasetChangeEvent immutableChangeEvent = new DatasetChangeEvent(this, this);
// the list that is the source of all data
private final EventList sourceList;
// the list that groups the data into sections of the pie
private final GroupingList groupingList;
// a function that extracts keys from the groups
private final FunctionList keyList;
// a function that extracts values from the groups
private final FunctionList valueList;
// listen to changes in the {@link sourceList} and rebroadcast them as changes to this PieDataset
private final ListEventListener datasetEventListener = new DatasetEventListener();
/**
* Adapts the given source
to the PieDataset interface. The
* given keyFunction
is then applied to each element of the
* source
to produce the unique key for the element and the
* given valueFunction
is applied to produce the value for an
* element.
*
* This constructor should be used when the elements in
* source
do not need to be grouped together in order to
* represent pie data.
*
* @param source the {@link EventList} containing the data to chart
* @param keyFunction produces the keys of the source elements in the pie chart
* @param valueFunction produces the values of the source elements in the pie chart
*/
public EventListPieDataset(EventList source, FunctionList.Function> keyFunction, FunctionList.Function valueFunction) {
this.groupingList = null;
this.sourceList = source;
this.keyList = new FunctionList(source, keyFunction);
this.valueList = new FunctionList(source, valueFunction);
source.addListEventListener(this.datasetEventListener);
}
/**
* Adapts the given source
to the PieDataset interface by
* applying the groupingComparator
to forms groups to be
* represented in the pie chart. The given keyFunction
is then
* applied to produce the key for a group and the given
* valueFunction
is applied to produce the value for a group.
*
* @param source the {@link EventList} containing the data to chart
* @param groupingComparator produces the groups in the pie chart
* @param keyFunction produces the keys of the groups in the pie chart
* @param valueFunction produces the values of the groups in the pie chart
*/
public EventListPieDataset(EventList source, Comparator groupingComparator, FunctionList.Function, Comparable> keyFunction, FunctionList.Function, Number> valueFunction) {
this.groupingList = new GroupingList(source, groupingComparator);
this.sourceList = this.groupingList;
this.keyList = new FunctionList(this.groupingList, keyFunction);
this.valueList = new FunctionList(this.groupingList, valueFunction);
this.groupingList.addListEventListener(this.datasetEventListener);
}
/**
* Returns the key of the value at the given index
.
*
* @param index the item index (zero-based)
* @return the key
*
* @throws IndexOutOfBoundsException if index
is out of bounds
*/
public Comparable getKey(int index) {
return this.keyList.get(index);
}
/**
* Returns the index for a given key.
*
* @param key the key
* @return the index, or -1
if the key is unrecognised
*/
public int getIndex(Comparable key) {
return this.keyList.indexOf(key);
}
/**
* Returns the keys for the values in this PieDataset. Note that you can
* access the values in this PieDataset by key or by index. For this
* reason, the key order is important - this method should return the keys
* in order. The returned list may be unmodifiable.
*
* @return the keys (never null
).
*/
public List getKeys() {
return this.keyList;
}
/**
* Returns the value for a given key.
*
* @param key the key
* @return the value (possibly null
)
*
* @throws org.jfree.data.UnknownKeyException if the key is not recognised
*/
public Number getValue(Comparable key) {
return getValue(this.getIndex(key));
}
/**
* Returns the number of items (values).
*/
public int getItemCount() {
return this.keyList.size();
}
/**
* Returns the value at the given index
.
*
* @param index the index of interest (zero-based index).
* @return the value
*/
public Number getValue(int index) {
return this.valueList.get(index);
}
/**
* Releases the resources consumed by this EventListPieDataset so that it
* may eventually be garbage collected. This is important when the
* {@link EventList} that backs this EventListPieDataset should outlast
* this EventListPieDataset. This method should be called as soon as this
* EventListPieDataset is no longer useful.
*
* Warning: It is an error
* to call any method on an EventListPieDataset after it has been disposed.
*/
public void dispose() {
this.keyList.dispose();
this.valueList.dispose();
this.sourceList.removeListEventListener(this.datasetEventListener);
if (this.groupingList != null)
this.groupingList.dispose();
}
/**
* We override this method for speed reasons, since the super needlessly
* constructs a new DatasetChangedEvent each time this method is called.
*/
@Override
protected void fireDatasetChanged() {
notifyListeners(immutableChangeEvent);
}
/**
* This listener rebroadcasts ListEvents as DatasetChangeEvents.
*/
private class DatasetEventListener implements ListEventListener {
public void listChanged(ListEvent listChanges) {
fireDatasetChanged();
}
}
}