    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     * ClipPath.java
    029     * -------------
    030     * (C) Copyright 2003, 2004, by David M. O'Donnell and Contributors.
    031     *
    032     * Original Author:  David M. O'Donnell;
    033     * Contributor(s):   David Gilbert (for Object Refinery Limited);
    034     *                   Nicolas Brodu;
    035     *
    036     * $Id: ClipPath.java,v 1.2.2.1 2005/10/25 16:50:20 mungady Exp $
    037     *
    038     * Changes
    039     * -------
    040     * 22-Apr-2003 : Added standard header (DG);
    041     * 09-May-2003 : Added AxisLocation (DG);
    042     * 11-Sep-2003 : Implemented Cloneable (NB);
    043     * 21-Jan-2004 : Update for renamed method in ValueAxis (DG);
    044     *
    045     */
    046
    047    package org.jfree.chart;
    048
    049    import java.awt.BasicStroke;
    050    import java.awt.Composite;
    051    import java.awt.Graphics2D;
    052    import java.awt.Paint;
    053    import java.awt.Stroke;
    054    import java.awt.geom.GeneralPath;
    055    import java.awt.geom.Rectangle2D;
    056
    057    import org.jfree.chart.axis.ValueAxis;
    058    import org.jfree.ui.RectangleEdge;
    059
    060    /**
    061     * This class would typically be used with a
    062     * {@link org.jfree.chart.plot.ContourPlot}.  It allows the user to define a
    063     * <code>GeneralPath</code> curve in plot coordinates.  This curve can then be
    064     * used mask off or define regions within the contour plot.  The data must be
    065     * sorted.
    066     *
    067     * @author dmo
    068     */
    069    public class ClipPath implements Cloneable {
    070
    071        /** The x values. */
    072        private double[] xValue = null;
    073
    074        /** The y values. */
    075        private double[] yValue = null;
    076
    077        /** Controls whether drawing will be clipped (
    078         * false would still allow the drawing or filling of path */
    079        private boolean clip = true;
    080
    081        /** Controls whether the path is drawn as an outline. */
    082        private boolean drawPath = false;
    083
    084        /** Controls whether the path is filled. */
    085        private boolean fillPath = false;
    086
    087        /** The fill paint. */
    088        private Paint fillPaint = null;
    089
    090        /** The draw paint. */
    091        private Paint drawPaint = null;
    092
    093        /** The draw stroke. */
    094        private Stroke drawStroke = null;
    095
    096        /** The composite. */
    097        private Composite composite = null;
    098
    099        /**
    100         * Constructor for ClipPath.
    101         */
    102        public ClipPath() {
    103            super();
    104        }
    105
    106        /**
    107         * Constructor for ClipPath.
    108         * Default values are assumed for the fillPath and drawPath options as
    109         * false and true respectively.  The fillPaint is set to Color.GRAY, the
    110         * drawColor is Color.BLUE, the stroke is BasicStroke(1)
    111         * and the composite is AlphaComposite.Src.
    112         *
    113         * @param xValue  x coordinates of curved to be created
    114         * @param yValue  y coordinates of curved to be created
    115         */
    116        public ClipPath(double[] xValue, double[] yValue) {
    117            this(xValue, yValue, true, false, true);
    118        }
    119
    120
    121        /**
    122         * Constructor for ClipPath.
    123         * The fillPaint is set to Color.GRAY, the drawColor is Color.BLUE, the
    124         * stroke is BasicStroke(1) and the composite is AlphaComposite.Src.
    125         *
    126         * @param xValue  x coordinates of curved to be created
    127         * @param yValue  y coordinates of curved to be created
    128         * @param clip  clip?
    129         * @param fillPath  whether the path is to filled
    130         * @param drawPath  whether the path is to drawn as an outline
    131         */
    132        public ClipPath(double[] xValue, double[] yValue,
    133                        boolean clip, boolean fillPath, boolean drawPath) {
    134            this.xValue = xValue;
    135            this.yValue = yValue;
    136
    137            this.clip = clip;
    138            this.fillPath = fillPath;
    139            this.drawPath = drawPath;
    140
    141            this.fillPaint = java.awt.Color.gray;
    142            this.drawPaint = java.awt.Color.blue;
    143            this.drawStroke = new BasicStroke(1);
    144            this.composite = java.awt.AlphaComposite.Src;
    145        }
    146
    147        /**
    148         * Constructor for ClipPath.
    149         *
    150         * @param xValue  x coordinates of curved to be created
    151         * @param yValue  y coordinates of curved to be created
    152         * @param fillPath  whether the path is to filled
    153         * @param drawPath  whether the path is to drawn as an outline
    154         * @param fillPaint  the fill paint
    155         * @param drawPaint  the outline stroke color
    156         * @param drawStroke  the stroke style
    157         * @param composite  the composite rule
    158         */
    159        public ClipPath(double[] xValue, double[] yValue, boolean fillPath,
    160                        boolean drawPath, Paint fillPaint, Paint drawPaint,
    161                        Stroke drawStroke, Composite composite) {
    162
    163            this.xValue = xValue;
    164            this.yValue = yValue;
    165
    166            this.fillPath = fillPath;
    167            this.drawPath = drawPath;
    168
    169            this.fillPaint = fillPaint;
    170            this.drawPaint = drawPaint;
    171            this.drawStroke = drawStroke;
    172            this.composite = composite;
    173
    174        }
    175
    176        /**
    177         * Draws the clip path.
    178         *
    179         * @param g2  current graphics2D.
    180         * @param dataArea  the dataArea that the plot is being draw in.
    181         * @param horizontalAxis  the horizontal axis.
    182         * @param verticalAxis  the vertical axis.
    183         *
    184         * @return The GeneralPath defining the outline
    185         */
    186        public GeneralPath draw(Graphics2D g2,
    187                                Rectangle2D dataArea,
    188                                ValueAxis horizontalAxis, ValueAxis verticalAxis) {
    189
    190            GeneralPath generalPath = generateClipPath(
    191                dataArea, horizontalAxis, verticalAxis
    192            );
    193            if (this.fillPath || this.drawPath) {
    194                Composite saveComposite = g2.getComposite();
    195                Paint savePaint = g2.getPaint();
    196                Stroke saveStroke = g2.getStroke();
    197
    198                if (this.fillPaint != null) {
    199                    g2.setPaint(this.fillPaint);
    200                }
    201                if (this.composite != null) {
    202                    g2.setComposite(this.composite);
    203                }
    204                if (this.fillPath) {
    205                    g2.fill(generalPath);
    206                }
    207
    208                if (this.drawStroke != null) {
    209                    g2.setStroke(this.drawStroke);
    210                }
    211                if (this.drawPath) {
    212                    g2.draw(generalPath);
    213                }
    214                g2.setPaint(savePaint);
    215                g2.setComposite(saveComposite);
    216                g2.setStroke(saveStroke);
    217            }
    218            return generalPath;
    219
    220        }
    221
    222        /**
    223         * Generates the clip path.
    224         *
    225         * @param dataArea  the dataArea that the plot is being draw in.
    226         * @param horizontalAxis  the horizontal axis.
    227         * @param verticalAxis  the vertical axis.
    228         *
    229         * @return The GeneralPath defining the outline
    230         */
    231        public GeneralPath generateClipPath(Rectangle2D dataArea,
    232                                            ValueAxis horizontalAxis,
    233                                            ValueAxis verticalAxis) {
    234
    235            GeneralPath generalPath = new GeneralPath();
    236            double transX = horizontalAxis.valueToJava2D(
    237                this.xValue[0], dataArea, RectangleEdge.BOTTOM
    238            );
    239            double transY = verticalAxis.valueToJava2D(
    240                this.yValue[0], dataArea, RectangleEdge.LEFT
    241            );
    242            generalPath.moveTo((float) transX, (float) transY);
    243            for (int k = 0; k < this.yValue.length; k++) {
    244                transX = horizontalAxis.valueToJava2D(
    245                    this.xValue[k], dataArea, RectangleEdge.BOTTOM
    246                );
    247                transY = verticalAxis.valueToJava2D(
    248                    this.yValue[k], dataArea, RectangleEdge.LEFT
    249                );
    250                generalPath.lineTo((float) transX, (float) transY);
    251            }
    252            generalPath.closePath();
    253
    254            return generalPath;
    255
    256        }
    257
    258        /**
    259         * Returns the composite.
    260         *
    261         * @return Composite
    262         */
    263        public Composite getComposite() {
    264            return this.composite;
    265        }
    266
    267        /**
    268         * Returns the drawPaint.
    269         *
    270         * @return Paint
    271         */
    272        public Paint getDrawPaint() {
    273            return this.drawPaint;
    274        }
    275
    276        /**
    277         * Returns the drawPath.
    278         *
    279         * @return boolean
    280         */
    281        public boolean isDrawPath() {
    282            return this.drawPath;
    283        }
    284
    285        /**
    286         * Returns the drawStroke.
    287         *
    288         * @return Stroke
    289         */
    290        public Stroke getDrawStroke() {
    291            return this.drawStroke;
    292        }
    293
    294        /**
    295         * Returns the fillPaint.
    296         *
    297         * @return Paint
    298         */
    299        public Paint getFillPaint() {
    300            return this.fillPaint;
    301        }
    302
    303        /**
    304         * Returns the fillPath.
    305         *
    306         * @return boolean
    307         */
    308        public boolean isFillPath() {
    309            return this.fillPath;
    310        }
    311
    312        /**
    313         * Returns the xValue.
    314         *
    315         * @return double[]
    316         */
    317        public double[] getXValue() {
    318            return this.xValue;
    319        }
    320
    321        /**
    322         * Returns the yValue.
    323         *
    324         * @return double[]
    325         */
    326        public double[] getYValue() {
    327            return this.yValue;
    328        }
    329
    330        /**
    331         * Sets the composite.
    332         *
    333         * @param composite The composite to set
    334         */
    335        public void setComposite(Composite composite) {
    336            this.composite = composite;
    337        }
    338
    339        /**
    340         * Sets the drawPaint.
    341         *
    342         * @param drawPaint The drawPaint to set
    343         */
    344        public void setDrawPaint(Paint drawPaint) {
    345            this.drawPaint = drawPaint;
    346        }
    347
    348        /**
    349         * Sets the drawPath.
    350         *
    351         * @param drawPath The drawPath to set
    352         */
    353        public void setDrawPath(boolean drawPath) {
    354            this.drawPath = drawPath;
    355        }
    356
    357        /**
    358         * Sets the drawStroke.
    359         *
    360         * @param drawStroke The drawStroke to set
    361         */
    362        public void setDrawStroke(Stroke drawStroke) {
    363            this.drawStroke = drawStroke;
    364        }
    365
    366        /**
    367         * Sets the fillPaint.
    368         *
    369         * @param fillPaint The fillPaint to set
    370         */
    371        public void setFillPaint(Paint fillPaint) {
    372            this.fillPaint = fillPaint;
    373        }
    374
    375        /**
    376         * Sets the fillPath.
    377         *
    378         * @param fillPath The fillPath to set
    379         */
    380        public void setFillPath(boolean fillPath) {
    381            this.fillPath = fillPath;
    382        }
    383
    384        /**
    385         * Sets the xValue.
    386         *
    387         * @param xValue The xValue to set
    388         */
    389        public void setXValue(double[] xValue) {
    390            this.xValue = xValue;
    391        }
    392
    393        /**
    394         * Sets the yValue.
    395         *
    396         * @param yValue The yValue to set
    397         */
    398        public void setYValue(double[] yValue) {
    399            this.yValue = yValue;
    400        }
    401
    402        /**
    403         * Returns the clip.
    404         *
    405         * @return boolean
    406         */
    407        public boolean isClip() {
    408            return this.clip;
    409        }
    410
    411        /**
    412         * Sets the clip.
    413         *
    414         * @param clip The clip to set
    415         */
    416        public void setClip(boolean clip) {
    417            this.clip = clip;
    418        }
    419
    420        /**
    421         * Returns a clone of the object (a deeper clone than default to avoid bugs
    422         * when setting values in cloned object).
    423         *
    424         * @return The clone.
    425         *
    426         * @throws CloneNotSupportedException if cloning is not supported.
    427         */
    428        public Object clone() throws CloneNotSupportedException {
    429            ClipPath clone = (ClipPath) super.clone();
    430            clone.xValue = (double[]) this.xValue.clone();
    431            clone.yValue = (double[]) this.yValue.clone();
    432            return clone;
    433        }
    434
    435    }