    001    /* ===========================================================
    002     * JFreeChart : a free chart library for the Java(tm) platform
    003     * ===========================================================
    004     *
    005     * (C) Copyright 2000-2005, 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     * Marker.java
    029     * -----------
    030     * (C) Copyright 2002-2005, by Object Refinery Limited.
    031     *
    032     * Original Author:  David Gilbert (for Object Refinery Limited);
    033     * Contributor(s):   Nicolas Brodu;
    034     *
    035     * $Id: Marker.java,v 1.10.2.3 2005/10/25 20:52:08 mungady Exp $
    036     *
    037     * Changes (since 2-Jul-2002)
    038     * --------------------------
    039     * 02-Jul-2002 : Added extra constructor, standard header and Javadoc
    040     *               comments (DG);
    041     * 20-Aug-2002 : Added the outline stroke attribute (DG);
    042     * 02-Oct-2002 : Fixed errors reported by Checkstyle (DG);
    043     * 16-Oct-2002 : Added new constructor (DG);
    044     * 26-Mar-2003 : Implemented Serializable (DG);
    045     * 21-May-2003 : Added labels (DG);
    046     * 11-Sep-2003 : Implemented Cloneable (NB);
    047     * 05-Nov-2003 : Added checks to ensure some attributes are never null (DG);
    048     * 11-Feb-2003 : Moved to org.jfree.chart.plot package, plus significant API
    049     *               changes to support IntervalMarker in plots (DG);
    050     * 14-Jun-2004 : Updated equals() method (DG);
    051     * 21-Jan-2005 : Added settings to control direction of horizontal and
    052     *               vertical label offsets (DG);
    053     * 01-Jun-2005 : Modified to use only one label offset type - this will be
    054     *               applied to the domain or range axis as appropriate (DG);
    055     * 06-Jun-2005 : Fix equals() method to handle GradientPaint (DG);
    056     * 19-Aug-2005 : Changed constructor from public --> protected (DG);
    057     *
    058     */
    059
    060    package org.jfree.chart.plot;
    061
    062    import java.awt.BasicStroke;
    063    import java.awt.Color;
    064    import java.awt.Font;
    065    import java.awt.Paint;
    066    import java.awt.Stroke;
    067    import java.io.IOException;
    068    import java.io.ObjectInputStream;
    069    import java.io.ObjectOutputStream;
    070    import java.io.Serializable;
    071
    072    import org.jfree.io.SerialUtilities;
    073    import org.jfree.ui.LengthAdjustmentType;
    074    import org.jfree.ui.RectangleAnchor;
    075    import org.jfree.ui.RectangleInsets;
    076    import org.jfree.ui.TextAnchor;
    077    import org.jfree.util.ObjectUtilities;
    078    import org.jfree.util.PaintUtilities;
    079
    080    /**
    081     * The base class for markers that can be added to plots to highlight a value
    082     * or range of values.
    083     */
    084    public abstract class Marker implements Cloneable, Serializable {
    085
    086        /** For serialization. */
    087        private static final long serialVersionUID = -734389651405327166L;
    088
    089        /** The paint. */
    090        private transient Paint paint;
    091
    092        /** The stroke. */
    093        private transient Stroke stroke;
    094
    095        /** The outline paint. */
    096        private transient Paint outlinePaint;
    097
    098        /** The outline stroke. */
    099        private transient Stroke outlineStroke;
    100
    101        /** The alpha transparency. */
    102        private float alpha;
    103
    104        /** The label. */
    105        private String label = null;
    106
    107        /** The label font. */
    108        private Font labelFont;
    109
    110        /** The label paint. */
    111        private transient Paint labelPaint;
    112
    113        /** The label position. */
    114        private RectangleAnchor labelAnchor;
    115
    116        /** The text anchor for the label. */
    117        private TextAnchor labelTextAnchor;
    118
    119        /** The label offset from the marker rectangle. */
    120        private RectangleInsets labelOffset;
    121
    122        /**
    123         * The offset type for the domain or range axis (never <code>null</code>).
    124         */
    125        private LengthAdjustmentType labelOffsetType;
    126
    127        /**
    128         * Creates a new marker with default attributes.
    129         */
    130        protected Marker() {
    131            this(Color.gray);
    132        }
    133
    134        /**
    135         * Constructs a new marker.
    136         *
    137         * @param paint  the paint (<code>null</code> not permitted).
    138         */
    139        protected Marker(Paint paint) {
    140            this(
    141                paint, new BasicStroke(0.5f), Color.gray,
    142                new BasicStroke(0.5f), 0.80f
    143            );
    144        }
    145
    146        /**
    147         * Constructs a new marker.
    148         *
    149         * @param paint  the paint (<code>null</code> not permitted).
    150         * @param stroke  the stroke (<code>null</code> not permitted).
    151         * @param outlinePaint  the outline paint (<code>null</code> permitted).
    152         * @param outlineStroke  the outline stroke (<code>null</code> permitted).
    153         * @param alpha  the alpha transparency.
    154         */
    155        protected Marker(Paint paint, Stroke stroke,
    156                         Paint outlinePaint, Stroke outlineStroke,
    157                         float alpha) {
    158
    159            if (paint == null) {
    160                throw new IllegalArgumentException("Null 'paint' argument.");
    161            }
    162            if (stroke == null) {
    163                throw new IllegalArgumentException("Null 'stroke' argument.");
    164            }
    165
    166            this.paint = paint;
    167            this.stroke = stroke;
    168            this.outlinePaint = outlinePaint;
    169            this.outlineStroke = outlineStroke;
    170            this.alpha = alpha;
    171
    172            this.labelFont = new Font("SansSerif", Font.PLAIN, 9);
    173            this.labelPaint = Color.black;
    174            this.labelAnchor = RectangleAnchor.TOP_LEFT;
    175            this.labelOffset = new RectangleInsets(3.0, 3.0, 3.0, 3.0);
    176            this.labelOffsetType = LengthAdjustmentType.CONTRACT;
    177            this.labelTextAnchor = TextAnchor.CENTER;
    178
    179        }
    180
    181        /**
    182         * Returns the paint.
    183         *
    184         * @return The paint (never <code>null</code>).
    185         */
    186        public Paint getPaint() {
    187            return this.paint;
    188        }
    189
    190        /**
    191         * Sets the paint.
    192         *
    193         * @param paint  the paint (<code>null</code> not permitted).
    194         */
    195        public void setPaint(Paint paint) {
    196            if (paint == null) {
    197                throw new IllegalArgumentException("Null 'paint' argument.");
    198            }
    199            this.paint = paint;
    200        }
    201
    202        /**
    203         * Returns the stroke.
    204         *
    205         * @return The stroke (never <code>null</code>).
    206         */
    207        public Stroke getStroke() {
    208            return this.stroke;
    209        }
    210
    211        /**
    212         * Sets the stroke.
    213         *
    214         * @param stroke  the stroke (<code>null</code> not permitted).
    215         */
    216        public void setStroke(Stroke stroke) {
    217            if (stroke == null) {
    218                throw new IllegalArgumentException("Null 'stroke' argument.");
    219            }
    220            this.stroke = stroke;
    221        }
    222
    223        /**
    224         * Returns the outline paint.
    225         *
    226         * @return The outline paint (possibly <code>null</code>).
    227         */
    228        public Paint getOutlinePaint() {
    229            return this.outlinePaint;
    230        }
    231
    232        /**
    233         * Sets the outline paint.
    234         *
    235         * @param paint  the paint (<code>null</code> permitted).
    236         */
    237        public void setOutlinePaint(Paint paint) {
    238            this.outlinePaint = paint;
    239        }
    240
    241        /**
    242         * Returns the outline stroke.
    243         *
    244         * @return The outline stroke (possibly <code>null</code>).
    245         */
    246        public Stroke getOutlineStroke() {
    247            return this.outlineStroke;
    248        }
    249
    250        /**
    251         * Sets the outline stroke.
    252         *
    253         * @param stroke  the stroke (<code>null</code> permitted).
    254         */
    255        public void setOutlineStroke(Stroke stroke) {
    256            this.outlineStroke = stroke;
    257        }
    258
    259        /**
    260         * Returns the alpha transparency.
    261         *
    262         * @return The alpha transparency.
    263         */
    264        public float getAlpha() {
    265            return this.alpha;
    266        }
    267
    268        /**
    269         * Sets the alpha transparency.
    270         *
    271         * @param alpha  the alpha transparency.
    272         */
    273        public void setAlpha(float alpha) {
    274            this.alpha = alpha;
    275        }
    276
    277        /**
    278         * Returns the label (if <code>null</code> no label is displayed).
    279         *
    280         * @return The label (possibly <code>null</code>).
    281         */
    282        public String getLabel() {
    283            return this.label;
    284        }
    285
    286        /**
    287         * Sets the label (if <code>null</code> no label is displayed).
    288         *
    289         * @param label  the label (<code>null</code> permitted).
    290         */
    291        public void setLabel(String label) {
    292            this.label = label;
    293        }
    294
    295        /**
    296         * Returns the label font.
    297         *
    298         * @return The label font (never <code>null</code>).
    299         */
    300        public Font getLabelFont() {
    301            return this.labelFont;
    302        }
    303
    304        /**
    305         * Sets the label font.
    306         *
    307         * @param font  the font (<code>null</code> not permitted).
    308         */
    309        public void setLabelFont(Font font) {
    310            if (font == null) {
    311                throw new IllegalArgumentException("Null 'font' argument.");
    312            }
    313            this.labelFont = font;
    314        }
    315
    316        /**
    317         * Returns the label paint.
    318         *
    319         * @return The label paint (never </code>null</code>).
    320         */
    321        public Paint getLabelPaint() {
    322            return this.labelPaint;
    323        }
    324
    325        /**
    326         * Sets the label paint.
    327         *
    328         * @param paint  the paint (<code>null</code> not permitted).
    329         */
    330        public void setLabelPaint(Paint paint) {
    331            if (paint == null) {
    332                throw new IllegalArgumentException("Null 'paint' argument.");
    333            }
    334            this.labelPaint = paint;
    335        }
    336
    337        /**
    338         * Returns the label anchor.
    339         *
    340         * @return The label anchor (never <code>null</code>).
    341         */
    342        public RectangleAnchor getLabelAnchor() {
    343            return this.labelAnchor;
    344        }
    345
    346        /**
    347         * Sets the label anchor.
    348         *
    349         * @param anchor  the anchor (<code>null</code> not permitted).
    350         */
    351        public void setLabelAnchor(RectangleAnchor anchor) {
    352            if (anchor == null) {
    353                throw new IllegalArgumentException("Null 'anchor' argument.");
    354            }
    355            this.labelAnchor = anchor;
    356        }
    357
    358        /**
    359         * Returns the label offset.
    360         *
    361         * @return The label offset (never <code>null</code>).
    362         */
    363        public RectangleInsets getLabelOffset() {
    364            return this.labelOffset;
    365        }
    366
    367        /**
    368         * Sets the label offset.
    369         *
    370         * @param offset  the label offset (<code>null</code> not permitted).
    371         */
    372        public void setLabelOffset(RectangleInsets offset) {
    373            if (offset == null) {
    374                throw new IllegalArgumentException("Null 'offset' argument.");
    375            }
    376            this.labelOffset = offset;
    377        }
    378
    379        /**
    380         * Returns the label offset type.
    381         *
    382         * @return The type (never <code>null</code>).
    383         */
    384        public LengthAdjustmentType getLabelOffsetType() {
    385            return this.labelOffsetType;
    386        }
    387
    388        /**
    389         * Sets the label offset type.
    390         *
    391         * @param adj  the type (<code>null</code> not permitted).
    392         */
    393        public void setLabelOffsetType(LengthAdjustmentType adj) {
    394            if (adj == null) {
    395                throw new IllegalArgumentException("Null 'adj' argument.");
    396            }
    397            this.labelOffsetType = adj;
    398        }
    399
    400        /**
    401         * Returns the label text anchor.
    402         *
    403         * @return The label text anchor (never <code>null</code>).
    404         */
    405        public TextAnchor getLabelTextAnchor() {
    406            return this.labelTextAnchor;
    407        }
    408
    409        /**
    410         * Sets the label text anchor.
    411         *
    412         * @param anchor  the label text anchor (<code>null</code> not permitted).
    413         */
    414        public void setLabelTextAnchor(TextAnchor anchor) {
    415            if (anchor == null) {
    416                throw new IllegalArgumentException("Null 'anchor' argument.");
    417            }
    418            this.labelTextAnchor = anchor;
    419        }
    420
    421        /**
    422         * Tests the marker for equality with an arbitrary object.
    423         *
    424         * @param obj  the object (<code>null</code> permitted).
    425         *
    426         * @return A boolean.
    427         */
    428        public boolean equals(Object obj) {
    429            if (obj == this) {
    430                return true;
    431            }
    432            if (!(obj instanceof Marker)) {
    433                return false;
    434            }
    435            Marker that = (Marker) obj;
    436            if (!PaintUtilities.equal(this.paint, that.paint)) {
    437                return false;
    438            }
    439            if (!ObjectUtilities.equal(this.stroke, that.stroke)) {
    440                return false;
    441            }
    442            if (!PaintUtilities.equal(this.outlinePaint, that.outlinePaint)) {
    443                return false;
    444            }
    445            if (!ObjectUtilities.equal(this.outlineStroke, that.outlineStroke)) {
    446                return false;
    447            }
    448            if (this.alpha != that.alpha) {
    449                return false;
    450            }
    451            if (!ObjectUtilities.equal(this.label, that.label)) {
    452                return false;
    453            }
    454            if (!ObjectUtilities.equal(this.labelFont, that.labelFont)) {
    455                return false;
    456            }
    457            if (!PaintUtilities.equal(this.labelPaint, that.labelPaint)) {
    458                return false;
    459            }
    460            if (this.labelAnchor != that.labelAnchor) {
    461                return false;
    462            }
    463            if (this.labelTextAnchor != that.labelTextAnchor) {
    464                return false;
    465            }
    466            if (!ObjectUtilities.equal(this.labelOffset, that.labelOffset)) {
    467                return false;
    468            }
    469            if (!this.labelOffsetType.equals(that.labelOffsetType)) {
    470                return false;
    471            }
    472            return true;
    473        }
    474
    475        /**
    476         * Creates a clone of the marker.
    477         *
    478         * @return A clone.
    479         *
    480         * @throws CloneNotSupportedException never.
    481         */
    482        public Object clone() throws CloneNotSupportedException {
    483            return super.clone();
    484        }
    485
    486        /**
    487         * Provides serialization support.
    488         *
    489         * @param stream  the output stream.
    490         *
    491         * @throws IOException  if there is an I/O error.
    492         */
    493        private void writeObject(ObjectOutputStream stream) throws IOException {
    494            stream.defaultWriteObject();
    495            SerialUtilities.writePaint(this.paint, stream);
    496            SerialUtilities.writeStroke(this.stroke, stream);
    497            SerialUtilities.writePaint(this.outlinePaint, stream);
    498            SerialUtilities.writeStroke(this.outlineStroke, stream);
    499            SerialUtilities.writePaint(this.labelPaint, stream);
    500        }
    501
    502        /**
    503         * Provides serialization support.
    504         *
    505         * @param stream  the input stream.
    506         *
    507         * @throws IOException  if there is an I/O error.
    508         * @throws ClassNotFoundException  if there is a classpath problem.
    509         */
    510        private void readObject(ObjectInputStream stream)
    511            throws IOException, ClassNotFoundException {
    512            stream.defaultReadObject();
    513            this.paint = SerialUtilities.readPaint(stream);
    514            this.stroke = SerialUtilities.readStroke(stream);
    515            this.outlinePaint = SerialUtilities.readPaint(stream);
    516            this.outlineStroke = SerialUtilities.readStroke(stream);
    517            this.labelPaint = SerialUtilities.readPaint(stream);
    518        }
    519
    520    }