    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
    095    package org.jfree.chart.renderer;
    096
    097    import java.awt.BasicStroke;
    098    import java.awt.Color;
    099    import java.awt.Font;
    100    import java.awt.Paint;
    101    import java.awt.Shape;
    102    import java.awt.Stroke;
    103    import java.awt.geom.Point2D;
    104    import java.awt.geom.Rectangle2D;
    105    import java.io.IOException;
    106    import java.io.ObjectInputStream;
    107    import java.io.ObjectOutputStream;
    108    import java.io.Serializable;
    109    import java.util.Arrays;
    110    import java.util.EventListener;
    111    import java.util.List;
    112
    113    import javax.swing.event.EventListenerList;
    114
    115    import org.jfree.chart.HashUtilities;
    116    import org.jfree.chart.event.RendererChangeEvent;
    117    import org.jfree.chart.event.RendererChangeListener;
    118    import org.jfree.chart.labels.ItemLabelAnchor;
    119    import org.jfree.chart.labels.ItemLabelPosition;
    120    import org.jfree.chart.plot.DrawingSupplier;
    121    import org.jfree.chart.plot.PlotOrientation;
    122    import org.jfree.chart.title.LegendTitle;
    123    import org.jfree.io.SerialUtilities;
    124    import org.jfree.ui.TextAnchor;
    125    import org.jfree.util.BooleanList;
    126    import org.jfree.util.BooleanUtilities;
    127    import org.jfree.util.ObjectList;
    128    import org.jfree.util.ObjectUtilities;
    129    import org.jfree.util.PaintList;
    130    import org.jfree.util.PaintUtilities;
    131    import org.jfree.util.ShapeList;
    132    import org.jfree.util.ShapeUtilities;
    133    import 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     */
    141    public 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    }