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 }