001    /* ===========================================================
002     * JFreeChart : a free chart library for the Java(tm) platform
003     * ===========================================================
004     *
005     * (C) Copyright 2000-2008, 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-2008, 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     */
086    
087    package org.jfree.chart.renderer;
088    
089    import java.awt.BasicStroke;
090    import java.awt.Color;
091    import java.awt.Font;
092    import java.awt.Paint;
093    import java.awt.Shape;
094    import java.awt.Stroke;
095    import java.awt.geom.Point2D;
096    import java.awt.geom.Rectangle2D;
097    import java.io.IOException;
098    import java.io.ObjectInputStream;
099    import java.io.ObjectOutputStream;
100    import java.io.Serializable;
101    import java.util.Arrays;
102    import java.util.EventListener;
103    import java.util.List;
104    
105    import javax.swing.event.EventListenerList;
106    
107    import org.jfree.chart.HashUtilities;
108    import org.jfree.chart.event.RendererChangeEvent;
109    import org.jfree.chart.event.RendererChangeListener;
110    import org.jfree.chart.labels.ItemLabelAnchor;
111    import org.jfree.chart.labels.ItemLabelPosition;
112    import org.jfree.chart.plot.DrawingSupplier;
113    import org.jfree.chart.plot.PlotOrientation;
114    import org.jfree.chart.title.LegendTitle;
115    import org.jfree.io.SerialUtilities;
116    import org.jfree.ui.TextAnchor;
117    import org.jfree.util.BooleanList;
118    import org.jfree.util.BooleanUtilities;
119    import org.jfree.util.ObjectList;
120    import org.jfree.util.ObjectUtilities;
121    import org.jfree.util.PaintList;
122    import org.jfree.util.PaintUtilities;
123    import org.jfree.util.ShapeList;
124    import org.jfree.util.ShapeUtilities;
125    import org.jfree.util.StrokeList;
126    
127    /**
128     * Base class providing common services for renderers.  Most methods that update
129     * attributes of the renderer will fire a {@link RendererChangeEvent}, which
130     * normally means the plot that owns the renderer will receive notification that
131     * the renderer has been changed (the plot will, in turn, notify the chart).
132     */
133    public abstract class AbstractRenderer implements Cloneable, Serializable {
134    
135        /** For serialization. */
136        private static final long serialVersionUID = -828267569428206075L;
137    
138        /** Zero represented as a <code>Double</code>. */
139        public static final Double ZERO = new Double(0.0);
140    
141        /** The default paint. */
142        public static final Paint DEFAULT_PAINT = Color.blue;
143    
144        /** The default outline paint. */
145        public static final Paint DEFAULT_OUTLINE_PAINT = Color.gray;
146    
147        /** The default stroke. */
148        public static final Stroke DEFAULT_STROKE = new BasicStroke(1.0f);
149    
150        /** The default outline stroke. */
151        public static final Stroke DEFAULT_OUTLINE_STROKE = new BasicStroke(1.0f);
152    
153        /** The default shape. */
154        public static final Shape DEFAULT_SHAPE
155                = new Rectangle2D.Double(-3.0, -3.0, 6.0, 6.0);
156    
157        /** The default value label font. */
158        public static final Font DEFAULT_VALUE_LABEL_FONT
159                = new Font("SansSerif", Font.PLAIN, 10);
160    
161        /** The default value label paint. */
162        public static final Paint DEFAULT_VALUE_LABEL_PAINT = Color.black;
163    
164        /**
165         * A flag that controls the visibility of ALL series.
166         *
167         * @deprecated This field is redundant, you can rely on seriesVisibleList
168         *     and baseSeriesVisible.  Deprecated from version 1.0.6 onwards.
169         */
170        private Boolean seriesVisible;
171    
172        /** A list of flags that controls whether or not each series is visible. */
173        private BooleanList seriesVisibleList;
174    
175        /** The default visibility for each series. */
176        private boolean baseSeriesVisible;
177    
178        /**
179         * A flag that controls the visibility of ALL series in the legend.
180         *
181         * @deprecated This field is redundant, you can rely on
182         *     seriesVisibleInLegendList and baseSeriesVisibleInLegend.
183         *     Deprecated from version 1.0.6 onwards.
184         */
185        private Boolean seriesVisibleInLegend;
186    
187        /**
188         * A list of flags that controls whether or not each series is visible in
189         * the legend.
190         */
191        private BooleanList seriesVisibleInLegendList;
192    
193        /** The default visibility for each series in the legend. */
194        private boolean baseSeriesVisibleInLegend;
195    
196        /**
197         * The paint for ALL series (optional).
198         *
199         * @deprecated This field is redundant, you can rely on paintList and
200         *     basePaint.  Deprecated from version 1.0.6 onwards.
201         */
202        private transient Paint paint;
203    
204        /** The paint list. */
205        private PaintList paintList;
206    
207        /**
208         * A flag that controls whether or not the paintList is auto-populated
209         * in the {@link #lookupSeriesPaint(int)} method.
210         *
211         * @since 1.0.6
212         */
213        private boolean autoPopulateSeriesPaint;
214    
215        /** The base paint. */
216        private transient Paint basePaint;
217    
218        /**
219         * The fill paint for ALL series (optional).
220         *
221         * @deprecated This field is redundant, you can rely on fillPaintList and
222         *     baseFillPaint.  Deprecated from version 1.0.6 onwards.
223         */
224        private transient Paint fillPaint;
225    
226        /** The fill paint list. */
227        private PaintList fillPaintList;
228    
229        /**
230         * A flag that controls whether or not the fillPaintList is auto-populated
231         * in the {@link #lookupSeriesFillPaint(int)} method.
232         *
233         * @since 1.0.6
234         */
235        private boolean autoPopulateSeriesFillPaint;
236    
237        /** The base fill paint. */
238        private transient Paint baseFillPaint;
239    
240        /**
241         * The outline paint for ALL series (optional).
242         *
243         * @deprecated This field is redundant, you can rely on outlinePaintList
244         *         and baseOutlinePaint.  Deprecated from version 1.0.6 onwards.
245         */
246        private transient Paint outlinePaint;
247    
248        /** The outline paint list. */
249        private PaintList outlinePaintList;
250    
251        /**
252         * A flag that controls whether or not the outlinePaintList is
253         * auto-populated in the {@link #lookupSeriesOutlinePaint(int)} method.
254         *
255         * @since 1.0.6
256         */
257        private boolean autoPopulateSeriesOutlinePaint;
258    
259        /** The base outline paint. */
260        private transient Paint baseOutlinePaint;
261    
262        /**
263         * The stroke for ALL series (optional).
264         *
265         * @deprecated This field is redundant, you can rely on strokeList and
266         *     baseStroke.  Deprecated from version 1.0.6 onwards.
267         */
268        private transient Stroke stroke;
269    
270        /** The stroke list. */
271        private StrokeList strokeList;
272    
273        /**
274         * A flag that controls whether or not the strokeList is auto-populated
275         * in the {@link #lookupSeriesStroke(int)} method.
276         *
277         * @since 1.0.6
278         */
279        private boolean autoPopulateSeriesStroke;
280    
281        /** The base stroke. */
282        private transient Stroke baseStroke;
283    
284        /**
285         * The outline stroke for ALL series (optional).
286         *
287         * @deprecated This field is redundant, you can rely on strokeList and
288         *     baseStroke.  Deprecated from version 1.0.6 onwards.
289         */
290        private transient Stroke outlineStroke;
291    
292        /** The outline stroke list. */
293        private StrokeList outlineStrokeList;
294    
295        /** The base outline stroke. */
296        private transient Stroke baseOutlineStroke;
297    
298        /**
299         * A flag that controls whether or not the outlineStrokeList is
300         * auto-populated in the {@link #lookupSeriesOutlineStroke(int)} method.
301         *
302         * @since 1.0.6
303         */
304        private boolean autoPopulateSeriesOutlineStroke;
305    
306        /**
307         * The shape for ALL series (optional).
308         *
309         * @deprecated This field is redundant, you can rely on shapeList and
310         *     baseShape.  Deprecated from version 1.0.6 onwards.
311         */
312        private transient Shape shape;
313    
314        /** A shape list. */
315        private ShapeList shapeList;
316    
317        /**
318         * A flag that controls whether or not the shapeList is auto-populated
319         * in the {@link #lookupSeriesShape(int)} method.
320         *
321         * @since 1.0.6
322         */
323        private boolean autoPopulateSeriesShape;
324    
325        /** The base shape. */
326        private transient Shape baseShape;
327    
328        /**
329         * Visibility of the item labels for ALL series (optional).
330         *
331         * @deprecated This field is redundant, you can rely on
332         *     itemLabelsVisibleList and baseItemLabelsVisible.  Deprecated from
333         *     version 1.0.6 onwards.
334         */
335        private Boolean itemLabelsVisible;
336    
337        /** Visibility of the item labels PER series. */
338        private BooleanList itemLabelsVisibleList;
339    
340        /** The base item labels visible. */
341        private Boolean baseItemLabelsVisible;
342    
343        /**
344         * The item label font for ALL series (optional).
345         *
346         * @deprecated This field is redundant, you can rely on itemLabelFontList
347         *     and baseItemLabelFont.  Deprecated from version 1.0.6 onwards.
348         */
349        private Font itemLabelFont;
350    
351        /** The item label font list (one font per series). */
352        private ObjectList itemLabelFontList;
353    
354        /** The base item label font. */
355        private Font baseItemLabelFont;
356    
357        /**
358         * The item label paint for ALL series.
359         *
360         * @deprecated This field is redundant, you can rely on itemLabelPaintList
361         *     and baseItemLabelPaint.  Deprecated from version 1.0.6 onwards.
362         */
363        private transient Paint itemLabelPaint;
364    
365        /** The item label paint list (one paint per series). */
366        private PaintList itemLabelPaintList;
367    
368        /** The base item label paint. */
369        private transient Paint baseItemLabelPaint;
370    
371        /**
372         * The positive item label position for ALL series (optional).
373         *
374         * @deprecated This field is redundant, you can rely on the
375         *     positiveItemLabelPositionList and basePositiveItemLabelPosition
376         *     fields.  Deprecated from version 1.0.6 onwards.
377         */
378        private ItemLabelPosition positiveItemLabelPosition;
379    
380        /** The positive item label position (per series). */
381        private ObjectList positiveItemLabelPositionList;
382    
383        /** The fallback positive item label position. */
384        private ItemLabelPosition basePositiveItemLabelPosition;
385    
386        /**
387         * The negative item label position for ALL series (optional).
388         *
389         * @deprecated This field is redundant, you can rely on the
390         *     negativeItemLabelPositionList and baseNegativeItemLabelPosition
391         *     fields.  Deprecated from version 1.0.6 onwards.
392         */
393        private ItemLabelPosition negativeItemLabelPosition;
394    
395        /** The negative item label position (per series). */
396        private ObjectList negativeItemLabelPositionList;
397    
398        /** The fallback negative item label position. */
399        private ItemLabelPosition baseNegativeItemLabelPosition;
400    
401        /** The item label anchor offset. */
402        private double itemLabelAnchorOffset = 2.0;
403    
404        /**
405         * A flag that controls whether or not entities are generated for
406         * ALL series (optional).
407         *
408         * @deprecated This field is redundant, you can rely on the
409         *     createEntitiesList and baseCreateEntities fields.  Deprecated from
410         *     version 1.0.6 onwards.
411         */
412        private Boolean createEntities;
413    
414        /**
415         * Flags that control whether or not entities are generated for each
416         * series.  This will be overridden by 'createEntities'.
417         */
418        private BooleanList createEntitiesList;
419    
420        /**
421         * The default flag that controls whether or not entities are generated.
422         * This flag is used when both the above flags return null.
423         */
424        private boolean baseCreateEntities;
425    
426        /**
427         * The per-series legend shape settings.
428         *
429         * @since 1.0.11
430         */
431        private ShapeList legendShape;
432    
433        /**
434         * The base shape for legend items.  If this is <code>null</code>, the
435         * series shape will be used.
436         *
437         * @since 1.0.11
438         */
439        private transient Shape baseLegendShape;
440    
441        /**
442         * The per-series legend text font.
443         *
444         * @since 1.0.11
445         */
446        private ObjectList legendTextFont;
447    
448        /**
449         * The base legend font.
450         *
451         * @since 1.0.11
452         */
453        private Font baseLegendTextFont;
454    
455        /**
456         * The per series legend text paint settings.
457         *
458         * @since 1.0.11
459         */
460        private PaintList legendTextPaint;
461    
462        /**
463         * The default paint for the legend text items (if this is
464         * <code>null</code>, the {@link LegendTitle} class will determine the
465         * text paint to use.
466         *
467         * @since 1.0.11
468         */
469        private transient Paint baseLegendTextPaint;
470    
471        /** Storage for registered change listeners. */
472        private transient EventListenerList listenerList;
473    
474        /** An event for re-use. */
475        private transient RendererChangeEvent event;
476    
477        /**
478         * Default constructor.
479         */
480        public AbstractRenderer() {
481    
482            this.seriesVisible = null;
483            this.seriesVisibleList = new BooleanList();
484            this.baseSeriesVisible = true;
485    
486            this.seriesVisibleInLegend = null;
487            this.seriesVisibleInLegendList = new BooleanList();
488            this.baseSeriesVisibleInLegend = true;
489    
490            this.paint = null;
491            this.paintList = new PaintList();
492            this.basePaint = DEFAULT_PAINT;
493            this.autoPopulateSeriesPaint = true;
494    
495            this.fillPaint = null;
496            this.fillPaintList = new PaintList();
497            this.baseFillPaint = Color.white;
498            this.autoPopulateSeriesFillPaint = false;
499    
500            this.outlinePaint = null;
501            this.outlinePaintList = new PaintList();
502            this.baseOutlinePaint = DEFAULT_OUTLINE_PAINT;
503            this.autoPopulateSeriesOutlinePaint = false;
504    
505            this.stroke = null;
506            this.strokeList = new StrokeList();
507            this.baseStroke = DEFAULT_STROKE;
508            this.autoPopulateSeriesStroke = true;
509    
510            this.outlineStroke = null;
511            this.outlineStrokeList = new StrokeList();
512            this.baseOutlineStroke = DEFAULT_OUTLINE_STROKE;
513            this.autoPopulateSeriesOutlineStroke = false;
514    
515            this.shape = null;
516            this.shapeList = new ShapeList();
517            this.baseShape = DEFAULT_SHAPE;
518            this.autoPopulateSeriesShape = true;
519    
520            this.itemLabelsVisible = null;
521            this.itemLabelsVisibleList = new BooleanList();
522            this.baseItemLabelsVisible = Boolean.FALSE;
523    
524            this.itemLabelFont = null;
525            this.itemLabelFontList = new ObjectList();
526            this.baseItemLabelFont = new Font("SansSerif", Font.PLAIN, 10);
527    
528            this.itemLabelPaint = null;
529            this.itemLabelPaintList = new PaintList();
530            this.baseItemLabelPaint = Color.black;
531    
532            this.positiveItemLabelPosition = null;
533            this.positiveItemLabelPositionList = new ObjectList();
534            this.basePositiveItemLabelPosition = new ItemLabelPosition(
535                    ItemLabelAnchor.OUTSIDE12, TextAnchor.BOTTOM_CENTER);
536    
537            this.negativeItemLabelPosition = null;
538            this.negativeItemLabelPositionList = new ObjectList();
539            this.baseNegativeItemLabelPosition = new ItemLabelPosition(
540                    ItemLabelAnchor.OUTSIDE6, TextAnchor.TOP_CENTER);
541    
542            this.createEntities = null;
543            this.createEntitiesList = new BooleanList();
544            this.baseCreateEntities = true;
545    
546            this.legendShape = new ShapeList();
547            this.baseLegendShape = null;
548    
549            this.legendTextFont = new ObjectList();
550            this.baseLegendTextFont = null;
551    
552            this.legendTextPaint = new PaintList();
553            this.baseLegendTextPaint = null;
554    
555            this.listenerList = new EventListenerList();
556    
557        }
558    
559        /**
560         * Returns the drawing supplier from the plot.
561         *
562         * @return The drawing supplier.
563         */
564        public abstract DrawingSupplier getDrawingSupplier();
565    
566        // SERIES VISIBLE (not yet respected by all renderers)
567    
568        /**
569         * Returns a boolean that indicates whether or not the specified item
570         * should be drawn (this is typically used to hide an entire series).
571         *
572         * @param series  the series index.
573         * @param item  the item index.
574         *
575         * @return A boolean.
576         */
577        public boolean getItemVisible(int series, int item) {
578            return isSeriesVisible(series);
579        }
580    
581        /**
582         * Returns a boolean that indicates whether or not the specified series
583         * should be drawn.
584         *
585         * @param series  the series index.
586         *
587         * @return A boolean.
588         */
589        public boolean isSeriesVisible(int series) {
590            boolean result = this.baseSeriesVisible;
591            if (this.seriesVisible != null) {
592                result = this.seriesVisible.booleanValue();
593            }
594            else {
595                Boolean b = this.seriesVisibleList.getBoolean(series);
596                if (b != null) {
597                    result = b.booleanValue();
598                }
599            }
600            return result;
601        }
602    
603        /**
604         * Returns the flag that controls the visibility of ALL series.  This flag
605         * overrides the per series and default settings - you must set it to
606         * <code>null</code> if you want the other settings to apply.
607         *
608         * @return The flag (possibly <code>null</code>).
609         *
610         * @see #setSeriesVisible(Boolean)
611         *
612         * @deprecated This method should no longer be used (as of version 1.0.6).
613         *     It is sufficient to rely on {@link #getSeriesVisible(int)} and
614         *     {@link #getBaseSeriesVisible()}.
615         */
616        public Boolean getSeriesVisible() {
617            return this.seriesVisible;
618        }
619    
620        /**
621         * Sets the flag that controls the visibility of ALL series and sends a
622         * {@link RendererChangeEvent} to all registered listeners.  This flag
623         * overrides the per series and default settings - you must set it to
624         * <code>null</code> if you want the other settings to apply.
625         *
626         * @param visible  the flag (<code>null</code> permitted).
627         *
628         * @see #getSeriesVisible()
629         *
630         * @deprecated This method should no longer be used (as of version 1.0.6).
631         *     It is sufficient to rely on {@link #setSeriesVisible(int, Boolean)}
632         *     and {@link #setBaseSeriesVisible(boolean)}.
633         */
634        public void setSeriesVisible(Boolean visible) {
635             setSeriesVisible(visible, true);
636        }
637    
638        /**
639         * Sets the flag that controls the visibility of ALL series and sends a
640         * {@link RendererChangeEvent} to all registered listeners.  This flag
641         * overrides the per series and default settings - you must set it to
642         * <code>null</code> if you want the other settings to apply.
643         *
644         * @param visible  the flag (<code>null</code> permitted).
645         * @param notify  notify listeners?
646         *
647         * @see #getSeriesVisible()
648         *
649         * @deprecated This method should no longer be used (as of version 1.0.6).
650         *     It is sufficient to rely on {@link #setSeriesVisible(int, Boolean)}
651         *     and {@link #setBaseSeriesVisible(boolean)}.
652         */
653        public void setSeriesVisible(Boolean visible, boolean notify) {
654            this.seriesVisible = visible;
655            if (notify) {
656                fireChangeEvent();
657            }
658        }
659    
660        /**
661         * Returns the flag that controls whether a series is visible.
662         *
663         * @param series  the series index (zero-based).
664         *
665         * @return The flag (possibly <code>null</code>).
666         *
667         * @see #setSeriesVisible(int, Boolean)
668         */
669        public Boolean getSeriesVisible(int series) {
670            return this.seriesVisibleList.getBoolean(series);
671        }
672    
673        /**
674         * Sets the flag that controls whether a series is visible and sends a
675         * {@link RendererChangeEvent} to all registered listeners.
676         *
677         * @param series  the series index (zero-based).
678         * @param visible  the flag (<code>null</code> permitted).
679         *
680         * @see #getSeriesVisible(int)
681         */
682        public void setSeriesVisible(int series, Boolean visible) {
683            setSeriesVisible(series, visible, true);
684        }
685    
686        /**
687         * Sets the flag that controls whether a series is visible and, if
688         * requested, sends a {@link RendererChangeEvent} to all registered
689         * listeners.
690         *
691         * @param series  the series index.
692         * @param visible  the flag (<code>null</code> permitted).
693         * @param notify  notify listeners?
694         *
695         * @see #getSeriesVisible(int)
696         */
697        public void setSeriesVisible(int series, Boolean visible, boolean notify) {
698            this.seriesVisibleList.setBoolean(series, visible);
699            if (notify) {
700                fireChangeEvent();
701            }
702        }
703    
704        /**
705         * Returns the base visibility for all series.
706         *
707         * @return The base visibility.
708         *
709         * @see #setBaseSeriesVisible(boolean)
710         */
711        public boolean getBaseSeriesVisible() {
712            return this.baseSeriesVisible;
713        }
714    
715        /**
716         * Sets the base visibility and sends a {@link RendererChangeEvent}
717         * to all registered listeners.
718         *
719         * @param visible  the flag.
720         *
721         * @see #getBaseSeriesVisible()
722         */
723        public void setBaseSeriesVisible(boolean visible) {
724            // defer argument checking...
725            setBaseSeriesVisible(visible, true);
726        }
727    
728        /**
729         * Sets the base visibility and, if requested, sends
730         * a {@link RendererChangeEvent} to all registered listeners.
731         *
732         * @param visible  the visibility.
733         * @param notify  notify listeners?
734         *
735         * @see #getBaseSeriesVisible()
736         */
737        public void setBaseSeriesVisible(boolean visible, boolean notify) {
738            this.baseSeriesVisible = visible;
739            if (notify) {
740                fireChangeEvent();
741            }
742        }
743    
744        // SERIES VISIBLE IN LEGEND (not yet respected by all renderers)
745    
746        /**
747         * Returns <code>true</code> if the series should be shown in the legend,
748         * and <code>false</code> otherwise.
749         *
750         * @param series  the series index.
751         *
752         * @return A boolean.
753         */
754        public boolean isSeriesVisibleInLegend(int series) {
755            boolean result = this.baseSeriesVisibleInLegend;
756            if (this.seriesVisibleInLegend != null) {
757                result = this.seriesVisibleInLegend.booleanValue();
758            }
759            else {
760                Boolean b = this.seriesVisibleInLegendList.getBoolean(series);
761                if (b != null) {
762                    result = b.booleanValue();
763                }
764            }
765            return result;
766        }
767    
768        /**
769         * Returns the flag that controls the visibility of ALL series in the
770         * legend.  This flag overrides the per series and default settings - you
771         * must set it to <code>null</code> if you want the other settings to
772         * apply.
773         *
774         * @return The flag (possibly <code>null</code>).
775         *
776         * @see #setSeriesVisibleInLegend(Boolean)
777         *
778         * @deprecated This method should no longer be used (as of version 1.0.6).
779         *     It is sufficient to rely on {@link #getSeriesVisibleInLegend(int)}
780         *     and {@link #getBaseSeriesVisibleInLegend()}.
781         */
782        public Boolean getSeriesVisibleInLegend() {
783            return this.seriesVisibleInLegend;
784        }
785    
786        /**
787         * Sets the flag that controls the visibility of ALL series in the legend
788         * and sends a {@link RendererChangeEvent} to all registered listeners.
789         * This flag overrides the per series and default settings - you must set
790         * it to <code>null</code> if you want the other settings to apply.
791         *
792         * @param visible  the flag (<code>null</code> permitted).
793         *
794         * @see #getSeriesVisibleInLegend()
795         *
796         * @deprecated This method should no longer be used (as of version 1.0.6).
797         *     It is sufficient to rely on {@link #setSeriesVisibleInLegend(int,
798         *     Boolean)} and {@link #setBaseSeriesVisibleInLegend(boolean)}.
799         */
800        public void setSeriesVisibleInLegend(Boolean visible) {
801             setSeriesVisibleInLegend(visible, true);
802        }
803    
804        /**
805         * Sets the flag that controls the visibility of ALL series in the legend
806         * and sends a {@link RendererChangeEvent} to all registered listeners.
807         * This flag overrides the per series and default settings - you must set
808         * it to <code>null</code> if you want the other settings to apply.
809         *
810         * @param visible  the flag (<code>null</code> permitted).
811         * @param notify  notify listeners?
812         *
813         * @see #getSeriesVisibleInLegend()
814         *
815         * @deprecated This method should no longer be used (as of version 1.0.6).
816         *     It is sufficient to rely on {@link #setSeriesVisibleInLegend(int,
817         *     Boolean, boolean)} and {@link #setBaseSeriesVisibleInLegend(boolean,
818         *     boolean)}.
819         */
820        public void setSeriesVisibleInLegend(Boolean visible, boolean notify) {
821            this.seriesVisibleInLegend = visible;
822            if (notify) {
823                fireChangeEvent();
824            }
825        }
826    
827        /**
828         * Returns the flag that controls whether a series is visible in the
829         * legend.  This method returns only the "per series" settings - to
830         * incorporate the override and base settings as well, you need to use the
831         * {@link #isSeriesVisibleInLegend(int)} method.
832         *
833         * @param series  the series index (zero-based).
834         *
835         * @return The flag (possibly <code>null</code>).
836         *
837         * @see #setSeriesVisibleInLegend(int, Boolean)
838         */
839        public Boolean getSeriesVisibleInLegend(int series) {
840            return this.seriesVisibleInLegendList.getBoolean(series);
841        }
842    
843        /**
844         * Sets the flag that controls whether a series is visible in the legend
845         * and sends a {@link RendererChangeEvent} to all registered listeners.
846         *
847         * @param series  the series index (zero-based).
848         * @param visible  the flag (<code>null</code> permitted).
849         *
850         * @see #getSeriesVisibleInLegend(int)
851         */
852        public void setSeriesVisibleInLegend(int series, Boolean visible) {
853            setSeriesVisibleInLegend(series, visible, true);
854        }
855    
856        /**
857         * Sets the flag that controls whether a series is visible in the legend
858         * and, if requested, sends a {@link RendererChangeEvent} to all registered
859         * listeners.
860         *
861         * @param series  the series index.
862         * @param visible  the flag (<code>null</code> permitted).
863         * @param notify  notify listeners?
864         *
865         * @see #getSeriesVisibleInLegend(int)
866         */
867        public void setSeriesVisibleInLegend(int series, Boolean visible,
868                                             boolean notify) {
869            this.seriesVisibleInLegendList.setBoolean(series, visible);
870            if (notify) {
871                fireChangeEvent();
872            }
873        }
874    
875        /**
876         * Returns the base visibility in the legend for all series.
877         *
878         * @return The base visibility.
879         *
880         * @see #setBaseSeriesVisibleInLegend(boolean)
881         */
882        public boolean getBaseSeriesVisibleInLegend() {
883            return this.baseSeriesVisibleInLegend;
884        }
885    
886        /**
887         * Sets the base visibility in the legend and sends a
888         * {@link RendererChangeEvent} to all registered listeners.
889         *
890         * @param visible  the flag.
891         *
892         * @see #getBaseSeriesVisibleInLegend()
893         */
894        public void setBaseSeriesVisibleInLegend(boolean visible) {
895            // defer argument checking...
896            setBaseSeriesVisibleInLegend(visible, true);
897        }
898    
899        /**
900         * Sets the base visibility in the legend and, if requested, sends
901         * a {@link RendererChangeEvent} to all registered listeners.
902         *
903         * @param visible  the visibility.
904         * @param notify  notify listeners?
905         *
906         * @see #getBaseSeriesVisibleInLegend()
907         */
908        public void setBaseSeriesVisibleInLegend(boolean visible, boolean notify) {
909            this.baseSeriesVisibleInLegend = visible;
910            if (notify) {
911                fireChangeEvent();
912            }
913        }
914    
915        // PAINT
916    
917        /**
918         * Returns the paint used to fill data items as they are drawn.
919         * <p>
920         * The default implementation passes control to the
921         * <code>lookupSeriesPaint()</code> method. You can override this method
922         * if you require different behaviour.
923         *
924         * @param row  the row (or series) index (zero-based).
925         * @param column  the column (or category) index (zero-based).
926         *
927         * @return The paint (never <code>null</code>).
928         */
929        public Paint getItemPaint(int row, int column) {
930            return lookupSeriesPaint(row);
931        }
932    
933        /**
934         * Returns the paint used to fill an item drawn by the renderer.
935         *
936         * @param series  the series index (zero-based).
937         *
938         * @return The paint (never <code>null</code>).
939         *
940         * @since 1.0.6
941         */
942        public Paint lookupSeriesPaint(int series) {
943    
944            // return the override, if there is one...
945            if (this.paint != null) {
946                return this.paint;
947            }
948    
949            // otherwise look up the paint list
950            Paint seriesPaint = getSeriesPaint(series);
951            if (seriesPaint == null && this.autoPopulateSeriesPaint) {
952                DrawingSupplier supplier = getDrawingSupplier();
953                if (supplier != null) {
954                    seriesPaint = supplier.getNextPaint();
955                    setSeriesPaint(series, seriesPaint, false);
956                }
957            }
958            if (seriesPaint == null) {
959                seriesPaint = this.basePaint;
960            }
961            return seriesPaint;
962    
963        }
964    
965        /**
966         * Sets the paint to be used for ALL series, and sends a
967         * {@link RendererChangeEvent} to all registered listeners.  If this is
968         * <code>null</code>, the renderer will use the paint for the series.
969         *
970         * @param paint  the paint (<code>null</code> permitted).
971         *
972         * @deprecated This method should no longer be used (as of version 1.0.6).
973         *     It is sufficient to rely on {@link #setSeriesPaint(int, Paint)} and
974         *     {@link #setBasePaint(Paint)}.
975         */
976        public void setPaint(Paint paint) {
977            setPaint(paint, true);
978        }
979    
980        /**
981         * Sets the paint to be used for all series and, if requested, sends a
982         * {@link RendererChangeEvent} to all registered listeners.
983         *
984         * @param paint  the paint (<code>null</code> permitted).
985         * @param notify  notify listeners?
986         *
987         * @deprecated This method should no longer be used (as of version 1.0.6).
988         *     It is sufficient to rely on {@link #setSeriesPaint(int, Paint,
989         *     boolean)} and {@link #setBasePaint(Paint, boolean)}.
990         */
991        public void setPaint(Paint paint, boolean notify) {
992            this.paint = paint;
993            if (notify) {
994                fireChangeEvent();
995            }
996        }
997    
998        /**
999         * Returns the paint used to fill an item drawn by the renderer.
1000         *
1001         * @param series  the series index (zero-based).
1002         *
1003         * @return The paint (possibly <code>null</code>).
1004         *
1005         * @see #setSeriesPaint(int, Paint)
1006         */
1007        public Paint getSeriesPaint(int series) {
1008            return this.paintList.getPaint(series);
1009        }
1010    
1011        /**
1012         * Sets the paint used for a series and sends a {@link RendererChangeEvent}
1013         * to all registered listeners.
1014         *
1015         * @param series  the series index (zero-based).
1016         * @param paint  the paint (<code>null</code> permitted).
1017         *
1018         * @see #getSeriesPaint(int)
1019         */
1020        public void setSeriesPaint(int series, Paint paint) {
1021            setSeriesPaint(series, paint, true);
1022        }
1023    
1024        /**
1025         * Sets the paint used for a series and, if requested, sends a
1026         * {@link RendererChangeEvent} to all registered listeners.
1027         *
1028         * @param series  the series index.
1029         * @param paint  the paint (<code>null</code> permitted).
1030         * @param notify  notify listeners?
1031         *
1032         * @see #getSeriesPaint(int)
1033         */
1034        public void setSeriesPaint(int series, Paint paint, boolean notify) {
1035            this.paintList.setPaint(series, paint);
1036            if (notify) {
1037                fireChangeEvent();
1038            }
1039        }
1040    
1041        /**
1042         * Clears the series paint settings for this renderer and, if requested,
1043         * sends a {@link RendererChangeEvent} to all registered listeners.
1044         *
1045         * @param notify  notify listeners?
1046         *
1047         * @since 1.0.11
1048         */
1049        public void clearSeriesPaints(boolean notify) {
1050            this.paintList.clear();
1051            if (notify) {
1052                fireChangeEvent();
1053            }
1054        }
1055    
1056        /**
1057         * Returns the base paint.
1058         *
1059         * @return The base paint (never <code>null</code>).
1060         *
1061         * @see #setBasePaint(Paint)
1062         */
1063        public Paint getBasePaint() {
1064            return this.basePaint;
1065        }
1066    
1067        /**
1068         * Sets the base paint and sends a {@link RendererChangeEvent} to all
1069         * registered listeners.
1070         *
1071         * @param paint  the paint (<code>null</code> not permitted).
1072         *
1073         * @see #getBasePaint()
1074         */
1075        public void setBasePaint(Paint paint) {
1076            // defer argument checking...
1077            setBasePaint(paint, true);
1078        }
1079    
1080        /**
1081         * Sets the base paint and, if requested, sends a
1082         * {@link RendererChangeEvent} to all registered listeners.
1083         *
1084         * @param paint  the paint (<code>null</code> not permitted).
1085         * @param notify  notify listeners?
1086         *
1087         * @see #getBasePaint()
1088         */
1089        public void setBasePaint(Paint paint, boolean notify) {
1090            this.basePaint = paint;
1091            if (notify) {
1092                fireChangeEvent();
1093            }
1094        }
1095    
1096        /**
1097         * Returns the flag that controls whether or not the series paint list is
1098         * automatically populated when {@link #lookupSeriesPaint(int)} is called.
1099         *
1100         * @return A boolean.
1101         *
1102         * @since 1.0.6
1103         *
1104         * @see #setAutoPopulateSeriesPaint(boolean)
1105         */
1106        public boolean getAutoPopulateSeriesPaint() {
1107            return this.autoPopulateSeriesPaint;
1108        }
1109    
1110        /**
1111         * Sets the flag that controls whether or not the series paint list is
1112         * automatically populated when {@link #lookupSeriesPaint(int)} is called.
1113         *
1114         * @param auto  the new flag value.
1115         *
1116         * @since 1.0.6
1117         *
1118         * @see #getAutoPopulateSeriesPaint()
1119         */
1120        public void setAutoPopulateSeriesPaint(boolean auto) {
1121            this.autoPopulateSeriesPaint = auto;
1122        }
1123    
1124        //// FILL PAINT //////////////////////////////////////////////////////////
1125    
1126        /**
1127         * Returns the paint used to fill data items as they are drawn.  The
1128         * default implementation passes control to the
1129         * {@link #lookupSeriesFillPaint(int)} method - you can override this
1130         * method if you require different behaviour.
1131         *
1132         * @param row  the row (or series) index (zero-based).
1133         * @param column  the column (or category) index (zero-based).
1134         *
1135         * @return The paint (never <code>null</code>).
1136         */
1137        public Paint getItemFillPaint(int row, int column) {
1138            return lookupSeriesFillPaint(row);
1139        }
1140    
1141        /**
1142         * Returns the paint used to fill an item drawn by the renderer.
1143         *
1144         * @param series  the series (zero-based index).
1145         *
1146         * @return The paint (never <code>null</code>).
1147         *
1148         * @since 1.0.6
1149         */
1150        public Paint lookupSeriesFillPaint(int series) {
1151    
1152            // return the override, if there is one...
1153            if (this.fillPaint != null) {
1154                return this.fillPaint;
1155            }
1156    
1157            // otherwise look up the paint table
1158            Paint seriesFillPaint = getSeriesFillPaint(series);
1159            if (seriesFillPaint == null && this.autoPopulateSeriesFillPaint) {
1160                DrawingSupplier supplier = getDrawingSupplier();
1161                if (supplier != null) {
1162                    seriesFillPaint = supplier.getNextFillPaint();
1163                    setSeriesFillPaint(series, seriesFillPaint, false);
1164                }
1165            }
1166            if (seriesFillPaint == null) {
1167                seriesFillPaint = this.baseFillPaint;
1168            }
1169            return seriesFillPaint;
1170    
1171        }
1172    
1173        /**
1174         * Returns the paint used to fill an item drawn by the renderer.
1175         *
1176         * @param series  the series (zero-based index).
1177         *
1178         * @return The paint (never <code>null</code>).
1179         *
1180         * @see #setSeriesFillPaint(int, Paint)
1181         */
1182        public Paint getSeriesFillPaint(int series) {
1183            return this.fillPaintList.getPaint(series);
1184        }
1185    
1186        /**
1187         * Sets the paint used for a series fill and sends a
1188         * {@link RendererChangeEvent} to all registered listeners.
1189         *
1190         * @param series  the series index (zero-based).
1191         * @param paint  the paint (<code>null</code> permitted).
1192         *
1193         * @see #getSeriesFillPaint(int)
1194         */
1195        public void setSeriesFillPaint(int series, Paint paint) {
1196            setSeriesFillPaint(series, paint, true);
1197        }
1198    
1199        /**
1200         * Sets the paint used to fill a series and, if requested,
1201         * sends a {@link RendererChangeEvent} to all registered listeners.
1202         *
1203         * @param series  the series index (zero-based).
1204         * @param paint  the paint (<code>null</code> permitted).
1205         * @param notify  notify listeners?
1206         *
1207         * @see #getSeriesFillPaint(int)
1208         */
1209        public void setSeriesFillPaint(int series, Paint paint, boolean notify) {
1210            this.fillPaintList.setPaint(series, paint);
1211            if (notify) {
1212                fireChangeEvent();
1213            }
1214        }
1215    
1216        /**
1217         * Sets the fill paint for ALL series (optional).
1218         *
1219         * @param paint  the paint (<code>null</code> permitted).
1220         *
1221         * @deprecated This method should no longer be used (as of version 1.0.6).
1222         *     It is sufficient to rely on {@link #setSeriesFillPaint(int, Paint)}
1223         *     and {@link #setBaseFillPaint(Paint)}.
1224         */
1225        public void setFillPaint(Paint paint) {
1226            setFillPaint(paint, true);
1227        }
1228    
1229        /**
1230         * Sets the fill paint for ALL series and, if requested, sends a
1231         * {@link RendererChangeEvent} to all registered listeners.
1232         *
1233         * @param paint  the paint (<code>null</code> permitted).
1234         * @param notify  notify listeners?
1235         *
1236         * @deprecated This method should no longer be used (as of version 1.0.6).
1237         *     It is sufficient to rely on {@link #setSeriesFillPaint(int, Paint,
1238         *     boolean)} and {@link #setBaseFillPaint(Paint, boolean)}.
1239         */
1240        public void setFillPaint(Paint paint, boolean notify) {
1241            this.fillPaint = paint;
1242            if (notify) {
1243                fireChangeEvent();
1244            }
1245        }
1246    
1247        /**
1248         * Returns the base fill paint.
1249         *
1250         * @return The paint (never <code>null</code>).
1251         *
1252         * @see #setBaseFillPaint(Paint)
1253         */
1254        public Paint getBaseFillPaint() {
1255            return this.baseFillPaint;
1256        }
1257    
1258        /**
1259         * Sets the base fill paint and sends a {@link RendererChangeEvent} to
1260         * all registered listeners.
1261         *
1262         * @param paint  the paint (<code>null</code> not permitted).
1263         *
1264         * @see #getBaseFillPaint()
1265         */
1266        public void setBaseFillPaint(Paint paint) {
1267            // defer argument checking...
1268            setBaseFillPaint(paint, true);
1269        }
1270    
1271        /**
1272         * Sets the base fill paint and, if requested, sends a
1273         * {@link RendererChangeEvent} to all registered listeners.
1274         *
1275         * @param paint  the paint (<code>null</code> not permitted).
1276         * @param notify  notify listeners?
1277         *
1278         * @see #getBaseFillPaint()
1279         */
1280        public void setBaseFillPaint(Paint paint, boolean notify) {
1281            if (paint == null) {
1282                throw new IllegalArgumentException("Null 'paint' argument.");
1283            }
1284            this.baseFillPaint = paint;
1285            if (notify) {
1286                fireChangeEvent();
1287            }
1288        }
1289    
1290        /**
1291         * Returns the flag that controls whether or not the series fill paint list
1292         * is automatically populated when {@link #lookupSeriesFillPaint(int)} is
1293         * called.
1294         *
1295         * @return A boolean.
1296         *
1297         * @since 1.0.6
1298         *
1299         * @see #setAutoPopulateSeriesFillPaint(boolean)
1300         */
1301        public boolean getAutoPopulateSeriesFillPaint() {
1302            return this.autoPopulateSeriesFillPaint;
1303        }
1304    
1305        /**
1306         * Sets the flag that controls whether or not the series fill paint list is
1307         * automatically populated when {@link #lookupSeriesFillPaint(int)} is
1308         * called.
1309         *
1310         * @param auto  the new flag value.
1311         *
1312         * @since 1.0.6
1313         *
1314         * @see #getAutoPopulateSeriesFillPaint()
1315         */
1316        public void setAutoPopulateSeriesFillPaint(boolean auto) {
1317            this.autoPopulateSeriesFillPaint = auto;
1318        }
1319    
1320        // OUTLINE PAINT //////////////////////////////////////////////////////////
1321    
1322        /**
1323         * Returns the paint used to outline data items as they are drawn.
1324         * <p>
1325         * The default implementation passes control to the
1326         * {@link #lookupSeriesOutlinePaint} method.  You can override this method
1327         * if you require different behaviour.
1328         *
1329         * @param row  the row (or series) index (zero-based).
1330         * @param column  the column (or category) index (zero-based).
1331         *
1332         * @return The paint (never <code>null</code>).
1333         */
1334        public Paint getItemOutlinePaint(int row, int column) {
1335            return lookupSeriesOutlinePaint(row);
1336        }
1337    
1338        /**
1339         * Returns the paint used to outline an item drawn by the renderer.
1340         *
1341         * @param series  the series (zero-based index).
1342         *
1343         * @return The paint (never <code>null</code>).
1344         *
1345         * @since 1.0.6
1346         */
1347        public Paint lookupSeriesOutlinePaint(int series) {
1348    
1349            // return the override, if there is one...
1350            if (this.outlinePaint != null) {
1351                return this.outlinePaint;
1352            }
1353    
1354            // otherwise look up the paint table
1355            Paint seriesOutlinePaint = getSeriesOutlinePaint(series);
1356            if (seriesOutlinePaint == null && this.autoPopulateSeriesOutlinePaint) {
1357                DrawingSupplier supplier = getDrawingSupplier();
1358                if (supplier != null) {
1359                    seriesOutlinePaint = supplier.getNextOutlinePaint();
1360                    setSeriesOutlinePaint(series, seriesOutlinePaint, false);
1361                }
1362            }
1363            if (seriesOutlinePaint == null) {
1364                seriesOutlinePaint = this.baseOutlinePaint;
1365            }
1366            return seriesOutlinePaint;
1367    
1368        }
1369    
1370        /**
1371         * Returns the paint used to outline an item drawn by the renderer.
1372         *
1373         * @param series  the series (zero-based index).
1374         *
1375         * @return The paint (possibly <code>null</code>).
1376         *
1377         * @see #setSeriesOutlinePaint(int, Paint)
1378         */
1379        public Paint getSeriesOutlinePaint(int series) {
1380            return this.outlinePaintList.getPaint(series);
1381        }
1382    
1383        /**
1384         * Sets the paint used for a series outline and sends a
1385         * {@link RendererChangeEvent} to all registered listeners.
1386         *
1387         * @param series  the series index (zero-based).
1388         * @param paint  the paint (<code>null</code> permitted).
1389         *
1390         * @see #getSeriesOutlinePaint(int)
1391         */
1392        public void setSeriesOutlinePaint(int series, Paint paint) {
1393            setSeriesOutlinePaint(series, paint, true);
1394        }
1395    
1396        /**
1397         * Sets the paint used to draw the outline for a series and, if requested,
1398         * sends a {@link RendererChangeEvent} to all registered listeners.
1399         *
1400         * @param series  the series index (zero-based).
1401         * @param paint  the paint (<code>null</code> permitted).
1402         * @param notify  notify listeners?
1403         *
1404         * @see #getSeriesOutlinePaint(int)
1405         */
1406        public void setSeriesOutlinePaint(int series, Paint paint, boolean notify) {
1407            this.outlinePaintList.setPaint(series, paint);
1408            if (notify) {
1409                fireChangeEvent();
1410            }
1411        }
1412    
1413        /**
1414         * Sets the outline paint for ALL series (optional) and sends a
1415         * {@link RendererChangeEvent} to all registered listeners.
1416         *
1417         * @param paint  the paint (<code>null</code> permitted).
1418         *
1419         * @deprecated This method should no longer be used (as of version 1.0.6).
1420         *     It is sufficient to rely on {@link #setSeriesOutlinePaint(int,
1421         *     Paint)} and {@link #setBaseOutlinePaint(Paint)}.
1422         */
1423        public void setOutlinePaint(Paint paint) {
1424            setOutlinePaint(paint, true);
1425        }
1426    
1427        /**
1428         * Sets the outline paint for ALL series and, if requested, sends a
1429         * {@link RendererChangeEvent} to all registered listeners.
1430         *
1431         * @param paint  the paint (<code>null</code> permitted).
1432         * @param notify  notify listeners?
1433         *
1434         * @deprecated This method should no longer be used (as of version 1.0.6).
1435         *     It is sufficient to rely on {@link #setSeriesOutlinePaint(int,
1436         *     Paint, boole