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     * LegendItem.java
029     * ---------------
030     * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
031     *
032     * Original Author:  David Gilbert (for Object Refinery Limited);
033     * Contributor(s):   Andrzej Porebski;
034     *                   David Li;
035     *                   Wolfgang Irler;
036     *                   Luke Quinane;
037     *
038     * Changes (from 2-Oct-2002)
039     * -------------------------
040     * 02-Oct-2002 : Fixed errors reported by Checkstyle (DG);
041     * 17-Jan-2003 : Dropped outlineStroke attribute (DG);
042     * 08-Oct-2003 : Applied patch for displaying series line style, contributed by
043     *               Luke Quinane (DG);
044     * 21-Jan-2004 : Added the shapeFilled flag (DG);
045     * 04-Jun-2004 : Added equals() method, implemented Serializable (DG);
046     * 25-Nov-2004 : Changes required by new LegendTitle implementation (DG);
047     * 11-Jan-2005 : Removed deprecated code in preparation for the 1.0.0 
048     *               release (DG);
049     * 20-Apr-2005 : Added tooltip and URL text (DG);
050     * 28-Nov-2005 : Separated constructors for AttributedString labels (DG);
051     * 10-Dec-2005 : Fixed serialization bug (1377239) (DG);
052     * ------------- JFREECHART 1.0.x ---------------------------------------------
053     * 20-Jul-2006 : Added dataset and series index fields (DG);
054     * 13-Dec-2006 : Added fillPaintTransformer attribute (DG);
055     * 18-May-2007 : Added dataset and seriesKey fields (DG);
056     * 03-Aug-2007 : Fixed null pointer exception (DG);
057     *
058     */
059    
060    package org.jfree.chart;
061    
062    import java.awt.BasicStroke;
063    import java.awt.Color;
064    import java.awt.Paint;
065    import java.awt.Shape;
066    import java.awt.Stroke;
067    import java.awt.geom.Line2D;
068    import java.io.IOException;
069    import java.io.ObjectInputStream;
070    import java.io.ObjectOutputStream;
071    import java.io.Serializable;
072    import java.text.AttributedString;
073    import java.text.CharacterIterator;
074    
075    import org.jfree.data.general.Dataset;
076    import org.jfree.io.SerialUtilities;
077    import org.jfree.ui.GradientPaintTransformer;
078    import org.jfree.ui.StandardGradientPaintTransformer;
079    import org.jfree.util.AttributedStringUtilities;
080    import org.jfree.util.ObjectUtilities;
081    import org.jfree.util.ShapeUtilities;
082    
083    /**
084     * A temporary storage object for recording the properties of a legend item, 
085     * without any consideration for layout issues. 
086     */
087    public class LegendItem implements Serializable {
088    
089        /** For serialization. */
090        private static final long serialVersionUID = -797214582948827144L;
091        
092        /**
093         * The dataset.
094         * 
095         * @since 1.0.6
096         */
097        private Dataset dataset;
098        
099        /**
100         * The series key.
101         * 
102         * @since 1.0.6
103         */
104        private Comparable seriesKey;
105        
106        /** The dataset index. */
107        private int datasetIndex;
108        
109        /** The series index. */
110        private int series;
111        
112        /** The label. */
113        private String label;
114        
115        /** The attributed label (if null, fall back to the regular label). */
116        private transient AttributedString attributedLabel;
117    
118        /** 
119         * The description (not currently used - could be displayed as a tool tip). 
120         */
121        private String description;
122        
123        /** The tool tip text. */
124        private String toolTipText;
125        
126        /** The url text. */
127        private String urlText;
128    
129        /** A flag that controls whether or not the shape is visible. */
130        private boolean shapeVisible;
131        
132        /** The shape. */
133        private transient Shape shape;
134        
135        /** A flag that controls whether or not the shape is filled. */
136        private boolean shapeFilled;
137    
138        /** The paint. */
139        private transient Paint fillPaint;
140        
141        /** 
142         * A gradient paint transformer. 
143         * 
144         * @since 1.0.4
145         */
146        private GradientPaintTransformer fillPaintTransformer;
147        
148        /** A flag that controls whether or not the shape outline is visible. */
149        private boolean shapeOutlineVisible;
150        
151        /** The outline paint. */
152        private transient Paint outlinePaint;
153        
154        /** The outline stroke. */
155        private transient Stroke outlineStroke;
156    
157        /** A flag that controls whether or not the line is visible. */
158        private boolean lineVisible;
159        
160        /** The line. */
161        private transient Shape line;
162        
163        /** The stroke. */
164        private transient Stroke lineStroke;
165        
166        /** The line paint. */
167        private transient Paint linePaint;
168    
169        /**
170         * The shape must be non-null for a LegendItem - if no shape is required,
171         * use this.
172         */
173        private static final Shape UNUSED_SHAPE = new Line2D.Float();
174        
175        /**
176         * The stroke must be non-null for a LegendItem - if no stroke is required,
177         * use this.
178         */
179        private static final Stroke UNUSED_STROKE = new BasicStroke(0.0f);
180        
181        /**
182         * Creates a legend item with a filled shape.  The shape is not outlined,
183         * and no line is visible.
184         * 
185         * @param label  the label (<code>null</code> not permitted).
186         * @param description  the description (<code>null</code> permitted).
187         * @param toolTipText  the tool tip text (<code>null</code> permitted).
188         * @param urlText  the URL text (<code>null</code> permitted).
189         * @param shape  the shape (<code>null</code> not permitted).
190         * @param fillPaint  the paint used to fill the shape (<code>null</code>
191         *                   not permitted).
192         */
193        public LegendItem(String label, String description, 
194                          String toolTipText, String urlText, 
195                          Shape shape, Paint fillPaint) {
196            
197            this(label, description, toolTipText, urlText, 
198                    /* shape visible = */ true, shape, 
199                    /* shape filled = */ true, fillPaint, 
200                    /* shape outlined */ false, Color.black, UNUSED_STROKE,
201                    /* line visible */ false, UNUSED_SHAPE, UNUSED_STROKE,
202                    Color.black);
203    
204        }
205        
206        /**
207         * Creates a legend item with a filled and outlined shape.
208         * 
209         * @param label  the label (<code>null</code> not permitted).
210         * @param description  the description (<code>null</code> permitted).
211         * @param toolTipText  the tool tip text (<code>null</code> permitted).
212         * @param urlText  the URL text (<code>null</code> permitted).
213         * @param shape  the shape (<code>null</code> not permitted).
214         * @param fillPaint  the paint used to fill the shape (<code>null</code>
215         *                   not permitted).
216         * @param outlineStroke  the outline stroke (<code>null</code> not 
217         *                       permitted).
218         * @param outlinePaint  the outline paint (<code>null</code> not 
219         *                      permitted).
220         */
221        public LegendItem(String label, String description, 
222                          String toolTipText, String urlText, 
223                          Shape shape, Paint fillPaint, 
224                          Stroke outlineStroke, Paint outlinePaint) {
225            
226            this(label, description, toolTipText, urlText,
227                    /* shape visible = */ true, shape, 
228                    /* shape filled = */ true, fillPaint, 
229                    /* shape outlined = */ true, outlinePaint, outlineStroke,
230                    /* line visible */ false, UNUSED_SHAPE, UNUSED_STROKE,
231                    Color.black);
232    
233        }
234        
235        /**
236         * Creates a legend item using a line.
237         * 
238         * @param label  the label (<code>null</code> not permitted).
239         * @param description  the description (<code>null</code> permitted).
240         * @param toolTipText  the tool tip text (<code>null</code> permitted).
241         * @param urlText  the URL text (<code>null</code> permitted).
242         * @param line  the line (<code>null</code> not permitted).
243         * @param lineStroke  the line stroke (<code>null</code> not permitted).
244         * @param linePaint  the line paint (<code>null</code> not permitted).
245         */
246        public LegendItem(String label, String description, 
247                          String toolTipText, String urlText, 
248                          Shape line, Stroke lineStroke, Paint linePaint) {
249            
250            this(label, description, toolTipText, urlText,
251                    /* shape visible = */ false, UNUSED_SHAPE,
252                    /* shape filled = */ false, Color.black,
253                    /* shape outlined = */ false, Color.black, UNUSED_STROKE,
254                    /* line visible = */ true, line, lineStroke, linePaint);
255        }
256        
257        /**
258         * Creates a new legend item.
259         *
260         * @param label  the label (<code>null</code> not permitted).
261         * @param description  the description (not currently used, 
262         *        <code>null</code> permitted).
263         * @param toolTipText  the tool tip text (<code>null</code> permitted).
264         * @param urlText  the URL text (<code>null</code> permitted).
265         * @param shapeVisible  a flag that controls whether or not the shape is 
266         *                      displayed.
267         * @param shape  the shape (<code>null</code> permitted).
268         * @param shapeFilled  a flag that controls whether or not the shape is 
269         *                     filled.
270         * @param fillPaint  the fill paint (<code>null</code> not permitted).
271         * @param shapeOutlineVisible  a flag that controls whether or not the 
272         *                             shape is outlined.
273         * @param outlinePaint  the outline paint (<code>null</code> not permitted).
274         * @param outlineStroke  the outline stroke (<code>null</code> not 
275         *                       permitted).
276         * @param lineVisible  a flag that controls whether or not the line is 
277         *                     visible.
278         * @param line  the line.
279         * @param lineStroke  the stroke (<code>null</code> not permitted).
280         * @param linePaint  the line paint (<code>null</code> not permitted).
281         */
282        public LegendItem(String label, String description,
283                          String toolTipText, String urlText,
284                          boolean shapeVisible, Shape shape,
285                          boolean shapeFilled, Paint fillPaint, 
286                          boolean shapeOutlineVisible, Paint outlinePaint,
287                          Stroke outlineStroke,
288                          boolean lineVisible, Shape line,
289                          Stroke lineStroke, Paint linePaint) {
290            
291            if (label == null) {
292                throw new IllegalArgumentException("Null 'label' argument.");   
293            }
294            if (fillPaint == null) {
295                throw new IllegalArgumentException("Null 'fillPaint' argument.");   
296            }
297            if (lineStroke == null) {
298                throw new IllegalArgumentException("Null 'lineStroke' argument.");
299            }
300            if (outlinePaint == null) {
301                throw new IllegalArgumentException("Null 'outlinePaint' argument.");
302            }
303            if (outlineStroke == null) {
304                throw new IllegalArgumentException(
305                        "Null 'outlineStroke' argument.");   
306            }
307            this.label = label;
308            this.attributedLabel = null;
309            this.description = description;
310            this.shapeVisible = shapeVisible;
311            this.shape = shape;
312            this.shapeFilled = shapeFilled;
313            this.fillPaint = fillPaint;
314            this.fillPaintTransformer = new StandardGradientPaintTransformer();
315            this.shapeOutlineVisible = shapeOutlineVisible;
316            this.outlinePaint = outlinePaint;
317            this.outlineStroke = outlineStroke;
318            this.lineVisible = lineVisible;
319            this.line = line;
320            this.lineStroke = lineStroke;
321            this.linePaint = linePaint;
322            this.toolTipText = toolTipText;
323            this.urlText = urlText;
324        }
325        
326        /**
327         * Creates a legend item with a filled shape.  The shape is not outlined,
328         * and no line is visible.
329         * 
330         * @param label  the label (<code>null</code> not permitted).
331         * @param description  the description (<code>null</code> permitted).
332         * @param toolTipText  the tool tip text (<code>null</code> permitted).
333         * @param urlText  the URL text (<code>null</code> permitted).
334         * @param shape  the shape (<code>null</code> not permitted).
335         * @param fillPaint  the paint used to fill the shape (<code>null</code>
336         *                   not permitted).
337         */
338        public LegendItem(AttributedString label, String description, 
339                          String toolTipText, String urlText, 
340                          Shape shape, Paint fillPaint) {
341            
342            this(label, description, toolTipText, urlText, 
343                    /* shape visible = */ true, shape,
344                    /* shape filled = */ true, fillPaint,
345                    /* shape outlined = */ false, Color.black, UNUSED_STROKE,
346                    /* line visible = */ false, UNUSED_SHAPE, UNUSED_STROKE,
347                    Color.black);
348            
349        }
350        
351        /**
352         * Creates a legend item with a filled and outlined shape.
353         * 
354         * @param label  the label (<code>null</code> not permitted).
355         * @param description  the description (<code>null</code> permitted).
356         * @param toolTipText  the tool tip text (<code>null</code> permitted).
357         * @param urlText  the URL text (<code>null</code> permitted).
358         * @param shape  the shape (<code>null</code> not permitted).
359         * @param fillPaint  the paint used to fill the shape (<code>null</code>
360         *                   not permitted).
361         * @param outlineStroke  the outline stroke (<code>null</code> not 
362         *                       permitted).
363         * @param outlinePaint  the outline paint (<code>null</code> not 
364         *                      permitted).
365         */
366        public LegendItem(AttributedString label, String description, 
367                          String toolTipText, String urlText, 
368                          Shape shape, Paint fillPaint, 
369                          Stroke outlineStroke, Paint outlinePaint) {
370            
371            this(label, description, toolTipText, urlText,
372                    /* shape visible = */ true, shape,
373                    /* shape filled = */ true, fillPaint,
374                    /* shape outlined = */ true, outlinePaint, outlineStroke,
375                    /* line visible = */ false, UNUSED_SHAPE, UNUSED_STROKE,
376                    Color.black);
377        }
378        
379        /**
380         * Creates a legend item using a line.
381         * 
382         * @param label  the label (<code>null</code> not permitted).
383         * @param description  the description (<code>null</code> permitted).
384         * @param toolTipText  the tool tip text (<code>null</code> permitted).
385         * @param urlText  the URL text (<code>null</code> permitted).
386         * @param line  the line (<code>null</code> not permitted).
387         * @param lineStroke  the line stroke (<code>null</code> not permitted).
388         * @param linePaint  the line paint (<code>null</code> not permitted).
389         */
390        public LegendItem(AttributedString label, String description, 
391                          String toolTipText, String urlText, 
392                          Shape line, Stroke lineStroke, Paint linePaint) {
393            
394            this(label, description, toolTipText, urlText,
395                    /* shape visible = */ false, UNUSED_SHAPE,
396                    /* shape filled = */ false, Color.black,
397                    /* shape outlined = */ false, Color.black, UNUSED_STROKE,
398                    /* line visible = */ true, line, lineStroke, linePaint
399            );
400        }
401        
402        /**
403         * Creates a new legend item.
404         *
405         * @param label  the label (<code>null</code> not permitted).
406         * @param description  the description (not currently used, 
407         *        <code>null</code> permitted).
408         * @param toolTipText  the tool tip text (<code>null</code> permitted).
409         * @param urlText  the URL text (<code>null</code> permitted).
410         * @param shapeVisible  a flag that controls whether or not the shape is 
411         *                      displayed.
412         * @param shape  the shape (<code>null</code> permitted).
413         * @param shapeFilled  a flag that controls whether or not the shape is 
414         *                     filled.
415         * @param fillPaint  the fill paint (<code>null</code> not permitted).
416         * @param shapeOutlineVisible  a flag that controls whether or not the 
417         *                             shape is outlined.
418         * @param outlinePaint  the outline paint (<code>null</code> not permitted).
419         * @param outlineStroke  the outline stroke (<code>null</code> not 
420         *                       permitted).
421         * @param lineVisible  a flag that controls whether or not the line is 
422         *                     visible.
423         * @param line  the line.
424         * @param lineStroke  the stroke (<code>null</code> not permitted).
425         * @param linePaint  the line paint (<code>null</code> not permitted).
426         */
427        public LegendItem(AttributedString label, String description,
428                          String toolTipText, String urlText,
429                          boolean shapeVisible, Shape shape,
430                          boolean shapeFilled, Paint fillPaint, 
431                          boolean shapeOutlineVisible, Paint outlinePaint,
432                          Stroke outlineStroke,
433                          boolean lineVisible, Shape line, Stroke lineStroke,
434                          Paint linePaint) {
435            
436            if (label == null) {
437                throw new IllegalArgumentException("Null 'label' argument.");   
438            }
439            if (fillPaint == null) {
440                throw new IllegalArgumentException("Null 'fillPaint' argument.");   
441            }
442            if (lineStroke == null) {
443                throw new IllegalArgumentException("Null 'lineStroke' argument.");
444            }
445            if (outlinePaint == null) {
446                throw new IllegalArgumentException("Null 'outlinePaint' argument.");
447            }
448            if (outlineStroke == null) {
449                throw new IllegalArgumentException(
450                    "Null 'outlineStroke' argument.");   
451            }
452            this.label = characterIteratorToString(label.getIterator());
453            this.attributedLabel = label;
454            this.description = description;
455            this.shapeVisible = shapeVisible;
456            this.shape = shape;
457            this.shapeFilled = shapeFilled;
458            this.fillPaint = fillPaint;
459            this.fillPaintTransformer = new StandardGradientPaintTransformer();
460            this.shapeOutlineVisible = shapeOutlineVisible;
461            this.outlinePaint = outlinePaint;
462            this.outlineStroke = outlineStroke;
463            this.lineVisible = lineVisible;
464            this.line = line;
465            this.lineStroke = lineStroke;
466            this.linePaint = linePaint;
467            this.toolTipText = toolTipText;
468            this.urlText = urlText;
469        }
470    
471        /**
472         * Returns a string containing the characters from the given iterator.
473         * 
474         * @param iterator  the iterator (<code>null</code> not permitted).
475         * 
476         * @return A string.
477         */
478        private String characterIteratorToString(CharacterIterator iterator) {
479            int endIndex = iterator.getEndIndex();
480            int beginIndex = iterator.getBeginIndex();
481            int count = endIndex - beginIndex;
482            if (count <= 0) {
483                return "";
484            }
485            char[] chars = new char[count];
486            int i = 0;
487            char c = iterator.first();
488            while (c != CharacterIterator.DONE) {
489                chars[i] = c;
490                i++;
491                c = iterator.next();
492            }
493            return new String(chars);
494        }
495        
496        /**
497         * Returns the dataset.
498         * 
499         * @return The dataset.
500         * 
501         * @since 1.0.6
502         * 
503         * @see #setDatasetIndex(int)
504         */
505        public Dataset getDataset() {
506            return this.dataset;
507        }
508        
509        /**
510         * Sets the dataset.
511         * 
512         * @param dataset  the dataset.
513         * 
514         * @since 1.0.6
515         */
516        public void setDataset(Dataset dataset) {
517            this.dataset = dataset;
518        }
519        
520        /**
521         * Returns the dataset index for this legend item.
522         * 
523         * @return The dataset index.
524         * 
525         * @since 1.0.2
526         * 
527         * @see #setDatasetIndex(int)
528         * @see #getDataset()
529         */
530        public int getDatasetIndex() {
531            return this.datasetIndex;
532        }
533        
534        /**
535         * Sets the dataset index for this legend item.
536         * 
537         * @param index  the index.
538         * 
539         * @since 1.0.2
540         * 
541         * @see #getDatasetIndex()
542         */
543        public void setDatasetIndex(int index) {
544            this.datasetIndex = index;
545        }
546        
547        /**
548         * Returns the series key.
549         * 
550         * @return The series key.
551         * 
552         * @since 1.0.6
553         * 
554         * @see #setSeriesKey(Comparable)
555         */
556        public Comparable getSeriesKey() {
557            return this.seriesKey;
558        }
559        
560        /**
561         * Sets the series key.
562         * 
563         * @param key  the series key.
564         * 
565         * @since 1.0.6
566         */
567        public void setSeriesKey(Comparable key) {
568            this.seriesKey = key;
569        }
570        
571        /**
572         * Returns the series index for this legend item.
573         * 
574         * @return The series index.
575         * 
576         * @since 1.0.2
577         */
578        public int getSeriesIndex() {
579            return this.series;
580        }
581        
582        /**
583         * Sets the series index for this legend item.
584         * 
585         * @param index  the index.
586         * 
587         * @since 1.0.2
588         */
589        public void setSeriesIndex(int index) {
590            this.series = index;
591        }
592        
593        /**
594         * Returns the label.
595         *
596         * @return The label (never <code>null</code>).
597         */
598        public String getLabel() {
599            return this.label;
600        }
601    
602        /**
603         * Returns the attributed label.
604         *
605         * @return The attributed label (possibly <code>null</code>).
606         */
607        public AttributedString getAttributedLabel() {
608            return this.attributedLabel;
609        }
610    
611        /**
612         * Returns the description for the legend item.
613         * 
614         * @return The description.
615         */
616        public String getDescription() {
617            return this.description;   
618        }
619        
620        /**
621         * Returns the tool tip text.
622         * 
623         * @return The tool tip text (possibly <code>null</code>).
624         */
625        public String getToolTipText() {
626            return this.toolTipText;   
627        }
628        
629        /**
630         * Returns the URL text.
631         * 
632         * @return The URL text (possibly <code>null</code>).
633         */
634        public String getURLText() {
635            return this.urlText; 
636        }
637        
638        /**
639         * Returns a flag that indicates whether or not the shape is visible.
640         * 
641         * @return A boolean.
642         */
643        public boolean isShapeVisible() {
644            return this.shapeVisible;
645        }
646        
647        /**
648         * Returns the shape used to label the series represented by this legend 
649         * item.
650         *
651         * @return The shape (never <code>null</code>).
652         */
653        public Shape getShape() {
654            return this.shape;
655        }
656        
657        /**
658         * Returns a flag that controls whether or not the shape is filled.
659         * 
660         * @return A boolean.
661         */
662        public boolean isShapeFilled() {
663            return this.shapeFilled;
664        }
665    
666        /**
667         * Returns the fill paint.
668         *
669         * @return The fill paint (never <code>null</code>).
670         */
671        public Paint getFillPaint() {
672            return this.fillPaint;
673        }
674    
675        /**
676         * Returns the flag that controls whether or not the shape outline
677         * is visible.
678         * 
679         * @return A boolean.
680         */
681        public boolean isShapeOutlineVisible() {
682            return this.shapeOutlineVisible;
683        }
684        
685        /**
686         * Returns the line stroke for the series.
687         *
688         * @return The stroke (never <code>null</code>).
689         */
690        public Stroke getLineStroke() {
691            return this.lineStroke;
692        }
693        
694        /**
695         * Returns the paint used for lines.
696         * 
697         * @return The paint.
698         */
699        public Paint getLinePaint() {
700            return this.linePaint;
701        }
702        
703        /**
704         * Returns the outline paint.
705         *
706         * @return The outline paint (never <code>null</code>).
707         */
708        public Paint getOutlinePaint() {
709            return this.outlinePaint;
710        }
711    
712        /**
713         * Returns the outline stroke.
714         *
715         * @return The outline stroke (never <code>null</code>).
716         */
717        public Stroke getOutlineStroke() {
718            return this.outlineStroke;
719        }
720        
721        /**
722         * Returns a flag that indicates whether or not the line is visible.
723         * 
724         * @return A boolean.
725         */
726        public boolean isLineVisible() {
727            return this.lineVisible;
728        }
729        
730        /**
731         * Returns the line.
732         * 
733         * @return The line.
734         */
735        public Shape getLine() {
736            return this.line;
737        }
738        
739        /**
740         * Returns the transformer used when the fill paint is an instance of 
741         * <code>GradientPaint</code>.
742         * 
743         * @return The transformer (never <code>null</code>).
744         * 
745         * @since 1.0.4
746         * 
747         * @see #setFillPaintTransformer(GradientPaintTransformer)
748         */
749        public GradientPaintTransformer getFillPaintTransformer() {
750            return this.fillPaintTransformer;
751        }
752        
753        /**
754         * Sets the transformer used when the fill paint is an instance of 
755         * <code>GradientPaint</code>.
756         * 
757         * @param transformer  the transformer (<code>null</code> not permitted).
758         * 
759         * @since 1.0.4
760         * 
761         * @see #getFillPaintTransformer()
762         */
763        public void setFillPaintTransformer(GradientPaintTransformer transformer) {
764            if (transformer == null) { 
765                throw new IllegalArgumentException("Null 'transformer' attribute.");
766            }
767            this.fillPaintTransformer = transformer;
768        }
769        
770        /**
771         * Tests this item for equality with an arbitrary object.
772         * 
773         * @param obj  the object (<code>null</code> permitted).
774         * 
775         * @return A boolean.
776         */
777        public boolean equals(Object obj) {
778            if (obj == this) {
779                return true;   
780            }
781            if (!(obj instanceof LegendItem)) {
782                    return false;
783            }
784            LegendItem that = (LegendItem) obj;
785            if (this.datasetIndex != that.datasetIndex) {
786                return false;
787            }
788            if (this.series != that.series) {
789                return false;
790            }
791            if (!this.label.equals(that.label)) {
792                return false;
793            }
794            if (!AttributedStringUtilities.equal(this.attributedLabel, 
795                    that.attributedLabel)) {
796                return false;
797            }
798            if (!ObjectUtilities.equal(this.description, that.description)) {
799                return false;
800            }
801            if (this.shapeVisible != that.shapeVisible) {
802                return false;
803            }
804            if (!ShapeUtilities.equal(this.shape, that.shape)) {
805                return false;
806            }
807            if (this.shapeFilled != that.shapeFilled) {
808                return false;
809            }
810            if (!this.fillPaint.equals(that.fillPaint)) {
811                return false;   
812            }
813            if (!ObjectUtilities.equal(this.fillPaintTransformer, 
814                    that.fillPaintTransformer)) {
815                return false;
816            }
817            if (this.shapeOutlineVisible != that.shapeOutlineVisible) {
818                return false;
819            }
820            if (!this.outlineStroke.equals(that.outlineStroke)) {
821                return false;   
822            }
823            if (!this.outlinePaint.equals(that.outlinePaint)) {
824                return false;   
825            }
826            if (!this.lineVisible == that.lineVisible) {
827                return false;
828            }
829            if (!ShapeUtilities.equal(this.line, that.line)) {
830                return false;
831            }
832            if (!this.lineStroke.equals(that.lineStroke)) {
833                return false;   
834            }
835            if (!this.linePaint.equals(that.linePaint)) {
836                return false;
837            }
838            return true;
839        }
840        
841        /**
842         * Provides serialization support.
843         *
844         * @param stream  the output stream (<code>null</code> not permitted).
845         *
846         * @throws IOException  if there is an I/O error.
847         */
848        private void writeObject(ObjectOutputStream stream) throws IOException {
849            stream.defaultWriteObject();
850            SerialUtilities.writeAttributedString(this.attributedLabel, stream);
851            SerialUtilities.writeShape(this.shape, stream);
852            SerialUtilities.writePaint(this.fillPaint, stream);
853            SerialUtilities.writeStroke(this.outlineStroke, stream);
854            SerialUtilities.writePaint(this.outlinePaint, stream);
855            SerialUtilities.writeShape(this.line, stream);
856            SerialUtilities.writeStroke(this.lineStroke, stream);
857            SerialUtilities.writePaint(this.linePaint, stream);
858        }
859    
860        /**
861         * Provides serialization support.
862         *
863         * @param stream  the input stream (<code>null</code> not permitted).
864         *
865         * @throws IOException  if there is an I/O error.
866         * @throws ClassNotFoundException  if there is a classpath problem.
867         */
868        private void readObject(ObjectInputStream stream) 
869            throws IOException, ClassNotFoundException {
870            stream.defaultReadObject();
871            this.attributedLabel = SerialUtilities.readAttributedString(stream);
872            this.shape = SerialUtilities.readShape(stream);
873            this.fillPaint = SerialUtilities.readPaint(stream);
874            this.outlineStroke = SerialUtilities.readStroke(stream);
875            this.outlinePaint = SerialUtilities.readPaint(stream);
876            this.line = SerialUtilities.readShape(stream);
877            this.lineStroke = SerialUtilities.readStroke(stream);
878            this.linePaint = SerialUtilities.readPaint(stream);
879        }
880        
881    }