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