    001    /* ===========================================================
    002     * JFreeChart : a free chart library for the Java(tm) platform
    003     * ===========================================================
    004     *
    005     * (C) Copyright 2000-2008, by Object Refinery Limited and Contributors.
    006     *
    007     * Project Info:  http://www.jfree.org/jfreechart/index.html
    008     *
    009     * This library is free software; you can redistribute it and/or modify it
    010     * under the terms of the GNU Lesser General Public License as published by
    011     * the Free Software Foundation; either version 2.1 of the License, or
    012     * (at your option) any later version.
    013     *
    014     * This library is distributed in the hope that it will be useful, but
    015     * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    016     * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
    017     * License for more details.
    018     *
    019     * You should have received a copy of the GNU Lesser General Public
    020     * License along with this library; if not, write to the Free Software
    021     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
    022     * USA.
    023     *
    024     * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
    025     * in the United States and other countries.]
    026     *
    027     * ---------------
    028     * LegendItem.java
    029     * ---------------
    030     * (C) Copyright 2000-2008, 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     * 23-Apr-2008 : Added new constructor and implemented Cloneable (DG);
    058     *
    059     */
    060
    061    package org.jfree.chart;
    062
    063    import java.awt.BasicStroke;
    064    import java.awt.Color;
    065    import java.awt.Paint;
    066    import java.awt.Shape;
    067    import java.awt.Stroke;
    068    import java.awt.geom.Line2D;
    069    import java.awt.geom.Rectangle2D;
    070    import java.io.IOException;
    071    import java.io.ObjectInputStream;
    072    import java.io.ObjectOutputStream;
    073    import java.io.Serializable;
    074    import java.text.AttributedString;
    075    import java.text.CharacterIterator;
    076
    077    import org.jfree.data.general.Dataset;
    078    import org.jfree.io.SerialUtilities;
    079    import org.jfree.ui.GradientPaintTransformer;
    080    import org.jfree.ui.StandardGradientPaintTransformer;
    081    import org.jfree.util.AttributedStringUtilities;
    082    import org.jfree.util.ObjectUtilities;
    083    import org.jfree.util.PublicCloneable;
    084    import org.jfree.util.ShapeUtilities;
    085
    086    /**
    087     * A temporary storage object for recording the properties of a legend item,
    088     * without any consideration for layout issues.
    089     */
    090    public class LegendItem implements Cloneable, Serializable {
    091
    092        /** For serialization. */
    093        private static final long serialVersionUID = -797214582948827144L;
    094
    095        /**
    096         * The dataset.
    097         *
    098         * @since 1.0.6
    099         */
    100        private Dataset dataset;
    101
    102        /**
    103         * The series key.
    104         *
    105         * @since 1.0.6
    106         */
    107        private Comparable seriesKey;
    108
    109        /** The dataset index. */
    110        private int datasetIndex;
    111
    112        /** The series index. */
    113        private int series;
    114
    115        /** The label. */
    116        private String label;
    117
    118        /** The attributed label (if null, fall back to the regular label). */
    119        private transient AttributedString attributedLabel;
    120
    121        /**
    122         * The description (not currently used - could be displayed as a tool tip).
    123         */
    124        private String description;
    125
    126        /** The tool tip text. */
    127        private String toolTipText;
    128
    129        /** The url text. */
    130        private String urlText;
    131
    132        /** A flag that controls whether or not the shape is visible. */
    133        private boolean shapeVisible;
    134
    135        /** The shape. */
    136        private transient Shape shape;
    137
    138        /** A flag that controls whether or not the shape is filled. */
    139        private boolean shapeFilled;
    140
    141        /** The paint. */
    142        private transient Paint fillPaint;
    143
    144        /**
    145         * A gradient paint transformer.
    146         *
    147         * @since 1.0.4
    148         */
    149        private GradientPaintTransformer fillPaintTransformer;
    150
    151        /** A flag that controls whether or not the shape outline is visible. */
    152        private boolean shapeOutlineVisible;
    153
    154        /** The outline paint. */
    155        private transient Paint outlinePaint;
    156
    157        /** The outline stroke. */
    158        private transient Stroke outlineStroke;
    159
    160        /** A flag that controls whether or not the line is visible. */
    161        private boolean lineVisible;
    162
    163        /** The line. */
    164        private transient Shape line;
    165
    166        /** The stroke. */
    167        private transient Stroke lineStroke;
    168
    169        /** The line paint. */
    170        private transient Paint linePaint;
    171
    172        /**
    173         * The shape must be non-null for a LegendItem - if no shape is required,
    174         * use this.
    175         */
    176        private static final Shape UNUSED_SHAPE = new Line2D.Float();
    177
    178        /**
    179         * The stroke must be non-null for a LegendItem - if no stroke is required,
    180         * use this.
    181         */
    182        private static final Stroke UNUSED_STROKE = new BasicStroke(0.0f);
    183
    184        /**
    185         * Creates a legend item with the specified label.  The remaining
    186         * attributes take default values.
    187         *
    188         * @param label  the label (<code>null</code> not permitted).
    189         *
    190         * @since 1.0.10
    191         */
    192        public LegendItem(String label) {
    193            this(label, null, null, null, new Rectangle2D.Double(-4.0, -4.0, 8.0,
    194                    8.0), Color.black);
    195        }
    196
    197        /**
    198         * Creates a legend item with a filled shape.  The shape is not outlined,
    199         * and no line is visible.
    200         *
    201         * @param label  the label (<code>null</code> not permitted).
    202         * @param description  the description (<code>null</code> permitted).
    203         * @param toolTipText  the tool tip text (<code>null</code> permitted).
    204         * @param urlText  the URL text (<code>null</code> permitted).
    205         * @param shape  the shape (<code>null</code> not permitted).
    206         * @param fillPaint  the paint used to fill the shape (<code>null</code>
    207         *                   not permitted).
    208         */
    209        public LegendItem(String label, String description,
    210                          String toolTipText, String urlText,
    211                          Shape shape, Paint fillPaint) {
    212
    213            this(label, description, toolTipText, urlText,
    214                    /* shape visible = */ true, shape,
    215                    /* shape filled = */ true, fillPaint,
    216                    /* shape outlined */ false, Color.black, UNUSED_STROKE,
    217                    /* line visible */ false, UNUSED_SHAPE, UNUSED_STROKE,
    218                    Color.black);
    219
    220        }
    221
    222        /**
    223         * Creates a legend item with a filled and outlined shape.
    224         *
    225         * @param label  the label (<code>null</code> not permitted).
    226         * @param description  the description (<code>null</code> permitted).
    227         * @param toolTipText  the tool tip text (<code>null</code> permitted).
    228         * @param urlText  the URL text (<code>null</code> permitted).
    229         * @param shape  the shape (<code>null</code> not permitted).
    230         * @param fillPaint  the paint used to fill the shape (<code>null</code>
    231         *                   not permitted).
    232         * @param outlineStroke  the outline stroke (<code>null</code> not
    233         *                       permitted).
    234         * @param outlinePaint  the outline paint (<code>null</code> not
    235         *                      permitted).
    236         */
    237        public LegendItem(String label, String description,
    238                          String toolTipText, String urlText,
    239                          Shape shape, Paint fillPaint,
    240                          Stroke outlineStroke, Paint outlinePaint) {
    241
    242            this(label, description, toolTipText, urlText,
    243                    /* shape visible = */ true, shape,
    244                    /* shape filled = */ true, fillPaint,
    245                    /* shape outlined = */ true, outlinePaint, outlineStroke,
    246                    /* line visible */ false, UNUSED_SHAPE, UNUSED_STROKE,
    247                    Color.black);
    248
    249        }
    250
    251        /**
    252         * Creates a legend item using a line.
    253         *
    254         * @param label  the label (<code>null</code> not permitted).
    255         * @param description  the description (<code>null</code> permitted).
    256         * @param toolTipText  the tool tip text (<code>null</code> permitted).
    257         * @param urlText  the URL text (<code>null</code> permitted).
    258         * @param line  the line (<code>null</code> not permitted).
    259         * @param lineStroke  the line stroke (<code>null</code> not permitted).
    260         * @param linePaint  the line paint (<code>null</code> not permitted).
    261         */
    262        public LegendItem(String label, String description,
    263                          String toolTipText, String urlText,
    264                          Shape line, Stroke lineStroke, Paint linePaint) {
    265
    266            this(label, description, toolTipText, urlText,
    267                    /* shape visible = */ false, UNUSED_SHAPE,
    268                    /* shape filled = */ false, Color.black,
    269                    /* shape outlined = */ false, Color.black, UNUSED_STROKE,
    270                    /* line visible = */ true, line, lineStroke, linePaint);
    271        }
    272
    273        /**
    274         * Creates a new legend item.
    275         *
    276         * @param label  the label (<code>null</code> not permitted).
    277         * @param description  the description (not currently used,
    278         *        <code>null</code> permitted).
    279         * @param toolTipText  the tool tip text (<code>null</code> permitted).
    280         * @param urlText  the URL text (<code>null</code> permitted).
    281         * @param shapeVisible  a flag that controls whether or not the shape is
    282         *                      displayed.
    283         * @param shape  the shape (<code>null</code> permitted).
    284         * @param shapeFilled  a flag that controls whether or not the shape is
    285         *                     filled.
    286         * @param fillPaint  the fill paint (<code>null</code> not permitted).
    287         * @param shapeOutlineVisible  a flag that controls whether or not the
    288         *                             shape is outlined.
    289         * @param outlinePaint  the outline paint (<code>null</code> not permitted).
    290         * @param outlineStroke  the outline stroke (<code>null</code> not
    291         *                       permitted).
    292         * @param lineVisible  a flag that controls whether or not the line is
    293         *                     visible.
    294         * @param line  the line.
    295         * @param lineStroke  the stroke (<code>null</code> not permitted).
    296         * @param linePaint  the line paint (<code>null</code> not permitted).
    297         */
    298        public LegendItem(String label, String description,
    299                          String toolTipText, String urlText,
    300                          boolean shapeVisible, Shape shape,
    301                          boolean shapeFilled, Paint fillPaint,
    302                          boolean shapeOutlineVisible, Paint outlinePaint,
    303                          Stroke outlineStroke,
    304                          boolean lineVisible, Shape line,
    305                          Stroke lineStroke, Paint linePaint) {
    306
    307            if (label == null) {
    308                throw new IllegalArgumentException("Null 'label' argument.");
    309            }
    310            if (fillPaint == null) {
    311                throw new IllegalArgumentException("Null 'fillPaint' argument.");
    312            }
    313            if (lineStroke == null) {
    314                throw new IllegalArgumentException("Null 'lineStroke' argument.");
    315            }
    316            if (outlinePaint == null) {
    317                throw new IllegalArgumentException("Null 'outlinePaint' argument.");
    318            }
    319            if (outlineStroke == null) {
    320                throw new IllegalArgumentException(
    321                        "Null 'outlineStroke' argument.");
    322            }
    323            this.label = label;
    324            this.attributedLabel = null;
    325            this.description = description;
    326            this.shapeVisible = shapeVisible;
    327            this.shape = shape;
    328            this.shapeFilled = shapeFilled;
    329            this.fillPaint = fillPaint;
    330            this.fillPaintTransformer = new StandardGradientPaintTransformer();
    331            this.shapeOutlineVisible = shapeOutlineVisible;
    332            this.outlinePaint = outlinePaint;
    333            this.outlineStroke = outlineStroke;
    334            this.lineVisible = lineVisible;
    335            this.line = line;
    336            this.lineStroke = lineStroke;
    337            this.linePaint = linePaint;
    338            this.toolTipText = toolTipText;
    339            this.urlText = urlText;
    340        }
    341
    342        /**
    343         * Creates a legend item with a filled shape.  The shape is not outlined,
    344         * and no line is visible.
    345         *
    346         * @param label  the label (<code>null</code> not permitted).
    347         * @param description  the description (<code>null</code> permitted).
    348         * @param toolTipText  the tool tip text (<code>null</code> permitted).
    349         * @param urlText  the URL text (<code>null</code> permitted).
    350         * @param shape  the shape (<code>null</code> not permitted).
    351         * @param fillPaint  the paint used to fill the shape (<code>null</code>
    352         *                   not permitted).
    353         */
    354        public LegendItem(AttributedString label, String description,
    355                          String toolTipText, String urlText,
    356                          Shape shape, Paint fillPaint) {
    357
    358            this(label, description, toolTipText, urlText,
    359                    /* shape visible = */ true, shape,
    360                    /* shape filled = */ true, fillPaint,
    361                    /* shape outlined = */ false, Color.black, UNUSED_STROKE,
    362                    /* line visible = */ false, UNUSED_SHAPE, UNUSED_STROKE,
    363                    Color.black);
    364
    365        }
    366
    367        /**
    368         * Creates a legend item with a filled and outlined shape.
    369         *
    370         * @param label  the label (<code>null</code> not permitted).
    371         * @param description  the description (<code>null</code> permitted).
    372         * @param toolTipText  the tool tip text (<code>null</code> permitted).
    373         * @param urlText  the URL text (<code>null</code> permitted).
    374         * @param shape  the shape (<code>null</code> not permitted).
    375         * @param fillPaint  the paint used to fill the shape (<code>null</code>
    376         *                   not permitted).
    377         * @param outlineStroke  the outline stroke (<code>null</code> not
    378         *                       permitted).
    379         * @param outlinePaint  the outline paint (<code>null</code> not
    380         *                      permitted).
    381         */
    382        public LegendItem(AttributedString label, String description,
    383                          String toolTipText, String urlText,
    384                          Shape shape, Paint fillPaint,
    385                          Stroke outlineStroke, Paint outlinePaint) {
    386
    387            this(label, description, toolTipText, urlText,
    388                    /* shape visible = */ true, shape,
    389                    /* shape filled = */ true, fillPaint,
    390                    /* shape outlined = */ true, outlinePaint, outlineStroke,
    391                    /* line visible = */ false, UNUSED_SHAPE, UNUSED_STROKE,
    392                    Color.black);
    393        }
    394
    395        /**
    396         * Creates a legend item using a line.
    397         *
    398         * @param label  the label (<code>null</code> not permitted).
    399         * @param description  the description (<code>null</code> permitted).
    400         * @param toolTipText  the tool tip text (<code>null</code> permitted).
    401         * @param urlText  the URL text (<code>null</code> permitted).
    402         * @param line  the line (<code>null</code> not permitted).
    403         * @param lineStroke  the line stroke (<code>null</code> not permitted).
    404         * @param linePaint  the line paint (<code>null</code> not permitted).
    405         */
    406        public LegendItem(AttributedString label, String description,
    407                          String toolTipText, String urlText,
    408                          Shape line, Stroke lineStroke, Paint linePaint) {
    409
    410            this(label, description, toolTipText, urlText,
    411                    /* shape visible = */ false, UNUSED_SHAPE,
    412                    /* shape filled = */ false, Color.black,
    413                    /* shape outlined = */ false, Color.black, UNUSED_STROKE,
    414                    /* line visible = */ true, line, lineStroke, linePaint
    415            );
    416        }
    417
    418        /**
    419         * Creates a new legend item.
    420         *
    421         * @param label  the label (<code>null</code> not permitted).
    422         * @param description  the description (not currently used,
    423         *        <code>null</code> permitted).
    424         * @param toolTipText  the tool tip text (<code>null</code> permitted).
    425         * @param urlText  the URL text (<code>null</code> permitted).
    426         * @param shapeVisible  a flag that controls whether or not the shape is
    427         *                      displayed.
    428         * @param shape  the shape (<code>null</code> permitted).
    429         * @param shapeFilled  a flag that controls whether or not the shape is
    430         *                     filled.
    431         * @param fillPaint  the fill paint (<code>null</code> not permitted).
    432         * @param shapeOutlineVisible  a flag that controls whether or not the
    433         *                             shape is outlined.
    434         * @param outlinePaint  the outline paint (<code>null</code> not permitted).
    435         * @param outlineStroke  the outline stroke (<code>null</code> not
    436         *                       permitted).
    437         * @param lineVisible  a flag that controls whether or not the line is
    438         *                     visible.
    439         * @param line  the line (<code>null</code> not permitted).
    440         * @param lineStroke  the stroke (<code>null</code> not permitted).
    441         * @param linePaint  the line paint (<code>null</code> not permitted).
    442         */
    443        public LegendItem(AttributedString label, String description,
    444                          String toolTipText, String urlText,
    445                          boolean shapeVisible, Shape shape,
    446                          boolean shapeFilled, Paint fillPaint,
    447                          boolean shapeOutlineVisible, Paint outlinePaint,
    448                          Stroke outlineStroke,
    449                          boolean lineVisible, Shape line, Stroke lineStroke,
    450                          Paint linePaint) {
    451
    452            if (label == null) {
    453                throw new IllegalArgumentException("Null 'label' argument.");
    454            }
    455            if (fillPaint == null) {
    456                throw new IllegalArgumentException("Null 'fillPaint' argument.");
    457            }
    458            if (lineStroke == null) {
    459                throw new IllegalArgumentException("Null 'lineStroke' argument.");
    460            }
    461            if (line == null) {
    462                throw new IllegalArgumentException("Null 'line' argument.");
    463            }
    464            if (linePaint == null) {
    465                throw new IllegalArgumentException("Null 'linePaint' argument.");
    466            }
    467            if (outlinePaint == null) {
    468                throw new IllegalArgumentException("Null 'outlinePaint' argument.");
    469            }
    470            if (outlineStroke == null) {
    471                throw new IllegalArgumentException(
    472                    "Null 'outlineStroke' argument.");
    473            }
    474            this.label = characterIteratorToString(label.getIterator());
    475            this.attributedLabel = label;
    476            this.description = description;
    477            this.shapeVisible = shapeVisible;
    478            this.shape = shape;
    479            this.shapeFilled = shapeFilled;
    480            this.fillPaint = fillPaint;
    481            this.fillPaintTransformer = new StandardGradientPaintTransformer();
    482            this.shapeOutlineVisible = shapeOutlineVisible;
    483            this.outlinePaint = outlinePaint;
    484            this.outlineStroke = outlineStroke;
    485            this.lineVisible = lineVisible;
    486            this.line = line;
    487            this.lineStroke = lineStroke;
    488            this.linePaint = linePaint;
    489            this.toolTipText = toolTipText;
    490            this.urlText = urlText;
    491        }
    492
    493        /**
    494         * Returns a string containing the characters from the given iterator.
    495         *
    496         * @param iterator  the iterator (<code>null</code> not permitted).
    497         *
    498         * @return A string.
    499         */
    500        private String characterIteratorToString(CharacterIterator iterator) {
    501            int endIndex = iterator.getEndIndex();
    502            int beginIndex = iterator.getBeginIndex();
    503            int count = endIndex - beginIndex;
    504            if (count <= 0) {
    505                return "";
    506            }
    507            char[] chars = new char[count];
    508            int i = 0;
    509            char c = iterator.first();
    510            while (c != CharacterIterator.DONE) {
    511                chars[i] = c;
    512                i++;
    513                c = iterator.next();
    514            }
    515            return new String(chars);
    516        }
    517
    518        /**
    519         * Returns the dataset.
    520         *
    521         * @return The dataset.
    522         *
    523         * @since 1.0.6
    524         *
    525         * @see #setDatasetIndex(int)
    526         */
    527        public Dataset getDataset() {
    528            return this.dataset;
    529        }
    530
    531        /**
    532         * Sets the dataset.
    533         *
    534         * @param dataset  the dataset.
    535         *
    536         * @since 1.0.6
    537         */
    538        public void setDataset(Dataset dataset) {
    539            this.dataset = dataset;
    540        }
    541
    542        /**
    543         * Returns the dataset index for this legend item.
    544         *
    545         * @return The dataset index.
    546         *
    547         * @since 1.0.2
    548         *
    549         * @see #setDatasetIndex(int)
    550         * @see #getDataset()
    551         */
    552        public int getDatasetIndex() {
    553            return this.datasetIndex;
    554        }
    555
    556        /**
    557         * Sets the dataset index for this legend item.
    558         *
    559         * @param index  the index.
    560         *
    561         * @since 1.0.2
    562         *
    563         * @see #getDatasetIndex()
    564         */
    565        public void setDatasetIndex(int index) {
    566            this.datasetIndex = index;
    567        }
    568
    569        /**
    570         * Returns the series key.
    571         *
    572         * @return The series key.
    573         *
    574         * @since 1.0.6
    575         *
    576         * @see #setSeriesKey(Comparable)
    577         */
    578        public Comparable getSeriesKey() {
    579            return this.seriesKey;
    580        }
    581
    582        /**
    583         * Sets the series key.
    584         *
    585         * @param key  the series key.
    586         *
    587         * @since 1.0.6
    588         */
    589        public void setSeriesKey(Comparable key) {
    590            this.seriesKey = key;
    591        }
    592
    593        /**
    594         * Returns the series index for this legend item.
    595         *
    596         * @return The series index.
    597         *
    598         * @since 1.0.2
    599         */
    600        public int getSeriesIndex() {
    601            return this.series;
    602        }
    603
    604        /**
    605         * Sets the series index for this legend item.
    606         *
    607         * @param index  the index.
    608         *
    609         * @since 1.0.2
    610         */
    611        public void setSeriesIndex(int index) {
    612            this.series = index;
    613        }
    614
    615        /**
    616         * Returns the label.
    617         *
    618         * @return The label (never <code>null</code>).
    619         */
    620        public String getLabel() {
    621            return this.label;
    622        }
    623
    624        /**
    625         * Returns the attributed label.
    626         *
    627         * @return The attributed label (possibly <code>null</code>).
    628         */
    629        public AttributedString getAttributedLabel() {
    630            return this.attributedLabel;
    631        }
    632
    633        /**
    634         * Returns the description for the legend item.
    635         *
    636         * @return The description.
    637         */
    638        public String getDescription() {
    639            return this.description;
    640        }
    641
    642        /**
    643         * Returns the tool tip text.
    644         *
    645         * @return The tool tip text (possibly <code>null</code>).
    646         */
    647        public String getToolTipText() {
    648            return this.toolTipText;
    649        }
    650
    651        /**
    652         * Returns the URL text.
    653         *
    654         * @return The URL text (possibly <code>null</code>).
    655         */
    656        public String getURLText() {
    657            return this.urlText;
    658        }
    659
    660        /**
    661         * Returns a flag that indicates whether or not the shape is visible.
    662         *
    663         * @return A boolean.
    664         */
    665        public boolean isShapeVisible() {
    666            return this.shapeVisible;
    667        }
    668
    669        /**
    670         * Returns the shape used to label the series represented by this legend
    671         * item.
    672         *
    673         * @return The shape (never <code>null</code>).
    674         */
    675        public Shape getShape() {
    676            return this.shape;
    677        }
    678
    679        /**
    680         * Returns a flag that controls whether or not the shape is filled.
    681         *
    682         * @return A boolean.
    683         */
    684        public boolean isShapeFilled() {
    685            return this.shapeFilled;
    686        }
    687
    688        /**
    689         * Returns the fill paint.
    690         *
    691         * @return The fill paint (never <code>null</code>).
    692         */
    693        public Paint getFillPaint() {
    694            return this.fillPaint;
    695        }
    696
    697        /**
    698         * Returns the flag that controls whether or not the shape outline
    699         * is visible.
    700         *
    701         * @return A boolean.
    702         */
    703        public boolean isShapeOutlineVisible() {
    704            return this.shapeOutlineVisible;
    705        }
    706
    707        /**
    708         * Returns the line stroke for the series.
    709         *
    710         * @return The stroke (never <code>null</code>).
    711         */
    712        public Stroke getLineStroke() {
    713            return this.lineStroke;
    714        }
    715
    716        /**
    717         * Returns the paint used for lines.
    718         *
    719         * @return The paint.
    720         */
    721        public Paint getLinePaint() {
    722            return this.linePaint;
    723        }
    724
    725        /**
    726         * Returns the outline paint.
    727         *
    728         * @return The outline paint (never <code>null</code>).
    729         */
    730        public Paint getOutlinePaint() {
    731            return this.outlinePaint;
    732        }
    733
    734        /**
    735         * Returns the outline stroke.
    736         *
    737         * @return The outline stroke (never <code>null</code>).
    738         */
    739        public Stroke getOutlineStroke() {
    740            return this.outlineStroke;
    741        }
    742
    743        /**
    744         * Returns a flag that indicates whether or not the line is visible.
    745         *
    746         * @return A boolean.
    747         */
    748        public boolean isLineVisible() {
    749            return this.lineVisible;
    750        }
    751
    752        /**
    753         * Returns the line.
    754         *
    755         * @return The line (never <code>null</code>).
    756         */
    757        public Shape getLine() {
    758            return this.line;
    759        }
    760
    761        /**
    762         * Returns the transformer used when the fill paint is an instance of
    763         * <code>GradientPaint</code>.
    764         *
    765         * @return The transformer (never <code>null</code>).
    766         *
    767         * @since 1.0.4
    768         *
    769         * @see #setFillPaintTransformer(GradientPaintTransformer)
    770         */
    771        public GradientPaintTransformer getFillPaintTransformer() {
    772            return this.fillPaintTransformer;
    773        }
    774
    775        /**
    776         * Sets the transformer used when the fill paint is an instance of
    777         * <code>GradientPaint</code>.
    778         *
    779         * @param transformer  the transformer (<code>null</code> not permitted).
    780         *
    781         * @since 1.0.4
    782         *
    783         * @see #getFillPaintTransformer()
    784         */
    785        public void setFillPaintTransformer(GradientPaintTransformer transformer) {
    786            if (transformer == null) {
    787                throw new IllegalArgumentException("Null 'transformer' attribute.");
    788            }
    789            this.fillPaintTransformer = transformer;
    790        }
    791
    792        /**
    793         * Tests this item for equality with an arbitrary object.
    794         *
    795         * @param obj  the object (<code>null</code> permitted).
    796         *
    797         * @return A boolean.
    798         */
    799        public boolean equals(Object obj) {
    800            if (obj == this) {
    801                return true;
    802            }
    803            if (!(obj instanceof LegendItem)) {
    804                    return false;
    805            }
    806            LegendItem that = (LegendItem) obj;
    807            if (this.datasetIndex != that.datasetIndex) {
    808                return false;
    809            }
    810            if (this.series != that.series) {
    811                return false;
    812            }
    813            if (!this.label.equals(that.label)) {
    814                return false;
    815            }
    816            if (!AttributedStringUtilities.equal(this.attributedLabel,
    817                    that.attributedLabel)) {
    818                return false;
    819            }
    820            if (!ObjectUtilities.equal(this.description, that.description)) {
    821                return false;
    822            }
    823            if (this.shapeVisible != that.shapeVisible) {
    824                return false;
    825            }
    826            if (!ShapeUtilities.equal(this.shape, that.shape)) {
    827                return false;
    828            }
    829            if (this.shapeFilled != that.shapeFilled) {
    830                return false;
    831            }
    832            if (!this.fillPaint.equals(that.fillPaint)) {
    833                return false;
    834            }
    835            if (!ObjectUtilities.equal(this.fillPaintTransformer,
    836                    that.fillPaintTransformer)) {
    837                return false;
    838            }
    839            if (this.shapeOutlineVisible != that.shapeOutlineVisible) {
    840                return false;
    841            }
    842            if (!this.outlineStroke.equals(that.outlineStroke)) {
    843                return false;
    844            }
    845            if (!this.outlinePaint.equals(that.outlinePaint)) {
    846                return false;
    847            }
    848            if (!this.lineVisible == that.lineVisible) {
    849                return false;
    850            }
    851            if (!ShapeUtilities.equal(this.line, that.line)) {
    852                return false;
    853            }
    854            if (!this.lineStroke.equals(that.lineStroke)) {
    855                return false;
    856            }
    857            if (!this.linePaint.equals(that.linePaint)) {
    858                return false;
    859            }
    860            return true;
    861        }
    862
    863        /**
    864         * Returns an independent copy of this object (except that the clone will
    865         * still reference the same dataset as the original
    866         * <code>LegendItem</code>).
    867         *
    868         * @return A clone.
    869         *
    870         * @since 1.0.10
    871         */
    872        public Object clone() throws CloneNotSupportedException {
    873            LegendItem clone = (LegendItem) super.clone();
    874            if (this.seriesKey instanceof PublicCloneable) {
    875                PublicCloneable pc = (PublicCloneable) this.seriesKey;
    876                clone.seriesKey = (Comparable) pc.clone();
    877            }
    878            // FIXME: Clone the attributed string if it is not null
    879            clone.shape = ShapeUtilities.clone(this.shape);
    880            if (this.fillPaintTransformer instanceof PublicCloneable) {
    881                PublicCloneable pc = (PublicCloneable) this.fillPaintTransformer;
    882                clone.fillPaintTransformer = (GradientPaintTransformer) pc.clone();
    883
    884            }
    885            clone.line = ShapeUtilities.clone(this.line);
    886            return clone;
    887        }
    888
    889        /**
    890         * Provides serialization support.
    891         *
    892         * @param stream  the output stream (<code>null</code> not permitted).
    893         *
    894         * @throws IOException  if there is an I/O error.
    895         */
    896        private void writeObject(ObjectOutputStream stream) throws IOException {
    897            stream.defaultWriteObject();
    898            SerialUtilities.writeAttributedString(this.attributedLabel, stream);
    899            SerialUtilities.writeShape(this.shape, stream);
    900            SerialUtilities.writePaint(this.fillPaint, stream);
    901            SerialUtilities.writeStroke(this.outlineStroke, stream);
    902            SerialUtilities.writePaint(this.outlinePaint, stream);
    903            SerialUtilities.writeShape(this.line, stream);
    904            SerialUtilities.writeStroke(this.lineStroke, stream);
    905            SerialUtilities.writePaint(this.linePaint, stream);
    906        }
    907
    908        /**
    909         * Provides serialization support.
    910         *
    911         * @param stream  the input stream (<code>null</code> not permitted).
    912         *
    913         * @throws IOException  if there is an I/O error.
    914         * @throws ClassNotFoundException  if there is a classpath problem.
    915         */
    916        private void readObject(ObjectInputStream stream)
    917            throws IOException, ClassNotFoundException {
    918            stream.defaultReadObject();
    919            this.attributedLabel = SerialUtilities.readAttributedString(stream);
    920            this.shape = SerialUtilities.readShape(stream);
    921            this.fillPaint = SerialUtilities.readPaint(stream);
    922            this.outlineStroke = SerialUtilities.readStroke(stream);
    923            this.outlinePaint = SerialUtilities.readPaint(stream);
    924            this.line = SerialUtilities.readShape(stream);
    925            this.lineStroke = SerialUtilities.readStroke(stream);
    926            this.linePaint = SerialUtilities.readPaint(stream);
    927        }
    928
    929    }