    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 * AbstractRenderer.java
    029 * ---------------------
    030 * (C) Copyright 2002-2011, by Object Refinery Limited.
    031 *
    032 * Original Author:  David Gilbert (for Object Refinery Limited);
    033 * Contributor(s):   Nicolas Brodu;
    034 *
    035 * Changes:
    036 * --------
    037 * 22-Aug-2002 : Version 1, draws code out of AbstractXYItemRenderer to share
    038 *               with AbstractCategoryItemRenderer (DG);
    039 * 01-Oct-2002 : Fixed errors reported by Checkstyle (DG);
    040 * 06-Nov-2002 : Moved to the com.jrefinery.chart.renderer package (DG);
    041 * 21-Nov-2002 : Added a paint table for the renderer to use (DG);
    042 * 17-Jan-2003 : Moved plot classes into a separate package (DG);
    043 * 25-Mar-2003 : Implemented Serializable (DG);
    044 * 29-Apr-2003 : Added valueLabelFont and valueLabelPaint attributes, based on
    045 *               code from Arnaud Lelievre (DG);
    046 * 29-Jul-2003 : Amended code that doesn't compile with JDK 1.2.2 (DG);
    047 * 13-Aug-2003 : Implemented Cloneable (DG);
    048 * 15-Sep-2003 : Fixed serialization (NB);
    049 * 17-Sep-2003 : Changed ChartRenderingInfo --> PlotRenderingInfo (DG);
    050 * 07-Oct-2003 : Moved PlotRenderingInfo into RendererState to allow for
    051 *               multiple threads using a single renderer (DG);
    052 * 20-Oct-2003 : Added missing setOutlinePaint() method (DG);
    053 * 23-Oct-2003 : Split item label attributes into 'positive' and 'negative'
    054 *               values (DG);
    055 * 26-Nov-2003 : Added methods to get the positive and negative item label
    056 *               positions (DG);
    057 * 01-Mar-2004 : Modified readObject() method to prevent null pointer exceptions
    058 *               after deserialization (DG);
    059 * 19-Jul-2004 : Fixed bug in getItemLabelFont(int, int) method (DG);
    060 * 04-Oct-2004 : Updated equals() method, eliminated use of NumberUtils,
    061 *               renamed BooleanUtils --> BooleanUtilities, ShapeUtils -->
    062 *               ShapeUtilities (DG);
    063 * 15-Mar-2005 : Fixed serialization of baseFillPaint (DG);
    064 * 16-May-2005 : Base outline stroke should never be null (DG);
    065 * 01-Jun-2005 : Added hasListener() method for unit testing (DG);
    066 * 08-Jun-2005 : Fixed equals() method to handle GradientPaint (DG);
    067 * ------------- JFREECHART 1.0.x ---------------------------------------------
    068 * 02-Feb-2007 : Minor API doc update (DG);
    069 * 19-Feb-2007 : Fixes for clone() method (DG);
    070 * 28-Feb-2007 : Use cached event to signal changes (DG);
    071 * 19-Apr-2007 : Deprecated seriesVisible and seriesVisibleInLegend flags (DG);
    072 * 20-Apr-2007 : Deprecated paint, fillPaint, outlinePaint, stroke,
    073 *               outlineStroke, shape, itemLabelsVisible, itemLabelFont,
    074 *               itemLabelPaint, positiveItemLabelPosition,
    075 *               negativeItemLabelPosition and createEntities override
    076 *               fields (DG);
    077 * 13-Jun-2007 : Added new autoPopulate flags for core series attributes (DG);
    078 * 23-Oct-2007 : Updated lookup methods to better handle overridden
    079 *               methods (DG);
    080 * 04-Dec-2007 : Modified hashCode() implementation (DG);
    081 * 29-Apr-2008 : Minor API doc update (DG);
    082 * 17-Jun-2008 : Added legendShape, legendTextFont and legendTextPaint
    083 *               attributes (DG);
    084 * 18-Aug-2008 : Added clearSeriesPaints() and clearSeriesStrokes() (DG);
    085 * 28-Jan-2009 : Equals method doesn't test Shape equality correctly (DG);
    086 * 27-Mar-2009 : Added dataBoundsIncludesVisibleSeriesOnly attribute, and
    087 *               updated renderer events for series visibility changes (DG);
    088 * 01-Apr-2009 : Factored up the defaultEntityRadius field from the
    089 *               AbstractXYItemRenderer class (DG);
    090 * 28-Apr-2009 : Added flag to allow a renderer to treat the legend shape as
    091 *               a line (DG);
    092 *
    093 */
    094
    095package org.jfree.chart.renderer;
    096
    097import java.awt.BasicStroke;
    098import java.awt.Color;
    099import java.awt.Font;
    100import java.awt.Paint;
    101import java.awt.Shape;
    102import java.awt.Stroke;
    103import java.awt.geom.Point2D;
    104import java.awt.geom.Rectangle2D;
    105import java.io.IOException;
    106import java.io.ObjectInputStream;
    107import java.io.ObjectOutputStream;
    108import java.io.Serializable;
    109import java.util.Arrays;
    110import java.util.EventListener;
    111import java.util.List;
    112
    113import javax.swing.event.EventListenerList;
    114
    115import org.jfree.chart.HashUtilities;
    116import org.jfree.chart.event.RendererChangeEvent;
    117import org.jfree.chart.event.RendererChangeListener;
    118import org.jfree.chart.labels.ItemLabelAnchor;
    119import org.jfree.chart.labels.ItemLabelPosition;
    120import org.jfree.chart.plot.DrawingSupplier;
    121import org.jfree.chart.plot.PlotOrientation;
    122import org.jfree.chart.title.LegendTitle;
    123import org.jfree.io.SerialUtilities;
    124import org.jfree.ui.TextAnchor;
    125import org.jfree.util.BooleanList;
    126import org.jfree.util.BooleanUtilities;
    127import org.jfree.util.ObjectList;
    128import org.jfree.util.ObjectUtilities;
    129import org.jfree.util.PaintList;
    130import org.jfree.util.PaintUtilities;
    131import org.jfree.util.ShapeList;
    132import org.jfree.util.ShapeUtilities;
    133import org.jfree.util.StrokeList;
    134
    135/**
    136 * Base class providing common services for renderers.  Most methods that update
    137 * attributes of the renderer will fire a {@link RendererChangeEvent}, which
    138 * normally means the plot that owns the renderer will receive notification that
    139 * the renderer has been changed (the plot will, in turn, notify the chart).
    140 */
    141public abstract class AbstractRenderer implements Cloneable, Serializable {
    142
    143    /** For serialization. */
    144    private static final long serialVersionUID = -828267569428206075L;
    145
    146    /** Zero represented as a <code>Double</code>. */
    147    public static final Double ZERO = new Double(0.0);
    148
    149    /** The default paint. */
    150    public static final Paint DEFAULT_PAINT = Color.blue;
    151
    152    /** The default outline paint. */
    153    public static final Paint DEFAULT_OUTLINE_PAINT = Color.gray;
    154
    155    /** The default stroke. */
    156    public static final Stroke DEFAULT_STROKE = new BasicStroke(1.0f);
    157
    158    /** The default outline stroke. */
    159    public static final Stroke DEFAULT_OUTLINE_STROKE = new BasicStroke(1.0f);
    160
    161    /** The default shape. */
    162    public static final Shape DEFAULT_SHAPE
    163            = new Rectangle2D.Double(-3.0, -3.0, 6.0, 6.0);
    164
    165    /** The default value label font. */
    166    public static final Font DEFAULT_VALUE_LABEL_FONT
    167            = new Font("SansSerif", Font.PLAIN, 10);
    168
    169    /** The default value label paint. */
    170    public static final Paint DEFAULT_VALUE_LABEL_PAINT = Color.black;
    171
    172    /** A list of flags that controls whether or not each series is visible. */
    173    private BooleanList seriesVisibleList;
    174
    175    /** The default visibility for each series. */
    176    private boolean baseSeriesVisible;
    177
    178    /**
    179     * A list of flags that controls whether or not each series is visible in
    180     * the legend.
    181     */
    182    private BooleanList seriesVisibleInLegendList;
    183
    184    /** The default visibility for each series in the legend. */
    185    private boolean baseSeriesVisibleInLegend;
    186
    187    /** The paint list. */
    188    private PaintList paintList;
    189
    190    /**
    191     * A flag that controls whether or not the paintList is auto-populated
    192     * in the {@link #lookupSeriesPaint(int)} method.
    193     *
    194     * @since 1.0.6
    195     */
    196    private boolean autoPopulateSeriesPaint;
    197
    198    /** The base paint. */
    199    private transient Paint basePaint;
    200
    201    /** The fill paint list. */
    202    private PaintList fillPaintList;
    203
    204    /**
    205     * A flag that controls whether or not the fillPaintList is auto-populated
    206     * in the {@link #lookupSeriesFillPaint(int)} method.
    207     *
    208     * @since 1.0.6
    209     */
    210    private boolean autoPopulateSeriesFillPaint;
    211
    212    /** The base fill paint. */
    213    private transient Paint baseFillPaint;
    214
    215    /** The outline paint list. */
    216    private PaintList outlinePaintList;
    217
    218    /**
    219     * A flag that controls whether or not the outlinePaintList is
    220     * auto-populated in the {@link #lookupSeriesOutlinePaint(int)} method.
    221     *
    222     * @since 1.0.6
    223     */
    224    private boolean autoPopulateSeriesOutlinePaint;
    225
    226    /** The base outline paint. */
    227    private transient Paint baseOutlinePaint;
    228
    229    /** The stroke list. */
    230    private StrokeList strokeList;
    231
    232    /**
    233     * A flag that controls whether or not the strokeList is auto-populated
    234     * in the {@link #lookupSeriesStroke(int)} method.
    235     *
    236     * @since 1.0.6
    237     */
    238    private boolean autoPopulateSeriesStroke;
    239
    240    /** The base stroke. */
    241    private transient Stroke baseStroke;
    242
    243    /** The outline stroke list. */
    244    private StrokeList outlineStrokeList;
    245
    246    /** The base outline stroke. */
    247    private transient Stroke baseOutlineStroke;
    248
    249    /**
    250     * A flag that controls whether or not the outlineStrokeList is
    251     * auto-populated in the {@link #lookupSeriesOutlineStroke(int)} method.
    252     *
    253     * @since 1.0.6
    254     */
    255    private boolean autoPopulateSeriesOutlineStroke;
    256
    257    /** A shape list. */
    258    private ShapeList shapeList;
    259
    260    /**
    261     * A flag that controls whether or not the shapeList is auto-populated
    262     * in the {@link #lookupSeriesShape(int)} method.
    263     *
    264     * @since 1.0.6
    265     */
    266    private boolean autoPopulateSeriesShape;
    267
    268    /** The base shape. */
    269    private transient Shape baseShape;
    270
    271    /** Visibility of the item labels PER series. */
    272    private BooleanList itemLabelsVisibleList;
    273
    274    /** The base item labels visible. */
    275    private Boolean baseItemLabelsVisible;
    276
    277    /** The item label font list (one font per series). */
    278    private ObjectList itemLabelFontList;
    279
    280    /** The base item label font. */
    281    private Font baseItemLabelFont;
    282
    283    /** The item label paint list (one paint per series). */
    284    private PaintList itemLabelPaintList;
    285
    286    /** The base item label paint. */
    287    private transient Paint baseItemLabelPaint;
    288
    289    /** The positive item label position (per series). */
    290    private ObjectList positiveItemLabelPositionList;
    291
    292    /** The fallback positive item label position. */
    293    private ItemLabelPosition basePositiveItemLabelPosition;
    294
    295    /** The negative item label position (per series). */
    296    private ObjectList negativeItemLabelPositionList;
    297
    298    /** The fallback negative item label position. */
    299    private ItemLabelPosition baseNegativeItemLabelPosition;
    300
    301    /** The item label anchor offset. */
    302    private double itemLabelAnchorOffset = 2.0;
    303
    304    /**
    305     * Flags that control whether or not entities are generated for each
    306     * series.  This will be overridden by 'createEntities'.
    307     */
    308    private BooleanList createEntitiesList;
    309
    310    /**
    311     * The default flag that controls whether or not entities are generated.
    312     * This flag is used when both the above flags return null.
    313     */
    314    private boolean baseCreateEntities;
    315
    316    /**
    317     * The per-series legend shape settings.
    318     *
    319     * @since 1.0.11
    320     */
    321    private ShapeList legendShapeList;
    322
    323    /**
    324     * The base shape for legend items.  If this is <code>null</code>, the
    325     * series shape will be used.
    326     *
    327     * @since 1.0.11
    328     */
    329    private transient Shape baseLegendShape;
    330
    331    /**
    332     * A special flag that, if true, will cause the getLegendItem() method
    333     * to configure the legend shape as if it were a line.
    334     *
    335     * @since 1.0.14
    336     */
    337    private boolean treatLegendShapeAsLine;
    338
    339    /**
    340     * The per-series legend text font.
    341     *
    342     * @since 1.0.11
    343     */
    344    private ObjectList legendTextFont;
    345
    346    /**
    347     * The base legend font.
    348     *
    349     * @since 1.0.11
    350     */
    351    private Font baseLegendTextFont;
    352
    353    /**
    354     * The per series legend text paint settings.
    355     *
    356     * @since 1.0.11
    357     */
    358    private PaintList legendTextPaint;
    359
    360    /**
    361     * The default paint for the legend text items (if this is
    362     * <code>null</code>, the {@link LegendTitle} class will determine the
    363     * text paint to use.
    364     *
    365     * @since 1.0.11
    366     */
    367    private transient Paint baseLegendTextPaint;
    368
    369    /**
    370     * A flag that controls whether or not the renderer will include the
    371     * non-visible series when calculating the data bounds.
    372     *
    373     * @since 1.0.13
    374     */
    375    private boolean dataBoundsIncludesVisibleSeriesOnly = true;
    376
    377    /** The default radius for the entity 'hotspot' */
    378    private int defaultEntityRadius;
    379
    380    /** Storage for registered change listeners. */
    381    private transient EventListenerList listenerList;
    382
    383    /** An event for re-use. */
    384    private transient RendererChangeEvent event;
    385
    386    /**
    387     * Default constructor.
    388     */
    389    public AbstractRenderer() {
    390
    391        this.seriesVisible = null;
    392        this.seriesVisibleList = new BooleanList();
    393        this.baseSeriesVisible = true;
    394
    395        this.seriesVisibleInLegend = null;
    396        this.seriesVisibleInLegendList = new BooleanList();
    397        this.baseSeriesVisibleInLegend = true;
    398
    399        this.paint = null;
    400        this.paintList = new PaintList();
    401        this.basePaint = DEFAULT_PAINT;
    402        this.autoPopulateSeriesPaint = true;
    403
    404        this.fillPaint = null;
    405        this.fillPaintList = new PaintList();
    406        this.baseFillPaint = Color.white;
    407        this.autoPopulateSeriesFillPaint = false;
    408
    409        this.outlinePaint = null;
    410        this.outlinePaintList = new PaintList();
    411        this.baseOutlinePaint = DEFAULT_OUTLINE_PAINT;
    412        this.autoPopulateSeriesOutlinePaint = false;
    413
    414        this.stroke = null;
    415        this.strokeList = new StrokeList();
    416        this.baseStroke = DEFAULT_STROKE;
    417        this.autoPopulateSeriesStroke = true;
    418
    419        this.outlineStroke = null;
    420        this.outlineStrokeList = new StrokeList();
    421        this.baseOutlineStroke = DEFAULT_OUTLINE_STROKE;
    422        this.autoPopulateSeriesOutlineStroke = false;
    423
    424        this.shape = null;
    425        this.shapeList = new ShapeList();
    426        this.baseShape = DEFAULT_SHAPE;
    427        this.autoPopulateSeriesShape = true;
    428
    429        this.itemLabelsVisible = null;
    430        this.itemLabelsVisibleList = new BooleanList();
    431        this.baseItemLabelsVisible = Boolean.FALSE;
    432
    433        this.itemLabelFont = null;
    434        this.itemLabelFontList = new ObjectList();
    435        this.baseItemLabelFont = new Font("SansSerif", Font.PLAIN, 10);
    436
    437        this.itemLabelPaint = null;
    438        this.itemLabelPaintList = new PaintList();
    439        this.baseItemLabelPaint = Color.black;
    440
    441        this.positiveItemLabelPosition = null;
    442        this.positiveItemLabelPositionList = new ObjectList();
    443        this.basePositiveItemLabelPosition = new ItemLabelPosition(
    444                ItemLabelAnchor.OUTSIDE12, TextAnchor.BOTTOM_CENTER);
    445
    446        this.negativeItemLabelPosition = null;
    447        this.negativeItemLabelPositionList = new ObjectList();
    448        this.baseNegativeItemLabelPosition = new ItemLabelPosition(
    449                ItemLabelAnchor.OUTSIDE6, TextAnchor.TOP_CENTER);
    450
    451        this.createEntities = null;
    452        this.createEntitiesList = new BooleanList();
    453        this.baseCreateEntities = true;
    454
    455        this.defaultEntityRadius = 3;
    456
    457        this.legendShapeList = new ShapeList();
    458        this.baseLegendShape = null;
    459
    460        this.treatLegendShapeAsLine = false;
    461
    462        this.legendTextFont = new ObjectList();
    463        this.baseLegendTextFont = null;
    464
    465        this.legendTextPaint = new PaintList();
    466        this.baseLegendTextPaint = null;
    467
    468        this.listenerList = new EventListenerList();
    469
    470    }
    471
    472    /**
    473     * Returns the drawing supplier from the plot.
    474     *
    475     * @return The drawing supplier.
    476     */
    477    public abstract DrawingSupplier getDrawingSupplier();
    478
    479    // SERIES VISIBLE (not yet respected by all renderers)
    480
    481    /**
    482     * Returns a boolean that indicates whether or not the specified item
    483     * should be drawn (this is typically used to hide an entire series).
    484     *
    485     * @param series  the series index.
    486     * @param item  the item index.
    487     *
    488     * @return A boolean.
    489     */
    490    public boolean getItemVisible(int series, int item) {
    491        return isSeriesVisible(series);
    492    }
    493
    494    /**
    495     * Returns a boolean that indicates whether or not the specified series
    496     * should be drawn.
    497     *
    498     * @param series  the series index.
    499     *
    500     * @return A boolean.
    501     */
    502    public boolean isSeriesVisible(int series) {
    503        boolean result = this.baseSeriesVisible;
    504        if (this.seriesVisible != null) {
    505            result = this.seriesVisible.booleanValue();
    506        }
    507        else {
    508            Boolean b = this.seriesVisibleList.getBoolean(series);
    509            if (b != null) {
    510                result = b.booleanValue();
    511            }
    512        }
    513        return result;
    514    }
    515
    516    /**
    517     * Returns the flag that controls whether a series is visible.
    518     *
    519     * @param series  the series index (zero-based).
    520     *
    521     * @return The flag (possibly <code>null</code>).
    522     *
    523     * @see #setSeriesVisible(int, Boolean)
    524     */
    525    public Boolean getSeriesVisible(int series) {
    526        return this.seriesVisibleList.getBoolean(series);
    527    }
    528
    529    /**
    530     * Sets the flag that controls whether a series is visible and sends a
    531     * {@link RendererChangeEvent} to all registered listeners.
    532     *
    533     * @param series  the series index (zero-based).
    534     * @param visible  the flag (<code>null</code> permitted).
    535     *
    536     * @see #getSeriesVisible(int)
    537     */
    538    public void setSeriesVisible(int series, Boolean visible) {
    539        setSeriesVisible(series, visible, true);
    540    }
    541
    542    /**
    543     * Sets the flag that controls whether a series is visible and, if
    544     * requested, sends a {@link RendererChangeEvent} to all registered
    545     * listeners.
    546     *
    547     * @param series  the series index.
    548     * @param visible  the flag (<code>null</code> permitted).
    549     * @param notify  notify listeners?
    550     *
    551     * @see #getSeriesVisible(int)
    552     */
    553    public void setSeriesVisible(int series, Boolean visible, boolean notify) {
    554        this.seriesVisibleList.setBoolean(series, visible);
    555        if (notify) {
    556            // we create an event with a special flag set...the purpose of
    557            // this is to communicate to the plot (the default receiver of
    558            // the event) that series visibility has changed so the axis
    559            // ranges might need updating...
    560            RendererChangeEvent e = new RendererChangeEvent(this, true);
    561            notifyListeners(e);
    562        }
    563    }
    564
    565    /**
    566     * Returns the base visibility for all series.
    567     *
    568     * @return The base visibility.
    569     *
    570     * @see #setBaseSeriesVisible(boolean)
    571     */
    572    public boolean getBaseSeriesVisible() {
    573        return this.baseSeriesVisible;
    574    }
    575
    576    /**
    577     * Sets the base visibility and sends a {@link RendererChangeEvent}
    578     * to all registered listeners.
    579     *
    580     * @param visible  the flag.
    581     *
    582     * @see #getBaseSeriesVisible()
    583     */
    584    public void setBaseSeriesVisible(boolean visible) {
    585        // defer argument checking...
    586        setBaseSeriesVisible(visible, true);
    587    }
    588
    589    /**
    590     * Sets the base visibility and, if requested, sends
    591     * a {@link RendererChangeEvent} to all registered listeners.
    592     *
    593     * @param visible  the visibility.
    594     * @param notify  notify listeners?
    595     *
    596     * @see #getBaseSeriesVisible()
    597     */
    598    public void setBaseSeriesVisible(boolean visible, boolean notify) {
    599        this.baseSeriesVisible = visible;
    600        if (notify) {
    601            // we create an event with a special flag set...the purpose of
    602            // this is to communicate to the plot (the default receiver of
    603            // the event) that series visibility has changed so the axis
    604            // ranges might need updating...
    605            RendererChangeEvent e = new RendererChangeEvent(this, true);
    606            notifyListeners(e);
    607        }
    608    }
    609
    610    // SERIES VISIBLE IN LEGEND (not yet respected by all renderers)
    611
    612    /**
    613     * Returns <code>true</code> if the series should be shown in the legend,
    614     * and <code>false</code> otherwise.
    615     *
    616     * @param series  the series index.
    617     *
    618     * @return A boolean.
    619     */
    620    public boolean isSeriesVisibleInLegend(int series) {
    621        boolean result = this.baseSeriesVisibleInLegend;
    622        if (this.seriesVisibleInLegend != null) {
    623            result = this.seriesVisibleInLegend.booleanValue();
    624        }
    625        else {
    626            Boolean b = this.seriesVisibleInLegendList.getBoolean(series);
    627            if (b != null) {
    628                result = b.booleanValue();
    629            }
    630        }
    631        return result;
    632    }
    633
    634    /**
    635     * Returns the flag that controls whether a series is visible in the
    636     * legend.  This method returns only the "per series" settings - to
    637     * incorporate the override and base settings as well, you need to use the
    638     * {@link #isSeriesVisibleInLegend(int)} method.
    639     *
    640     * @param series  the series index (zero-based).
    641     *
    642     * @return The flag (possibly <code>null</code>).
    643     *
    644     * @see #setSeriesVisibleInLegend(int, Boolean)
    645     */
    646    public Boolean getSeriesVisibleInLegend(int series) {
    647        return this.seriesVisibleInLegendList.getBoolean(series);
    648    }
    649
    650    /**
    651     * Sets the flag that controls whether a series is visible in the legend
    652     * and sends a {@link RendererChangeEvent} to all registered listeners.
    653     *
    654     * @param series  the series index (zero-based).
    655     * @param visible  the flag (<code>null</code> permitted).
    656     *
    657     * @see #getSeriesVisibleInLegend(int)
    658     */
    659    public void setSeriesVisibleInLegend(int series, Boolean visible) {
    660        setSeriesVisibleInLegend(series, visible, true);
    661    }
    662
    663    /**
    664     * Sets the flag that controls whether a series is visible in the legend
    665     * and, if requested, sends a {@link RendererChangeEvent} to all registered
    666     * listeners.
    667     *
    668     * @param series  the series index.
    669     * @param visible  the flag (<code>null</code> permitted).
    670     * @param notify  notify listeners?
    671     *
    672     * @see #getSeriesVisibleInLegend(int)
    673     */
    674    public void setSeriesVisibleInLegend(int series, Boolean visible,
    675                                         boolean notify) {
    676        this.seriesVisibleInLegendList.setBoolean(series, visible);
    677        if (notify) {
    678            fireChangeEvent();
    679        }
    680    }
    681
    682    /**
    683     * Returns the base visibility in the legend for all series.
    684     *
    685     * @return The base visibility.
    686     *
    687     * @see #setBaseSeriesVisibleInLegend(boolean)
    688     */
    689    public boolean getBaseSeriesVisibleInLegend() {
    690        return this.baseSeriesVisibleInLegend;
    691    }
    692
    693    /**
    694     * Sets the base visibility in the legend and sends a
    695     * {@link RendererChangeEvent} to all registered listeners.
    696     *
    697     * @param visible  the flag.
    698     *
    699     * @see #getBaseSeriesVisibleInLegend()
    700     */
    701    public void setBaseSeriesVisibleInLegend(boolean visible) {
    702        // defer argument checking...
    703        setBaseSeriesVisibleInLegend(visible, true);
    704    }
    705
    706    /**
    707     * Sets the base visibility in the legend and, if requested, sends
    708     * a {@link RendererChangeEvent} to all registered listeners.
    709     *
    710     * @param visible  the visibility.
    711     * @param notify  notify listeners?
    712     *
    713     * @see #getBaseSeriesVisibleInLegend()
    714     */
    715    public void setBaseSeriesVisibleInLegend(boolean visible, boolean notify) {
    716        this.baseSeriesVisibleInLegend = visible;
    717        if (notify) {
    718            fireChangeEvent();
    719        }
    720    }
    721
    722    // PAINT
    723
    724    /**
    725     * Returns the paint used to fill data items as they are drawn.
    726     * <p>
    727     * The default implementation passes control to the
    728     * <code>lookupSeriesPaint()</code> method. You can override this method
    729     * if you require different behaviour.
    730     *
    731     * @param row  the row (or series) index (zero-based).
    732     * @param column  the column (or category) index (zero-based).
    733     *
    734     * @return The paint (never <code>null</code>).
    735     */
    736    public Paint getItemPaint(int row, int column) {
    737        return lookupSeriesPaint(row);
    738    }
    739
    740    /**
    741     * Returns the paint used to fill an item drawn by the renderer.
    742     *
    743     * @param series  the series index (zero-based).
    744     *
    745     * @return The paint (never <code>null</code>).
    746     *
    747     * @since 1.0.6
    748     */
    749    public Paint lookupSeriesPaint(int series) {
    750
    751        // return the override, if there is one...
    752        if (this.paint != null) {
    753            return this.paint;
    754        }
    755
    756        // otherwise look up the paint list
    757        Paint seriesPaint = getSeriesPaint(series);
    758        if (seriesPaint == null && this.autoPopulateSeriesPaint) {
    759            DrawingSupplier supplier = getDrawingSupplier();
    760            if (supplier != null) {
    761                seriesPaint = supplier.getNextPaint();
    762                setSeriesPaint(series, seriesPaint, false);
    763            }
    764        }
    765        if (seriesPaint == null) {
    766            seriesPaint = this.basePaint;
    767        }
    768        return seriesPaint;
    769
    770    }
    771
    772    /**
    773     * Returns the paint used to fill an item drawn by the renderer.
    774     *
    775     * @param series  the series index (zero-based).
    776     *
    777     * @return The paint (possibly <code>null</code>).
    778     *
    779     * @see #setSeriesPaint(int, Paint)
    780     */
    781    public Paint getSeriesPaint(int series) {
    782        return this.paintList.getPaint(series);
    783    }
    784
    785    /**
    786     * Sets the paint used for a series and sends a {@link RendererChangeEvent}
    787     * to all registered listeners.
    788     *
    789     * @param series  the series index (zero-based).
    790     * @param paint  the paint (<code>null</code> permitted).
    791     *
    792     * @see #getSeriesPaint(int)
    793     */
    794    public void setSeriesPaint(int series, Paint paint) {
    795        setSeriesPaint(series, paint, true);
    796    }
    797
    798    /**
    799     * Sets the paint used for a series and, if requested, sends a
    800     * {@link RendererChangeEvent} to all registered listeners.
    801     *
    802     * @param series  the series index.
    803     * @param paint  the paint (<code>null</code> permitted).
    804     * @param notify  notify listeners?
    805     *
    806     * @see #getSeriesPaint(int)
    807     */
    808    public void setSeriesPaint(int series, Paint paint, boolean notify) {
    809        this.paintList.setPaint(series, paint);
    810        if (notify) {
    811            fireChangeEvent();
    812        }
    813    }
    814
    815    /**
    816     * Clears the series paint settings for this renderer and, if requested,
    817     * sends a {@link RendererChangeEvent} to all registered listeners.
    818     *
    819     * @param notify  notify listeners?
    820     *
    821     * @since 1.0.11
    822     */
    823    public void clearSeriesPaints(boolean notify) {
    824        this.paintList.clear();
    825        if (notify) {
    826            fireChangeEvent();
    827        }
    828    }
    829
    830    /**
    831     * Returns the base paint.
    832     *
    833     * @return The base paint (never <code>null</code>).
    834     *
    835     * @see #setBasePaint(Paint)
    836     */
    837    public Paint getBasePaint() {
    838        return this.basePaint;
    839    }
    840
    841    /**
    842     * Sets the base paint and sends a {@link RendererChangeEvent} to all
    843     * registered listeners.
    844     *
    845     * @param paint  the paint (<code>null</code> not permitted).
    846     *
    847     * @see #getBasePaint()
    848     */
    849    public void setBasePaint(Paint paint) {
    850        // defer argument checking...
    851        setBasePaint(paint, true);
    852    }
    853
    854    /**
    855     * Sets the base paint and, if requested, sends a
    856     * {@link RendererChangeEvent} to all registered listeners.
    857     *
    858     * @param paint  the paint (<code>null</code> not permitted).
    859     * @param notify  notify listeners?
    860     *
    861     * @see #getBasePaint()
    862     */
    863    public void setBasePaint(Paint paint, boolean notify) {
    864        this.basePaint = paint;
    865        if (notify) {
    866            fireChangeEvent();
    867        }
    868    }
    869
    870    /**
    871     * Returns the flag that controls whether or not the series paint list is
    872     * automatically populated when {@link #lookupSeriesPaint(int)} is called.
    873     *
    874     * @return A boolean.
    875     *
    876     * @since 1.0.6
    877     *
    878     * @see #setAutoPopulateSeriesPaint(boolean)
    879     */
    880    public boolean getAutoPopulateSeriesPaint() {
    881        return this.autoPopulateSeriesPaint;
    882    }
    883
    884    /**
    885     * Sets the flag that controls whether or not the series paint list is
    886     * automatically populated when {@link #lookupSeriesPaint(int)} is called.
    887     *
    888     * @param auto  the new flag value.
    889     *
    890     * @since 1.0.6
    891     *
    892     * @see #getAutoPopulateSeriesPaint()
    893     */
    894    public void setAutoPopulateSeriesPaint(boolean auto) {
    895        this.autoPopulateSeriesPaint = auto;
    896    }
    897
    898    //// FILL PAINT //////////////////////////////////////////////////////////
    899
    900    /**
    901     * Returns the paint used to fill data items as they are drawn.  The
    902     * default implementation passes control to the
    903     * {@link #lookupSeriesFillPaint(int)} method - you can override this
    904     * method if you require different behaviour.
    905     *
    906     * @param row  the row (or series) index (zero-based).
    907     * @param column  the column (or category) index (zero-based).
    908     *
    909     * @return The paint (never <code>null</code>).
    910     */
    911    public Paint getItemFillPaint(int row, int column) {
    912        return lookupSeriesFillPaint(row);
    913    }
    914
    915    /**
    916     * Returns the paint used to fill an item drawn by the renderer.
    917     *
    918     * @param series  the series (zero-based index).
    919     *
    920     * @return The paint (never <code>null</code>).
    921     *
    922     * @since 1.0.6
    923     */
    924    public Paint lookupSeriesFillPaint(int series) {
    925
    926        // return the override, if there is one...
    927        if (this.fillPaint != null) {
    928            return this.fillPaint;
    929        }
    930
    931        // otherwise look up the paint table
    932        Paint seriesFillPaint = getSeriesFillPaint(series);
    933        if (seriesFillPaint == null && this.autoPopulateSeriesFillPaint) {
    934            DrawingSupplier supplier = getDrawingSupplier();
    935            if (supplier != null) {
    936                seriesFillPaint = supplier.getNextFillPaint();
    937                setSeriesFillPaint(series, seriesFillPaint, false);
    938            }
    939        }
    940        if (seriesFillPaint == null) {
    941            seriesFillPaint = this.baseFillPaint;
    942        }
    943        return seriesFillPaint;
    944
    945    }
    946
    947    /**
    948     * Returns the paint used to fill an item drawn by the renderer.
    949     *
    950     * @param series  the series (zero-based index).
    951     *
    952     * @return The paint (never <code>null</code>).
    953     *
    954     * @see #setSeriesFillPaint(int, Paint)
    955     */
    956    public Paint getSeriesFillPaint(int series) {
    957        return this.fillPaintList.getPaint(series);
    958    }
    959
    960    /**
    961     * Sets the paint used for a series fill and sends a
    962     * {@link RendererChangeEvent} to all registered listeners.
    963     *
    964     * @param series  the series index (zero-based).
    965     * @param paint  the paint (<code>null</code> permitted).
    966     *
    967     * @see #getSeriesFillPaint(int)
    968     */
    969    public void setSeriesFillPaint(int series, Paint paint) {
    970        setSeriesFillPaint(series, paint, true);
    971    }
    972
    973    /**
    974     * Sets the paint used to fill a series and, if requested,
    975     * sends a {@link RendererChangeEvent} to all registered listeners.
    976     *
    977     * @param series  the series index (zero-based).
    978     * @param paint  the paint (<code>null</code> permitted).
    979     * @param notify  notify listeners?
    980     *
    981     * @see #getSeriesFillPaint(int)
    982     */
    983    public void setSeriesFillPaint(int series, Paint paint, boolean notify) {
    984        this.fillPaintList.setPaint(series, paint);
    985        if (notify) {
    986            fireChangeEvent();
    987        }
    988    }
    989
    990    /**
    991     * Returns the base fill paint.
    992     *
    993     * @return The paint (never <code>null</code>).
    994     *
    995     * @see #setBaseFillPaint(Paint)
    996     */
    997    public Paint getBaseFillPaint() {
    998        return this.baseFillPaint;
    999    }
    1000
    1001    /**
    1002     * Sets the base fill paint and sends a {@link RendererChangeEvent} to
    1003     * all registered listeners.
    1004     *
    1005     * @param paint  the paint (<code>null</code> not permitted).
    1006     *
    1007     * @see #getBaseFillPaint()
    1008     */
    1009    public void setBaseFillPaint(Paint paint) {
    1010        // defer argument checking...
    1011        setBaseFillPaint(paint, true);
    1012    }
    1013
    1014    /**
    1015     * Sets the base fill paint and, if requested, sends a
    1016     * {@link RendererChangeEvent} to all registered listeners.
    1017     *
    1018     * @param paint  the paint (<code>null</code> not permitted).
    1019     * @param notify  notify listeners?
    1020     *
    1021     * @see #getBaseFillPaint()
    1022     */
    1023    public void setBaseFillPaint(Paint paint, boolean notify) {
    1024        if (paint == null) {
    1025            throw new IllegalArgumentException("Null 'paint' argument.");
    1026        }
    1027        this.baseFillPaint = paint;
    1028        if (notify) {
    1029            fireChangeEvent();
    1030        }
    1031    }
    1032
    1033    /**
    1034     * Returns the flag that controls whether or not the series fill paint list
    1035     * is automatically populated when {@link #lookupSeriesFillPaint(int)} is
    1036     * called.
    1037     *
    1038     * @return A boolean.
    1039     *
    1040     * @since 1.0.6
    1041     *
    1042     * @see #setAutoPopulateSeriesFillPaint(boolean)
    1043     */
    1044    public boolean getAutoPopulateSeriesFillPaint() {
    1045        return this.autoPopulateSeriesFillPaint;
    1046    }
    1047
    1048    /**
    1049     * Sets the flag that controls whether or not the series fill paint list is
    1050     * automatically populated when {@link #lookupSeriesFillPaint(int)} is
    1051     * called.
    1052     *
    1053     * @param auto  the new flag value.
    1054     *
    1055     * @since 1.0.6
    1056     *
    1057     * @see #getAutoPopulateSeriesFillPaint()
    1058     */
    1059    public void setAutoPopulateSeriesFillPaint(boolean auto) {
    1060        this.autoPopulateSeriesFillPaint = auto;
    1061    }
    1062
    1063    // OUTLINE PAINT //////////////////////////////////////////////////////////
    1064
    1065    /**
    1066     * Returns the paint used to outline data items as they are drawn.
    1067     * <p>
    1068     * The default implementation passes control to the
    1069     * {@link #lookupSeriesOutlinePaint} method.  You can override this method
    1070     * if you require different behaviour.
    1071     *
    1072     * @param row  the row (or series) index (zero-based).
    1073     * @param column  the column (or category) index (zero-based).
    1074     *
    1075     * @return The paint (never <code>null</code>).
    1076     */
    1077    public Paint getItemOutlinePaint(int row, int column) {
    1078        return lookupSeriesOutlinePaint(row);
    1079    }
    1080
    1081    /**
    1082     * Returns the paint used to outline an item drawn by the renderer.
    1083     *
    1084     * @param series  the series (zero-based index).
    1085     *
    1086     * @return The paint (never <code>null</code>).
    1087     *
    1088     * @since 1.0.6
    1089     */
    1090    public Paint lookupSeriesOutlinePaint(int series) {
    1091
    1092        // return the override, if there is one...
    1093        if (this.outlinePaint != null) {
    1094            return this.outlinePaint;
    1095        }
    1096
    1097        // otherwise look up the paint table
    1098        Paint seriesOutlinePaint = getSeriesOutlinePaint(series);
    1099        if (seriesOutlinePaint == null && this.autoPopulateSeriesOutlinePaint) {
    1100            DrawingSupplier supplier = getDrawingSupplier();
    1101            if (supplier != null) {
    1102                seriesOutlinePaint = supplier.getNextOutlinePaint();
    1103                setSeriesOutlinePaint(series, seriesOutlinePaint, false);
    1104            }
    1105        }
    1106        if (seriesOutlinePaint == null) {
    1107            seriesOutlinePaint = this.baseOutlinePaint;
    1108        }
    1109        return seriesOutlinePaint;
    1110
    1111    }
    1112
    1113    /**
    1114     * Returns the paint used to outline an item drawn by the renderer.
    1115     *
    1116     * @param series  the series (zero-based index).
    1117     *
    1118     * @return The paint (possibly <code>null</code>).
    1119     *
    1120     * @see #setSeriesOutlinePaint(int, Paint)
    1121     */
    1122    public Paint getSeriesOutlinePaint(int series) {
    1123        return this.outlinePaintList.getPaint(series);
    1124    }
    1125
    1126    /**
    1127     * Sets the paint used for a series outline and sends a
    1128     * {@link RendererChangeEvent} to all registered listeners.
    1129     *
    1130     * @param series  the series index (zero-based).
    1131     * @param paint  the paint (<code>null</code> permitted).
    1132     *
    1133     * @see #getSeriesOutlinePaint(int)
    1134     */
    1135    public void setSeriesOutlinePaint(int series, Paint paint) {
    1136        setSeriesOutlinePaint(series, paint, true);
    1137    }
    1138
    1139    /**
    1140     * Sets the paint used to draw the outline for a series and, if requested,
    1141     * sends a {@link RendererChangeEvent} to all registered listeners.
    1142     *
    1143     * @param series  the series index (zero-based).
    1144     * @param paint  the paint (<code>null</code> permitted).
    1145     * @param notify  notify listeners?
    1146     *
    1147     * @see #getSeriesOutlinePaint(int)
    1148     */
    1149    public void setSeriesOutlinePaint(int series, Paint paint, boolean notify) {
    1150        this.outlinePaintList.setPaint(series, paint);
    1151        if (notify) {
    1152            fireChangeEvent();
    1153        }
    1154    }
    1155
    1156    /**
    1157     * Returns the base outline paint.
    1158     *
    1159     * @return The paint (never <code>null</code>).
    1160     *
    1161     * @see #setBaseOutlinePaint(Paint)
    1162     */
    1163    public Paint getBaseOutlinePaint() {
    1164        return this.baseOutlinePaint;
    1165    }
    1166
    1167    /**
    1168     * Sets the base outline paint and sends a {@link RendererChangeEvent} to
    1169     * all registered listeners.
    1170     *
    1171     * @param paint  the paint (<code>null</code> not permitted).
    1172     *
    1173     * @see #getBaseOutlinePaint()
    1174     */
    1175    public void setBaseOutlinePaint(Paint paint) {
    1176        // defer argument checking...
    1177        setBaseOutlinePaint(paint, true);
    1178    }
    1179
    1180    /**
    1181     * Sets the base outline paint and, if requested, sends a
    1182     * {@link RendererChangeEvent} to all registered listeners.
    1183     *
    1184     * @param paint  the paint (<code>null</code> not permitted).
    1185     * @param notify  notify listeners?
    1186     *
    1187     * @see #getBaseOutlinePaint()
    1188     */
    1189    public void setBaseOutlinePaint(Paint paint, boolean notify) {
    1190        if (paint == null) {
    1191            throw new IllegalArgumentException("Null 'paint' argument.");
    1192        }
    1193        this.baseOutlinePaint = paint;
    1194        if (notify) {
    1195            fireChangeEvent();
    1196        }
    1197    }
    1198
    1199    /**
    1200     * Returns the flag that controls whether or not the series outline paint
    1201     * list is automatically populated when
    1202     * {@link #lookupSeriesOutlinePaint(int)} is called.
    1203     *
    1204     * @return A boolean.
    1205     *
    1206     * @since 1.0.6
    1207     *
    1208     * @see #setAutoPopulateSeriesOutlinePaint(boolean)
    1209     */
    1210    public boolean getAutoPopulateSeriesOutlinePaint() {
    1211        return this.autoPopulateSeriesOutlinePaint;
    1212    }
    1213
    1214    /**
    1215     * Sets the flag that controls whether or not the series outline paint list
    1216     * is automatically populated when {@link #lookupSeriesOutlinePaint(int)}
    1217     * is called.
    1218     *
    1219     * @param auto  the new flag value.
    1220     *
    1221     * @since 1.0.6
    1222     *
    1223     * @see #getAutoPopulateSeriesOutlinePaint()
    1224     */
    1225    public void setAutoPopulateSeriesOutlinePaint(boolean auto) {
    1226        this.autoPopulateSeriesOutlinePaint = auto;
    1227    }
    1228
    1229    // STROKE
    1230
    1231    /**
    1232     * Returns the stroke used to draw data items.
    1233     * <p>
    1234     * The default implementation passes control to the getSeriesStroke method.
    1235     * You can override this method if you require different behaviour.
    1236     *
    1237     * @param row  the row (or series) index (zero-based).
    1238     * @param column  the column (or category) index (zero-based).
    1239     *
    1240     * @return The stroke (never <code>null</code>).
    1241     */
    1242    public Stroke getItemStroke(int row, int column) {
    1243        return lookupSeriesStroke(row);
    1244    }
    1245
    1246    /**
    1247     * Returns the stroke used to draw the items in a series.
    1248     *
    1249     * @param series  the series (zero-based index).
    1250     *
    1251     * @return The stroke (never <code>null</code>).
    1252     *
    1253     * @since 1.0.6
    1254     */
    1255    public Stroke lookupSeriesStroke(int series) {
    1256
    1257        // return the override, if there is one...
    1258        if (this.stroke != null) {
    1259            return this.stroke;
    1260        }
    1261
    1262        // otherwise look up the paint table
    1263        Stroke result = getSeriesStroke(series);
    1264        if (result == null && this.autoPopulateSeriesStroke) {
    1265            DrawingSupplier supplier = getDrawingSupplier();
    1266            if (supplier != null) {
    1267                result = supplier.getNextStroke();
    1268                setSeriesStroke(series, result, false);
    1269            }
    1270        }
    1271        if (result == null) {
    1272            result = this.baseStroke;
    1273        }
    1274        return result;
    1275
    1276    }
    1277
    1278    /**
    1279     * Returns the stroke used to draw the items in a series.
    1280     *
    1281     * @param series  the series (zero-based index).
    1282     *
    1283     * @return The stroke (possibly <code>null</code>).
    1284     *
    1285     * @see #setSeriesStroke(int, Stroke)
    1286     */
    1287    public Stroke getSeriesStroke(int series) {
    1288        return this.strokeList.getStroke(series);
    1289    }
    1290
    1291    /**
    1292     * Sets the stroke used for a series and sends a {@link RendererChangeEvent}
    1293     * to all registered listeners.
    1294     *
    1295     * @param series  the series index (zero-based).
    1296     * @param stroke  the stroke (<code>null</code> permitted).
    1297     *
    1298     * @see #getSeriesStroke(int)
    1299     */
    1300    public void setSeriesStroke(int series, Stroke stroke) {
    1301        setSeriesStroke(series, stroke, true);
    1302    }
    1303
    1304    /**
    1305     * Sets the stroke for a series and, if requested, sends a
    1306     * {@link RendererChangeEvent} to all registered listeners.
    1307     *
    1308     * @param series  the series index (zero-based).
    1309     * @param stroke  the stroke (<code>null</code> permitted).
    1310     * @param notify  notify listeners?
    1311     *
    1312     * @see #getSeriesStroke(int)
    1313     */
    1314    public void setSeriesStroke(int series, Stroke stroke, boolean notify) {
    1315        this.strokeList.setStroke(series, stroke);
    1316        if (notify) {
    1317            fireChangeEvent();
    1318        }
    1319    }
    1320
    1321    /**
    1322     * Clears the series stroke settings for this renderer and, if requested,
    1323     * sends a {@link RendererChangeEvent} to all registered listeners.
    1324     *
    1325     * @param notify  notify listeners?
    1326     *
    1327     * @since 1.0.11
    1328     */
    1329    public void clearSeriesStrokes(boolean notify) {
    1330        this.strokeList.clear();
    1331        if (notify) {
    1332            fireChangeEvent();
    1333        }
    1334    }
    1335
    1336    /**
    1337     * Returns the base stroke.
    1338     *
    1339     * @return The base stroke (never <code>null</code>).
    1340     *
    1341     * @see #setBaseStroke(Stroke)
    1342     */
    1343    public Stroke getBaseStroke() {
    1344        return this.baseStroke;
    1345    }
    1346
    1347    /**
    1348     * Sets the base stroke and sends a {@link RendererChangeEvent} to all
    1349     * registered listeners.
    1350     *
    1351     * @param stroke  the stroke (<code>null</code> not permitted).
    1352     *
    1353     * @see #getBaseStroke()
    1354     */
    1355    public void setBaseStroke(Stroke stroke) {
    1356        // defer argument checking...
    1357        setBaseStroke(stroke, true);
    1358    }
    1359
    1360    /**
    1361     * Sets the base stroke and, if requested, sends a
    1362     * {@link RendererChangeEvent} to all registered listeners.
    1363     *
    1364     * @param stroke  the stroke (<code>null</code> not permitted).
    1365     * @param notify  notify listeners?
    1366     *
    1367     * @see #getBaseStroke()
    1368     */
    1369    public void setBaseStroke(Stroke stroke, boolean notify) {
    1370        if (stroke == null) {
    1371            throw new IllegalArgumentException("Null 'stroke' argument.");
    1372        }
    1373        this.baseStroke = stroke;
    1374        if (notify) {
    1375            fireChangeEvent();
    1376        }
    1377    }
    1378
    1379    /**
    1380     * Returns the flag that controls whether or not the series stroke list is
    1381     * automatically populated when {@link #lookupSeriesStroke(int)} is called.
    1382     *
    1383     * @return A boolean.
    1384     *
    1385     * @since 1.0.6
    1386     *
    1387     * @see #setAutoPopulateSeriesStroke(boolean)
    1388     */
    1389    public boolean getAutoPopulateSeriesStroke() {
    1390        return this.autoPopulateSeriesStroke;
    1391    }
    1392
    1393    /**
    1394     * Sets the flag that controls whether or not the series stroke list is
    1395     * automatically populated when {@link #lookupSeriesStroke(int)} is called.
    1396     *
    1397     * @param auto  the new flag value.
    1398     *
    1399     * @since 1.0.6
    1400     *
    1401     * @see #getAutoPopulateSeriesStroke()
    1402     */
    1403    public void setAutoPopulateSeriesStroke(boolean auto) {
    1404        this.autoPopulateSeriesStroke = auto;
    1405    }
    1406
    1407    // OUTLINE STROKE
    1408
    1409    /**
    1410     * Returns the stroke used to outline data items.  The default
    1411     * implementation passes control to the
    1412     * {@link #lookupSeriesOutlineStroke(int)} method. You can override this
    1413     * method if you require different behaviour.
    1414     *
    1415     * @param row  the row (or series) index (zero-based).
    1416     * @param column  the column (or category) index (zero-based).
    1417     *
    1418     * @return The stroke (never <code>null</code>).
    1419     */
    1420    public Stroke getItemOutlineStroke(int row, int column) {
    1421        return lookupSeriesOutlineStroke(row);
    1422    }
    1423
    1424    /**
    1425     * Returns the stroke used to outline the items in a series.
    1426     *
    1427     * @param series  the series (zero-based index).
    1428     *
    1429     * @return The stroke (never <code>null</code>).
    1430     *
    1431     * @since 1.0.6
    1432     */
    1433    public Stroke lookupSeriesOutlineStroke(int series) {
    1434
    1435        // return the override, if there is one...
    1436        if (this.outlineStroke != null) {
    1437            return this.outlineStroke;
    1438        }
    1439
    1440        // otherwise look up the stroke table
    1441        Stroke result = getSeriesOutlineStroke(series);
    1442        if (result == null && this.autoPopulateSeriesOutlineStroke) {
    1443            DrawingSupplier supplier = getDrawingSupplier();
    1444            if (supplier != null) {
    1445                result = supplier.getNextOutlineStroke();
    1446                setSeriesOutlineStroke(series, result, false);
    1447            }
    1448        }
    1449        if (result == null) {
    1450            result = this.baseOutlineStroke;
    1451        }
    1452        return result;
    1453
    1454    }
    1455
    1456    /**
    1457     * Returns the stroke used to outline the items in a series.
    1458     *
    1459     * @param series  the series (zero-based index).
    1460     *
    1461     * @return The stroke (possibly <code>null</code>).
    1462     *
    1463     * @see #setSeriesOutlineStroke(int, Stroke)
    1464     */
    1465    public Stroke getSeriesOutlineStroke(int series) {
    1466        return this.outlineStrokeList.getStroke(series);
    1467    }
    1468
    1469    /**
    1470     * Sets the outline stroke used for a series and sends a
    1471     * {@link RendererChangeEvent} to all registered listeners.
    1472     *
    1473     * @param series  the series index (zero-based).
    1474     * @param stroke  the stroke (<code>null</code> permitted).
    1475     *
    1476     * @see #getSeriesOutlineStroke(int)
    1477     */
    1478    public void setSeriesOutlineStroke(int series, Stroke stroke) {
    1479        setSeriesOutlineStroke(series, stroke, true);
    1480    }
    1481
    1482    /**
    1483     * Sets the outline stroke for a series and, if requested, sends a
    1484     * {@link RendererChangeEvent} to all registered listeners.
    1485     *
    1486     * @param series  the series index.
    1487     * @param stroke  the stroke (<code>null</code> permitted).
    1488     * @param notify  notify listeners?
    1489     *
    1490     * @see #getSeriesOutlineStroke(int)
    1491     */
    1492    public void setSeriesOutlineStroke(int series, Stroke stroke,
    1493                                       boolean notify) {
    1494        this.outlineStrokeList.setStroke(series, stroke);
    1495        if (notify) {
    1496            fireChangeEvent();
    1497        }
    1498    }
    1499
    1500    /**
    1501     * Returns the base outline stroke.
    1502     *
    1503     * @return The stroke (never <code>null</code>).
    1504     *
    1505     * @see #setBaseOutlineStroke(Stroke)
    1506     */
    1507    public Stroke getBaseOutlineStroke() {
    1508        return this.baseOutlineStroke;
    1509    }
    1510
    1511    /**
    1512     * Sets the base outline stroke and sends a {@link RendererChangeEvent} to
    1513     * all registered listeners.
    1514     *
    1515     * @param stroke  the stroke (<code>null</code> not permitted).
    1516     *
    1517     * @see #getBaseOutlineStroke()
    1518     */
    1519    public void setBaseOutlineStroke(Stroke stroke) {
    1520        setBaseOutlineStroke(stroke, true);
    1521    }
    1522
    1523    /**
    1524     * Sets the base outline stroke and, if requested, sends a
    1525     * {@link RendererChangeEvent} to all registered listeners.
    1526     *
    1527     * @param stroke  the stroke (<code>null</code> not permitted).
    1528     * @param notify  a flag that controls whether or not listeners are
    1529     *                notified.
    1530     *
    1531     * @see #getBaseOutlineStroke()
    1532     */
    1533    public void setBaseOutlineStroke(Stroke stroke, boolean notify) {
    1534        if (stroke == null) {
    1535            throw new IllegalArgumentException("Null 'stroke' argument.");
    1536        }
    1537        this.baseOutlineStroke = stroke;
    1538        if (notify) {
    1539            fireChangeEvent();
    1540        }
    1541    }
    1542
    1543    /**
    1544     * Returns the flag that controls whether or not the series outline stroke
    1545     * list is automatically populated when
    1546     * {@link #lookupSeriesOutlineStroke(int)} is called.
    1547     *
    1548     * @return A boolean.
    1549     *
    1550     * @since 1.0.6
    1551     *
    1552     * @see #setAutoPopulateSeriesOutlineStroke(boolean)
    1553     */
    1554    public boolean getAutoPopulateSeriesOutlineStroke() {
    1555        return this.autoPopulateSeriesOutlineStroke;
    1556    }
    1557
    1558    /**
    1559     * Sets the flag that controls whether or not the series outline stroke list
    1560     * is automatically populated when {@link #lookupSeriesOutlineStroke(int)}
    1561     * is called.
    1562     *
    1563     * @param auto  the new flag value.
    1564     *
    1565     * @since 1.0.6
    1566     *
    1567     * @see #getAutoPopulateSeriesOutlineStroke()
    1568     */
    1569    public void setAutoPopulateSeriesOutlineStroke(boolean auto) {
    1570        this.autoPopulateSeriesOutlineStroke = auto;
    1571    }
    1572
    1573    // SHAPE
    1574
    1575    /**
    1576     * Returns a shape used to represent a data item.
    1577     * <p>
    1578     * The default implementation passes control to the getSeriesShape method.
    1579     * You can override this method if you require different behaviour.
    1580     *
    1581     * @param row  the row (or series) index (zero-based).
    1582     * @param column  the column (or category) index (zero-based).
    1583     *
    1584     * @return The shape (never <code>null</code>).
    1585     */
    1586    public Shape getItemShape(int row, int column) {
    1587        return lookupSeriesShape(row);
    1588    }
    1589
    1590    /**
    1591     * Returns a shape used to represent the items in a series.
    1592     *
    1593     * @param series  the series (zero-based index).
    1594     *
    1595     * @return The shape (never <code>null</code>).
    1596     *
    1597     * @since 1.0.6
    1598     */
    1599    public Shape lookupSeriesShape(int series) {
    1600
    1601        // return the override, if there is one...
    1602        if (this.shape != null) {
    1603            return this.shape;
    1604        }
    1605
    1606        // otherwise look up the shape list
    1607        Shape result = getSeriesShape(series);
    1608        if (result == null && this.autoPopulateSeriesShape) {
    1609            DrawingSupplier supplier = getDrawingSupplier();
    1610            if (supplier != null) {
    1611                result = supplier.getNextShape();
    1612                setSeriesShape(series, result, false);
    1613            }
    1614        }
    1615        if (result == null) {
    1616            result = this.baseShape;
    1617        }
    1618        return result;
    1619
    1620    }
    1621
    1622    /**
    1623     * Returns a shape used to represent the items in a series.
    1624     *
    1625     * @param series  the series (zero-based index).
    1626     *
    1627     * @return The shape (possibly <code>null</code>).
    1628     *
    1629     * @see #setSeriesShape(int, Shape)
    1630     */
    1631    public Shape getSeriesShape(int series) {
    1632        return this.shapeList.getShape(series);
    1633    }
    1634
    1635    /**
    1636     * Sets the shape used for a series and sends a {@link RendererChangeEvent}
    1637     * to all registered listeners.
    1638     *
    1639     * @param series  the series index (zero-based).
    1640     * @param shape  the shape (<code>null</code> permitted).
    1641     *
    1642     * @see #getSeriesShape(int)
    1643     */
    1644    public void setSeriesShape(int series, Shape shape) {
    1645        setSeriesShape(series, shape, true);
    1646    }
    1647
    1648    /**
    1649     * Sets the shape for a series and, if requested, sends a
    1650     * {@link RendererChangeEvent} to all registered listeners.
    1651     *
    1652     * @param series  the series index (zero based).
    1653     * @param shape  the shape (<code>null</code> permitted).
    1654     * @param notify  notify listeners?
    1655     *
    1656     * @see #getSeriesShape(int)
    1657     */
    1658    public void setSeriesShape(int series, Shape shape, boolean notify) {
    1659        this.shapeList.setShape(series, shape);
    1660        if (notify) {
    1661            fireChangeEvent();
    1662        }
    1663    }
    1664
    1665    /**
    1666     * Returns the base shape.
    1667     *
    1668     * @return The shape (never <code>null</code>).
    1669     *
    1670     * @see #setBaseShape(Shape)
    1671     */
    1672    public Shape getBaseShape() {
    1673        return this.baseShape;
    1674    }
    1675
    1676    /**
    1677     * Sets the base shape and sends a {@link RendererChangeEvent} to all
    1678     * registered listeners.
    1679     *
    1680     * @param shape  the shape (<code>null</code> not permitted).
    1681     *
    1682     * @see #getBaseShape()
    1683     */
    1684    public void setBaseShape(Shape shape) {
    1685        // defer argument checking...
    1686        setBaseShape(shape, true);
    1687    }
    1688
    1689    /**
    1690     * Sets the base shape and, if requested, sends a
    1691     * {@link RendererChangeEvent} to all registered listeners.
    1692     *
    1693     * @param shape  the shape (<code>null</code> not permitted).
    1694     * @param notify  notify listeners?
    1695     *
    1696     * @see #getBaseShape()
    1697     */
    1698    public void setBaseShape(Shape shape, boolean notify) {
    1699        if (shape == null) {
    1700            throw new IllegalArgumentException("Null 'shape' argument.");
    1701        }
    1702        this.baseShape = shape;
    1703        if (notify) {
    1704            fireChangeEvent();
    1705        }
    1706    }
    1707
    1708    /**
    1709     * Returns the flag that controls whether or not the series shape list is
    1710     * automatically populated when {@link #lookupSeriesShape(int)} is called.
    1711     *
    1712     * @return A boolean.
    1713     *
    1714     * @since 1.0.6
    1715     *
    1716     * @see #setAutoPopulateSeriesShape(boolean)
    1717     */
    1718    public boolean getAutoPopulateSeriesShape() {
    1719        return this.autoPopulateSeriesShape;
    1720    }
    1721
    1722    /**
    1723     * Sets the flag that controls whether or not the series shape list is
    1724     * automatically populated when {@link #lookupSeriesShape(int)} is called.
    1725     *
    1726     * @param auto  the new flag value.
    1727     *
    1728     * @since 1.0.6
    1729     *
    1730     * @see #getAutoPopulateSeriesShape()
    1731     */
    1732    public void setAutoPopulateSeriesShape(boolean auto) {
    1733        this.autoPopulateSeriesShape = auto;
    1734    }
    1735
    1736    // ITEM LABEL VISIBILITY...
    1737
    1738    /**
    1739     * Returns <code>true</code> if an item label is visible, and
    1740     * <code>false</code> otherwise.
    1741     *
    1742     * @param row  the row index (zero-based).
    1743     * @param column  the column index (zero-based).
    1744     *
    1745     * @return A boolean.
    1746     */
    1747    public boolean isItemLabelVisible(int row, int column) {
    1748        return isSeriesItemLabelsVisible(row);
    1749    }
    1750
    1751    /**
    1752     * Returns <code>true</code> if the item labels for a series are visible,
    1753     * and <code>false</code> otherwise.
    1754     *
    1755     * @param series  the series index (zero-based).
    1756     *
    1757     * @return A boolean.
    1758     */
    1759    public boolean isSeriesItemLabelsVisible(int series) {
    1760
    1761        // return the override, if there is one...
    1762        if (this.itemLabelsVisible != null) {
    1763            return this.itemLabelsVisible.booleanValue();
    1764        }
    1765
    1766        // otherwise look up the boolean table
    1767        Boolean b = this.itemLabelsVisibleList.getBoolean(series);
    1768        if (b == null) {
    1769            b = this.baseItemLabelsVisible;
    1770        }
    1771        if (b == null) {
    1772            b = Boolean.FALSE;
    1773        }
    1774        return b.booleanValue();
    1775
    1776    }
    1777
    1778    /**
    1779     * Sets a flag that controls the visibility of the item labels for a series,
    1780     * and sends a {@link RendererChangeEvent} to all registered listeners.
    1781     *
    1782     * @param series  the series index (zero-based).
    1783     * @param visible  the flag.
    1784     */
    1785    public void setSeriesItemLabelsVisible(int series, boolean visible) {
    1786        setSeriesItemLabelsVisible(series, BooleanUtilities.valueOf(visible));
    1787    }
    1788
    1789    /**
    1790     * Sets the visibility of the item labels for a series and sends a
    1791     * {@link RendererChangeEvent} to all registered listeners.
    1792     *
    1793     * @param series  the series index (zero-based).
    1794     * @param visible  the flag (<code>null</code> permitted).
    1795     */
    1796    public void setSeriesItemLabelsVisible(int series, Boolean visible) {
    1797        setSeriesItemLabelsVisible(series, visible, true);
    1798    }
    1799
    1800    /**
    1801     * Sets the visibility of item labels for a series and, if requested, sends
    1802     * a {@link RendererChangeEvent} to all registered listeners.
    1803     *
    1804     * @param series  the series index (zero-based).
    1805     * @param visible  the visible flag.
    1806     * @param notify  a flag that controls whether or not listeners are
    1807     *                notified.
    1808     */
    1809    public void setSeriesItemLabelsVisible(int series, Boolean visible,
    1810                                           boolean notify) {
    1811        this.itemLabelsVisibleList.setBoolean(series, visible);
    1812        if (notify) {
    1813            fireChangeEvent();
    1814        }
    1815    }
    1816
    1817    /**
    1818     * Returns the base setting for item label visibility.  A <code>null</code>
    1819     * result should be interpreted as equivalent to <code>Boolean.FALSE</code>.
    1820     *
    1821     * @return A flag (possibly <code>null</code>).
    1822     *
    1823     * @see #setBaseItemLabelsVisible(boolean)
    1824     */
    1825    public Boolean getBaseItemLabelsVisible() {
    1826        // this should have been defined as a boolean primitive, because
    1827        // allowing null values is a nuisance...but it is part of the final
    1828        // API now, so we'll have to support it.
    1829        return this.baseItemLabelsVisible;
    1830    }
    1831
    1832    /**
    1833     * Sets the base flag that controls whether or not item labels are visible,
    1834     * and sends a {@link RendererChangeEvent} to all registered listeners.
    1835     *
    1836     * @param visible  the flag.
    1837     *
    1838     * @see #getBaseItemLabelsVisible()
    1839     */
    1840    public void setBaseItemLabelsVisible(boolean visible) {
    1841        setBaseItemLabelsVisible(BooleanUtilities.valueOf(visible));
    1842    }
    1843
    1844    /**
    1845     * Sets the base setting for item label visibility and sends a
    1846     * {@link RendererChangeEvent} to all registered listeners.
    1847     *
    1848     * @param visible  the flag (<code>null</code> is permitted, and viewed
    1849     *     as equivalent to <code>Boolean.FALSE</code>).
    1850     */
    1851    public void setBaseItemLabelsVisible(Boolean visible) {
    1852        setBaseItemLabelsVisible(visible, true);
    1853    }
    1854
    1855    /**
    1856     * Sets the base visibility for item labels and, if requested, sends a
    1857     * {@link RendererChangeEvent} to all registered listeners.
    1858     *
    1859     * @param visible  the flag (<code>null</code> is permitted, and viewed
    1860     *     as equivalent to <code>Boolean.FALSE</code>).
    1861     * @param notify  a flag that controls whether or not listeners are
    1862     *                notified.
    1863     *
    1864     * @see #getBaseItemLabelsVisible()
    1865     */
    1866    public void setBaseItemLabelsVisible(Boolean visible, boolean notify) {
    1867        this.baseItemLabelsVisible = visible;
    1868        if (notify) {
    1869            fireChangeEvent();
    1870        }
    1871    }
    1872
    1873    //// ITEM LABEL FONT //////////////////////////////////////////////////////
    1874
    1875    /**
    1876     * Returns the font for an item label.
    1877     *
    1878     * @param row  the row index (zero-based).
    1879     * @param column  the column index (zero-based).
    1880     *
    1881     * @return The font (never <code>null</code>).
    1882     */
    1883    public Font getItemLabelFont(int row, int column) {
    1884        Font result = this.itemLabelFont;
    1885        if (result == null) {
    1886            result = getSeriesItemLabelFont(row);
    1887            if (result == null) {
    1888                result = this.baseItemLabelFont;
    1889            }
    1890        }
    1891        return result;
    1892    }
    1893
    1894    /**
    1895     * Returns the font for all the item labels in a series.
    1896     *
    1897     * @param series  the series index (zero-based).
    1898     *
    1899     * @return The font (possibly <code>null</code>).
    1900     *
    1901     * @see #setSeriesItemLabelFont(int, Font)
    1902     */
    1903    public Font getSeriesItemLabelFont(int series) {
    1904        return (Font) this.itemLabelFontList.get(series);
    1905    }
    1906
    1907    /**
    1908     * Sets the item label font for a series and sends a
    1909     * {@link RendererChangeEvent} to all registered listeners.
    1910     *
    1911     * @param series  the series index (zero-based).
    1912     * @param font  the font (<code>null</code> permitted).
    1913     *
    1914     * @see #getSeriesItemLabelFont(int)
    1915     */
    1916    public void setSeriesItemLabelFont(int series, Font font) {
    1917        setSeriesItemLabelFont(series, font, true);
    1918    }
    1919
    1920    /**
    1921     * Sets the item label font for a series and, if requested, sends a
    1922     * {@link RendererChangeEvent} to all registered listeners.
    1923     *
    1924     * @param series  the series index (zero based).
    1925     * @param font  the font (<code>null</code> permitted).
    1926     * @param notify  a flag that controls whether or not listeners are
    1927     *                notified.
    1928     *
    1929     * @see #getSeriesItemLabelFont(int)
    1930     */
    1931    public void setSeriesItemLabelFont(int series, Font font, boolean notify) {
    1932        this.itemLabelFontList.set(series, font);
    1933        if (notify) {
    1934            fireChangeEvent();
    1935        }
    1936    }
    1937
    1938    /**
    1939     * Returns the base item label font (this is used when no other font
    1940     * setting is available).
    1941     *
    1942     * @return The font (<code>never</code> null).
    1943     *
    1944     * @see #setBaseItemLabelFont(Font)
    1945     */
    1946    public Font getBaseItemLabelFont() {
    1947        return this.baseItemLabelFont;
    1948    }
    1949
    1950    /**
    1951     * Sets the base item label font and sends a {@link RendererChangeEvent} to
    1952     * all registered listeners.
    1953     *
    1954     * @param font  the font (<code>null</code> not permitted).
    1955     *
    1956     * @see #getBaseItemLabelFont()
    1957     */
    1958    public void setBaseItemLabelFont(Font font) {
    1959        if (font == null) {
    1960            throw new IllegalArgumentException("Null 'font' argument.");
    1961        }
    1962        setBaseItemLabelFont(font, true);
    1963    }
    1964
    1965    /**
    1966     * Sets the base item label font and, if requested, sends a
    1967     * {@link RendererChangeEvent} to all registered listeners.
    1968     *
    1969     * @param font  the font (<code>null</code> not permitted).
    1970     * @param notify  a flag that controls whether or not listeners are
    1971     *                notified.
    1972     *
    1973     * @see #getBaseItemLabelFont()
    1974     */
    1975    public void setBaseItemLabelFont(Font font, boolean notify) {
    1976        this.baseItemLabelFont = font;
    1977        if (notify) {
    1978            fireChangeEvent();
    1979        }
    1980    }
    1981
    1982    //// ITEM LABEL PAINT  ////////////////////////////////////////////////////
    1983
    1984    /**
    1985     * Returns the paint used to draw an item label.
    1986     *
    1987     * @param row  the row index (zero based).
    1988     * @param column  the column index (zero based).
    1989     *
    1990     * @return The paint (never <code>null</code>).
    1991     */
    1992    public Paint getItemLabelPaint(int row, int column) {
    1993        Paint result = this.itemLabelPaint;
    1994        if (result == null) {
    1995            result = getSeriesItemLabelPaint(row);
    1996            if (result == null) {
    1997                result = this.baseItemLabelPaint;
    1998            }
    1999        }
    2000        return result;
    2001    }
    2002
    2003    /**
    2004     * Returns the paint used to draw the item labels for a series.
    2005     *
    2006     * @param series  the series index (zero based).
    2007     *
    2008     * @return The paint (possibly <code>null</code>).
    2009     *
    2010     * @see #setSeriesItemLabelPaint(int, Paint)
    2011     */
    2012    public Paint getSeriesItemLabelPaint(int series) {
    2013        return this.itemLabelPaintList.getPaint(series);
    2014    }
    2015
    2016    /**
    2017     * Sets the item label paint for a series and sends a
    2018     * {@link RendererChangeEvent} to all registered listeners.
    2019     *
    2020     * @param series  the series (zero based index).
    2021     * @param paint  the paint (<code>null</code> permitted).
    2022     *
    2023     * @see #getSeriesItemLabelPaint(int)
    2024     */
    2025    public void setSeriesItemLabelPaint(int series, Paint paint) {
    2026        setSeriesItemLabelPaint(series, paint, true);
    2027    }
    2028
    2029    /**
    2030     * Sets the item label paint for a series and, if requested, sends a
    2031     * {@link RendererChangeEvent} to all registered listeners.
    2032     *
    2033     * @param series  the series index (zero based).
    2034     * @param paint  the paint (<code>null</code> permitted).
    2035     * @param notify  a flag that controls whether or not listeners are
    2036     *                notified.
    2037     *
    2038     * @see #getSeriesItemLabelPaint(int)
    2039     */
    2040    public void setSeriesItemLabelPaint(int series, Paint paint,
    2041                                        boolean notify) {
    2042        this.itemLabelPaintList.setPaint(series, paint);
    2043        if (notify) {
    2044            fireChangeEvent();
    2045        }
    2046    }
    2047
    2048    /**
    2049     * Returns the base item label paint.
    2050     *
    2051     * @return The paint (never <code>null</code>).
    2052     *
    2053     * @see #setBaseItemLabelPaint(Paint)
    2054     */
    2055    public Paint getBaseItemLabelPaint() {
    2056        return this.baseItemLabelPaint;
    2057    }
    2058
    2059    /**
    2060     * Sets the base item label paint and sends a {@link RendererChangeEvent}
    2061     * to all registered listeners.
    2062     *
    2063     * @param paint  the paint (<code>null</code> not permitted).
    2064     *
    2065     * @see #getBaseItemLabelPaint()
    2066     */
    2067    public void setBaseItemLabelPaint(Paint paint) {
    2068        // defer argument checking...
    2069        setBaseItemLabelPaint(paint, true);
    2070    }
    2071
    2072    /**
    2073     * Sets the base item label paint and, if requested, sends a
    2074     * {@link RendererChangeEvent} to all registered listeners..
    2075     *
    2076     * @param paint  the paint (<code>null</code> not permitted).
    2077     * @param notify  a flag that controls whether or not listeners are
    2078     *                notified.
    2079     *
    2080     * @see #getBaseItemLabelPaint()
    2081     */
    2082    public void setBaseItemLabelPaint(Paint paint, boolean notify) {
    2083        if (paint == null) {
    2084            throw new IllegalArgumentException("Null 'paint' argument.");
    2085        }
    2086        this.baseItemLabelPaint = paint;
    2087        if (notify) {
    2088            fireChangeEvent();
    2089        }
    2090    }
    2091
    2092    // POSITIVE ITEM LABEL POSITION...
    2093
    2094    /**
    2095     * Returns the item label position for positive values.
    2096     *
    2097     * @param row  the row index (zero-based).
    2098     * @param column  the column index (zero-based).
    2099     *
    2100     * @return The item label position (never <code>null</code>).
    2101     *
    2102     * @see #getNegativeItemLabelPosition(int, int)
    2103     */
    2104    public ItemLabelPosition getPositiveItemLabelPosition(int row, int column) {
    2105        return getSeriesPositiveItemLabelPosition(row);
    2106    }
    2107
    2108    /**
    2109     * Returns the item label position for all positive values in a series.
    2110     *
    2111     * @param series  the series index (zero-based).
    2112     *
    2113     * @return The item label position (never <code>null</code>).
    2114     *
    2115     * @see #setSeriesPositiveItemLabelPosition(int, ItemLabelPosition)
    2116     */
    2117    public ItemLabelPosition getSeriesPositiveItemLabelPosition(int series) {
    2118
    2119        // return the override, if there is one...
    2120        if (this.positiveItemLabelPosition != null) {
    2121            return this.positiveItemLabelPosition;
    2122        }
    2123
    2124        // otherwise look up the position table
    2125        ItemLabelPosition position = (ItemLabelPosition)
    2126            this.positiveItemLabelPositionList.get(series);
    2127        if (position == null) {
    2128            position = this.basePositiveItemLabelPosition;
    2129        }
    2130        return position;
    2131
    2132    }
    2133
    2134    /**
    2135     * Sets the item label position for all positive values in a series and
    2136     * sends a {@link RendererChangeEvent} to all registered listeners.
    2137     *
    2138     * @param series  the series index (zero-based).
    2139     * @param position  the position (<code>null</code> permitted).
    2140     *
    2141     * @see #getSeriesPositiveItemLabelPosition(int)
    2142     */
    2143    public void setSeriesPositiveItemLabelPosition(int series,
    2144                                                   ItemLabelPosition position) {
    2145        setSeriesPositiveItemLabelPosition(series, position, true);
    2146    }
    2147
    2148    /**
    2149     * Sets the item label position for all positive values in a series and (if
    2150     * requested) sends a {@link RendererChangeEvent} to all registered
    2151     * listeners.
    2152     *
    2153     * @param series  the series index (zero-based).
    2154     * @param position  the position (<code>null</code> permitted).
    2155     * @param notify  notify registered listeners?
    2156     *
    2157     * @see #getSeriesPositiveItemLabelPosition(int)
    2158     */
    2159    public void setSeriesPositiveItemLabelPosition(int series,
    2160                                                   ItemLabelPosition position,
    2161                                                   boolean notify) {
    2162        this.positiveItemLabelPositionList.set(series, position);
    2163        if (notify) {
    2164            fireChangeEvent();
    2165        }
    2166    }
    2167
    2168    /**
    2169     * Returns the base positive item label position.
    2170     *
    2171     * @return The position (never <code>null</code>).
    2172     *
    2173     * @see #setBasePositiveItemLabelPosition(ItemLabelPosition)
    2174     */
    2175    public ItemLabelPosition getBasePositiveItemLabelPosition() {
    2176        return this.basePositiveItemLabelPosition;
    2177    }
    2178
    2179    /**
    2180     * Sets the base positive item label position.
    2181     *
    2182     * @param position  the position (<code>null</code> not permitted).
    2183     *
    2184     * @see #getBasePositiveItemLabelPosition()
    2185     */
    2186    public void setBasePositiveItemLabelPosition(ItemLabelPosition position) {
    2187        // defer argument checking...
    2188        setBasePositiveItemLabelPosition(position, true);
    2189    }
    2190
    2191    /**
    2192     * Sets the base positive item label position and, if requested, sends a
    2193     * {@link RendererChangeEvent} to all registered listeners.
    2194     *
    2195     * @param position  the position (<code>null</code> not permitted).
    2196     * @param notify  notify registered listeners?
    2197     *
    2198     * @see #getBasePositiveItemLabelPosition()
    2199     */
    2200    public void setBasePositiveItemLabelPosition(ItemLabelPosition position,
    2201                                                 boolean notify) {
    2202        if (position == null) {
    2203            throw new IllegalArgumentException("Null 'position' argument.");
    2204        }
    2205        this.basePositiveItemLabelPosition = position;
    2206        if (notify) {
    2207            fireChangeEvent();
    2208        }
    2209    }
    2210
    2211    // NEGATIVE ITEM LABEL POSITION...
    2212
    2213    /**
    2214     * Returns the item label position for negative values.  This method can be
    2215     * overridden to provide customisation of the item label position for
    2216     * individual data items.
    2217     *
    2218     * @param row  the row index (zero-based).
    2219     * @param column  the column (zero-based).
    2220     *
    2221     * @return The item label position (never <code>null</code>).
    2222     *
    2223     * @see #getPositiveItemLabelPosition(int, int)
    2224     */
    2225    public ItemLabelPosition getNegativeItemLabelPosition(int row, int column) {
    2226        return getSeriesNegativeItemLabelPosition(row);
    2227    }
    2228
    2229    /**
    2230     * Returns the item label position for all negative values in a series.
    2231     *
    2232     * @param series  the series index (zero-based).
    2233     *
    2234     * @return The item label position (never <code>null</code>).
    2235     *
    2236     * @see #setSeriesNegativeItemLabelPosition(int, ItemLabelPosition)
    2237     */
    2238    public ItemLabelPosition getSeriesNegativeItemLabelPosition(int series) {
    2239
    2240        // return the override, if there is one...
    2241        if (this.negativeItemLabelPosition != null) {
    2242            return this.negativeItemLabelPosition;
    2243        }
    2244
    2245        // otherwise look up the position list
    2246        ItemLabelPosition position = (ItemLabelPosition)
    2247            this.negativeItemLabelPositionList.get(series);
    2248        if (position == null) {
    2249            position = this.baseNegativeItemLabelPosition;
    2250        }
    2251        return position;
    2252
    2253    }
    2254
    2255    /**
    2256     * Sets the item label position for negative values in a series and sends a
    2257     * {@link RendererChangeEvent} to all registered listeners.
    2258     *
    2259     * @param series  the series index (zero-based).
    2260     * @param position  the position (<code>null</code> permitted).
    2261     *
    2262     * @see #getSeriesNegativeItemLabelPosition(int)
    2263     */
    2264    public void setSeriesNegativeItemLabelPosition(int series,
    2265                                                   ItemLabelPosition position) {
    2266        setSeriesNegativeItemLabelPosition(series, position, true);
    2267    }
    2268
    2269    /**
    2270     * Sets the item label position for negative values in a series and (if
    2271     * requested) sends a {@link RendererChangeEvent} to all registered
    2272     * listeners.
    2273     *
    2274     * @param series  the series index (zero-based).
    2275     * @param position  the position (<code>null</code> permitted).
    2276     * @param notify  notify registered listeners?
    2277     *
    2278     * @see #getSeriesNegativeItemLabelPosition(int)
    2279     */
    2280    public void setSeriesNegativeItemLabelPosition(int series,
    2281                                                   ItemLabelPosition position,
    2282                                                   boolean notify) {
    2283        this.negativeItemLabelPositionList.set(series, position);
    2284        if (notify) {
    2285            fireChangeEvent();
    2286        }
    2287    }
    2288
    2289    /**
    2290     * Returns the base item label position for negative values.
    2291     *
    2292     * @return The position (never <code>null</code>).
    2293     *
    2294     * @see #setBaseNegativeItemLabelPosition(ItemLabelPosition)
    2295     */
    2296    public ItemLabelPosition getBaseNegativeItemLabelPosition() {
    2297        return this.baseNegativeItemLabelPosition;
    2298    }
    2299
    2300    /**
    2301     * Sets the base item label position for negative values and sends a
    2302     * {@link RendererChangeEvent} to all registered listeners.
    2303     *
    2304     * @param position  the position (<code>null</code> not permitted).
    2305     *
    2306     * @see #getBaseNegativeItemLabelPosition()
    2307     */
    2308    public void setBaseNegativeItemLabelPosition(ItemLabelPosition position) {
    2309        setBaseNegativeItemLabelPosition(position, true);
    2310    }
    2311
    2312    /**
    2313     * Sets the base negative item label position and, if requested, sends a
    2314     * {@link RendererChangeEvent} to all registered listeners.
    2315     *
    2316     * @param position  the position (<code>null</code> not permitted).
    2317     * @param notify  notify registered listeners?
    2318     *
    2319     * @see #getBaseNegativeItemLabelPosition()
    2320     */
    2321    public void setBaseNegativeItemLabelPosition(ItemLabelPosition position,
    2322                                                 boolean notify) {
    2323        if (position == null) {
    2324            throw new IllegalArgumentException("Null 'position' argument.");
    2325        }
    2326        this.baseNegativeItemLabelPosition = position;
    2327        if (notify) {
    2328            fireChangeEvent();
    2329        }
    2330    }
    2331
    2332    /**
    2333     * Returns the item label anchor offset.
    2334     *
    2335     * @return The offset.
    2336     *
    2337     * @see #setItemLabelAnchorOffset(double)
    2338     */
    2339    public double getItemLabelAnchorOffset() {
    2340        return this.itemLabelAnchorOffset;
    2341    }
    2342
    2343    /**
    2344     * Sets the item label anchor offset.
    2345     *
    2346     * @param offset  the offset.
    2347     *
    2348     * @see #getItemLabelAnchorOffset()
    2349     */
    2350    public void setItemLabelAnchorOffset(double offset) {
    2351        this.itemLabelAnchorOffset = offset;
    2352        fireChangeEvent();
    2353    }
    2354
    2355    /**
    2356     * Returns a boolean that indicates whether or not the specified item
    2357     * should have a chart entity created for it.
    2358     *
    2359     * @param series  the series index.
    2360     * @param item  the item index.
    2361     *
    2362     * @return A boolean.
    2363     */
    2364    public boolean getItemCreateEntity(int series, int item) {
    2365        if (this.createEntities != null) {
    2366            return this.createEntities.booleanValue();
    2367        }
    2368        else {
    2369            Boolean b = getSeriesCreateEntities(series);
    2370            if (b != null) {
    2371                return b.booleanValue();
    2372            }
    2373            else {
    2374                return this.baseCreateEntities;
    2375            }
    2376        }
    2377    }
    2378
    2379    /**
    2380     * Returns the flag that controls whether entities are created for a
    2381     * series.
    2382     *
    2383     * @param series  the series index (zero-based).
    2384     *
    2385     * @return The flag (possibly <code>null</code>).
    2386     *
    2387     * @see #setSeriesCreateEntities(int, Boolean)
    2388     */
    2389    public Boolean getSeriesCreateEntities(int series) {
    2390        return this.createEntitiesList.getBoolean(series);
    2391    }
    2392
    2393    /**
    2394     * Sets the flag that controls whether entities are created for a series,
    2395     * and sends a {@link RendererChangeEvent} to all registered listeners.
    2396     *
    2397     * @param series  the series index (zero-based).
    2398     * @param create  the flag (<code>null</code> permitted).
    2399     *
    2400     * @see #getSeriesCreateEntities(int)
    2401     */
    2402    public void setSeriesCreateEntities(int series, Boolean create) {
    2403        setSeriesCreateEntities(series, create, true);
    2404    }
    2405
    2406    /**
    2407     * Sets the flag that controls whether entities are created for a series
    2408     * and, if requested, sends a {@link RendererChangeEvent} to all registered
    2409     * listeners.
    2410     *
    2411     * @param series  the series index.
    2412     * @param create  the flag (<code>null</code> permitted).
    2413     * @param notify  notify listeners?
    2414     *
    2415     * @see #getSeriesCreateEntities(int)
    2416     */
    2417    public void setSeriesCreateEntities(int series, Boolean create,
    2418                                        boolean notify) {
    2419        this.createEntitiesList.setBoolean(series, create);
    2420        if (notify) {
    2421            fireChangeEvent();
    2422        }
    2423    }
    2424
    2425    /**
    2426     * Returns the base visibility for all series.
    2427     *
    2428     * @return The base visibility.
    2429     *
    2430     * @see #setBaseCreateEntities(boolean)
    2431     */
    2432    public boolean getBaseCreateEntities() {
    2433        return this.baseCreateEntities;
    2434    }
    2435
    2436    /**
    2437     * Sets the base flag that controls whether entities are created
    2438     * for a series, and sends a {@link RendererChangeEvent}
    2439     * to all registered listeners.
    2440     *
    2441     * @param create  the flag.
    2442     *
    2443     * @see #getBaseCreateEntities()
    2444     */
    2445    public void setBaseCreateEntities(boolean create) {
    2446        // defer argument checking...
    2447        setBaseCreateEntities(create, true);
    2448    }
    2449
    2450    /**
    2451     * Sets the base flag that controls whether entities are created and,
    2452     * if requested, sends a {@link RendererChangeEvent} to all registered
    2453     * listeners.
    2454     *
    2455     * @param create  the visibility.
    2456     * @param notify  notify listeners?
    2457     *
    2458     * @see #getBaseCreateEntities()
    2459     */
    2460    public void setBaseCreateEntities(boolean create, boolean notify) {
    2461        this.baseCreateEntities = create;
    2462        if (notify) {
    2463            fireChangeEvent();
    2464        }
    2465    }
    2466
    2467    /**
    2468     * Returns the radius of the circle used for the default entity area
    2469     * when no area is specified.
    2470     *
    2471     * @return A radius.
    2472     *
    2473     * @see #setDefaultEntityRadius(int)
    2474     */
    2475    public int getDefaultEntityRadius() {
    2476        return this.defaultEntityRadius;
    2477    }
    2478
    2479    /**
    2480     * Sets the radius of the circle used for the default entity area
    2481     * when no area is specified.
    2482     *
    2483     * @param radius  the radius.
    2484     *
    2485     * @see #getDefaultEntityRadius()
    2486     */
    2487    public void setDefaultEntityRadius(int radius) {
    2488        this.defaultEntityRadius = radius;
    2489    }
    2490
    2491    /**
    2492     * Performs a lookup for the legend shape.
    2493     *
    2494     * @param series  the series index.
    2495     *
    2496     * @return The shape (possibly <code>null</code>).
    2497     *
    2498     * @since 1.0.11
    2499     */
    2500    public Shape lookupLegendShape(int series) {
    2501        Shape result = getLegendShape(series);
    2502        if (result == null) {
    2503            result = this.baseLegendShape;
    2504        }
    2505        if (result == null) {
    2506            result = lookupSeriesShape(series);
    2507        }
    2508        return result;
    2509    }
    2510
    2511    /**
    2512     * Returns the legend shape defined for the specified series (possibly
    2513     * <code>null</code>).
    2514     *
    2515     * @param series  the series index.
    2516     *
    2517     * @return The shape (possibly <code>null</code>).
    2518     *
    2519     * @see #lookupLegendShape(int)
    2520     *
    2521     * @since 1.0.11
    2522     */
    2523    public Shape getLegendShape(int series) {
    2524        return this.legendShapeList.getShape(series);
    2525    }
    2526
    2527    /**
    2528     * Sets the shape used for the legend item for the specified series, and
    2529     * sends a {@link RendererChangeEvent} to all registered listeners.
    2530     *
    2531     * @param series  the series index.
    2532     * @param shape  the shape (<code>null</code> permitted).
    2533     *
    2534     * @since 1.0.11
    2535     */
    2536    public void setLegendShape(int series, Shape shape) {
    2537        this.legendShapeList.setShape(series, shape);
    2538        fireChangeEvent();
    2539    }
    2540
    2541    /**
    2542     * Returns the default legend shape, which may be <code>null</code>.
    2543     *
    2544     * @return The default legend shape.
    2545     *
    2546     * @since 1.0.11
    2547     */
    2548    public Shape getBaseLegendShape() {
    2549        return this.baseLegendShape;
    2550    }
    2551
    2552    /**
    2553     * Sets the default legend shape and sends a
    2554     * {@link RendererChangeEvent} to all registered listeners.
    2555     *
    2556     * @param shape  the shape (<code>null</code> permitted).
    2557     *
    2558     * @since 1.0.11
    2559     */
    2560    public void setBaseLegendShape(Shape shape) {
    2561        this.baseLegendShape = shape;
    2562        fireChangeEvent();
    2563    }
    2564
    2565    /**
    2566     * Returns the flag that controls whether or not the legend shape is
    2567     * treated as a line when creating legend items.
    2568     *
    2569     * @return A boolean.
    2570     *
    2571     * @since 1.0.14
    2572     */
    2573    protected boolean getTreatLegendShapeAsLine() {
    2574        return this.treatLegendShapeAsLine;
    2575    }
    2576
    2577    /**
    2578     * Sets the flag that controls whether or not the legend shape is
    2579     * treated as a line when creating legend items.
    2580     *
    2581     * @param treatAsLine  the new flag value.
    2582     *
    2583     * @since 1.0.14
    2584     */
    2585    protected void setTreatLegendShapeAsLine(boolean treatAsLine) {
    2586        if (this.treatLegendShapeAsLine != treatAsLine) {
    2587            this.treatLegendShapeAsLine = treatAsLine;
    2588            fireChangeEvent();
    2589        }
    2590    }
    2591
    2592    /**
    2593     * Performs a lookup for the legend text font.
    2594     *
    2595     * @param series  the series index.
    2596     *
    2597     * @return The font (possibly <code>null</code>).
    2598     *
    2599     * @since 1.0.11
    2600     */
    2601    public Font lookupLegendTextFont(int series) {
    2602        Font result = getLegendTextFont(series);
    2603        if (result == null) {
    2604            result = this.baseLegendTextFont;
    2605        }
    2606        return result;
    2607    }
    2608
    2609    /**
    2610     * Returns the legend text font defined for the specified series (possibly
    2611     * <code>null</code>).
    2612     *
    2613     * @param series  the series index.
    2614     *
    2615     * @return The font (possibly <code>null</code>).
    2616     *
    2617     * @see #lookupLegendTextFont(int)
    2618     *
    2619     * @since 1.0.11
    2620     */
    2621    public Font getLegendTextFont(int series) {
    2622        return (Font) this.legendTextFont.get(series);
    2623    }
    2624
    2625    /**
    2626     * Sets the font used for the legend text for the specified series, and
    2627     * sends a {@link RendererChangeEvent} to all registered listeners.
    2628     *
    2629     * @param series  the series index.
    2630     * @param font  the font (<code>null</code> permitted).
    2631     *
    2632     * @since 1.0.11
    2633     */
    2634    public void setLegendTextFont(int series, Font font) {
    2635        this.legendTextFont.set(series, font);
    2636        fireChangeEvent();
    2637    }
    2638
    2639    /**
    2640     * Returns the default legend text font, which may be <code>null</code>.
    2641     *
    2642     * @return The default legend text font.
    2643     *
    2644     * @since 1.0.11
    2645     */
    2646    public Font getBaseLegendTextFont() {
    2647        return this.baseLegendTextFont;
    2648    }
    2649
    2650    /**
    2651     * Sets the default legend text font and sends a
    2652     * {@link RendererChangeEvent} to all registered listeners.
    2653     *
    2654     * @param font  the font (<code>null</code> permitted).
    2655     *
    2656     * @since 1.0.11
    2657     */
    2658    public void setBaseLegendTextFont(Font font) {
    2659        this.baseLegendTextFont = font;
    2660        fireChangeEvent();
    2661    }
    2662
    2663    /**
    2664     * Performs a lookup for the legend text paint.
    2665     *
    2666     * @param series  the series index.
    2667     *
    2668     * @return The paint (possibly <code>null</code>).
    2669     *
    2670     * @since 1.0.11
    2671     */
    2672    public Paint lookupLegendTextPaint(int series) {
    2673        Paint result = getLegendTextPaint(series);
    2674        if (result == null) {
    2675            result = this.baseLegendTextPaint;
    2676        }
    2677        return result;
    2678    }
    2679
    2680    /**
    2681     * Returns the legend text paint defined for the specified series (possibly
    2682     * <code>null</code>).
    2683     *
    2684     * @param series  the series index.
    2685     *
    2686     * @return The paint (possibly <code>null</code>).
    2687     *
    2688     * @see #lookupLegendTextPaint(int)
    2689     *
    2690     * @since 1.0.11
    2691     */
    2692    public Paint getLegendTextPaint(int series) {
    2693        return this.legendTextPaint.getPaint(series);
    2694    }
    2695
    2696    /**
    2697     * Sets the paint used for the legend text for the specified series, and
    2698     * sends a {@link RendererChangeEvent} to all registered listeners.
    2699     *
    2700     * @param series  the series index.
    2701     * @param paint  the paint (<code>null</code> permitted).
    2702     *
    2703     * @since 1.0.11
    2704     */
    2705    public void setLegendTextPaint(int series, Paint paint) {
    2706        this.legendTextPaint.setPaint(series, paint);
    2707        fireChangeEvent();
    2708    }
    2709
    2710    /**
    2711     * Returns the default legend text paint, which may be <code>null</code>.
    2712     *
    2713     * @return The default legend text paint.
    2714     *
    2715     * @since 1.0.11
    2716     */
    2717    public Paint getBaseLegendTextPaint() {
    2718        return this.baseLegendTextPaint;
    2719    }
    2720
    2721    /**
    2722     * Sets the default legend text paint and sends a
    2723     * {@link RendererChangeEvent} to all registered listeners.
    2724     *
    2725     * @param paint  the paint (<code>null</code> permitted).
    2726     *
    2727     * @since 1.0.11
    2728     */
    2729    public void setBaseLegendTextPaint(Paint paint) {
    2730        this.baseLegendTextPaint = paint;
    2731        fireChangeEvent();
    2732    }
    2733
    2734    /**
    2735     * Returns the flag that controls whether or not the data bounds reported
    2736     * by this renderer will exclude non-visible series.
    2737     *
    2738     * @return A boolean.
    2739     *
    2740     * @since 1.0.13
    2741     */
    2742    public boolean getDataBoundsIncludesVisibleSeriesOnly() {
    2743        return this.dataBoundsIncludesVisibleSeriesOnly;
    2744    }
    2745
    2746    /**
    2747     * Sets the flag that controls whether or not the data bounds reported
    2748     * by this renderer will exclude non-visible series and sends a
    2749     * {@link RendererChangeEvent} to all registered listeners.
    2750     *
    2751     * @param visibleOnly  include only visible series.
    2752     *
    2753     * @since 1.0.13
    2754     */
    2755    public void setDataBoundsIncludesVisibleSeriesOnly(boolean visibleOnly) {
    2756        this.dataBoundsIncludesVisibleSeriesOnly = visibleOnly;
    2757        notifyListeners(new RendererChangeEvent(this, true));
    2758    }
    2759
    2760    /** The adjacent offset. */
    2761    private static final double ADJ = Math.cos(Math.PI / 6.0);
    2762
    2763    /** The opposite offset. */
    2764    private static final double OPP = Math.sin(Math.PI / 6.0);
    2765
    2766    /**
    2767     * Calculates the item label anchor point.
    2768     *
    2769     * @param anchor  the anchor.
    2770     * @param x  the x coordinate.
    2771     * @param y  the y coordinate.
    2772     * @param orientation  the plot orientation.
    2773     *
    2774     * @return The anchor point (never <code>null</code>).
    2775     */
    2776    protected Point2D calculateLabelAnchorPoint(ItemLabelAnchor anchor,
    2777            double x, double y, PlotOrientation orientation) {
    2778        Point2D result = null;
    2779        if (anchor == ItemLabelAnchor.CENTER) {
    2780            result = new Point2D.Double(x, y);
    2781        }
    2782        else if (anchor == ItemLabelAnchor.INSIDE1) {
    2783            result = new Point2D.Double(x + OPP * this.itemLabelAnchorOffset,
    2784                    y - ADJ * this.itemLabelAnchorOffset);
    2785        }
    2786        else if (anchor == ItemLabelAnchor.INSIDE2) {
    2787            result = new Point2D.Double(x + ADJ * this.itemLabelAnchorOffset,
    2788                    y - OPP * this.itemLabelAnchorOffset);
    2789        }
    2790        else if (anchor == ItemLabelAnchor.INSIDE3) {
    2791            result = new Point2D.Double(x + this.itemLabelAnchorOffset, y);
    2792        }
    2793        else if (anchor == ItemLabelAnchor.INSIDE4) {
    2794            result = new Point2D.Double(x + ADJ * this.itemLabelAnchorOffset,
    2795                    y + OPP * this.itemLabelAnchorOffset);
    2796        }
    2797        else if (anchor == ItemLabelAnchor.INSIDE5) {
    2798            result = new Point2D.Double(x + OPP * this.itemLabelAnchorOffset,
    2799                    y + ADJ * this.itemLabelAnchorOffset);
    2800        }
    2801        else if (anchor == ItemLabelAnchor.INSIDE6) {
    2802            result = new Point2D.Double(x, y + this.itemLabelAnchorOffset);
    2803        }
    2804        else if (anchor == ItemLabelAnchor.INSIDE7) {
    2805            result = new Point2D.Double(x - OPP * this.itemLabelAnchorOffset,
    2806                    y + ADJ * this.itemLabelAnchorOffset);
    2807        }
    2808        else if (anchor == ItemLabelAnchor.INSIDE8) {
    2809            result = new Point2D.Double(x - ADJ * this.itemLabelAnchorOffset,
    2810                    y + OPP * this.itemLabelAnchorOffset);
    2811        }
    2812        else if (anchor == ItemLabelAnchor.INSIDE9) {
    2813            result = new Point2D.Double(x - this.itemLabelAnchorOffset, y);
    2814        }
    2815        else if (anchor == ItemLabelAnchor.INSIDE10) {
    2816            result = new Point2D.Double(x - ADJ * this.itemLabelAnchorOffset,
    2817                    y - OPP * this.itemLabelAnchorOffset);
    2818        }
    2819        else if (anchor == ItemLabelAnchor.INSIDE11) {
    2820            result = new Point2D.Double(x - OPP * this.itemLabelAnchorOffset,
    2821                    y - ADJ * this.itemLabelAnchorOffset);
    2822        }
    2823        else if (anchor == ItemLabelAnchor.INSIDE12) {
    2824            result = new Point2D.Double(x, y - this.itemLabelAnchorOffset);
    2825        }
    2826        else if (anchor == ItemLabelAnchor.OUTSIDE1) {
    2827            result = new Point2D.Double(
    2828                    x + 2.0 * OPP * this.itemLabelAnchorOffset,
    2829                    y - 2.0 * ADJ * this.itemLabelAnchorOffset);
    2830        }
    2831        else if (anchor == ItemLabelAnchor.OUTSIDE2) {
    2832            result = new Point2D.Double(
    2833                    x + 2.0 * ADJ * this.itemLabelAnchorOffset,
    2834                    y - 2.0 * OPP * this.itemLabelAnchorOffset);
    2835        }
    2836        else if (anchor == ItemLabelAnchor.OUTSIDE3) {
    2837            result = new Point2D.Double(x + 2.0 * this.itemLabelAnchorOffset,
    2838                    y);
    2839        }
    2840        else if (anchor == ItemLabelAnchor.OUTSIDE4) {
    2841            result = new Point2D.Double(
    2842                    x + 2.0 * ADJ * this.itemLabelAnchorOffset,
    2843                    y + 2.0 * OPP * this.itemLabelAnchorOffset);
    2844        }
    2845        else if (anchor == ItemLabelAnchor.OUTSIDE5) {
    2846            result = new Point2D.Double(
    2847                    x + 2.0 * OPP * this.itemLabelAnchorOffset,
    2848                    y + 2.0 * ADJ * this.itemLabelAnchorOffset);
    2849        }
    2850        else if (anchor == ItemLabelAnchor.OUTSIDE6) {
    2851            result = new Point2D.Double(x,
    2852                    y + 2.0 * this.itemLabelAnchorOffset);
    2853        }
    2854        else if (anchor == ItemLabelAnchor.OUTSIDE7) {
    2855            result = new Point2D.Double(
    2856                    x - 2.0 * OPP * this.itemLabelAnchorOffset,
    2857                    y + 2.0 * ADJ * this.itemLabelAnchorOffset);
    2858        }
    2859        else if (anchor == ItemLabelAnchor.OUTSIDE8) {
    2860            result = new Point2D.Double(
    2861                    x - 2.0 * ADJ * this.itemLabelAnchorOffset,
    2862                    y + 2.0 * OPP * this.itemLabelAnchorOffset);
    2863        }
    2864        else if (anchor == ItemLabelAnchor.OUTSIDE9) {
    2865            result = new Point2D.Double(x - 2.0 * this.itemLabelAnchorOffset,
    2866                    y);
    2867        }
    2868        else if (anchor == ItemLabelAnchor.OUTSIDE10) {
    2869            result = new Point2D.Double(
    2870                    x - 2.0 * ADJ * this.itemLabelAnchorOffset,
    2871                    y - 2.0 * OPP * this.itemLabelAnchorOffset);
    2872        }
    2873        else if (anchor == ItemLabelAnchor.OUTSIDE11) {
    2874            result = new Point2D.Double(
    2875                x - 2.0 * OPP * this.itemLabelAnchorOffset,
    2876                y - 2.0 * ADJ * this.itemLabelAnchorOffset);
    2877        }
    2878        else if (anchor == ItemLabelAnchor.OUTSIDE12) {
    2879            result = new Point2D.Double(x,
    2880                    y - 2.0 * this.itemLabelAnchorOffset);
    2881        }
    2882        return result;
    2883    }
    2884
    2885    /**
    2886     * Registers an object to receive notification of changes to the renderer.
    2887     *
    2888     * @param listener  the listener (<code>null</code> not permitted).
    2889     *
    2890     * @see #removeChangeListener(RendererChangeListener)
    2891     */
    2892    public void addChangeListener(RendererChangeListener listener) {
    2893        if (listener == null) {
    2894            throw new IllegalArgumentException("Null 'listener' argument.");
    2895        }
    2896        this.listenerList.add(RendererChangeListener.class, listener);
    2897    }
    2898
    2899    /**
    2900     * Deregisters an object so that it no longer receives
    2901     * notification of changes to the renderer.
    2902     *
    2903     * @param listener  the object (<code>null</code> not permitted).
    2904     *
    2905     * @see #addChangeListener(RendererChangeListener)
    2906     */
    2907    public void removeChangeListener(RendererChangeListener listener) {
    2908        if (listener == null) {
    2909            throw new IllegalArgumentException("Null 'listener' argument.");
    2910        }
    2911        this.listenerList.remove(RendererChangeListener.class, listener);
    2912    }
    2913
    2914    /**
    2915     * Returns <code>true</code> if the specified object is registered with
    2916     * the dataset as a listener.  Most applications won't need to call this
    2917     * method, it exists mainly for use by unit testing code.
    2918     *
    2919     * @param listener  the listener.
    2920     *
    2921     * @return A boolean.
    2922     */
    2923    public boolean hasListener(EventListener listener) {
    2924        List list = Arrays.asList(this.listenerList.getListenerList());
    2925        return list.contains(listener);
    2926    }
    2927
    2928    /**
    2929     * Sends a {@link RendererChangeEvent} to all registered listeners.
    2930     *
    2931     * @since 1.0.5
    2932     */
    2933    protected void fireChangeEvent() {
    2934
    2935        // the commented out code would be better, but only if
    2936        // RendererChangeEvent is immutable, which it isn't.  See if there is
    2937        // a way to fix this...
    2938
    2939        //if (this.event == null) {
    2940        //    this.event = new RendererChangeEvent(this);
    2941        //}
    2942        //notifyListeners(this.event);
    2943
    2944        notifyListeners(new RendererChangeEvent(this));
    2945    }
    2946
    2947    /**
    2948     * Notifies all registered listeners that the renderer has been modified.
    2949     *
    2950     * @param event  information about the change event.
    2951     */
    2952    public void notifyListeners(RendererChangeEvent event) {
    2953        Object[] ls = this.listenerList.getListenerList();
    2954        for (int i = ls.length - 2; i >= 0; i -= 2) {
    2955            if (ls[i] == RendererChangeListener.class) {
    2956                ((RendererChangeListener) ls[i + 1]).rendererChanged(event);
    2957            }
    2958        }
    2959    }
    2960
    2961    /**
    2962     * Tests this renderer for equality with another object.
    2963     *
    2964     * @param obj  the object (<code>null</code> permitted).
    2965     *
    2966     * @return <code>true</code> or <code>false</code>.
    2967     */
    2968    public boolean equals(Object obj) {
    2969        if (obj == this) {
    2970            return true;
    2971        }
    2972        if (!(obj instanceof AbstractRenderer)) {
    2973            return false;
    2974        }
    2975        AbstractRenderer that = (AbstractRenderer) obj;
    2976        if (this.dataBoundsIncludesVisibleSeriesOnly
    2977                != that.dataBoundsIncludesVisibleSeriesOnly) {
    2978            return false;
    2979        }
    2980        if (this.treatLegendShapeAsLine != that.treatLegendShapeAsLine) {
    2981            return false;
    2982        }
    2983        if (this.defaultEntityRadius != that.defaultEntityRadius) {
    2984            return false;
    2985        }
    2986        if (!ObjectUtilities.equal(this.seriesVisible, that.seriesVisible)) {
    2987            return false;
    2988        }
    2989        if (!this.seriesVisibleList.equals(that.seriesVisibleList)) {
    2990            return false;
    2991        }
    2992        if (this.baseSeriesVisible != that.baseSeriesVisible) {
    2993            return false;
    2994        }
    2995        if (!ObjectUtilities.equal(this.seriesVisibleInLegend,
    2996                that.seriesVisibleInLegend)) {
    2997            return false;
    2998        }
    2999        if (!this.seriesVisibleInLegendList.equals(
    3000                that.seriesVisibleInLegendList)) {
    3001            return false;
    3002        }
    3003        if (this.baseSeriesVisibleInLegend != that.baseSeriesVisibleInLegend) {
    3004            return false;
    3005        }
    3006        if (!PaintUtilities.equal(this.paint, that.paint)) {
    3007            return false;
    3008        }
    3009        if (!ObjectUtilities.equal(this.paintList, that.paintList)) {
    3010            return false;
    3011        }
    3012        if (!PaintUtilities.equal(this.basePaint, that.basePaint)) {
    3013            return false;
    3014        }
    3015        if (!PaintUtilities.equal(this.fillPaint, that.fillPaint)) {
    3016            return false;
    3017        }
    3018        if (!ObjectUtilities.equal(this.fillPaintList, that.fillPaintList)) {
    3019            return false;
    3020        }
    3021        if (!PaintUtilities.equal(this.baseFillPaint, that.baseFillPaint)) {
    3022            return false;
    3023        }
    3024        if (!PaintUtilities.equal(this.outlinePaint, that.outlinePaint)) {
    3025            return false;
    3026        }
    3027        if (!ObjectUtilities.equal(this.outlinePaintList,
    3028                that.outlinePaintList)) {
    3029            return false;
    3030        }
    3031        if (!PaintUtilities.equal(this.baseOutlinePaint,
    3032                that.baseOutlinePaint)) {
    3033            return false;
    3034        }
    3035        if (!ObjectUtilities.equal(this.stroke, that.stroke)) {
    3036            return false;
    3037        }
    3038        if (!ObjectUtilities.equal(this.strokeList, that.strokeList)) {
    3039            return false;
    3040        }
    3041        if (!ObjectUtilities.equal(this.baseStroke, that.baseStroke)) {
    3042            return false;
    3043        }
    3044        if (!ObjectUtilities.equal(this.outlineStroke, that.outlineStroke)) {
    3045            return false;
    3046        }
    3047        if (!ObjectUtilities.equal(this.outlineStrokeList,
    3048                that.outlineStrokeList)) {
    3049            return false;
    3050        }
    3051        if (!ObjectUtilities.equal(
    3052            this.baseOutlineStroke, that.baseOutlineStroke)
    3053        ) {
    3054            return false;
    3055        }
    3056        if (!ShapeUtilities.equal(this.shape, that.shape)) {
    3057            return false;
    3058        }
    3059        if (!ObjectUtilities.equal(this.shapeList, that.shapeList)) {
    3060            return false;
    3061        }
    3062        if (!ShapeUtilities.equal(this.baseShape, that.baseShape)) {
    3063            return false;
    3064        }
    3065        if (!ObjectUtilities.equal(this.itemLabelsVisible,
    3066                that.itemLabelsVisible)) {
    3067            return false;
    3068        }
    3069        if (!ObjectUtilities.equal(this.itemLabelsVisibleList,
    3070                that.itemLabelsVisibleList)) {
    3071            return false;
    3072        }
    3073        if (!ObjectUtilities.equal(this.baseItemLabelsVisible,
    3074                that.baseItemLabelsVisible)) {
    3075            return false;
    3076        }
    3077        if (!ObjectUtilities.equal(this.itemLabelFont, that.itemLabelFont)) {
    3078            return false;
    3079        }
    3080        if (!ObjectUtilities.equal(this.itemLabelFontList,
    3081                that.itemLabelFontList)) {
    3082            return false;
    3083        }
    3084        if (!ObjectUtilities.equal(this.baseItemLabelFont,
    3085                that.baseItemLabelFont)) {
    3086            return false;
    3087        }
    3088
    3089        if (!PaintUtilities.equal(this.itemLabelPaint, that.itemLabelPaint)) {
    3090            return false;
    3091        }
    3092        if (!ObjectUtilities.equal(this.itemLabelPaintList,
    3093                that.itemLabelPaintList)) {
    3094            return false;
    3095        }
    3096        if (!PaintUtilities.equal(this.baseItemLabelPaint,
    3097                that.baseItemLabelPaint)) {
    3098            return false;
    3099        }
    3100
    3101        if (!ObjectUtilities.equal(this.positiveItemLabelPosition,
    3102                that.positiveItemLabelPosition)) {
    3103            return false;
    3104        }
    3105        if (!ObjectUtilities.equal(this.positiveItemLabelPositionList,
    3106                that.positiveItemLabelPositionList)) {
    3107            return false;
    3108        }
    3109        if (!ObjectUtilities.equal(this.basePositiveItemLabelPosition,
    3110                that.basePositiveItemLabelPosition)) {
    3111            return false;
    3112        }
    3113
    3114        if (!ObjectUtilities.equal(this.negativeItemLabelPosition,
    3115                that.negativeItemLabelPosition)) {
    3116            return false;
    3117        }
    3118        if (!ObjectUtilities.equal(this.negativeItemLabelPositionList,
    3119                that.negativeItemLabelPositionList)) {
    3120            return false;
    3121        }
    3122        if (!ObjectUtilities.equal(this.baseNegativeItemLabelPosition,
    3123                that.baseNegativeItemLabelPosition)) {
    3124            return false;
    3125        }
    3126        if (this.itemLabelAnchorOffset != that.itemLabelAnchorOffset) {
    3127            return false;
    3128        }
    3129        if (!ObjectUtilities.equal(this.createEntities, that.createEntities)) {
    3130            return false;
    3131        }
    3132        if (!ObjectUtilities.equal(this.createEntitiesList,
    3133                that.createEntitiesList)) {
    3134            return false;
    3135        }
    3136        if (this.baseCreateEntities != that.baseCreateEntities) {
    3137            return false;
    3138        }
    3139        if (!ObjectUtilities.equal(this.legendShapeList,
    3140                that.legendShapeList)) {
    3141            return false;
    3142        }
    3143        if (!ShapeUtilities.equal(this.baseLegendShape,
    3144                that.baseLegendShape)) {
    3145            return false;
    3146        }
    3147        if (!ObjectUtilities.equal(this.legendTextFont, that.legendTextFont)) {
    3148            return false;
    3149        }
    3150        if (!ObjectUtilities.equal(this.baseLegendTextFont,
    3151                that.baseLegendTextFont)) {
    3152            return false;
    3153        }
    3154        if (!ObjectUtilities.equal(this.legendTextPaint,
    3155                that.legendTextPaint)) {
    3156            return false;
    3157        }
    3158        if (!PaintUtilities.equal(this.baseLegendTextPaint,
    3159                that.baseLegendTextPaint)) {
    3160            return false;
    3161        }
    3162        return true;
    3163    }
    3164
    3165    /**
    3166     * Returns a hashcode for the renderer.
    3167     *
    3168     * @return The hashcode.
    3169     */
    3170    public int hashCode() {
    3171        int result = 193;
    3172        result = HashUtilities.hashCode(result, this.seriesVisibleList);
    3173        result = HashUtilities.hashCode(result, this.baseSeriesVisible);
    3174        result = HashUtilities.hashCode(result, this.seriesVisibleInLegendList);
    3175        result = HashUtilities.hashCode(result, this.baseSeriesVisibleInLegend);
    3176        result = HashUtilities.hashCode(result, this.paintList);
    3177        result = HashUtilities.hashCode(result, this.basePaint);
    3178        result = HashUtilities.hashCode(result, this.fillPaintList);
    3179        result = HashUtilities.hashCode(result, this.baseFillPaint);
    3180        result = HashUtilities.hashCode(result, this.outlinePaintList);
    3181        result = HashUtilities.hashCode(result, this.baseOutlinePaint);
    3182        result = HashUtilities.hashCode(result, this.strokeList);
    3183        result = HashUtilities.hashCode(result, this.baseStroke);
    3184        result = HashUtilities.hashCode(result, this.outlineStrokeList);
    3185        result = HashUtilities.hashCode(result, this.baseOutlineStroke);
    3186        // shapeList
    3187        // baseShape
    3188        result = HashUtilities.hashCode(result, this.itemLabelsVisibleList);
    3189        result = HashUtilities.hashCode(result, this.baseItemLabelsVisible);
    3190        // itemLabelFontList
    3191        // baseItemLabelFont
    3192        // itemLabelPaintList
    3193        // baseItemLabelPaint
    3194        // positiveItemLabelPositionList
    3195        // basePositiveItemLabelPosition
    3196        // negativeItemLabelPositionList
    3197        // baseNegativeItemLabelPosition
    3198        // itemLabelAnchorOffset
    3199        // createEntityList
    3200        // baseCreateEntities
    3201        return result;
    3202    }
    3203
    3204    /**
    3205     * Returns an independent copy of the renderer.
    3206     *
    3207     * @return A clone.
    3208     *
    3209     * @throws CloneNotSupportedException if some component of the renderer
    3210     *         does not support cloning.
    3211     */
    3212    protected Object clone() throws CloneNotSupportedException {
    3213        AbstractRenderer clone = (AbstractRenderer) super.clone();
    3214
    3215        if (this.seriesVisibleList != null) {
    3216            clone.seriesVisibleList
    3217                    = (BooleanList) this.seriesVisibleList.clone();
    3218        }
    3219
    3220        if (this.seriesVisibleInLegendList != null) {
    3221            clone.seriesVisibleInLegendList
    3222                    = (BooleanList) this.seriesVisibleInLegendList.clone();
    3223        }
    3224
    3225        // 'paint' : immutable, no need to clone reference
    3226        if (this.paintList != null) {
    3227            clone.paintList = (PaintList) this.paintList.clone();
    3228        }
    3229        // 'basePaint' : immutable, no need to clone reference
    3230
    3231        if (this.fillPaintList != null) {
    3232            clone.fillPaintList = (PaintList) this.fillPaintList.clone();
    3233        }
    3234        // 'outlinePaint' : immutable, no need to clone reference
    3235        if (this.outlinePaintList != null) {
    3236            clone.outlinePaintList = (PaintList) this.outlinePaintList.clone();
    3237        }
    3238        // 'baseOutlinePaint' : immutable, no need to clone reference
    3239
    3240        // 'stroke' : immutable, no need to clone reference
    3241        if (this.strokeList != null) {
    3242            clone.strokeList = (StrokeList) this.strokeList.clone();
    3243        }
    3244        // 'baseStroke' : immutable, no need to clone reference
    3245
    3246        // 'outlineStroke' : immutable, no need to clone reference
    3247        if (this.outlineStrokeList != null) {
    3248            clone.outlineStrokeList
    3249                = (StrokeList) this.outlineStrokeList.clone();
    3250        }
    3251        // 'baseOutlineStroke' : immutable, no need to clone reference
    3252
    3253        if (this.shape != null) {
    3254            clone.shape = ShapeUtilities.clone(this.shape);
    3255        }
    3256        if (this.shapeList != null) {
    3257            clone.shapeList = (ShapeList) this.shapeList.clone();
    3258        }
    3259        if (this.baseShape != null) {
    3260            clone.baseShape = ShapeUtilities.clone(this.baseShape);
    3261        }
    3262
    3263        // 'itemLabelsVisible' : immutable, no need to clone reference
    3264        if (this.itemLabelsVisibleList != null) {
    3265            clone.itemLabelsVisibleList
    3266                = (BooleanList) this.itemLabelsVisibleList.clone();
    3267        }
    3268        // 'basePaint' : immutable, no need to clone reference
    3269
    3270        // 'itemLabelFont' : immutable, no need to clone reference
    3271        if (this.itemLabelFontList != null) {
    3272            clone.itemLabelFontList
    3273                = (ObjectList) this.itemLabelFontList.clone();
    3274        }
    3275        // 'baseItemLabelFont' : immutable, no need to clone reference
    3276
    3277        // 'itemLabelPaint' : immutable, no need to clone reference
    3278        if (this.itemLabelPaintList != null) {
    3279            clone.itemLabelPaintList
    3280                = (PaintList) this.itemLabelPaintList.clone();
    3281        }
    3282        // 'baseItemLabelPaint' : immutable, no need to clone reference
    3283
    3284        // 'postiveItemLabelAnchor' : immutable, no need to clone reference
    3285        if (this.positiveItemLabelPositionList != null) {
    3286            clone.positiveItemLabelPositionList
    3287                = (ObjectList) this.positiveItemLabelPositionList.clone();
    3288        }
    3289        // 'baseItemLabelAnchor' : immutable, no need to clone reference
    3290
    3291        // 'negativeItemLabelAnchor' : immutable, no need to clone reference
    3292        if (this.negativeItemLabelPositionList != null) {
    3293            clone.negativeItemLabelPositionList
    3294                = (ObjectList) this.negativeItemLabelPositionList.clone();
    3295        }
    3296        // 'baseNegativeItemLabelAnchor' : immutable, no need to clone reference
    3297
    3298        if (this.createEntitiesList != null) {
    3299            clone.createEntitiesList
    3300                    = (BooleanList) this.createEntitiesList.clone();
    3301        }
    3302
    3303        if (this.legendShapeList != null) {
    3304            clone.legendShapeList = (ShapeList) this.legendShapeList.clone();
    3305        }
    3306        if (this.legendTextFont != null) {
    3307            clone.legendTextFont = (ObjectList) this.legendTextFont.clone();
    3308        }
    3309        if (this.legendTextPaint != null) {
    3310            clone.legendTextPaint = (PaintList) this.legendTextPaint.clone();
    3311        }
    3312        clone.listenerList = new EventListenerList();
    3313        clone.event = null;
    3314        return clone;
    3315    }
    3316
    3317    /**
    3318     * Provides serialization support.
    3319     *
    3320     * @param stream  the output stream.
    3321     *
    3322     * @throws IOException  if there is an I/O error.
    3323     */
    3324    private void writeObject(ObjectOutputStream stream) throws IOException {
    3325
    3326        stream.defaultWriteObject();
    3327        SerialUtilities.writePaint(this.paint, stream);
    3328        SerialUtilities.writePaint(this.basePaint, stream);
    3329        SerialUtilities.writePaint(this.fillPaint, stream);
    3330        SerialUtilities.writePaint(this.baseFillPaint, stream);
    3331        SerialUtilities.writePaint(this.outlinePaint, stream);
    3332        SerialUtilities.writePaint(this.baseOutlinePaint, stream);
    3333        SerialUtilities.writeStroke(this.stroke, stream);
    3334        SerialUtilities.writeStroke(this.baseStroke, stream);
    3335        SerialUtilities.writeStroke(this.outlineStroke, stream);
    3336        SerialUtilities.writeStroke(this.baseOutlineStroke, stream);
    3337        SerialUtilities.writeShape(this.shape, stream);
    3338        SerialUtilities.writeShape(this.baseShape, stream);
    3339        SerialUtilities.writePaint(this.itemLabelPaint, stream);
    3340        SerialUtilities.writePaint(this.baseItemLabelPaint, stream);
    3341        SerialUtilities.writeShape(this.baseLegendShape, stream);
    3342        SerialUtilities.writePaint(this.baseLegendTextPaint, stream);
    3343
    3344    }
    3345
    3346    /**
    3347     * Provides serialization support.
    3348     *
    3349     * @param stream  the input stream.
    3350     *
    3351     * @throws IOException  if there is an I/O error.
    3352     * @throws ClassNotFoundException  if there is a classpath problem.
    3353     */
    3354    private void readObject(ObjectInputStream stream)
    3355        throws IOException, ClassNotFoundException {
    3356
    3357        stream.defaultReadObject();
    3358        this.paint = SerialUtilities.readPaint(stream);
    3359        this.basePaint = SerialUtilities.readPaint(stream);
    3360        this.fillPaint = SerialUtilities.readPaint(stream);
    3361        this.baseFillPaint = SerialUtilities.readPaint(stream);
    3362        this.outlinePaint = SerialUtilities.readPaint(stream);
    3363        this.baseOutlinePaint = SerialUtilities.readPaint(stream);
    3364        this.stroke = SerialUtilities.readStroke(stream);
    3365        this.baseStroke = SerialUtilities.readStroke(stream);
    3366        this.outlineStroke = SerialUtilities.readStroke(stream);
    3367        this.baseOutlineStroke = SerialUtilities.readStroke(stream);
    3368        this.shape = SerialUtilities.readShape(stream);
    3369        this.baseShape = SerialUtilities.readShape(stream);
    3370        this.itemLabelPaint = SerialUtilities.readPaint(stream);
    3371        this.baseItemLabelPaint = SerialUtilities.readPaint(stream);
    3372        this.baseLegendShape = SerialUtilities.readShape(stream);
    3373        this.baseLegendTextPaint = SerialUtilities.readPaint(stream);
    3374
    3375        // listeners are not restored automatically, but storage must be
    3376        // provided...
    3377        this.listenerList = new EventListenerList();
    3378
    3379    }
    3380
    3381    // === DEPRECATED CODE ===
    3382
    3383    /**
    3384     * A flag that controls the visibility of ALL series.
    3385     *
    3386     * @deprecated This field is redundant, you can rely on seriesVisibleList
    3387     *     and baseSeriesVisible.  Deprecated from version 1.0.6 onwards.
    3388     */
    3389    private Boolean seriesVisible;
    3390
    3391    /**
    3392     * A flag that controls the visibility of ALL series in the legend.
    3393     *
    3394     * @deprecated This field is redundant, you can rely on
    3395     *     seriesVisibleInLegendList and baseSeriesVisibleInLegend.
    3396     *     Deprecated from version 1.0.6 onwards.
    3397     */
    3398    private Boolean seriesVisibleInLegend;
    3399
    3400    /**
    3401     * The paint for ALL series (optional).
    3402     *
    3403     * @deprecated This field is redundant, you can rely on paintList and
    3404     *     basePaint.  Deprecated from version 1.0.6 onwards.
    3405     */
    3406    private transient Paint paint;
    3407
    3408    /**
    3409     * The fill paint for ALL series (optional).
    3410     *
    3411     * @deprecated This field is redundant, you can rely on fillPaintList and
    3412     *     baseFillPaint.  Deprecated from version 1.0.6 onwards.
    3413     */
    3414    private transient Paint fillPaint;
    3415
    3416    /**
    3417     * The outline paint for ALL series (optional).
    3418     *
    3419     * @deprecated This field is redundant, you can rely on outlinePaintList
    3420     *         and baseOutlinePaint.  Deprecated from version 1.0.6 onwards.
    3421     */
    3422    private transient Paint outlinePaint;
    3423
    3424    /**
    3425     * The stroke for ALL series (optional).
    3426     *
    3427     * @deprecated This field is redundant, you can rely on strokeList and
    3428     *     baseStroke.  Deprecated from version 1.0.6 onwards.
    3429     */
    3430    private transient Stroke stroke;
    3431
    3432    /**
    3433     * The outline stroke for ALL series (optional).
    3434     *
    3435     * @deprecated This field is redundant, you can rely on strokeList and
    3436     *     baseStroke.  Deprecated from version 1.0.6 onwards.
    3437     */
    3438    private transient Stroke outlineStroke;
    3439
    3440    /**
    3441     * The shape for ALL series (optional).
    3442     *
    3443     * @deprecated This field is redundant, you can rely on shapeList and
    3444     *     baseShape.  Deprecated from version 1.0.6 onwards.
    3445     */
    3446    private transient Shape shape;
    3447
    3448    /**
    3449     * Visibility of the item labels for ALL series (optional).
    3450     *
    3451     * @deprecated This field is redundant, you can rely on
    3452     *     itemLabelsVisibleList and baseItemLabelsVisible.  Deprecated from
    3453     *     version 1.0.6 onwards.
    3454     */
    3455    private Boolean itemLabelsVisible;
    3456
    3457    /**
    3458     * The item label font for ALL series (optional).
    3459     *
    3460     * @deprecated This field is redundant, you can rely on itemLabelFontList
    3461     *     and baseItemLabelFont.  Deprecated from version 1.0.6 onwards.
    3462     */
    3463    private Font itemLabelFont;
    3464
    3465    /**
    3466     * The item label paint for ALL series.
    3467     *
    3468     * @deprecated This field is redundant, you can rely on itemLabelPaintList
    3469     *     and baseItemLabelPaint.  Deprecated from version 1.0.6 onwards.
    3470     */
    3471    private transient Paint itemLabelPaint;
    3472
    3473    /**
    3474     * The positive item label position for ALL series (optional).
    3475     *
    3476     * @deprecated This field is redundant, you can rely on the
    3477     *     positiveItemLabelPositionList and basePositiveItemLabelPosition
    3478     *     fields.  Deprecated from version 1.0.6 onwards.
    3479     */
    3480    private ItemLabelPosition positiveItemLabelPosition;
    3481
    3482    /**
    3483     * The negative item label position for ALL series (optional).
    3484     *
    3485     * @deprecated This field is redundant, you can rely on the
    3486     *     negativeItemLabelPositionList and baseNegativeItemLabelPosition
    3487     *     fields.  Deprecated from version 1.0.6 onwards.
    3488     */
    3489    private ItemLabelPosition negativeItemLabelPosition;
    3490
    3491    /**
    3492     * A flag that controls whether or not entities are generated for
    3493     * ALL series (optional).
    3494     *
    3495     * @deprecated This field is redundant, you can rely on the
    3496     *     createEntitiesList and baseCreateEntities fields.  Deprecated from
    3497     *     version 1.0.6 onwards.
    3498     */
    3499    private Boolean createEntities;
    3500
    3501    /**
    3502     * Returns the flag that controls the visibility of ALL series.  This flag
    3503     * overrides the per series and default settings - you must set it to
    3504     * <code>null</code> if you want the other settings to apply.
    3505     *
    3506     * @return The flag (possibly <code>null</code>).
    3507     *
    3508     * @see #setSeriesVisible(Boolean)
    3509     *
    3510     * @deprecated This method should no longer be used (as of version 1.0.6).
    3511     *     It is sufficient to rely on {@link #getSeriesVisible(int)} and
    3512     *     {@link #getBaseSeriesVisible()}.
    3513     */
    3514    public Boolean getSeriesVisible() {
    3515        return this.seriesVisible;
    3516    }
    3517
    3518    /**
    3519     * Sets the flag that controls the visibility of ALL series and sends a
    3520     * {@link RendererChangeEvent} to all registered listeners.  This flag
    3521     * overrides the per series and default settings - you must set it to
    3522     * <code>null</code> if you want the other settings to apply.
    3523     *
    3524     * @param visible  the flag (<code>null</code> permitted).
    3525     *
    3526     * @see #getSeriesVisible()
    3527     *
    3528     * @deprecated This method should no longer be used (as of version 1.0.6).
    3529     *     It is sufficient to rely on {@link #setSeriesVisible(int, Boolean)}
    3530     *     and {@link #setBaseSeriesVisible(boolean)}.
    3531     */
    3532    public void setSeriesVisible(Boolean visible) {
    3533         setSeriesVisible(visible, true);
    3534    }
    3535
    3536    /**
    3537     * Sets the flag that controls the visibility of ALL series and sends a
    3538     * {@link RendererChangeEvent} to all registered listeners.  This flag
    3539     * overrides the per series and default settings - you must set it to
    3540     * <code>null</code> if you want the other settings to apply.
    3541     *
    3542     * @param visible  the flag (<code>null</code> permitted).
    3543     * @param notify  notify listeners?
    3544     *
    3545     * @see #getSeriesVisible()
    3546     *
    3547     * @deprecated This method should no longer be used (as of version 1.0.6).
    3548     *     It is sufficient to rely on {@link #setSeriesVisible(int, Boolean)}
    3549     *     and {@link #setBaseSeriesVisible(boolean)}.
    3550     */
    3551    public void setSeriesVisible(Boolean visible, boolean notify) {
    3552        this.seriesVisible = visible;
    3553        if (notify) {
    3554            // we create an event with a special flag set...the purpose of
    3555            // this is to communicate to the plot (the default receiver of
    3556            // the event) that series visibility has changed so the axis
    3557            // ranges might need updating...
    3558            RendererChangeEvent e = new RendererChangeEvent(this, true);
    3559            notifyListeners(e);
    3560        }
    3561    }
    3562
    3563    /**
    3564     * Returns the flag that controls the visibility of ALL series in the
    3565     * legend.  This flag overrides the per series and default settings - you
    3566     * must set it to <code>null</code> if you want the other settings to
    3567     * apply.
    3568     *
    3569     * @return The flag (possibly <code>null</code>).
    3570     *
    3571     * @see #setSeriesVisibleInLegend(Boolean)
    3572     *
    3573     * @deprecated This method should no longer be used (as of version 1.0.6).
    3574     *     It is sufficient to rely on {@link #getSeriesVisibleInLegend(int)}
    3575     *     and {@link #getBaseSeriesVisibleInLegend()}.
    3576     */
    3577    public Boolean getSeriesVisibleInLegend() {
    3578        return this.seriesVisibleInLegend;
    3579    }
    3580
    3581    /**
    3582     * Sets the flag that controls the visibility of ALL series in the legend
    3583     * and sends a {@link RendererChangeEvent} to all registered listeners.
    3584     * This flag overrides the per series and default settings - you must set
    3585     * it to <code>null</code> if you want the other settings to apply.
    3586     *
    3587     * @param visible  the flag (<code>null</code> permitted).
    3588     *
    3589     * @see #getSeriesVisibleInLegend()
    3590     *
    3591     * @deprecated This method should no longer be used (as of version 1.0.6).
    3592     *     It is sufficient to rely on {@link #setSeriesVisibleInLegend(int,
    3593     *     Boolean)} and {@link #setBaseSeriesVisibleInLegend(boolean)}.
    3594     */
    3595    public void setSeriesVisibleInLegend(Boolean visible) {
    3596         setSeriesVisibleInLegend(visible, true);
    3597    }
    3598
    3599    /**
    3600     * Sets the flag that controls the visibility of ALL series in the legend
    3601     * and sends a {@link RendererChangeEvent} to all registered listeners.
    3602     * This flag overrides the per series and default settings - you must set
    3603     * it to <code>null</code> if you want the other settings to apply.
    3604     *
    3605     * @param visible  the flag (<code>null</code> permitted).
    3606     * @param notify  notify listeners?
    3607     *
    3608     * @see #getSeriesVisibleInLegend()
    3609     *
    3610     * @deprecated This method should no longer be used (as of version 1.0.6).
    3611     *     It is sufficient to rely on {@link #setSeriesVisibleInLegend(int,
    3612     *     Boolean, boolean)} and {@link #setBaseSeriesVisibleInLegend(boolean,
    3613     *     boolean)}.
    3614     */
    3615    public void setSeriesVisibleInLegend(Boolean visible, boolean notify) {
    3616        this.seriesVisibleInLegend = visible;
    3617        if (notify) {
    3618            fireChangeEvent();
    3619        }
    3620    }
    3621
    3622    /**
    3623     * Sets the paint to be used for ALL series, and sends a
    3624     * {@link RendererChangeEvent} to all registered listeners.  If this is
    3625     * <code>null</code>, the renderer will use the paint for the series.
    3626     *
    3627     * @param paint  the paint (<code>null</code> permitted).
    3628     *
    3629     * @deprecated This method should no longer be used (as of version 1.0.6).
    3630     *     It is sufficient to rely on {@link #setSeriesPaint(int, Paint)} and
    3631     *     {@link #setBasePaint(Paint)}.
    3632     */
    3633    public void setPaint(Paint paint) {
    3634        setPaint(paint, true);
    3635    }
    3636
    3637    /**
    3638     * Sets the paint to be used for all series and, if requested, sends a
    3639     * {@link RendererChangeEvent} to all registered listeners.
    3640     *
    3641     * @param paint  the paint (<code>null</code> permitted).
    3642     * @param notify  notify listeners?
    3643     *
    3644     * @deprecated This method should no longer be used (as of version 1.0.6).
    3645     *     It is sufficient to rely on {@link #setSeriesPaint(int, Paint,
    3646     *     boolean)} and {@link #setBasePaint(Paint, boolean)}.
    3647     */
    3648    public void setPaint(Paint paint, boolean notify) {
    3649        this.paint = paint;
    3650        if (notify) {
    3651            fireChangeEvent();
    3652        }
    3653    }
    3654
    3655    /**
    3656     * Sets the fill paint for ALL series (optional).
    3657     *
    3658     * @param paint  the paint (<code>null</code> permitted).
    3659     *
    3660     * @deprecated This method should no longer be used (as of version 1.0.6).
    3661     *     It is sufficient to rely on {@link #setSeriesFillPaint(int, Paint)}
    3662     *     and {@link #setBaseFillPaint(Paint)}.
    3663     */
    3664    public void setFillPaint(Paint paint) {
    3665        setFillPaint(paint, true);
    3666    }
    3667
    3668    /**
    3669     * Sets the fill paint for ALL series and, if requested, sends a
    3670     * {@link RendererChangeEvent} to all registered listeners.
    3671     *
    3672     * @param paint  the paint (<code>null</code> permitted).
    3673     * @param notify  notify listeners?
    3674     *
    3675     * @deprecated This method should no longer be used (as of version 1.0.6).
    3676     *     It is sufficient to rely on {@link #setSeriesFillPaint(int, Paint,
    3677     *     boolean)} and {@link #setBaseFillPaint(Paint, boolean)}.
    3678     */
    3679    public void setFillPaint(Paint paint, boolean notify) {
    3680        this.fillPaint = paint;
    3681        if (notify) {
    3682            fireChangeEvent();
    3683        }
    3684    }
    3685
    3686    /**
    3687     * Sets the outline paint for ALL series (optional) and sends a
    3688     * {@link RendererChangeEvent} to all registered listeners.
    3689     *
    3690     * @param paint  the paint (<code>null</code> permitted).
    3691     *
    3692     * @deprecated This method should no longer be used (as of version 1.0.6).
    3693     *     It is sufficient to rely on {@link #setSeriesOutlinePaint(int,
    3694     *     Paint)} and {@link #setBaseOutlinePaint(Paint)}.
    3695     */
    3696    public void setOutlinePaint(Paint paint) {
    3697        setOutlinePaint(paint, true);
    3698    }
    3699
    3700    /**
    3701     * Sets the outline paint for ALL series and, if requested, sends a
    3702     * {@link RendererChangeEvent} to all registered listeners.
    3703     *
    3704     * @param paint  the paint (<code>null</code> permitted).
    3705     * @param notify  notify listeners?
    3706     *
    3707     * @deprecated This method should no longer be used (as of version 1.0.6).
    3708     *     It is sufficient to rely on {@link #setSeriesOutlinePaint(int,
    3709     *     Paint, boolean)} and {@link #setBaseOutlinePaint(Paint, boolean)}.
    3710     */
    3711    public void setOutlinePaint(Paint paint, boolean notify) {
    3712        this.outlinePaint = paint;
    3713        if (notify) {
    3714            fireChangeEvent();
    3715        }
    3716    }
    3717
    3718    /**
    3719     * Sets the stroke for ALL series and sends a {@link RendererChangeEvent}
    3720     * to all registered listeners.
    3721     *
    3722     * @param stroke  the stroke (<code>null</code> permitted).
    3723     *
    3724     * @deprecated This method should no longer be used (as of version 1.0.6).
    3725     *     It is sufficient to rely on {@link #setSeriesStroke(int, Stroke)}
    3726     *     and {@link #setBaseStroke(Stroke)}.
    3727     */
    3728    public void setStroke(Stroke stroke) {
    3729        setStroke(stroke, true);
    3730    }
    3731
    3732    /**
    3733     * Sets the stroke for ALL series and, if requested, sends a
    3734     * {@link RendererChangeEvent} to all registered listeners.
    3735     *
    3736     * @param stroke  the stroke (<code>null</code> permitted).
    3737     * @param notify  notify listeners?
    3738     *
    3739     * @deprecated This method should no longer be used (as of version 1.0.6).
    3740     *     It is sufficient to rely on {@link #setSeriesStroke(int, Stroke,
    3741     *     boolean)} and {@link #setBaseStroke(Stroke, boolean)}.
    3742     */
    3743    public void setStroke(Stroke stroke, boolean notify) {
    3744        this.stroke = stroke;
    3745        if (notify) {
    3746            fireChangeEvent();
    3747        }
    3748    }
    3749
    3750    /**
    3751     * Sets the outline stroke for ALL series and sends a
    3752     * {@link RendererChangeEvent} to all registered listeners.
    3753     *
    3754     * @param stroke  the stroke (<code>null</code> permitted).
    3755     *
    3756     * @deprecated This method should no longer be used (as of version 1.0.6).
    3757     *     It is sufficient to rely on {@link #setSeriesOutlineStroke(int,
    3758     *     Stroke)} and {@link #setBaseOutlineStroke(Stroke)}.
    3759     */
    3760    public void setOutlineStroke(Stroke stroke) {
    3761        setOutlineStroke(stroke, true);
    3762    }
    3763
    3764    /**
    3765     * Sets the outline stroke for ALL series and, if requested, sends a
    3766     * {@link RendererChangeEvent} to all registered listeners.
    3767     *
    3768     * @param stroke  the stroke (<code>null</code> permitted).
    3769     * @param notify  notify listeners?
    3770     *
    3771     * @deprecated This method should no longer be used (as of version 1.0.6).
    3772     *     It is sufficient to rely on {@link #setSeriesOutlineStroke(int,
    3773     *     Stroke, boolean)} and {@link #setBaseOutlineStroke(Stroke, boolean)}.
    3774     */
    3775    public void setOutlineStroke(Stroke stroke, boolean notify) {
    3776        this.outlineStroke = stroke;
    3777        if (notify) {
    3778            fireChangeEvent();
    3779        }
    3780    }
    3781
    3782    /**
    3783     * Sets the shape for ALL series (optional) and sends a
    3784     * {@link RendererChangeEvent} to all registered listeners.
    3785     *
    3786     * @param shape  the shape (<code>null</code> permitted).
    3787     *
    3788     * @deprecated This method should no longer be used (as of version 1.0.6).
    3789     *     It is sufficient to rely on {@link #setSeriesShape(int, Shape)}
    3790     *     and {@link #setBaseShape(Shape)}.
    3791     */
    3792    public void setShape(Shape shape) {
    3793        setShape(shape, true);
    3794    }
    3795
    3796    /**
    3797     * Sets the shape for ALL series and, if requested, sends a
    3798     * {@link RendererChangeEvent} to all registered listeners.
    3799     *
    3800     * @param shape  the shape (<code>null</code> permitted).
    3801     * @param notify  notify listeners?
    3802     *
    3803     * @deprecated This method should no longer be used (as of version 1.0.6).
    3804     *     It is sufficient to rely on {@link #setSeriesShape(int, Shape,
    3805     *     boolean)} and {@link #setBaseShape(Shape, boolean)}.
    3806     */
    3807    public void setShape(Shape shape, boolean notify) {
    3808        this.shape = shape;
    3809        if (notify) {
    3810            fireChangeEvent();
    3811        }
    3812    }
    3813
    3814    /**
    3815     * Sets the visibility of the item labels for ALL series.
    3816     *
    3817     * @param visible  the flag.
    3818     *
    3819     * @deprecated This method should no longer be used (as of version 1.0.6).
    3820     *     It is sufficient to rely on {@link #setSeriesItemLabelsVisible(int,
    3821     *     Boolean)} and {@link #setBaseItemLabelsVisible(boolean)}.
    3822     */
    3823    public void setItemLabelsVisible(boolean visible) {
    3824        setItemLabelsVisible(BooleanUtilities.valueOf(visible));
    3825        // The following alternative is only supported in JDK 1.4 - we support
    3826        // JDK 1.3.1 onwards
    3827        // setItemLabelsVisible(Boolean.valueOf(visible));
    3828    }
    3829
    3830    /**
    3831     * Sets the visibility of the item labels for ALL series (optional).
    3832     *
    3833     * @param visible  the flag (<code>null</code> permitted).
    3834     *
    3835     * @deprecated This method should no longer be used (as of version 1.0.6).
    3836     *     It is sufficient to rely on {@link #setSeriesItemLabelsVisible(int,
    3837     *     Boolean)} and {@link #setBaseItemLabelsVisible(boolean)}.
    3838     */
    3839    public void setItemLabelsVisible(Boolean visible) {
    3840        setItemLabelsVisible(visible, true);
    3841    }
    3842
    3843    /**
    3844     * Sets the visibility of item labels for ALL series and, if requested,
    3845     * sends a {@link RendererChangeEvent} to all registered listeners.
    3846     *
    3847     * @param visible  a flag that controls whether or not the item labels are
    3848     *                 visible (<code>null</code> permitted).
    3849     * @param notify  a flag that controls whether or not listeners are
    3850     *                notified.
    3851     *
    3852     * @deprecated This method should no longer be used (as of version 1.0.6).
    3853     *     It is sufficient to rely on {@link #setSeriesItemLabelsVisible(int,
    3854     *     Boolean, boolean)} and {@link #setBaseItemLabelsVisible(Boolean,
    3855     *     boolean)}.
    3856     */
    3857    public void setItemLabelsVisible(Boolean visible, boolean notify) {
    3858        this.itemLabelsVisible = visible;
    3859        if (notify) {
    3860            fireChangeEvent();
    3861        }
    3862    }
    3863
    3864    /**
    3865     * Returns the font used for all item labels.  This may be
    3866     * <code>null</code>, in which case the per series font settings will apply.
    3867     *
    3868     * @return The font (possibly <code>null</code>).
    3869     *
    3870     * @deprecated This method should no longer be used (as of version 1.0.6).
    3871     *     It is sufficient to rely on {@link #getSeriesItemLabelFont(int)} and
    3872     *     {@link #getBaseItemLabelFont()}.
    3873     */
    3874    public Font getItemLabelFont() {
    3875        return this.itemLabelFont;
    3876    }
    3877
    3878    /**
    3879     * Sets the item label font for ALL series and sends a
    3880     * {@link RendererChangeEvent} to all registered listeners.  You can set
    3881     * this to <code>null</code> if you prefer to set the font on a per series
    3882     * basis.
    3883     *
    3884     * @param font  the font (<code>null</code> permitted).
    3885     *
    3886     * @deprecated This method should no longer be used (as of version 1.0.6).
    3887     *     It is sufficient to rely on {@link #setSeriesItemLabelFont(int,
    3888     *     Font)} and {@link #setBaseItemLabelFont(Font)}.
    3889     */
    3890    public void setItemLabelFont(Font font) {
    3891        setItemLabelFont(font, true);
    3892    }
    3893
    3894    /**
    3895     * Sets the item label font for ALL series and, if requested, sends a
    3896     * {@link RendererChangeEvent} to all registered listeners.
    3897     *
    3898     * @param font  the font (<code>null</code> permitted).
    3899     * @param notify  a flag that controls whether or not listeners are
    3900     *                notified.
    3901     *
    3902     * @deprecated This method should no longer be used (as of version 1.0.6).
    3903     *     It is sufficient to rely on {@link #setSeriesItemLabelFont(int,
    3904     *     Font, boolean)} and {@link #setBaseItemLabelFont(Font, boolean)}.
    3905     */
    3906    public void setItemLabelFont(Font font, boolean notify) {
    3907        this.itemLabelFont = font;
    3908        if (notify) {
    3909            fireChangeEvent();
    3910        }
    3911    }
    3912
    3913    /**
    3914     * Returns the paint used for all item labels.  This may be
    3915     * <code>null</code>, in which case the per series paint settings will
    3916     * apply.
    3917     *
    3918     * @return The paint (possibly <code>null</code>).
    3919     *
    3920     * @deprecated This method should no longer be used (as of version 1.0.6).
    3921     *     It is sufficient to rely on {@link #getSeriesItemLabelPaint(int)}
    3922     *     and {@link #getBaseItemLabelPaint()}.
    3923     */
    3924    public Paint getItemLabelPaint() {
    3925        return this.itemLabelPaint;
    3926    }
    3927
    3928    /**
    3929     * Sets the item label paint for ALL series and sends a
    3930     * {@link RendererChangeEvent} to all registered listeners.
    3931     *
    3932     * @param paint  the paint (<code>null</code> permitted).
    3933     *
    3934     * @deprecated This method should no longer be used (as of version 1.0.6).
    3935     *     It is sufficient to rely on {@link #setSeriesItemLabelPaint(int,
    3936     *     Paint)} and {@link #setBaseItemLabelPaint(Paint)}.
    3937     */
    3938    public void setItemLabelPaint(Paint paint) {
    3939        setItemLabelPaint(paint, true);
    3940    }
    3941
    3942    /**
    3943     * Sets the item label paint for ALL series and, if requested, sends a
    3944     * {@link RendererChangeEvent} to all registered listeners.
    3945     *
    3946     * @param paint  the paint.
    3947     * @param notify  a flag that controls whether or not listeners are
    3948     *                notified.
    3949     *
    3950     * @deprecated This method should no longer be used (as of version 1.0.6).
    3951     *     It is sufficient to rely on {@link #setSeriesItemLabelPaint(int,
    3952     *     Paint, boolean)} and {@link #setBaseItemLabelPaint(Paint, boolean)}.
    3953     */
    3954    public void setItemLabelPaint(Paint paint, boolean notify) {
    3955        this.itemLabelPaint = paint;
    3956        if (notify) {
    3957            fireChangeEvent();
    3958        }
    3959    }
    3960
    3961    /**
    3962     * Returns the item label position for positive values in ALL series.
    3963     *
    3964     * @return The item label position (possibly <code>null</code>).
    3965     *
    3966     * @see #setPositiveItemLabelPosition(ItemLabelPosition)
    3967     *
    3968     * @deprecated This method should no longer be used (as of version 1.0.6).
    3969     *     It is sufficient to rely on
    3970     *     {@link #getSeriesPositiveItemLabelPosition(int)}
    3971     *     and {@link #getBasePositiveItemLabelPosition()}.
    3972     */
    3973    public ItemLabelPosition getPositiveItemLabelPosition() {
    3974        return this.positiveItemLabelPosition;
    3975    }
    3976
    3977    /**
    3978     * Sets the item label position for positive values in ALL series, and
    3979     * sends a {@link RendererChangeEvent} to all registered listeners.  You
    3980     * need to set this to <code>null</code> to expose the settings for
    3981     * individual series.
    3982     *
    3983     * @param position  the position (<code>null</code> permitted).
    3984     *
    3985     * @see #getPositiveItemLabelPosition()
    3986     *
    3987     * @deprecated This method should no longer be used (as of version 1.0.6).
    3988     *     It is sufficient to rely on
    3989     *     {@link #setSeriesPositiveItemLabelPosition(int, ItemLabelPosition)}
    3990     *     and {@link #setBasePositiveItemLabelPosition(ItemLabelPosition)}.
    3991     */
    3992    public void setPositiveItemLabelPosition(ItemLabelPosition position) {
    3993        setPositiveItemLabelPosition(position, true);
    3994    }
    3995
    3996    /**
    3997     * Sets the positive item label position for ALL series and (if requested)
    3998     * sends a {@link RendererChangeEvent} to all registered listeners.
    3999     *
    4000     * @param position  the position (<code>null</code> permitted).
    4001     * @param notify  notify registered listeners?
    4002     *
    4003     * @see #getPositiveItemLabelPosition()
    4004     *
    4005     * @deprecated This method should no longer be used (as of version 1.0.6).
    4006     *     It is sufficient to rely on
    4007     *     {@link #setSeriesPositiveItemLabelPosition(int, ItemLabelPosition,
    4008     *     boolean)} and {@link #setBasePositiveItemLabelPosition(
    4009     *     ItemLabelPosition, boolean)}.
    4010     */
    4011    public void setPositiveItemLabelPosition(ItemLabelPosition position,
    4012                                             boolean notify) {
    4013        this.positiveItemLabelPosition = position;
    4014        if (notify) {
    4015            fireChangeEvent();
    4016        }
    4017    }
    4018
    4019    /**
    4020     * Returns the item label position for negative values in ALL series.
    4021     *
    4022     * @return The item label position (possibly <code>null</code>).
    4023     *
    4024     * @see #setNegativeItemLabelPosition(ItemLabelPosition)
    4025     *
    4026     * @deprecated This method should no longer be used (as of version 1.0.6).
    4027     *     It is sufficient to rely on
    4028     *     {@link #getSeriesNegativeItemLabelPosition(int)}
    4029     *     and {@link #getBaseNegativeItemLabelPosition()}.
    4030     */
    4031    public ItemLabelPosition getNegativeItemLabelPosition() {
    4032        return this.negativeItemLabelPosition;
    4033    }
    4034
    4035    /**
    4036     * Sets the item label position for negative values in ALL series, and
    4037     * sends a {@link RendererChangeEvent} to all registered listeners.  You
    4038     * need to set this to <code>null</code> to expose the settings for
    4039     * individual series.
    4040     *
    4041     * @param position  the position (<code>null</code> permitted).
    4042     *
    4043     * @see #getNegativeItemLabelPosition()
    4044     *
    4045     * @deprecated This method should no longer be used (as of version 1.0.6).
    4046     *     It is sufficient to rely on
    4047     *     {@link #setSeriesNegativeItemLabelPosition(int, ItemLabelPosition)}
    4048     *     and {@link #setBaseNegativeItemLabelPosition(ItemLabelPosition)}.
    4049     */
    4050    public void setNegativeItemLabelPosition(ItemLabelPosition position) {
    4051        setNegativeItemLabelPosition(position, true);
    4052    }
    4053
    4054    /**
    4055     * Sets the item label position for negative values in ALL series and (if
    4056     * requested) sends a {@link RendererChangeEvent} to all registered
    4057     * listeners.
    4058     *
    4059     * @param position  the position (<code>null</code> permitted).
    4060     * @param notify  notify registered listeners?
    4061     *
    4062     * @see #getNegativeItemLabelPosition()
    4063     *
    4064     * @deprecated This method should no longer be used (as of version 1.0.6).
    4065     *     It is sufficient to rely on
    4066     *     {@link #setSeriesNegativeItemLabelPosition(int, ItemLabelPosition,
    4067     *     boolean)} and {@link #setBaseNegativeItemLabelPosition(
    4068     *     ItemLabelPosition, boolean)}.
    4069     */
    4070    public void setNegativeItemLabelPosition(ItemLabelPosition position,
    4071                                             boolean notify) {
    4072        this.negativeItemLabelPosition = position;
    4073        if (notify) {
    4074            fireChangeEvent();
    4075        }
    4076    }
    4077
    4078    /**
    4079     * Returns the flag that controls whether or not chart entities are created
    4080     * for the items in ALL series.  This flag overrides the per series and
    4081     * default settings - you must set it to <code>null</code> if you want the
    4082     * other settings to apply.
    4083     *
    4084     * @return The flag (possibly <code>null</code>).
    4085     *
    4086     * @deprecated This method should no longer be used (as of version 1.0.6).
    4087     *     It is sufficient to rely on {@link #getSeriesCreateEntities(int)}
    4088     *     and {@link #getBaseCreateEntities()}.
    4089     */
    4090    public Boolean getCreateEntities() {
    4091        return this.createEntities;
    4092    }
    4093
    4094    /**
    4095     * Sets the flag that controls whether or not chart entities are created
    4096     * for the items in ALL series, and sends a {@link RendererChangeEvent} to
    4097     * all registered listeners.  This flag overrides the per series and
    4098     * default settings - you must set it to <code>null</code> if you want the
    4099     * other settings to apply.
    4100     *
    4101     * @param create  the flag (<code>null</code> permitted).
    4102     *
    4103     * @deprecated This method should no longer be used (as of version 1.0.6).
    4104     *     It is sufficient to rely on {@link #setSeriesCreateEntities(int,
    4105     *     Boolean)} and {@link #setBaseCreateEntities(boolean)}.
    4106     */
    4107    public void setCreateEntities(Boolean create) {
    4108         setCreateEntities(create, true);
    4109    }
    4110
    4111    /**
    4112     * Sets the flag that controls whether or not chart entities are created
    4113     * for the items in ALL series, and sends a {@link RendererChangeEvent} to
    4114     * all registered listeners.  This flag overrides the per series and
    4115     * default settings - you must set it to <code>null</code> if you want the
    4116     * other settings to apply.
    4117     *
    4118     * @param create  the flag (<code>null</code> permitted).
    4119     * @param notify  notify listeners?
    4120     *
    4121     * @deprecated This method should no longer be used (as of version 1.0.6).
    4122     *     It is sufficient to rely on {@link #setSeriesItemLabelFont(int,
    4123     *     Font, boolean)} and {@link #setBaseItemLabelFont(Font, boolean)}.
    4124     */
    4125    public void setCreateEntities(Boolean create, boolean notify) {
    4126        this.createEntities = create;
    4127        if (notify) {
    4128            fireChangeEvent();
    4129        }
    4130    }
    4131
    4132}