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