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