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.