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.9 2007/03/22 16:27:46 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 *
074 */
075
076 package org.jfree.chart.renderer;
077
078 import java.awt.BasicStroke;
079 import java.awt.Color;
080 import java.awt.Font;
081 import java.awt.Paint;
082 import java.awt.Shape;
083 import java.awt.Stroke;
084 import java.awt.geom.Point2D;
085 import java.awt.geom.Rectangle2D;
086 import java.io.IOException;
087 import java.io.ObjectInputStream;
088 import java.io.ObjectOutputStream;
089 import java.io.Serializable;
090 import java.util.Arrays;
091 import java.util.EventListener;
092 import java.util.List;
093
094 import javax.swing.event.EventListenerList;
095
096 import org.jfree.chart.event.RendererChangeEvent;
097 import org.jfree.chart.event.RendererChangeListener;
098 import org.jfree.chart.labels.ItemLabelAnchor;
099 import org.jfree.chart.labels.ItemLabelPosition;
100 import org.jfree.chart.plot.DrawingSupplier;
101 import org.jfree.chart.plot.PlotOrientation;
102 import org.jfree.io.SerialUtilities;
103 import org.jfree.ui.TextAnchor;
104 import org.jfree.util.BooleanList;
105 import org.jfree.util.BooleanUtilities;
106 import org.jfree.util.ObjectList;
107 import org.jfree.util.ObjectUtilities;
108 import org.jfree.util.PaintList;
109 import org.jfree.util.PaintUtilities;
110 import org.jfree.util.ShapeList;
111 import org.jfree.util.ShapeUtilities;
112 import org.jfree.util.StrokeList;
113
114 /**
115 * Base class providing common services for renderers. Most methods that update
116 * attributes of the renderer will fire a {@link RendererChangeEvent}, which
117 * normally means the plot that owns the renderer will receive notification that
118 * the renderer has been changed (the plot will, in turn, notify the chart).
119 */
120 public abstract class AbstractRenderer implements Cloneable, Serializable {
121
122 /** For serialization. */
123 private static final long serialVersionUID = -828267569428206075L;
124
125 /** Zero represented as a <code>Double</code>. */
126 public static final Double ZERO = new Double(0.0);
127
128 /** The default paint. */
129 public static final Paint DEFAULT_PAINT = Color.blue;
130
131 /** The default outline paint. */
132 public static final Paint DEFAULT_OUTLINE_PAINT = Color.gray;
133
134 /** The default stroke. */
135 public static final Stroke DEFAULT_STROKE = new BasicStroke(1.0f);
136
137 /** The default outline stroke. */
138 public static final Stroke DEFAULT_OUTLINE_STROKE = new BasicStroke(1.0f);
139
140 /** The default shape. */
141 public static final Shape DEFAULT_SHAPE
142 = new Rectangle2D.Double(-3.0, -3.0, 6.0, 6.0);
143
144 /** The default value label font. */
145 public static final Font DEFAULT_VALUE_LABEL_FONT
146 = new Font("SansSerif", Font.PLAIN, 10);
147
148 /** The default value label paint. */
149 public static final Paint DEFAULT_VALUE_LABEL_PAINT = Color.black;
150
151 /** A flag that controls the visibility of ALL series. */
152 private Boolean seriesVisible;
153
154 /** A list of flags that controls whether or not each series is visible. */
155 private BooleanList seriesVisibleList;
156
157 /** The default visibility for each series. */
158 private boolean baseSeriesVisible;
159
160 /** A flag that controls the visibility of ALL series in the legend. */
161 private Boolean seriesVisibleInLegend;
162
163 /**
164 * A list of flags that controls whether or not each series is visible in
165 * the legend.
166 */
167 private BooleanList seriesVisibleInLegendList;
168
169 /** The default visibility for each series in the legend. */
170 private boolean baseSeriesVisibleInLegend;
171
172 /** The paint for ALL series (optional). */
173 private transient Paint paint;
174
175 /** The paint list. */
176 private PaintList paintList;
177
178 /** The base paint. */
179 private transient Paint basePaint;
180
181 /** The fill paint for ALL series (optional). */
182 private transient Paint fillPaint;
183
184 /** The fill paint list. */
185 private PaintList fillPaintList;
186
187 /** The base fill paint. */
188 private transient Paint baseFillPaint;
189
190 /** The outline paint for ALL series (optional). */
191 private transient Paint outlinePaint;
192
193 /** The outline paint list. */
194 private PaintList outlinePaintList;
195
196 /** The base outline paint. */
197 private transient Paint baseOutlinePaint;
198
199 /** The stroke for ALL series (optional). */
200 private transient Stroke stroke;
201
202 /** The stroke list. */
203 private StrokeList strokeList;
204
205 /** The base stroke. */
206 private transient Stroke baseStroke;
207
208 /** The outline stroke for ALL series (optional). */
209 private transient Stroke outlineStroke;
210
211 /** The outline stroke list. */
212 private StrokeList outlineStrokeList;
213
214 /** The base outline stroke. */
215 private transient Stroke baseOutlineStroke;
216
217 /** The shape for ALL series (optional). */
218 private transient Shape shape;
219
220 /** A shape list. */
221 private ShapeList shapeList;
222
223 /** The base shape. */
224 private transient Shape baseShape;
225
226 /** Visibility of the item labels for ALL series (optional). */
227 private Boolean itemLabelsVisible;
228
229 /** Visibility of the item labels PER series. */
230 private BooleanList itemLabelsVisibleList;
231
232 /** The base item labels visible. */
233 private Boolean baseItemLabelsVisible;
234
235 /** The item label font for ALL series (optional). */
236 private Font itemLabelFont;
237
238 /** The item label font list (one font per series). */
239 private ObjectList itemLabelFontList;
240
241 /** The base item label font. */
242 private Font baseItemLabelFont;
243
244 /** The item label paint for ALL series. */
245 private transient Paint itemLabelPaint;
246
247 /** The item label paint list (one paint per series). */
248 private PaintList itemLabelPaintList;
249
250 /** The base item label paint. */
251 private transient Paint baseItemLabelPaint;
252
253 /** The positive item label position for ALL series (optional). */
254 private ItemLabelPosition positiveItemLabelPosition;
255
256 /** The positive item label position (per series). */
257 private ObjectList positiveItemLabelPositionList;
258
259 /** The fallback positive item label position. */
260 private ItemLabelPosition basePositiveItemLabelPosition;
261
262 /** The negative item label position for ALL series (optional). */
263 private ItemLabelPosition negativeItemLabelPosition;
264
265 /** The negative item label position (per series). */
266 private ObjectList negativeItemLabelPositionList;
267
268 /** The fallback negative item label position. */
269 private ItemLabelPosition baseNegativeItemLabelPosition;
270
271 /** The item label anchor offset. */
272 private double itemLabelAnchorOffset = 2.0;
273
274 /**
275 * A flag that controls whether or not entities are generated for
276 * ALL series (optional).
277 */
278 private Boolean createEntities;
279
280 /**
281 * Flags that control whether or not entities are generated for each
282 * series. This will be overridden by 'createEntities'.
283 */
284 private BooleanList createEntitiesList;
285
286 /**
287 * The default flag that controls whether or not entities are generated.
288 * This flag is used when both the above flags return null.
289 */
290 private boolean baseCreateEntities;
291
292 /** Storage for registered change listeners. */
293 private transient EventListenerList listenerList;
294
295 /** An event for re-use. */
296 private transient RendererChangeEvent event;
297
298 /**
299 * Default constructor.
300 */
301 public AbstractRenderer() {
302
303 this.seriesVisible = null;
304 this.seriesVisibleList = new BooleanList();
305 this.baseSeriesVisible = true;
306
307 this.seriesVisibleInLegend = null;
308 this.seriesVisibleInLegendList = new BooleanList();
309 this.baseSeriesVisibleInLegend = true;
310
311 this.paint = null;
312 this.paintList = new PaintList();
313 this.basePaint = DEFAULT_PAINT;
314
315 this.fillPaint = null;
316 this.fillPaintList = new PaintList();
317 this.baseFillPaint = Color.white;
318
319 this.outlinePaint = null;
320 this.outlinePaintList = new PaintList();
321 this.baseOutlinePaint = DEFAULT_OUTLINE_PAINT;
322
323 this.stroke = null;
324 this.strokeList = new StrokeList();
325 this.baseStroke = DEFAULT_STROKE;
326
327 this.outlineStroke = null;
328 this.outlineStrokeList = new StrokeList();
329 this.baseOutlineStroke = DEFAULT_OUTLINE_STROKE;
330
331 this.shape = null;
332 this.shapeList = new ShapeList();
333 this.baseShape = DEFAULT_SHAPE;
334
335 this.itemLabelsVisible = null;
336 this.itemLabelsVisibleList = new BooleanList();
337 this.baseItemLabelsVisible = Boolean.FALSE;
338
339 this.itemLabelFont = null;
340 this.itemLabelFontList = new ObjectList();
341 this.baseItemLabelFont = new Font("SansSerif", Font.PLAIN, 10);
342
343 this.itemLabelPaint = null;
344 this.itemLabelPaintList = new PaintList();
345 this.baseItemLabelPaint = Color.black;
346
347 this.positiveItemLabelPosition = null;
348 this.positiveItemLabelPositionList = new ObjectList();
349 this.basePositiveItemLabelPosition = new ItemLabelPosition(
350 ItemLabelAnchor.OUTSIDE12, TextAnchor.BOTTOM_CENTER);
351
352 this.negativeItemLabelPosition = null;
353 this.negativeItemLabelPositionList = new ObjectList();
354 this.baseNegativeItemLabelPosition = new ItemLabelPosition(
355 ItemLabelAnchor.OUTSIDE6, TextAnchor.TOP_CENTER);
356
357 this.createEntities = null;
358 this.createEntitiesList = new BooleanList();
359 this.baseCreateEntities = true;
360
361 this.listenerList = new EventListenerList();
362
363 }
364
365 /**
366 * Returns the drawing supplier from the plot.
367 *
368 * @return The drawing supplier.
369 */
370 public abstract DrawingSupplier getDrawingSupplier();
371
372 // SERIES VISIBLE (not yet respected by all renderers)
373
374 /**
375 * Returns a boolean that indicates whether or not the specified item
376 * should be drawn (this is typically used to hide an entire series).
377 *
378 * @param series the series index.
379 * @param item the item index.
380 *
381 * @return A boolean.
382 */
383 public boolean getItemVisible(int series, int item) {
384 return isSeriesVisible(series);
385 }
386
387 /**
388 * Returns a boolean that indicates whether or not the specified series
389 * should be drawn.
390 *
391 * @param series the series index.
392 *
393 * @return A boolean.
394 */
395 public boolean isSeriesVisible(int series) {
396 boolean result = this.baseSeriesVisible;
397 if (this.seriesVisible != null) {
398 result = this.seriesVisible.booleanValue();
399 }
400 else {
401 Boolean b = this.seriesVisibleList.getBoolean(series);
402 if (b != null) {
403 result = b.booleanValue();
404 }
405 }
406 return result;
407 }
408
409 /**
410 * Returns the flag that controls the visibility of ALL series. This flag
411 * overrides the per series and default settings - you must set it to
412 * <code>null</code> if you want the other settings to apply.
413 *
414 * @return The flag (possibly <code>null</code>).
415 *
416 * @see #setSeriesVisible(Boolean)
417 */
418 public Boolean getSeriesVisible() {
419 return this.seriesVisible;
420 }
421
422 /**
423 * Sets the flag that controls the visibility of ALL series and sends a
424 * {@link RendererChangeEvent} to all registered listeners. This flag
425 * overrides the per series and default settings - you must set it to
426 * <code>null</code> if you want the other settings to apply.
427 *
428 * @param visible the flag (<code>null</code> permitted).
429 *
430 * @see #getSeriesVisible()
431 */
432 public void setSeriesVisible(Boolean visible) {
433 setSeriesVisible(visible, true);
434 }
435
436 /**
437 * Sets the flag that controls the visibility of ALL series and sends a
438 * {@link RendererChangeEvent} to all registered listeners. This flag
439 * overrides the per series and default settings - you must set it to
440 * <code>null</code> if you want the other settings to apply.
441 *
442 * @param visible the flag (<code>null</code> permitted).
443 * @param notify notify listeners?
444 *
445 * @see #getSeriesVisible()
446 */
447 public void setSeriesVisible(Boolean visible, boolean notify) {
448 this.seriesVisible = visible;
449 if (notify) {
450 fireChangeEvent();
451 }
452 }
453
454 /**
455 * Returns the flag that controls whether a series is visible.
456 *
457 * @param series the series index (zero-based).
458 *
459 * @return The flag (possibly <code>null</code>).
460 *
461 * @see #setSeriesVisible(int, Boolean)
462 */
463 public Boolean getSeriesVisible(int series) {
464 return this.seriesVisibleList.getBoolean(series);
465 }
466
467 /**
468 * Sets the flag that controls whether a series is visible and sends a
469 * {@link RendererChangeEvent} to all registered listeners.
470 *
471 * @param series the series index (zero-based).
472 * @param visible the flag (<code>null</code> permitted).
473 *
474 * @see #getSeriesVisible(int)
475 */
476 public void setSeriesVisible(int series, Boolean visible) {
477 setSeriesVisible(series, visible, true);
478 }
479
480 /**
481 * Sets the flag that controls whether a series is visible and, if
482 * requested, sends a {@link RendererChangeEvent} to all registered
483 * listeners.
484 *
485 * @param series the series index.
486 * @param visible the flag (<code>null</code> permitted).
487 * @param notify notify listeners?
488 *
489 * @see #getSeriesVisible(int)
490 */
491 public void setSeriesVisible(int series, Boolean visible, boolean notify) {
492 this.seriesVisibleList.setBoolean(series, visible);
493 if (notify) {
494 fireChangeEvent();
495 }
496 }
497
498 /**
499 * Returns the base visibility for all series.
500 *
501 * @return The base visibility.
502 *
503 * @see #setBaseSeriesVisible(boolean)
504 */
505 public boolean getBaseSeriesVisible() {
506 return this.baseSeriesVisible;
507 }
508
509 /**
510 * Sets the base visibility and sends a {@link RendererChangeEvent}
511 * to all registered listeners.
512 *
513 * @param visible the flag.
514 *
515 * @see #getBaseSeriesVisible()
516 */
517 public void setBaseSeriesVisible(boolean visible) {
518 // defer argument checking...
519 setBaseSeriesVisible(visible, true);
520 }
521
522 /**
523 * Sets the base visibility and, if requested, sends
524 * a {@link RendererChangeEvent} to all registered listeners.
525 *
526 * @param visible the visibility.
527 * @param notify notify listeners?
528 *
529 * @see #getBaseSeriesVisible()
530 */
531 public void setBaseSeriesVisible(boolean visible, boolean notify) {
532 this.baseSeriesVisible = visible;
533 if (notify) {
534 fireChangeEvent();
535 }
536 }
537
538 // SERIES VISIBLE IN LEGEND (not yet respected by all renderers)
539
540 /**
541 * Returns <code>true</code> if the series should be shown in the legend,
542 * and <code>false</code> otherwise.
543 *
544 * @param series the series index.
545 *
546 * @return A boolean.
547 */
548 public boolean isSeriesVisibleInLegend(int series) {
549 boolean result = this.baseSeriesVisibleInLegend;
550 if (this.seriesVisibleInLegend != null) {
551 result = this.seriesVisibleInLegend.booleanValue();
552 }
553 else {
554 Boolean b = this.seriesVisibleInLegendList.getBoolean(series);
555 if (b != null) {
556 result = b.booleanValue();
557 }
558 }
559 return result;
560 }
561
562 /**
563 * Returns the flag that controls the visibility of ALL series in the
564 * legend. This flag overrides the per series and default settings - you
565 * must set it to <code>null</code> if you want the other settings to
566 * apply.
567 *
568 * @return The flag (possibly <code>null</code>).
569 *
570 * @see #setSeriesVisibleInLegend(Boolean)
571 */
572 public Boolean getSeriesVisibleInLegend() {
573 return this.seriesVisibleInLegend;
574 }
575
576 /**
577 * Sets the flag that controls the visibility of ALL series in the legend
578 * and sends a {@link RendererChangeEvent} to all registered listeners.
579 * This flag overrides the per series and default settings - you must set
580 * it to <code>null</code> if you want the other settings to apply.
581 *
582 * @param visible the flag (<code>null</code> permitted).
583 *
584 * @see #getSeriesVisibleInLegend()
585 */
586 public void setSeriesVisibleInLegend(Boolean visible) {
587 setSeriesVisibleInLegend(visible, true);
588 }
589
590 /**
591 * Sets the flag that controls the visibility of ALL series in the legend
592 * and sends a {@link RendererChangeEvent} to all registered listeners.
593 * This flag overrides the per series and default settings - you must set
594 * it to <code>null</code> if you want the other settings to apply.
595 *
596 * @param visible the flag (<code>null</code> permitted).
597 * @param notify notify listeners?
598 *
599 * @see #getSeriesVisibleInLegend()
600 */
601 public void setSeriesVisibleInLegend(Boolean visible, boolean notify) {
602 this.seriesVisibleInLegend = visible;
603 if (notify) {
604 fireChangeEvent();
605 }
606 }
607
608 /**
609 * Returns the flag that controls whether a series is visible in the
610 * legend. This method returns only the "per series" settings - to
611 * incorporate the override and base settings as well, you need to use the
612 * {@link #isSeriesVisibleInLegend(int)} method.
613 *
614 * @param series the series index (zero-based).
615 *
616 * @return The flag (possibly <code>null</code>).
617 *
618 * @see #setSeriesVisibleInLegend(int, Boolean)
619 */
620 public Boolean getSeriesVisibleInLegend(int series) {
621 return this.seriesVisibleInLegendList.getBoolean(series);
622 }
623
624 /**
625 * Sets the flag that controls whether a series is visible in the legend
626 * and sends a {@link RendererChangeEvent} to all registered listeners.
627 *
628 * @param series the series index (zero-based).
629 * @param visible the flag (<code>null</code> permitted).
630 *
631 * @see #getSeriesVisibleInLegend(int)
632 */
633 public void setSeriesVisibleInLegend(int series, Boolean visible) {
634 setSeriesVisibleInLegend(series, visible, true);
635 }
636
637 /**
638 * Sets the flag that controls whether a series is visible in the legend
639 * and, if requested, sends a {@link RendererChangeEvent} to all registered
640 * listeners.
641 *
642 * @param series the series index.
643 * @param visible the flag (<code>null</code> permitted).
644 * @param notify notify listeners?
645 *
646 * @see #getSeriesVisibleInLegend(int)
647 */
648 public void setSeriesVisibleInLegend(int series, Boolean visible,
649 boolean notify) {
650 this.seriesVisibleInLegendList.setBoolean(series, visible);
651 if (notify) {
652 fireChangeEvent();
653 }
654 }
655
656 /**
657 * Returns the base visibility in the legend for all series.
658 *
659 * @return The base visibility.
660 *
661 * @see #setBaseSeriesVisibleInLegend(boolean)
662 */
663 public boolean getBaseSeriesVisibleInLegend() {
664 return this.baseSeriesVisibleInLegend;
665 }
666
667 /**
668 * Sets the base visibility in the legend and sends a
669 * {@link RendererChangeEvent} to all registered listeners.
670 *
671 * @param visible the flag.
672 *
673 * @see #getSeriesVisibleInLegend()
674 */
675 public void setBaseSeriesVisibleInLegend(boolean visible) {
676 // defer argument checking...
677 setBaseSeriesVisibleInLegend(visible, true);
678 }
679
680 /**
681 * Sets the base visibility in the legend and, if requested, sends
682 * a {@link RendererChangeEvent} to all registered listeners.
683 *
684 * @param visible the visibility.
685 * @param notify notify listeners?
686 *
687 * @see #getSeriesVisibleInLegend()
688 */
689 public void setBaseSeriesVisibleInLegend(boolean visible, boolean notify) {
690 this.baseSeriesVisibleInLegend = visible;
691 if (notify) {
692 fireChangeEvent();
693 }
694 }
695
696 // PAINT
697
698 /**
699 * Returns the paint used to fill data items as they are drawn.
700 * <p>
701 * The default implementation passes control to the
702 * <code>getSeriesPaint</code> method. You can override this method if you
703 * require different behaviour.
704 *
705 * @param row the row (or series) index (zero-based).
706 * @param column the column (or category) index (zero-based).
707 *
708 * @return The paint (never <code>null</code>).
709 */
710 public Paint getItemPaint(int row, int column) {
711 return getSeriesPaint(row);
712 }
713
714 /**
715 * Returns the paint used to fill an item drawn by the renderer.
716 *
717 * @param series the series index (zero-based).
718 *
719 * @return The paint (never <code>null</code>).
720 */
721 public Paint getSeriesPaint(int series) {
722
723 // return the override, if there is one...
724 if (this.paint != null) {
725 return this.paint;
726 }
727
728 // otherwise look up the paint list
729 Paint seriesPaint = this.paintList.getPaint(series);
730 if (seriesPaint == null) {
731 DrawingSupplier supplier = getDrawingSupplier();
732 if (supplier != null) {
733 seriesPaint = supplier.getNextPaint();
734 this.paintList.setPaint(series, seriesPaint);
735 }
736 else {
737 seriesPaint = this.basePaint;
738 }
739 }
740 return seriesPaint;
741
742 }
743
744 /**
745 * Sets the paint to be used for ALL series, and sends a
746 * {@link RendererChangeEvent} to all registered listeners. If this is
747 * <code>null</code>, the renderer will use the paint for the series.
748 *
749 * @param paint the paint (<code>null</code> permitted).
750 */
751 public void setPaint(Paint paint) {
752 setPaint(paint, true);
753 }
754
755 /**
756 * Sets the paint to be used for all series and, if requested, sends a
757 * {@link RendererChangeEvent} to all registered listeners.
758 *
759 * @param paint the paint (<code>null</code> permitted).
760 * @param notify notify listeners?
761 */
762 public void setPaint(Paint paint, boolean notify) {
763 this.paint = paint;
764 if (notify) {
765 fireChangeEvent();
766 }
767 }
768
769 /**
770 * Sets the paint used for a series and sends a {@link RendererChangeEvent}
771 * to all registered listeners.
772 *
773 * @param series the series index (zero-based).
774 * @param paint the paint (<code>null</code> permitted).
775 */
776 public void setSeriesPaint(int series, Paint paint) {
777 setSeriesPaint(series, paint, true);
778 }
779
780 /**
781 * Sets the paint used for a series and, if requested, sends a
782 * {@link RendererChangeEvent} to all registered listeners.
783 *
784 * @param series the series index.
785 * @param paint the paint (<code>null</code> permitted).
786 * @param notify notify listeners?
787 */
788 public void setSeriesPaint(int series, Paint paint, boolean notify) {
789 this.paintList.setPaint(series, paint);
790 if (notify) {
791 fireChangeEvent();
792 }
793 }
794
795 /**
796 * Returns the base paint.
797 *
798 * @return The base paint (never <code>null</code>).
799 */
800 public Paint getBasePaint() {
801 return this.basePaint;
802 }
803
804 /**
805 * Sets the base paint and sends a {@link RendererChangeEvent} to all
806 * registered listeners.
807 *
808 * @param paint the paint (<code>null</code> not permitted).
809 */
810 public void setBasePaint(Paint paint) {
811 // defer argument checking...
812 setBasePaint(paint, true);
813 }
814
815 /**
816 * Sets the base paint and, if requested, sends a
817 * {@link RendererChangeEvent} to all registered listeners.
818 *
819 * @param paint the paint (<code>null</code> not permitted).
820 * @param notify notify listeners?
821 */
822 public void setBasePaint(Paint paint, boolean notify) {
823 this.basePaint = paint;
824 if (notify) {
825 fireChangeEvent();
826 }
827 }
828
829 //// FILL PAINT //////////////////////////////////////////////////////////
830
831 /**
832 * Returns the paint used to fill data items as they are drawn. The
833 * default implementation passes control to the
834 * {@link #getSeriesFillPaint(int)} method - you can override this method
835 * if you require different behaviour.
836 *
837 * @param row the row (or series) index (zero-based).
838 * @param column the column (or category) index (zero-based).
839 *
840 * @return The paint (never <code>null</code>).
841 */
842 public Paint getItemFillPaint(int row, int column) {
843 return getSeriesFillPaint(row);
844 }
845
846 /**
847 * Returns the paint used to fill an item drawn by the renderer.
848 *
849 * @param series the series (zero-based index).
850 *
851 * @return The paint (never <code>null</code>).
852 */
853 public Paint getSeriesFillPaint(int series) {
854
855 // return the override, if there is one...
856 if (this.fillPaint != null) {
857 return this.fillPaint;
858 }
859
860 // otherwise look up the paint table
861 Paint seriesFillPaint = this.fillPaintList.getPaint(series);
862 if (seriesFillPaint == null) {
863 seriesFillPaint = this.baseFillPaint;
864 }
865 return seriesFillPaint;
866
867 }
868
869 /**
870 * Sets the paint used for a series fill and sends a
871 * {@link RendererChangeEvent} to all registered listeners.
872 *
873 * @param series the series index (zero-based).
874 * @param paint the paint (<code>null</code> permitted).
875 */
876 public void setSeriesFillPaint(int series, Paint paint) {
877 setSeriesFillPaint(series, paint, true);
878 }
879
880 /**
881 * Sets the paint used to fill a series and, if requested,
882 * sends a {@link RendererChangeEvent} to all registered listeners.
883 *
884 * @param series the series index (zero-based).
885 * @param paint the paint (<code>null</code> permitted).
886 * @param notify notify listeners?
887 */
888 public void setSeriesFillPaint(int series, Paint paint, boolean notify) {
889 this.fillPaintList.setPaint(series, paint);
890 if (notify) {
891 fireChangeEvent();
892 }
893 }
894
895 /**
896 * Sets the fill paint for ALL series (optional).
897 *
898 * @param paint the paint (<code>null</code> permitted).
899 */
900 public void setFillPaint(Paint paint) {
901 setFillPaint(paint, true);
902 }
903
904 /**
905 * Sets the fill paint for ALL series and, if requested, sends a
906 * {@link RendererChangeEvent} to all registered listeners.
907 *
908 * @param paint the paint (<code>null</code> permitted).
909 * @param notify notify listeners?
910 */
911 public void setFillPaint(Paint paint, boolean notify) {
912 this.fillPaint = paint;
913 if (notify) {
914 fireChangeEvent();
915 }
916 }
917
918 /**
919 * Returns the base fill paint.
920 *
921 * @return The paint (never <code>null</code>).
922 */
923 public Paint getBaseFillPaint() {
924 return this.baseFillPaint;
925 }
926
927 /**
928 * Sets the base fill paint and sends a {@link RendererChangeEvent} to
929 * all registered listeners.
930 *
931 * @param paint the paint (<code>null</code> not permitted).
932 */
933 public void setBaseFillPaint(Paint paint) {
934 // defer argument checking...
935 setBaseFillPaint(paint, true);
936 }
937
938 /**
939 * Sets the base fill paint and, if requested, sends a
940 * {@link RendererChangeEvent} to all registered listeners.
941 *
942 * @param paint the paint (<code>null</code> not permitted).
943 * @param notify notify listeners?
944 */
945 public void setBaseFillPaint(Paint paint, boolean notify) {
946 if (paint == null) {
947 throw new IllegalArgumentException("Null 'paint' argument.");
948 }
949 this.baseFillPaint = paint;
950 if (notify) {
951 fireChangeEvent();
952 }
953 }
954
955 // OUTLINE PAINT //////////////////////////////////////////////////////////
956
957 /**
958 * Returns the paint used to outline data items as they are drawn.
959 * <p>
960 * The default implementation passes control to the getSeriesOutlinePaint
961 * method. You can override this method if you require different behaviour.
962 *
963 * @param row the row (or series) index (zero-based).
964 * @param column the column (or category) index (zero-based).
965 *
966 * @return The paint (never <code>null</code>).
967 */
968 public Paint getItemOutlinePaint(int row, int column) {
969 return getSeriesOutlinePaint(row);
970 }
971
972 /**
973 * Returns the paint used to outline an item drawn by the renderer.
974 *
975 * @param series the series (zero-based index).
976 *
977 * @return The paint (never <code>null</code>).
978 */
979 public Paint getSeriesOutlinePaint(int series) {
980
981 // return the override, if there is one...
982 if (this.outlinePaint != null) {
983 return this.outlinePaint;
984 }
985
986 // otherwise look up the paint table
987 Paint seriesOutlinePaint = this.outlinePaintList.getPaint(series);
988 if (seriesOutlinePaint == null) {
989 DrawingSupplier supplier = getDrawingSupplier();
990 if (supplier != null) {
991 seriesOutlinePaint = supplier.getNextOutlinePaint();
992 this.outlinePaintList.setPaint(series, seriesOutlinePaint);
993 }
994 else {
995 seriesOutlinePaint = this.baseOutlinePaint;
996 }
997 }
998 return seriesOutlinePaint;
999
1000 }
1001
1002 /**
1003 * Sets the paint used for a series outline and sends a
1004 * {@link RendererChangeEvent} to all registered listeners.
1005 *
1006 * @param series the series index (zero-based).
1007 * @param paint the paint (<code>null</code> permitted).
1008 */
1009 public void setSeriesOutlinePaint(int series, Paint paint) {
1010 setSeriesOutlinePaint(series, paint, true);
1011 }
1012
1013 /**
1014 * Sets the paint used to draw the outline for a series and, if requested,
1015 * sends a {@link RendererChangeEvent} to all registered listeners.
1016 *
1017 * @param series the series index (zero-based).
1018 * @param paint the paint (<code>null</code> permitted).
1019 * @param notify notify listeners?
1020 */
1021 public void setSeriesOutlinePaint(int series, Paint paint, boolean notify) {
1022 this.outlinePaintList.setPaint(series, paint);
1023 if (notify) {
1024 fireChangeEvent();
1025 }
1026 }
1027
1028 /**
1029 * Sets the outline paint for ALL series (optional).
1030 *
1031 * @param paint the paint (<code>null</code> permitted).
1032 */
1033 public void setOutlinePaint(Paint paint) {
1034 setOutlinePaint(paint, true);
1035 }
1036
1037 /**
1038 * Sets the outline paint for ALL series and, if requested, sends a
1039 * {@link RendererChangeEvent} to all registered listeners.
1040 *
1041 * @param paint the paint (<code>null</code> permitted).
1042 * @param notify notify listeners?
1043 */
1044 public void setOutlinePaint(Paint paint, boolean notify) {
1045 this.outlinePaint = paint;
1046 if (notify) {
1047 fireChangeEvent();
1048 }
1049 }
1050
1051 /**
1052 * Returns the base outline paint.
1053 *
1054 * @return The paint (never <code>null</code>).
1055 */
1056 public Paint getBaseOutlinePaint() {
1057 return this.baseOutlinePaint;
1058 }
1059
1060 /**
1061 * Sets the base outline paint and sends a {@link RendererChangeEvent} to
1062 * all registered listeners.
1063 *
1064 * @param paint the paint (<code>null</code> not permitted).
1065 */
1066 public void setBaseOutlinePaint(Paint paint) {
1067 // defer argument checking...
1068 setBaseOutlinePaint(paint, true);
1069 }
1070
1071 /**
1072 * Sets the base outline paint and, if requested, sends a
1073 * {@link RendererChangeEvent} to all registered listeners.
1074 *
1075 * @param paint the paint (<code>null</code> not permitted).
1076 * @param notify notify listeners?
1077 */
1078 public void setBaseOutlinePaint(Paint paint, boolean notify) {
1079 if (paint == null) {
1080 throw new IllegalArgumentException("Null 'paint' argument.");
1081 }
1082 this.baseOutlinePaint = paint;
1083 if (notify) {
1084 fireChangeEvent();
1085 }
1086 }
1087
1088 // STROKE
1089
1090 /**
1091 * Returns the stroke used to draw data items.
1092 * <p>
1093 * The default implementation passes control to the getSeriesStroke method.
1094 * You can override this method if you require different behaviour.
1095 *
1096 * @param row the row (or series) index (zero-based).
1097 * @param column the column (or category) index (zero-based).
1098 *
1099 * @return The stroke (never <code>null</code>).
1100 */
1101 public Stroke getItemStroke(int row, int column) {
1102 return getSeriesStroke(row);
1103 }
1104
1105 /**
1106 * Returns the stroke used to draw the items in a series.
1107 *
1108 * @param series the series (zero-based index).
1109 *
1110 * @return The stroke (never <code>null</code>).
1111 */
1112 public Stroke getSeriesStroke(int series) {
1113
1114 // return the override, if there is one...
1115 if (this.stroke != null) {
1116 return this.stroke;
1117 }
1118
1119 // otherwise look up the paint table
1120 Stroke result = this.strokeList.getStroke(series);
1121 if (result == null) {
1122 DrawingSupplier supplier = getDrawingSupplier();
1123 if (supplier != null) {
1124 result = supplier.getNextStroke();
1125 this.strokeList.setStroke(series, result);
1126 }
1127 else {
1128 result = this.baseStroke;
1129 }
1130 }
1131 return result;
1132
1133 }
1134
1135 /**
1136 * Sets the stroke for ALL series and sends a {@link RendererChangeEvent}
1137 * to all registered listeners.
1138 *
1139 * @param stroke the stroke (<code>null</code> permitted).
1140 */
1141 public void setStroke(Stroke stroke) {
1142 setStroke(stroke, true);
1143 }
1144
1145 /**
1146 * Sets the stroke for ALL series and, if requested, sends a
1147 * {@link RendererChangeEvent} to all registered listeners.
1148 *
1149 * @param stroke the stroke (<code>null</code> permitted).
1150 * @param notify notify listeners?
1151 */
1152 public void setStroke(Stroke stroke, boolean notify) {
1153 this.stroke = stroke;
1154 if (notify) {
1155 fireChangeEvent();
1156 }
1157 }
1158
1159 /**
1160 * Sets the stroke used for a series and sends a {@link RendererChangeEvent}
1161 * to all registered listeners.
1162 *
1163 * @param series the series index (zero-based).
1164 * @param stroke the stroke (<code>null</code> permitted).
1165 */
1166 public void setSeriesStroke(int series, Stroke stroke) {
1167 setSeriesStroke(series, stroke, true);
1168 }
1169
1170 /**
1171 * Sets the stroke for a series and, if requested, sends a
1172 * {@link RendererChangeEvent} to all registered listeners.
1173 *
1174 * @param series the series index (zero-based).
1175 * @param stroke the stroke (<code>null</code> permitted).
1176 * @param notify notify listeners?
1177 */
1178 public void setSeriesStroke(int series, Stroke stroke, boolean notify) {
1179 this.strokeList.setStroke(series, stroke);
1180 if (notify) {
1181 fireChangeEvent();
1182 }
1183 }
1184
1185 /**
1186 * Returns the base stroke.
1187 *
1188 * @return The base stroke (never <code>null</code>).
1189 */
1190 public Stroke getBaseStroke() {
1191 return this.baseStroke;
1192 }
1193
1194 /**
1195 * Sets the base stroke.
1196 *
1197 * @param stroke the stroke (<code>null</code> not permitted).
1198 */
1199 public void setBaseStroke(Stroke stroke) {
1200 // defer argument checking...
1201 setBaseStroke(stroke, true);
1202 }
1203
1204 /**
1205 * Sets the base stroke and, if requested, sends a
1206 * {@link RendererChangeEvent} to all registered listeners.
1207 *
1208 * @param stroke the stroke (<code>null</code> not permitted).
1209 * @param notify notify listeners?
1210 */
1211 public void setBaseStroke(Stroke stroke, boolean notify) {
1212 if (stroke == null) {
1213 throw new IllegalArgumentException("Null 'stroke' argument.");
1214 }
1215 this.baseStroke = stroke;
1216 if (notify) {
1217 fireChangeEvent();
1218 }
1219 }
1220
1221 // OUTLINE STROKE
1222
1223 /**
1224 * Returns the stroke used to outline data items. The default
1225 * implementation passes control to the {@link #getSeriesOutlineStroke(int)}
1226 * method. You can override this method if you require different behaviour.
1227 *
1228 * @param row the row (or series) index (zero-based).
1229 * @param column the column (or category) index (zero-based).
1230 *
1231 * @return The stroke (never <code>null</code>).
1232 */
1233 public Stroke getItemOutlineStroke(int row, int column) {
1234 return getSeriesOutlineStroke(row);
1235 }
1236
1237 /**
1238 * Returns the stroke used to outline the items in a series.
1239 *
1240 * @param series the series (zero-based index).
1241 *
1242 * @return The stroke (never <code>null</code>).
1243 */
1244 public Stroke getSeriesOutlineStroke(int series) {
1245
1246 // return the override, if there is one...
1247 if (this.outlineStroke != null) {
1248 return this.outlineStroke;
1249 }
1250
1251 // otherwise look up the stroke table
1252 Stroke result = this.outlineStrokeList.getStroke(series);
1253 if (result == null) {
1254 DrawingSupplier supplier = getDrawingSupplier();
1255 if (supplier != null) {
1256 result = supplier.getNextOutlineStroke();
1257 this.outlineStrokeList.setStroke(series, result);
1258 }
1259 else {
1260 result = this.baseOutlineStroke;
1261 }
1262 }
1263 return result;
1264
1265 }
1266
1267 /**
1268 * Sets the outline stroke for ALL series and sends a
1269 * {@link RendererChangeEvent} to all registered listeners.
1270 *
1271 * @param stroke the stroke (<code>null</code> permitted).
1272 */
1273 public void setOutlineStroke(Stroke stroke) {
1274 setOutlineStroke(stroke, true);
1275 }
1276
1277 /**
1278 * Sets the outline stroke for ALL series and, if requested, sends a
1279 * {@link RendererChangeEvent} to all registered listeners.
1280 *
1281 * @param stroke the stroke (<code>null</code> permitted).
1282 * @param notify notify listeners?
1283 */
1284 public void setOutlineStroke(Stroke stroke, boolean notify) {
1285 this.outlineStroke = stroke;
1286 if (notify) {
1287 fireChangeEvent();
1288 }
1289 }
1290
1291 /**
1292 * Sets the outline stroke used for a series and sends a
1293 * {@link RendererChangeEvent} to all registered listeners.
1294 *
1295 * @param series the series index (zero-based).
1296 * @param stroke the stroke (<code>null</code> permitted).
1297 */
1298 public void setSeriesOutlineStroke(int series, Stroke stroke) {
1299 setSeriesOutlineStroke(series, stroke, true);
1300 }
1301
1302 /**
1303 * Sets the outline stroke for a series and, if requested, sends a
1304 * {@link RendererChangeEvent} to all registered listeners.
1305 *
1306 * @param series the series index.
1307 * @param stroke the stroke (<code>null</code> permitted).
1308 * @param notify notify listeners?
1309 */
1310 public void setSeriesOutlineStroke(int series, Stroke stroke,
1311 boolean notify) {
1312 this.outlineStrokeList.setStroke(series, stroke);
1313 if (notify) {
1314 fireChangeEvent();
1315 }
1316 }
1317
1318 /**
1319 * Returns the base outline stroke.
1320 *
1321 * @return The stroke (never <code>null</code>).
1322 */
1323 public Stroke getBaseOutlineStroke() {
1324 return this.baseOutlineStroke;
1325 }
1326
1327 /**
1328 * Sets the base outline stroke and sends a {@link RendererChangeEvent} to
1329 * all registered listeners.
1330 *
1331 * @param stroke the stroke (<code>null</code> not permitted).
1332 */
1333 public void setBaseOutlineStroke(Stroke stroke) {
1334 setBaseOutlineStroke(stroke, true);
1335 }
1336
1337 /**
1338 * Sets the base outline stroke and, if requested, sends a
1339 * {@link RendererChangeEvent} to all registered listeners.
1340 *
1341 * @param stroke the stroke (<code>null</code> not permitted).
1342 * @param notify a flag that controls whether or not listeners are
1343 * notified.
1344 */
1345 public void setBaseOutlineStroke(Stroke stroke, boolean notify) {
1346 if (stroke == null) {
1347 throw new IllegalArgumentException("Null 'stroke' argument.");
1348 }
1349 this.baseOutlineStroke = stroke;
1350 if (notify) {
1351 fireChangeEvent();
1352 }
1353 }
1354
1355 // SHAPE
1356
1357 /**
1358 * Returns a shape used to represent a data item.
1359 * <p>
1360 * The default implementation passes control to the getSeriesShape method.
1361 * You can override this method if you require different behaviour.
1362 *
1363 * @param row the row (or series) index (zero-based).
1364 * @param column the column (or category) index (zero-based).
1365 *
1366 * @return The shape (never <code>null</code>).
1367 */
1368 public Shape getItemShape(int row, int column) {
1369 return getSeriesShape(row);
1370 }
1371
1372 /**
1373 * Returns a shape used to represent the items in a series.
1374 *
1375 * @param series the series (zero-based index).
1376 *
1377 * @return The shape (never <code>null</code>).
1378 */
1379 public Shape getSeriesShape(int series) {
1380
1381 // return the override, if there is one...
1382 if (this.shape != null) {
1383 return this.shape;
1384 }
1385
1386 // otherwise look up the shape list
1387 Shape result = this.shapeList.getShape(series);
1388 if (result == null) {
1389 DrawingSupplier supplier = getDrawingSupplier();
1390 if (supplier != null) {
1391 result = supplier.getNextShape();
1392 this.shapeList.setShape(series, result);
1393 }
1394 else {
1395 result = this.baseShape;
1396 }
1397 }
1398 return result;
1399
1400 }
1401
1402 /**
1403 * Sets the shape for ALL series (optional) and sends a
1404 * {@link RendererChangeEvent} to all registered listeners.
1405 *
1406 * @param shape the shape (<code>null</code> permitted).
1407 */
1408 public void setShape(Shape shape) {
1409 setShape(shape, true);
1410 }
1411
1412 /**
1413 * Sets the shape for ALL series and, if requested, sends a
1414 * {@link RendererChangeEvent} to all registered listeners.
1415 *
1416 * @param shape the shape (<code>null</code> permitted).
1417 * @param notify notify listeners?
1418 */
1419 public void setShape(Shape shape, boolean notify) {
1420 this.shape = shape;
1421 if (notify) {
1422 fireChangeEvent();
1423 }
1424 }
1425
1426 /**
1427 * Sets the shape used for a series and sends a {@link RendererChangeEvent}
1428 * to all registered listeners.
1429 *
1430 * @param series the series index (zero-based).
1431 * @param shape the shape (<code>null</code> permitted).
1432 */
1433 public void setSeriesShape(int series, Shape shape) {
1434 setSeriesShape(series, shape, true);
1435 }
1436
1437 /**
1438 * Sets the shape for a series and, if requested, sends a
1439 * {@link RendererChangeEvent} to all registered listeners.
1440 *
1441 * @param series the series index (zero based).
1442 * @param shape the shape (<code>null</code> permitted).
1443 * @param notify notify listeners?
1444 */
1445 public void setSeriesShape(int series, Shape shape, boolean notify) {
1446 this.shapeList.setShape(series, shape);
1447 if (notify) {
1448 fireChangeEvent();
1449 }
1450 }
1451
1452 /**
1453 * Returns the base shape.
1454 *
1455 * @return The shape (never <code>null</code>).
1456 */
1457 public Shape getBaseShape() {
1458 return this.baseShape;
1459 }
1460
1461 /**
1462 * Sets the base shape and sends a {@link RendererChangeEvent} to all
1463 * registered listeners.
1464 *
1465 * @param shape the shape (<code>null</code> not permitted).
1466 */
1467 public void setBaseShape(Shape shape) {
1468 // defer argument checking...
1469 setBaseShape(shape, true);
1470 }
1471
1472 /**
1473 * Sets the base shape and, if requested, sends a
1474 * {@link RendererChangeEvent} to all registered listeners.
1475 *
1476 * @param shape the shape (<code>null</code> not permitted).
1477 * @param notify notify listeners?
1478 */
1479 public void setBaseShape(Shape shape, boolean notify) {
1480 if (shape == null) {
1481 throw new IllegalArgumentException("Null 'shape' argument.");
1482 }
1483 this.baseShape = shape;
1484 if (notify) {
1485 fireChangeEvent();
1486 }
1487 }
1488
1489 // ITEM LABEL VISIBILITY...
1490
1491 /**
1492 * Returns <code>true</code> if an item label is visible, and
1493 * <code>false</code> otherwise.
1494 *
1495 * @param row the row index (zero-based).
1496 * @param column the column index (zero-based).
1497 *
1498 * @return A boolean.
1499 */
1500 public boolean isItemLabelVisible(int row, int column) {
1501 return isSeriesItemLabelsVisible(row);
1502 }
1503
1504 /**
1505 * Returns <code>true</code> if the item labels for a series are visible,
1506 * and <code>false</code> otherwise.
1507 *
1508 * @param series the series index (zero-based).
1509 *
1510 * @return A boolean.
1511 */
1512 public boolean isSeriesItemLabelsVisible(int series) {
1513
1514 // return the override, if there is one...
1515 if (this.itemLabelsVisible != null) {
1516 return this.itemLabelsVisible.booleanValue();
1517 }
1518
1519 // otherwise look up the boolean table
1520 Boolean b = this.itemLabelsVisibleList.getBoolean(series);
1521 if (b == null) {
1522 b = this.baseItemLabelsVisible;
1523 }
1524 if (b == null) {
1525 b = Boolean.FALSE;
1526 }
1527 return b.booleanValue();
1528
1529 }
1530
1531 /**
1532 * Sets the visibility of the item labels for ALL series.
1533 *
1534 * @param visible the flag.
1535 */
1536 public void setItemLabelsVisible(boolean visible) {
1537 setItemLabelsVisible(BooleanUtilities.valueOf(visible));
1538 // The following alternative is only supported in JDK 1.4 - we support
1539 // JDK 1.2.2
1540 // setItemLabelsVisible(Boolean.valueOf(visible));
1541 }
1542
1543 /**
1544 * Sets the visibility of the item labels for ALL series (optional).
1545 *
1546 * @param visible the flag (<code>null</code> permitted).
1547 */
1548 public void setItemLabelsVisible(Boolean visible) {
1549 setItemLabelsVisible(visible, true);
1550 }
1551
1552 /**
1553 * Sets the visibility of item labels for ALL series and, if requested,
1554 * sends a {@link RendererChangeEvent} to all registered listeners.
1555 *
1556 * @param visible a flag that controls whether or not the item labels are
1557 * visible (<code>null</code> permitted).
1558 * @param notify a flag that controls whether or not listeners are
1559 * notified.
1560 */
1561 public void setItemLabelsVisible(Boolean visible, boolean notify) {
1562 this.itemLabelsVisible = visible;
1563 if (notify) {
1564 fireChangeEvent();
1565 }
1566 }
1567
1568 /**
1569 * Sets a flag that controls the visibility of the item labels for a series.
1570 *
1571 * @param series the series index (zero-based).
1572 * @param visible the flag.
1573 */
1574 public void setSeriesItemLabelsVisible(int series, boolean visible) {
1575 setSeriesItemLabelsVisible(series, BooleanUtilities.valueOf(visible));
1576 }
1577
1578 /**
1579 * Sets the visibility of the item labels for a series.
1580 *
1581 * @param series the series index (zero-based).
1582 * @param visible the flag (<code>null</code> permitted).
1583 */
1584 public void setSeriesItemLabelsVisible(int series, Boolean visible) {
1585 setSeriesItemLabelsVisible(series, visible, true);
1586 }
1587
1588 /**
1589 * Sets the visibility of item labels for a series and, if requested, sends
1590 * a {@link RendererChangeEvent} to all registered listeners.
1591 *
1592 * @param series the series index (zero-based).
1593 * @param visible the visible flag.
1594 * @param notify a flag that controls whether or not listeners are
1595 * notified.
1596 */
1597 public void setSeriesItemLabelsVisible(int series, Boolean visible,
1598 boolean notify) {
1599 this.itemLabelsVisibleList.setBoolean(series, visible);
1600 if (notify) {
1601 fireChangeEvent();
1602 }
1603 }
1604
1605 /**
1606 * Returns the base setting for item label visibility. A <code>null</code>
1607 * result should be interpreted as equivalent to <code>Boolean.FALSE</code>.
1608 *
1609 * @return A flag (possibly <code>null</code>).
1610 */
1611 public Boolean getBaseItemLabelsVisible() {
1612 // this should have been defined as a boolean primitive, because
1613 // allowing null values is a nuisance...but it is part of the final
1614 // API now, so we'll have to support it.
1615 return this.baseItemLabelsVisible;
1616 }
1617
1618 /**
1619 * Sets the base flag that controls whether or not item labels are visible.
1620 *
1621 * @param visible the flag.
1622 */
1623 public void setBaseItemLabelsVisible(boolean visible) {
1624 setBaseItemLabelsVisible(BooleanUtilities.valueOf(visible));
1625 }
1626
1627 /**
1628 * Sets the base setting for item label visibility.
1629 *
1630 * @param visible the flag (<code>null</code> is permitted, and viewed
1631 * as equivalent to <code>Boolean.FALSE</code>).
1632 */
1633 public void setBaseItemLabelsVisible(Boolean visible) {
1634 setBaseItemLabelsVisible(visible, true);
1635 }
1636
1637 /**
1638 * Sets the base visibility for item labels and, if requested, sends a
1639 * {@link RendererChangeEvent} to all registered listeners.
1640 *
1641 * @param visible the flag (<code>null</code> is permitted, and viewed
1642 * as equivalent to <code>Boolean.FALSE</code>).
1643 * @param notify a flag that controls whether or not listeners are
1644 * notified.
1645 */
1646 public void setBaseItemLabelsVisible(Boolean visible, boolean notify) {
1647 this.baseItemLabelsVisible = visible;
1648 if (notify) {
1649 fireChangeEvent();
1650 }
1651 }
1652
1653 //// ITEM LABEL FONT //////////////////////////////////////////////////////
1654
1655 /**
1656 * Returns the font for an item label.
1657 *
1658 * @param row the row index (zero-based).
1659 * @param column the column index (zero-based).
1660 *
1661 * @return The font (never <code>null</code>).
1662 */
1663 public Font getItemLabelFont(int row, int column) {
1664 Font result = this.itemLabelFont;
1665 if (result == null) {
1666 result = getSeriesItemLabelFont(row);
1667 if (result == null) {
1668 result = this.baseItemLabelFont;
1669 }
1670 }
1671 return result;
1672 }
1673
1674 /**
1675 * Returns the font used for all item labels. This may be
1676 * <code>null</code>, in which case the per series font settings will apply.
1677 *
1678 * @return The font (possibly <code>null</code>).
1679 */
1680 public Font getItemLabelFont() {
1681 return this.itemLabelFont;
1682 }
1683
1684 /**
1685 * Sets the item label font for ALL series and sends a
1686 * {@link RendererChangeEvent} to all registered listeners. You can set
1687 * this to <code>null</code> if you prefer to set the font on a per series
1688 * basis.
1689 *
1690 * @param font the font (<code>null</code> permitted).
1691 */
1692 public void setItemLabelFont(Font font) {
1693 setItemLabelFont(font, true);
1694 }
1695
1696 /**
1697 * Sets the item label font for ALL series and, if requested, sends a
1698 * {@link RendererChangeEvent} to all registered listeners.
1699 *
1700 * @param font the font (<code>null</code> permitted).
1701 * @param notify a flag that controls whether or not listeners are
1702 * notified.
1703 */
1704 public void setItemLabelFont(Font font, boolean notify) {
1705 this.itemLabelFont = font;
1706 if (notify) {
1707 fireChangeEvent();
1708 }
1709 }
1710
1711 /**
1712 * Returns the font for all the item labels in a series.
1713 *
1714 * @param series the series index (zero-based).
1715 *
1716 * @return The font (possibly <code>null</code>).
1717 */
1718 public Font getSeriesItemLabelFont(int series) {
1719 return (Font) this.itemLabelFontList.get(series);
1720 }
1721
1722 /**
1723 * Sets the item label font for a series and sends a
1724 * {@link RendererChangeEvent} to all registered listeners.
1725 *
1726 * @param series the series index (zero-based).
1727 * @param font the font (<code>null</code> permitted).
1728 */
1729 public void setSeriesItemLabelFont(int series, Font font) {
1730 setSeriesItemLabelFont(series, font, true);
1731 }
1732
1733 /**
1734 * Sets the item label font for a series and, if requested, sends a
1735 * {@link RendererChangeEvent} to all registered listeners.
1736 *
1737 * @param series the series index (zero based).
1738 * @param font the font (<code>null</code> permitted).
1739 * @param notify a flag that controls whether or not listeners are
1740 * notified.
1741 */
1742 public void setSeriesItemLabelFont(int series, Font font, boolean notify) {
1743 this.itemLabelFontList.set(series, font);
1744 if (notify) {
1745 fireChangeEvent();
1746 }
1747 }
1748
1749 /**
1750 * Returns the base item label font (this is used when no other font
1751 * setting is available).
1752 *
1753 * @return The font (<code>never</code> null).
1754 */
1755 public Font getBaseItemLabelFont() {
1756 return this.baseItemLabelFont;
1757 }
1758
1759 /**
1760 * Sets the base item label font and sends a {@link RendererChangeEvent} to
1761 * all registered listeners.
1762 *
1763 * @param font the font (<code>null</code> not permitted).
1764 */
1765 public void setBaseItemLabelFont(Font font) {
1766 if (font == null) {
1767 throw new IllegalArgumentException("Null 'font' argument.");
1768 }
1769 setBaseItemLabelFont(font, true);
1770 }
1771
1772 /**
1773 * Sets the base item label font and, if requested, sends a
1774 * {@link RendererChangeEvent} to all registered listeners.
1775 *
1776 * @param font the font (<code>null</code> not permitted).
1777 * @param notify a flag that controls whether or not listeners are
1778 * notified.
1779 */
1780 public void setBaseItemLabelFont(Font font, boolean notify) {
1781 this.baseItemLabelFont = font;
1782 if (notify) {
1783 fireChangeEvent();
1784 }
1785 }
1786
1787 //// ITEM LABEL PAINT ////////////////////////////////////////////////////
1788
1789 /**
1790 * Returns the paint used to draw an item label.
1791 *
1792 * @param row the row index (zero based).
1793 * @param column the column index (zero based).
1794 *
1795 * @return The paint (never <code>null</code>).
1796 */
1797 public Paint getItemLabelPaint(int row, int column) {
1798 Paint result = this.itemLabelPaint;
1799 if (result == null) {
1800 result = getSeriesItemLabelPaint(row);
1801 if (result == null) {
1802 result = this.baseItemLabelPaint;
1803 }
1804 }
1805 return result;
1806 }
1807
1808 /**
1809 * Returns the paint used for all item labels. This may be
1810 * <code>null</code>, in which case the per series paint settings will
1811 * apply.
1812 *
1813 * @return The paint (possibly <code>null</code>).
1814 */
1815 public Paint getItemLabelPaint() {
1816 return this.itemLabelPaint;
1817 }
1818
1819 /**
1820 * Sets the item label paint for ALL series and sends a
1821 * {@link RendererChangeEvent} to all registered listeners.
1822 *
1823 * @param paint the paint (<code>null</code> permitted).
1824 */
1825 public void setItemLabelPaint(Paint paint) {
1826 setItemLabelPaint(paint, true);
1827 }
1828
1829 /**
1830 * Sets the item label paint for ALL series and, if requested, sends a
1831 * {@link RendererChangeEvent} to all registered listeners.
1832 *
1833 * @param paint the paint.
1834 * @param notify a flag that controls whether or not listeners are
1835 * notified.
1836 */
1837 public void setItemLabelPaint(Paint paint, boolean notify) {
1838 this.itemLabelPaint = paint;
1839 if (notify) {
1840 fireChangeEvent();
1841 }
1842 }
1843
1844 /**
1845 * Returns the paint used to draw the item labels for a series.
1846 *
1847 * @param series the series index (zero based).
1848 *
1849 * @return The paint (possibly <code>null<code>).
1850 */
1851 public Paint getSeriesItemLabelPaint(int series) {
1852 return this.itemLabelPaintList.getPaint(series);
1853 }
1854
1855 /**
1856 * Sets the item label paint for a series and sends a
1857 * {@link RendererChangeEvent} to all registered listeners.
1858 *
1859 * @param series the series (zero based index).
1860 * @param paint the paint (<code>null</code> permitted).
1861 */
1862 public void setSeriesItemLabelPaint(int series, Paint paint) {
1863 setSeriesItemLabelPaint(series, paint, true);
1864 }
1865
1866 /**
1867 * Sets the item label paint for a series and, if requested, sends a
1868 * {@link RendererChangeEvent} to all registered listeners.
1869 *
1870 * @param series the series index (zero based).
1871 * @param paint the paint (<code>null</code> permitted).
1872 * @param notify a flag that controls whether or not listeners are
1873 * notified.
1874 */
1875 public void setSeriesItemLabelPaint(int series, Paint paint,
1876 boolean notify) {
1877 this.itemLabelPaintList.setPaint(series, paint);
1878 if (notify) {
1879 fireChangeEvent();
1880 }
1881 }
1882
1883 /**
1884 * Returns the base item label paint.
1885 *
1886 * @return The paint (never <code>null<code>).
1887 */
1888 public Paint getBaseItemLabelPaint() {
1889 return this.baseItemLabelPaint;
1890 }
1891
1892 /**
1893 * Sets the base item label paint and sends a {@link RendererChangeEvent}
1894 * to all registered listeners.
1895 *
1896 * @param paint the paint (<code>null</code> not permitted).
1897 */
1898 public void setBaseItemLabelPaint(Paint paint) {
1899 // defer argument checking...
1900 setBaseItemLabelPaint(paint, true);
1901 }
1902
1903 /**
1904 * Sets the base item label paint and, if requested, sends a
1905 * {@link RendererChangeEvent} to all registered listeners..
1906 *
1907 * @param paint the paint (<code>null</code> not permitted).
1908 * @param notify a flag that controls whether or not listeners are
1909 * notified.
1910 */
1911 public void setBaseItemLabelPaint(Paint paint, boolean notify) {
1912 if (paint == null) {
1913 throw new IllegalArgumentException("Null 'paint' argument.");
1914 }
1915 this.baseItemLabelPaint = paint;
1916 if (notify) {
1917 fireChangeEvent();
1918 }
1919 }
1920
1921 // POSITIVE ITEM LABEL POSITION...
1922
1923 /**
1924 * Returns the item label position for positive values.
1925 *
1926 * @param row the row index (zero-based).
1927 * @param column the column index (zero-based).
1928 *
1929 * @return The item label position (never <code>null</code>).
1930 *
1931 * @see #getNegativeItemLabelPosition(int, int)
1932 */
1933 public ItemLabelPosition getPositiveItemLabelPosition(int row, int column) {
1934 return getSeriesPositiveItemLabelPosition(row);
1935 }
1936
1937 /**
1938 * Returns the item label position for positive values in ALL series.
1939 *
1940 * @return The item label position (possibly <code>null</code>).
1941 *
1942 * @see #setPositiveItemLabelPosition(ItemLabelPosition)
1943 */
1944 public ItemLabelPosition getPositiveItemLabelPosition() {
1945 return this.positiveItemLabelPosition;
1946 }
1947
1948 /**
1949 * Sets the item label position for positive values in ALL series, and
1950 * sends a {@link RendererChangeEvent} to all registered listeners. You
1951 * need to set this to <code>null</code> to expose the settings for
1952 * individual series.
1953 *
1954 * @param position the position (<code>null</code> permitted).
1955 *
1956 * @see #getPositiveItemLabelPosition()
1957 */
1958 public void setPositiveItemLabelPosition(ItemLabelPosition position) {
1959 setPositiveItemLabelPosition(position, true);
1960 }
1961
1962 /**
1963 * Sets the positive item label position for ALL series and (if requested)
1964 * sends a {@link RendererChangeEvent} to all registered listeners.
1965 *
1966 * @param position the position (<code>null</code> permitted).
1967 * @param notify notify registered listeners?
1968 *
1969 * @see #getPositiveItemLabelPosition()
1970 */
1971 public void setPositiveItemLabelPosition(ItemLabelPosition position,
1972 boolean notify) {
1973 this.positiveItemLabelPosition = position;
1974 if (notify) {
1975 fireChangeEvent();
1976 }
1977 }
1978
1979 /**
1980 * Returns the item label position for all positive values in a series.
1981 *
1982 * @param series the series index (zero-based).
1983 *
1984 * @return The item label position (never <code>null</code>).
1985 *
1986 * @see #setSeriesPositiveItemLabelPosition(int, ItemLabelPosition)
1987 */
1988 public ItemLabelPosition getSeriesPositiveItemLabelPosition(int series) {
1989
1990 // return the override, if there is one...
1991 if (this.positiveItemLabelPosition != null) {
1992 return this.positiveItemLabelPosition;
1993 }
1994
1995 // otherwise look up the position table
1996 ItemLabelPosition position = (ItemLabelPosition)
1997 this.positiveItemLabelPositionList.get(series);
1998 if (position == null) {
1999 position = this.basePositiveItemLabelPosition;
2000 }
2001 return position;
2002
2003 }
2004
2005 /**
2006 * Sets the item label position for all positive values in a series and
2007 * sends a {@link RendererChangeEvent} to all registered listeners.
2008 *
2009 * @param series the series index (zero-based).
2010 * @param position the position (<code>null</code> permitted).
2011 *
2012 * @see #getSeriesPositiveItemLabelPosition(int)
2013 */
2014 public void setSeriesPositiveItemLabelPosition(int series,
2015 ItemLabelPosition position) {
2016 setSeriesPositiveItemLabelPosition(series, position, true);
2017 }
2018
2019 /**
2020 * Sets the item label position for all positive values in a series and (if
2021 * requested) sends a {@link RendererChangeEvent} to all registered
2022 * listeners.
2023 *
2024 * @param series the series index (zero-based).
2025 * @param position the position (<code>null</code> permitted).
2026 * @param notify notify registered listeners?
2027 *
2028 * @see #getSeriesPositiveItemLabelPosition(int)
2029 */
2030 public void setSeriesPositiveItemLabelPosition(int series,
2031 ItemLabelPosition position,
2032 boolean notify) {
2033 this.positiveItemLabelPositionList.set(series, position);
2034 if (notify) {
2035 fireChangeEvent();
2036 }
2037 }
2038
2039 /**
2040 * Returns the base positive item label position.
2041 *
2042 * @return The position (never <code>null</code>).
2043 *
2044 * @see #setBasePositiveItemLabelPosition(ItemLabelPosition)
2045 */
2046 public ItemLabelPosition getBasePositiveItemLabelPosition() {
2047 return this.basePositiveItemLabelPosition;
2048 }
2049
2050 /**
2051 * Sets the base positive item label position.
2052 *
2053 * @param position the position (<code>null</code> not permitted).
2054 *
2055 * @see #getBasePositiveItemLabelPosition()
2056 */
2057 public void setBasePositiveItemLabelPosition(ItemLabelPosition position) {
2058 // defer argument checking...
2059 setBasePositiveItemLabelPosition(position, true);
2060 }
2061
2062 /**
2063 * Sets the base positive item label position and, if requested, sends a
2064 * {@link RendererChangeEvent} to all registered listeners.
2065 *
2066 * @param position the position (<code>null</code> not permitted).
2067 * @param notify notify registered listeners?
2068 *
2069 * @see #getBasePositiveItemLabelPosition()
2070 */
2071 public void setBasePositiveItemLabelPosition(ItemLabelPosition position,
2072 boolean notify) {
2073 if (position == null) {
2074 throw new IllegalArgumentException("Null 'position' argument.");
2075 }
2076 this.basePositiveItemLabelPosition = position;
2077 if (notify) {
2078 fireChangeEvent();
2079 }
2080 }
2081
2082 // NEGATIVE ITEM LABEL POSITION...
2083
2084 /**
2085 * Returns the item label position for negative values. This method can be
2086 * overridden to provide customisation of the item label position for
2087 * individual data items.
2088 *
2089 * @param row the row index (zero-based).
2090 * @param column the column (zero-based).
2091 *
2092 * @return The item label position (never <code>null</code>).
2093 *
2094 * @see #getPositiveItemLabelPosition(int, int)
2095 */
2096 public ItemLabelPosition getNegativeItemLabelPosition(int row, int column) {
2097 return getSeriesNegativeItemLabelPosition(row);
2098 }
2099
2100 /**
2101 * Returns the item label position for negative values in ALL series.
2102 *
2103 * @return The item label position (possibly <code>null</code>).
2104 *
2105 * @see #setNegativeItemLabelPosition(ItemLabelPosition)
2106 */
2107 public ItemLabelPosition getNegativeItemLabelPosition() {
2108 return this.negativeItemLabelPosition;
2109 }
2110
2111 /**
2112 * Sets the item label position for negative values in ALL series, and
2113 * sends a {@link RendererChangeEvent} to all registered listeners. You
2114 * need to set this to <code>null</code> to expose the settings for
2115 * individual series.
2116 *
2117 * @param position the position (<code>null</code> permitted).
2118 *
2119 * @see #getNegativeItemLabelPosition()
2120 */
2121 public void setNegativeItemLabelPosition(ItemLabelPosition position) {
2122 setNegativeItemLabelPosition(position, true);
2123 }
2124
2125 /**
2126 * Sets the item label position for negative values in ALL series and (if
2127 * requested) sends a {@link RendererChangeEvent} to all registered
2128 * listeners.
2129 *
2130 * @param position the position (<code>null</code> permitted).
2131 * @param notify notify registered listeners?
2132 *
2133 * @see #getNegativeItemLabelPosition()
2134 */
2135 public void setNegativeItemLabelPosition(ItemLabelPosition position,
2136 boolean notify) {
2137 this.negativeItemLabelPosition = position;
2138 if (notify) {
2139 fireChangeEvent();
2140 }
2141 }
2142
2143 /**
2144 * Returns the item label position for all negative values in a series.
2145 *
2146 * @param series the series index (zero-based).
2147 *
2148 * @return The item label position (never <code>null</code>).
2149 *
2150 * @see #setSeriesNegativeItemLabelPosition(int, ItemLabelPosition)
2151 */
2152 public ItemLabelPosition getSeriesNegativeItemLabelPosition(int series) {
2153
2154 // return the override, if there is one...
2155 if (this.negativeItemLabelPosition != null) {
2156 return this.negativeItemLabelPosition;
2157 }
2158
2159 // otherwise look up the position list
2160 ItemLabelPosition position = (ItemLabelPosition)
2161 this.negativeItemLabelPositionList.get(series);
2162 if (position == null) {
2163 position = this.baseNegativeItemLabelPosition;
2164 }
2165 return position;
2166
2167 }
2168
2169 /**
2170 * Sets the item label position for negative values in a series and sends a
2171 * {@link RendererChangeEvent} to all registered listeners.
2172 *
2173 * @param series the series index (zero-based).
2174 * @param position the position (<code>null</code> permitted).
2175 *
2176 * @see #getSeriesNegativeItemLabelPosition(int)
2177 */
2178 public void setSeriesNegativeItemLabelPosition(int series,
2179 ItemLabelPosition position) {
2180 setSeriesNegativeItemLabelPosition(series, position, true);
2181 }
2182
2183 /**
2184 * Sets the item label position for negative values in a series and (if
2185 * requested) sends a {@link RendererChangeEvent} to all registered
2186 * listeners.
2187 *
2188 * @param series the series index (zero-based).
2189 * @param position the position (<code>null</code> permitted).
2190 * @param notify notify registered listeners?
2191 *
2192 * @see #getSeriesNegativeItemLabelPosition(int)
2193 */
2194 public void setSeriesNegativeItemLabelPosition(int series,
2195 ItemLabelPosition position,
2196 boolean notify) {
2197 this.negativeItemLabelPositionList.set(series, position);
2198 if (notify) {
2199 fireChangeEvent();
2200 }
2201 }
2202
2203 /**
2204 * Returns the base item label position for negative values.
2205 *
2206 * @return The position (never <code>null</code>).
2207 *
2208 * @see #setBaseNegativeItemLabelPosition(ItemLabelPosition)
2209 */
2210 public ItemLabelPosition getBaseNegativeItemLabelPosition() {
2211 return this.baseNegativeItemLabelPosition;
2212 }
2213
2214 /**
2215 * Sets the base item label position for negative values and sends a
2216 * {@link RendererChangeEvent} to all registered listeners.
2217 *
2218 * @param position the position (<code>null</code> not permitted).
2219 *
2220 * @see #getBaseNegativeItemLabelPosition()
2221 */
2222 public void setBaseNegativeItemLabelPosition(ItemLabelPosition position) {
2223 setBaseNegativeItemLabelPosition(position, true);
2224 }
2225
2226 /**
2227 * Sets the base negative item label position and, if requested, sends a
2228 * {@link RendererChangeEvent} to all registered listeners.
2229 *
2230 * @param position the position (<code>null</code> not permitted).
2231 * @param notify notify registered listeners?
2232 *
2233 * @see #getBaseNegativeItemLabelPosition()
2234 */
2235 public void setBaseNegativeItemLabelPosition(ItemLabelPosition position,
2236 boolean notify) {
2237 if (position == null) {
2238 throw new IllegalArgumentException("Null 'position' argument.");
2239 }
2240 this.baseNegativeItemLabelPosition = position;
2241 if (notify) {
2242 fireChangeEvent();
2243 }
2244 }
2245
2246 /**
2247 * Returns the item label anchor offset.
2248 *
2249 * @return The offset.
2250 *
2251 * @see #setItemLabelAnchorOffset(double)
2252 */
2253 public double getItemLabelAnchorOffset() {
2254 return this.itemLabelAnchorOffset;
2255 }
2256
2257 /**
2258 * Sets the item label anchor offset.
2259 *
2260 * @param offset the offset.
2261 *
2262 * @see #getItemLabelAnchorOffset()
2263 */
2264 public void setItemLabelAnchorOffset(double offset) {
2265 this.itemLabelAnchorOffset = offset;
2266 fireChangeEvent();
2267 }
2268
2269 /**
2270 * Returns a boolean that indicates whether or not the specified item
2271 * should have a chart entity created for it.
2272 *
2273 * @param series the series index.
2274 * @param item the item index.
2275 *
2276 * @return A boolean.
2277 */
2278 public boolean getItemCreateEntity(int series, int item) {
2279 if (this.createEntities != null) {
2280 return this.createEntities.booleanValue();
2281 }
2282 else {
2283 Boolean b = getSeriesCreateEntities(series);
2284 if (b != null) {
2285 return b.booleanValue();
2286 }
2287 else {
2288 return this.baseCreateEntities;
2289 }
2290 }
2291 }
2292
2293 /**
2294 * Returns the flag that controls whether or not chart entities are created
2295 * for the items in ALL series. This flag overrides the per series and
2296 * default settings - you must set it to <code>null</code> if you want the
2297 * other settings to apply.
2298 *
2299 * @return The flag (possibly <code>null</code>).
2300 */
2301 public Boolean getCreateEntities() {
2302 return this.createEntities;
2303 }
2304
2305 /**
2306 * Sets the flag that controls whether or not chart entities are created
2307 * for the items in ALL series, and sends a {@link RendererChangeEvent} to
2308 * all registered listeners. This flag overrides the per series and
2309 * default settings - you must set it to <code>null</code> if you want the
2310 * other settings to apply.
2311 *
2312 * @param create the flag (<code>null</code> permitted).
2313 */
2314 public void setCreateEntities(Boolean create) {
2315 setCreateEntities(create, true);
2316 }
2317
2318 /**
2319 * Sets the flag that controls whether or not chart entities are created
2320 * for the items in ALL series, and sends a {@link RendererChangeEvent} to
2321 * all registered listeners. This flag overrides the per series and
2322 * default settings - you must set it to <code>null</code> if you want the
2323 * other settings to apply.
2324 *
2325 * @param create the flag (<code>null</code> permitted).
2326 * @param notify notify listeners?
2327 */
2328 public void setCreateEntities(Boolean create, boolean notify) {
2329 this.createEntities = create;
2330 if (notify) {
2331 fireChangeEvent();
2332 }
2333 }
2334
2335 /**
2336 * Returns the flag that controls whether entities are created for a
2337 * series.
2338 *
2339 * @param series the series index (zero-based).
2340 *
2341 * @return The flag (possibly <code>null</code>).
2342 */
2343 public Boolean getSeriesCreateEntities(int series) {
2344 return this.createEntitiesList.getBoolean(series);
2345 }
2346
2347 /**
2348 * Sets the flag that controls whether entities are created for a series,
2349 * and sends a {@link RendererChangeEvent} to all registered listeners.
2350 *
2351 * @param series the series index (zero-based).
2352 * @param create the flag (<code>null</code> permitted).
2353 */
2354 public void setSeriesCreateEntities(int series, Boolean create) {
2355 setSeriesCreateEntities(series, create, true);
2356 }
2357
2358 /**
2359 * Sets the flag that controls whether entities are created for a series
2360 * and, if requested, sends a {@link RendererChangeEvent} to all registered
2361 * listeners.
2362 *
2363 * @param series the series index.
2364 * @param create the flag (<code>null</code> permitted).
2365 * @param notify notify listeners?
2366 */
2367 public void setSeriesCreateEntities(int series, Boolean create,
2368 boolean notify) {
2369 this.createEntitiesList.setBoolean(series, create);
2370 if (notify) {
2371 fireChangeEvent();
2372 }
2373 }
2374
2375 /**
2376 * Returns the base visibility for all series.
2377 *
2378 * @return The base visibility.
2379 */
2380 public boolean getBaseCreateEntities() {
2381 return this.baseCreateEntities;
2382 }
2383
2384 /**
2385 * Sets the base flag that controls whether entities are created
2386 * for a series, and sends a {@link RendererChangeEvent}
2387 * to all registered listeners.
2388 *
2389 * @param create the flag.
2390 */
2391 public void setBaseCreateEntities(boolean create) {
2392 // defer argument checking...
2393 setBaseCreateEntities(create, true);
2394 }
2395
2396 /**
2397 * Sets the base flag that controls whether entities are created and,
2398 * if requested, sends a {@link RendererChangeEvent} to all registered
2399 * listeners.
2400 *
2401 * @param create the visibility.
2402 * @param notify notify listeners?
2403 */
2404 public void setBaseCreateEntities(boolean create, boolean notify) {
2405 this.baseCreateEntities = create;
2406 if (notify) {
2407 fireChangeEvent();
2408 }
2409 }
2410
2411 /** The adjacent offset. */
2412 private static final double ADJ = Math.cos(Math.PI / 6.0);
2413
2414 /** The opposite offset. */
2415 private static final double OPP = Math.sin(Math.PI / 6.0);
2416
2417 /**
2418 * Calculates the item label anchor point.
2419 *
2420 * @param anchor the anchor.
2421 * @param x the x coordinate.
2422 * @param y the y coordinate.
2423 * @param orientation the plot orientation.
2424 *
2425 * @return The anchor point (never <code>null</code>).
2426 */
2427 protected Point2D calculateLabelAnchorPoint(ItemLabelAnchor anchor,
2428 double x, double y, PlotOrientation orientation) {
2429 Point2D result = null;
2430 if (anchor == ItemLabelAnchor.CENTER) {
2431 result = new Point2D.Double(x, y);
2432 }
2433 else if (anchor == ItemLabelAnchor.INSIDE1) {
2434 result = new Point2D.Double(x + OPP * this.itemLabelAnchorOffset,
2435 y - ADJ * this.itemLabelAnchorOffset);
2436 }
2437 else if (anchor == ItemLabelAnchor.INSIDE2) {
2438 result = new Point2D.Double(x + ADJ * this.itemLabelAnchorOffset,
2439 y - OPP * this.itemLabelAnchorOffset);
2440 }
2441 else if (anchor == ItemLabelAnchor.INSIDE3) {
2442 result = new Point2D.Double(x + this.itemLabelAnchorOffset, y);
2443 }
2444 else if (anchor == ItemLabelAnchor.INSIDE4) {
2445 result = new Point2D.Double(x + ADJ * this.itemLabelAnchorOffset,
2446 y + OPP * this.itemLabelAnchorOffset);
2447 }
2448 else if (anchor == ItemLabelAnchor.INSIDE5) {
2449 result = new Point2D.Double(x + OPP * this.itemLabelAnchorOffset,
2450 y + ADJ * this.itemLabelAnchorOffset);
2451 }
2452 else if (anchor == ItemLabelAnchor.INSIDE6) {
2453 result = new Point2D.Double(x, y + this.itemLabelAnchorOffset);
2454 }
2455 else if (anchor == ItemLabelAnchor.INSIDE7) {
2456 result = new Point2D.Double(x - OPP * this.itemLabelAnchorOffset,
2457 y + ADJ * this.itemLabelAnchorOffset);
2458 }
2459 else if (anchor == ItemLabelAnchor.INSIDE8) {
2460 result = new Point2D.Double(x - ADJ * this.itemLabelAnchorOffset,
2461 y + OPP * this.itemLabelAnchorOffset);
2462 }
2463 else if (anchor == ItemLabelAnchor.INSIDE9) {
2464 result = new Point2D.Double(x - this.itemLabelAnchorOffset, y);
2465 }
2466 else if (anchor == ItemLabelAnchor.INSIDE10) {
2467 result = new Point2D.Double(x - ADJ * this.itemLabelAnchorOffset,
2468 y - OPP * this.itemLabelAnchorOffset);
2469 }
2470 else if (anchor == ItemLabelAnchor.INSIDE11) {
2471 result = new Point2D.Double(x - OPP * this.itemLabelAnchorOffset,
2472 y - ADJ * this.itemLabelAnchorOffset);
2473 }
2474 else if (anchor == ItemLabelAnchor.INSIDE12) {
2475 result = new Point2D.Double(x, y - this.itemLabelAnchorOffset);
2476 }
2477 else if (anchor == ItemLabelAnchor.OUTSIDE1) {
2478 result = new Point2D.Double(
2479 x + 2.0 * OPP * this.itemLabelAnchorOffset,
2480 y - 2.0 * ADJ * this.itemLabelAnchorOffset);
2481 }
2482 else if (anchor == ItemLabelAnchor.OUTSIDE2) {
2483 result = new Point2D.Double(
2484 x + 2.0 * ADJ * this.itemLabelAnchorOffset,
2485 y - 2.0 * OPP * this.itemLabelAnchorOffset);
2486 }
2487 else if (anchor == ItemLabelAnchor.OUTSIDE3) {
2488 result = new Point2D.Double(x + 2.0 * this.itemLabelAnchorOffset,
2489 y);
2490 }
2491 else if (anchor == ItemLabelAnchor.OUTSIDE4) {
2492 result = new Point2D.Double(
2493 x + 2.0 * ADJ * this.itemLabelAnchorOffset,
2494 y + 2.0 * OPP * this.itemLabelAnchorOffset);
2495 }
2496 else if (anchor == ItemLabelAnchor.OUTSIDE5) {
2497 result = new Point2D.Double(
2498 x + 2.0 * OPP * this.itemLabelAnchorOffset,
2499 y + 2.0 * ADJ * this.itemLabelAnchorOffset);
2500 }
2501 else if (anchor == ItemLabelAnchor.OUTSIDE6) {
2502 result = new Point2D.Double(x,
2503 y + 2.0 * this.itemLabelAnchorOffset);
2504 }
2505 else if (anchor == ItemLabelAnchor.OUTSIDE7) {
2506 result = new Point2D.Double(
2507 x - 2.0 * OPP * this.itemLabelAnchorOffset,
2508 y + 2.0 * ADJ * this.itemLabelAnchorOffset);
2509 }
2510 else if (anchor == ItemLabelAnchor.OUTSIDE8) {
2511 result = new Point2D.Double(
2512 x - 2.0 * ADJ * this.itemLabelAnchorOffset,
2513 y + 2.0 * OPP * this.itemLabelAnchorOffset);
2514 }
2515 else if (anchor == ItemLabelAnchor.OUTSIDE9) {
2516 result = new Point2D.Double(x - 2.0 * this.itemLabelAnchorOffset,
2517 y);
2518 }
2519 else if (anchor == ItemLabelAnchor.OUTSIDE10) {
2520 result = new Point2D.Double(
2521 x - 2.0 * ADJ * this.itemLabelAnchorOffset,
2522 y - 2.0 * OPP * this.itemLabelAnchorOffset);
2523 }
2524 else if (anchor == ItemLabelAnchor.OUTSIDE11) {
2525 result = new Point2D.Double(
2526 x - 2.0 * OPP * this.itemLabelAnchorOffset,
2527 y - 2.0 * ADJ * this.itemLabelAnchorOffset);
2528 }
2529 else if (anchor == ItemLabelAnchor.OUTSIDE12) {
2530 result = new Point2D.Double(x,
2531 y - 2.0 * this.itemLabelAnchorOffset);
2532 }
2533 return result;
2534 }
2535
2536 /**
2537 * Registers an object to receive notification of changes to the renderer.
2538 *
2539 * @param listener the listener (<code>null</code> not permitted).
2540 */
2541 public void addChangeListener(RendererChangeListener listener) {
2542 if (listener == null) {
2543 throw new IllegalArgumentException("Null 'listener' argument.");
2544 }
2545 this.listenerList.add(RendererChangeListener.class, listener);
2546 }
2547
2548 /**
2549 * Deregisters an object so that it no longer receives
2550 * notification of changes to the renderer.
2551 *
2552 * @param listener the object (<code>null</code> not permitted).
2553 */
2554 public void removeChangeListener(RendererChangeListener listener) {
2555 if (listener == null) {
2556 throw new IllegalArgumentException("Null 'listener' argument.");
2557 }
2558 this.listenerList.remove(RendererChangeListener.class, listener);
2559 }
2560
2561 /**
2562 * Returns <code>true</code> if the specified object is registered with
2563 * the dataset as a listener. Most applications won't need to call this
2564 * method, it exists mainly for use by unit testing code.
2565 *
2566 * @param listener the listener.
2567 *
2568 * @return A boolean.
2569 */
2570 public boolean hasListener(EventListener listener) {
2571 List list = Arrays.asList(this.listenerList.getListenerList());
2572 return list.contains(listener);
2573 }
2574
2575 /**
2576 * Sends a {@link RendererChangeEvent} to all registered listeners.
2577 *
2578 * @since 1.0.5
2579 */
2580 protected void fireChangeEvent() {
2581
2582 // the commented out code would be better, but only if
2583 // RendererChangeEvent is immutable, which it isn't. See if there is
2584 // a way to fix this...
2585
2586 //if (this.event == null) {
2587 // this.event = new RendererChangeEvent(this);
2588 //}
2589 //notifyListeners(this.event);
2590
2591 notifyListeners(new RendererChangeEvent(this));
2592 }
2593
2594 /**
2595 * Notifies all registered listeners that the renderer has been modified.
2596 *
2597 * @param event information about the change event.
2598 */
2599 public void notifyListeners(RendererChangeEvent event) {
2600 Object[] ls = this.listenerList.getListenerList();
2601 for (int i = ls.length - 2; i >= 0; i -= 2) {
2602 if (ls[i] == RendererChangeListener.class) {
2603 ((RendererChangeListener) ls[i + 1]).rendererChanged(event);
2604 }
2605 }
2606 }
2607
2608 /**
2609 * Tests this renderer for equality with another object.
2610 *
2611 * @param obj the object (<code>null</code> permitted).
2612 *
2613 * @return <code>true</code> or <code>false</code>.
2614 */
2615 public boolean equals(Object obj) {
2616 if (obj == this) {
2617 return true;
2618 }
2619 if (!(obj instanceof AbstractRenderer)) {
2620 return false;
2621 }
2622 AbstractRenderer that = (AbstractRenderer) obj;
2623 if (!ObjectUtilities.equal(this.seriesVisible, that.seriesVisible)) {
2624 return false;
2625 }
2626 if (!this.seriesVisibleList.equals(that.seriesVisibleList)) {
2627 return false;
2628 }
2629 if (this.baseSeriesVisible != that.baseSeriesVisible) {
2630 return false;
2631 }
2632 if (!ObjectUtilities.equal(this.seriesVisibleInLegend,
2633 that.seriesVisibleInLegend)) {
2634 return false;
2635 }
2636 if (!this.seriesVisibleInLegendList.equals(
2637 that.seriesVisibleInLegendList)) {
2638 return false;
2639 }
2640 if (this.baseSeriesVisibleInLegend != that.baseSeriesVisibleInLegend) {
2641 return false;
2642 }
2643 if (!PaintUtilities.equal(this.paint, that.paint)) {
2644 return false;
2645 }
2646 if (!ObjectUtilities.equal(this.paintList, that.paintList)) {
2647 return false;
2648 }
2649 if (!PaintUtilities.equal(this.basePaint, that.basePaint)) {
2650 return false;
2651 }
2652 if (!PaintUtilities.equal(this.fillPaint, that.fillPaint)) {
2653 return false;
2654 }
2655 if (!ObjectUtilities.equal(this.fillPaintList, that.fillPaintList)) {
2656 return false;
2657 }
2658 if (!PaintUtilities.equal(this.baseFillPaint, that.baseFillPaint)) {
2659 return false;
2660 }
2661 if (!PaintUtilities.equal(this.outlinePaint, that.outlinePaint)) {
2662 return false;
2663 }
2664 if (!ObjectUtilities.equal(this.outlinePaintList,
2665 that.outlinePaintList)) {
2666 return false;
2667 }
2668 if (!PaintUtilities.equal(this.baseOutlinePaint,
2669 that.baseOutlinePaint)) {
2670 return false;
2671 }
2672 if (!ObjectUtilities.equal(this.stroke, that.stroke)) {
2673 return false;
2674 }
2675 if (!ObjectUtilities.equal(this.strokeList, that.strokeList)) {
2676 return false;
2677 }
2678 if (!ObjectUtilities.equal(this.baseStroke, that.baseStroke)) {
2679 return false;
2680 }
2681 if (!ObjectUtilities.equal(this.outlineStroke, that.outlineStroke)) {
2682 return false;
2683 }
2684 if (!ObjectUtilities.equal(this.outlineStrokeList,
2685 that.outlineStrokeList)) {
2686 return false;
2687 }
2688 if (!ObjectUtilities.equal(
2689 this.baseOutlineStroke, that.baseOutlineStroke)
2690 ) {
2691 return false;
2692 }
2693 if (!ObjectUtilities.equal(this.shape, that.shape)) {
2694 return false;
2695 }
2696 if (!ObjectUtilities.equal(this.shapeList, that.shapeList)) {
2697 return false;
2698 }
2699 if (!ObjectUtilities.equal(this.baseShape, that.baseShape)) {
2700 return false;
2701 }
2702 if (!ObjectUtilities.equal(this.itemLabelsVisible,
2703 that.itemLabelsVisible)) {
2704 return false;
2705 }
2706 if (!ObjectUtilities.equal(this.itemLabelsVisibleList,
2707 that.itemLabelsVisibleList)) {
2708 return false;
2709 }
2710 if (!ObjectUtilities.equal(this.baseItemLabelsVisible,
2711 that.baseItemLabelsVisible)) {
2712 return false;
2713 }
2714 if (!ObjectUtilities.equal(this.itemLabelFont, that.itemLabelFont)) {
2715 return false;
2716 }
2717 if (!ObjectUtilities.equal(this.itemLabelFontList,
2718 that.itemLabelFontList)) {
2719 return false;
2720 }
2721 if (!ObjectUtilities.equal(this.baseItemLabelFont,
2722 that.baseItemLabelFont)) {
2723 return false;
2724 }
2725
2726 if (!PaintUtilities.equal(this.itemLabelPaint, that.itemLabelPaint)) {
2727 return false;
2728 }
2729 if (!ObjectUtilities.equal(this.itemLabelPaintList,
2730 that.itemLabelPaintList)) {
2731 return false;
2732 }
2733 if (!PaintUtilities.equal(this.baseItemLabelPaint,
2734 that.baseItemLabelPaint)) {
2735 return false;
2736 }
2737
2738 if (!ObjectUtilities.equal(this.positiveItemLabelPosition,
2739 that.positiveItemLabelPosition)) {
2740 return false;
2741 }
2742 if (!ObjectUtilities.equal(this.positiveItemLabelPositionList,
2743 that.positiveItemLabelPositionList)) {
2744 return false;
2745 }
2746 if (!ObjectUtilities.equal(this.basePositiveItemLabelPosition,
2747 that.basePositiveItemLabelPosition)) {
2748 return false;
2749 }
2750
2751 if (!ObjectUtilities.equal(this.negativeItemLabelPosition,
2752 that.negativeItemLabelPosition)) {
2753 return false;
2754 }
2755 if (!ObjectUtilities.equal(this.negativeItemLabelPositionList,
2756 that.negativeItemLabelPositionList)) {
2757 return false;
2758 }
2759 if (!ObjectUtilities.equal(this.baseNegativeItemLabelPosition,
2760 that.baseNegativeItemLabelPosition)) {
2761 return false;
2762 }
2763 if (this.itemLabelAnchorOffset != that.itemLabelAnchorOffset) {
2764 return false;
2765 }
2766 if (!ObjectUtilities.equal(this.createEntities, that.createEntities)) {
2767 return false;
2768 }
2769 if (!ObjectUtilities.equal(this.createEntitiesList,
2770 that.createEntitiesList)) {
2771 return false;
2772 }
2773 if (this.baseCreateEntities != that.baseCreateEntities) {
2774 return false;
2775 }
2776 return true;
2777 }
2778
2779 /**
2780 * Returns a hashcode for the renderer.
2781 *
2782 * @return The hashcode.
2783 */
2784 public int hashCode() {
2785 int result = 193;
2786 result = 37 * result + ObjectUtilities.hashCode(this.stroke);
2787 result = 37 * result + ObjectUtilities.hashCode(this.baseStroke);
2788 result = 37 * result + ObjectUtilities.hashCode(this.outlineStroke);
2789 result = 37 * result + ObjectUtilities.hashCode(this.baseOutlineStroke);
2790 return result;
2791 }
2792
2793 /**
2794 * Returns an independent copy of the renderer.
2795 *
2796 * @return A clone.
2797 *
2798 * @throws CloneNotSupportedException if some component of the renderer
2799 * does not support cloning.
2800 */
2801 protected Object clone() throws CloneNotSupportedException {
2802 AbstractRenderer clone = (AbstractRenderer) super.clone();
2803
2804 if (this.seriesVisibleList != null) {
2805 clone.seriesVisibleList
2806 = (BooleanList) this.seriesVisibleList.clone();
2807 }
2808
2809 if (this.seriesVisibleInLegendList != null) {
2810 clone.seriesVisibleInLegendList
2811 = (BooleanList) this.seriesVisibleInLegendList.clone();
2812 }
2813
2814 // 'paint' : immutable, no need to clone reference
2815 if (this.paintList != null) {
2816 clone.paintList = (PaintList) this.paintList.clone();
2817 }
2818 // 'basePaint' : immutable, no need to clone reference
2819
2820 if (this.fillPaintList != null) {
2821 clone.fillPaintList = (PaintList) this.fillPaintList.clone();
2822 }
2823 // 'outlinePaint' : immutable, no need to clone reference
2824 if (this.outlinePaintList != null) {
2825 clone.outlinePaintList = (PaintList) this.outlinePaintList.clone();
2826 }
2827 // 'baseOutlinePaint' : immutable, no need to clone reference
2828
2829 // 'stroke' : immutable, no need to clone reference
2830 if (this.strokeList != null) {
2831 clone.strokeList = (StrokeList) this.strokeList.clone();
2832 }
2833 // 'baseStroke' : immutable, no need to clone reference
2834
2835 // 'outlineStroke' : immutable, no need to clone reference
2836 if (this.outlineStrokeList != null) {
2837 clone.outlineStrokeList
2838 = (StrokeList) this.outlineStrokeList.clone();
2839 }
2840 // 'baseOutlineStroke' : immutable, no need to clone reference
2841
2842 if (this.shape != null) {
2843 clone.shape = ShapeUtilities.clone(this.shape);
2844 }
2845 if (this.shapeList != null) {
2846 clone.shapeList = (ShapeList) this.shapeList.clone();
2847 }
2848 if (this.baseShape != null) {
2849 clone.baseShape = ShapeUtilities.clone(this.baseShape);
2850 }
2851
2852 // 'itemLabelsVisible' : immutable, no need to clone reference
2853 if (this.itemLabelsVisibleList != null) {
2854 clone.itemLabelsVisibleList
2855 = (BooleanList) this.itemLabelsVisibleList.clone();
2856 }
2857 // 'basePaint' : immutable, no need to clone reference
2858
2859 // 'itemLabelFont' : immutable, no need to clone reference
2860 if (this.itemLabelFontList != null) {
2861 clone.itemLabelFontList
2862 = (ObjectList) this.itemLabelFontList.clone();
2863 }
2864 // 'baseItemLabelFont' : immutable, no need to clone reference
2865
2866 // 'itemLabelPaint' : immutable, no need to clone reference
2867 if (this.itemLabelPaintList != null) {
2868 clone.itemLabelPaintList
2869 = (PaintList) this.itemLabelPaintList.clone();
2870 }
2871 // 'baseItemLabelPaint' : immutable, no need to clone reference
2872
2873 // 'postiveItemLabelAnchor' : immutable, no need to clone reference
2874 if (this.positiveItemLabelPositionList != null) {
2875 clone.positiveItemLabelPositionList
2876 = (ObjectList) this.positiveItemLabelPositionList.clone();
2877 }
2878 // 'baseItemLabelAnchor' : immutable, no need to clone reference
2879
2880 // 'negativeItemLabelAnchor' : immutable, no need to clone reference
2881 if (this.negativeItemLabelPositionList != null) {
2882 clone.negativeItemLabelPositionList
2883 = (ObjectList) this.negativeItemLabelPositionList.clone();
2884 }
2885 // 'baseNegativeItemLabelAnchor' : immutable, no need to clone reference
2886
2887 if (this.createEntitiesList != null) {
2888 clone.createEntitiesList
2889 = (BooleanList) this.createEntitiesList.clone();
2890 }
2891 clone.listenerList = new EventListenerList();
2892 clone.event = null;
2893 return clone;
2894 }
2895
2896 /**
2897 * Provides serialization support.
2898 *
2899 * @param stream the output stream.
2900 *
2901 * @throws IOException if there is an I/O error.
2902 */
2903 private void writeObject(ObjectOutputStream stream) throws IOException {
2904
2905 stream.defaultWriteObject();
2906 SerialUtilities.writePaint(this.paint, stream);
2907 SerialUtilities.writePaint(this.basePaint, stream);
2908 SerialUtilities.writePaint(this.fillPaint, stream);
2909 SerialUtilities.writePaint(this.baseFillPaint, stream);
2910 SerialUtilities.writePaint(this.outlinePaint, stream);
2911 SerialUtilities.writePaint(this.baseOutlinePaint, stream);
2912 SerialUtilities.writeStroke(this.stroke, stream);
2913 SerialUtilities.writeStroke(this.baseStroke, stream);
2914 SerialUtilities.writeStroke(this.outlineStroke, stream);
2915 SerialUtilities.writeStroke(this.baseOutlineStroke, stream);
2916 SerialUtilities.writeShape(this.shape, stream);
2917 SerialUtilities.writeShape(this.baseShape, stream);
2918 SerialUtilities.writePaint(this.itemLabelPaint, stream);
2919 SerialUtilities.writePaint(this.baseItemLabelPaint, stream);
2920
2921 }
2922
2923 /**
2924 * Provides serialization support.
2925 *
2926 * @param stream the input stream.
2927 *
2928 * @throws IOException if there is an I/O error.
2929 * @throws ClassNotFoundException if there is a classpath problem.
2930 */
2931 private void readObject(ObjectInputStream stream)
2932 throws IOException, ClassNotFoundException {
2933
2934 stream.defaultReadObject();
2935 this.paint = SerialUtilities.readPaint(stream);
2936 this.basePaint = SerialUtilities.readPaint(stream);
2937 this.fillPaint = SerialUtilities.readPaint(stream);
2938 this.baseFillPaint = SerialUtilities.readPaint(stream);
2939 this.outlinePaint = SerialUtilities.readPaint(stream);
2940 this.baseOutlinePaint = SerialUtilities.readPaint(stream);
2941 this.stroke = SerialUtilities.readStroke(stream);
2942 this.baseStroke = SerialUtilities.readStroke(stream);
2943 this.outlineStroke = SerialUtilities.readStroke(stream);
2944 this.baseOutlineStroke = SerialUtilities.readStroke(stream);
2945 this.shape = SerialUtilities.readShape(stream);
2946 this.baseShape = SerialUtilities.readShape(stream);
2947 this.itemLabelPaint = SerialUtilities.readPaint(stream);
2948 this.baseItemLabelPaint = SerialUtilities.readPaint(stream);
2949
2950 // listeners are not restored automatically, but storage must be
2951 // provided...
2952 this.listenerList = new EventListenerList();
2953
2954 }
2955
2956 }