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 * MeterNeedle.java 029 * ---------------- 030 * (C) Copyright 2002-2007, by the Australian Antarctic Division and 031 * Contributors. 032 * 033 * Original Author: Bryan Scott (for the Australian Antarctic Division); 034 * Contributor(s): David Gilbert (for Object Refinery Limited); 035 * Nicolas Brodu (for Astrium and EADS Corporate Research 036 * Center); 037 * 038 * Changes: 039 * -------- 040 * 25-Sep-2002 : Version 1, contributed by Bryan Scott (DG); 041 * 07-Nov-2002 : Fixed errors reported by Checkstyle (DG); 042 * 01-Sep-2003 : Implemented Serialization (NB); 043 * 16-Mar-2004 : Changed transform from private to protected (BRS); 044 * 08-Jun-2005 : Fixed equals() method to handle GradientPaint (DG); 045 * 046 */ 047 048package org.jfree.chart.needle; 049 050import java.awt.BasicStroke; 051import java.awt.Color; 052import java.awt.Graphics2D; 053import java.awt.Paint; 054import java.awt.Shape; 055import java.awt.Stroke; 056import java.awt.geom.AffineTransform; 057import java.awt.geom.Point2D; 058import java.awt.geom.Rectangle2D; 059import java.io.IOException; 060import java.io.ObjectInputStream; 061import java.io.ObjectOutputStream; 062import java.io.Serializable; 063 064import org.jfree.io.SerialUtilities; 065import org.jfree.util.ObjectUtilities; 066import org.jfree.util.PaintUtilities; 067 068/** 069 * The base class used to represent the needle on a 070 * {@link org.jfree.chart.plot.CompassPlot}. 071 */ 072public abstract class MeterNeedle implements Serializable { 073 074 /** For serialization. */ 075 private static final long serialVersionUID = 5203064851510951052L; 076 077 /** The outline paint. */ 078 private transient Paint outlinePaint = Color.black; 079 080 /** The outline stroke. */ 081 private transient Stroke outlineStroke = new BasicStroke(2); 082 083 /** The fill paint. */ 084 private transient Paint fillPaint = null; 085 086 /** The highlight paint. */ 087 private transient Paint highlightPaint = null; 088 089 /** The size. */ 090 private int size = 5; 091 092 /** Scalar to aply to locate the rotation x point. */ 093 private double rotateX = 0.5; 094 095 /** Scalar to aply to locate the rotation y point. */ 096 private double rotateY = 0.5; 097 098 /** A transform. */ 099 protected static AffineTransform transform = new AffineTransform(); 100 101 /** 102 * Creates a new needle. 103 */ 104 public MeterNeedle() { 105 this(null, null, null); 106 } 107 108 /** 109 * Creates a new needle. 110 * 111 * @param outline the outline paint (<code>null</code> permitted). 112 * @param fill the fill paint (<code>null</code> permitted). 113 * @param highlight the highlight paint (<code>null</code> permitted). 114 */ 115 public MeterNeedle(Paint outline, Paint fill, Paint highlight) { 116 this.fillPaint = fill; 117 this.highlightPaint = highlight; 118 this.outlinePaint = outline; 119 } 120 121 /** 122 * Returns the outline paint. 123 * 124 * @return The outline paint. 125 */ 126 public Paint getOutlinePaint() { 127 return this.outlinePaint; 128 } 129 130 /** 131 * Sets the outline paint. 132 * 133 * @param p the new paint. 134 */ 135 public void setOutlinePaint(Paint p) { 136 if (p != null) { 137 this.outlinePaint = p; 138 } 139 } 140 141 /** 142 * Returns the outline stroke. 143 * 144 * @return The outline stroke. 145 */ 146 public Stroke getOutlineStroke() { 147 return this.outlineStroke; 148 } 149 150 /** 151 * Sets the outline stroke. 152 * 153 * @param s the new stroke. 154 */ 155 public void setOutlineStroke(Stroke s) { 156 if (s != null) { 157 this.outlineStroke = s; 158 } 159 } 160 161 /** 162 * Returns the fill paint. 163 * 164 * @return The fill paint. 165 */ 166 public Paint getFillPaint() { 167 return this.fillPaint; 168 } 169 170 /** 171 * Sets the fill paint. 172 * 173 * @param p the fill paint. 174 */ 175 public void setFillPaint(Paint p) { 176 if (p != null) { 177 this.fillPaint = p; 178 } 179 } 180 181 /** 182 * Returns the highlight paint. 183 * 184 * @return The highlight paint. 185 */ 186 public Paint getHighlightPaint() { 187 return this.highlightPaint; 188 } 189 190 /** 191 * Sets the highlight paint. 192 * 193 * @param p the highlight paint. 194 */ 195 public void setHighlightPaint(Paint p) { 196 if (p != null) { 197 this.highlightPaint = p; 198 } 199 } 200 201 /** 202 * Returns the scalar used for determining the rotation x value. 203 * 204 * @return The x rotate scalar. 205 */ 206 public double getRotateX() { 207 return this.rotateX; 208 } 209 210 /** 211 * Sets the rotateX value. 212 * 213 * @param x the new value. 214 */ 215 public void setRotateX(double x) { 216 this.rotateX = x; 217 } 218 219 /** 220 * Sets the rotateY value. 221 * 222 * @param y the new value. 223 */ 224 public void setRotateY(double y) { 225 this.rotateY = y; 226 } 227 228 /** 229 * Returns the scalar used for determining the rotation y value. 230 * 231 * @return The y rotate scalar. 232 */ 233 public double getRotateY() { 234 return this.rotateY; 235 } 236 237 /** 238 * Draws the needle. 239 * 240 * @param g2 the graphics device. 241 * @param plotArea the plot area. 242 */ 243 public void draw(Graphics2D g2, Rectangle2D plotArea) { 244 draw(g2, plotArea, 0); 245 } 246 247 /** 248 * Draws the needle. 249 * 250 * @param g2 the graphics device. 251 * @param plotArea the plot area. 252 * @param angle the angle. 253 */ 254 public void draw(Graphics2D g2, Rectangle2D plotArea, double angle) { 255 256 Point2D.Double pt = new Point2D.Double(); 257 pt.setLocation( 258 plotArea.getMinX() + this.rotateX * plotArea.getWidth(), 259 plotArea.getMinY() + this.rotateY * plotArea.getHeight() 260 ); 261 draw(g2, plotArea, pt, angle); 262 263 } 264 265 /** 266 * Draws the needle. 267 * 268 * @param g2 the graphics device. 269 * @param plotArea the plot area. 270 * @param rotate the rotation point. 271 * @param angle the angle. 272 */ 273 public void draw(Graphics2D g2, Rectangle2D plotArea, Point2D rotate, 274 double angle) { 275 276 Paint savePaint = g2.getColor(); 277 Stroke saveStroke = g2.getStroke(); 278 279 drawNeedle(g2, plotArea, rotate, Math.toRadians(angle)); 280 281 g2.setStroke(saveStroke); 282 g2.setPaint(savePaint); 283 284 } 285 286 /** 287 * Draws the needle. 288 * 289 * @param g2 the graphics device. 290 * @param plotArea the plot area. 291 * @param rotate the rotation point. 292 * @param angle the angle. 293 */ 294 protected abstract void drawNeedle(Graphics2D g2, 295 Rectangle2D plotArea, Point2D rotate, 296 double angle); 297 298 /** 299 * Displays a shape. 300 * 301 * @param g2 the graphics device. 302 * @param shape the shape. 303 */ 304 protected void defaultDisplay(Graphics2D g2, Shape shape) { 305 306 if (this.fillPaint != null) { 307 g2.setPaint(this.fillPaint); 308 g2.fill(shape); 309 } 310 311 if (this.outlinePaint != null) { 312 g2.setStroke(this.outlineStroke); 313 g2.setPaint(this.outlinePaint); 314 g2.draw(shape); 315 } 316 317 } 318 319 /** 320 * Returns the size. 321 * 322 * @return The size. 323 */ 324 public int getSize() { 325 return this.size; 326 } 327 328 /** 329 * Sets the size. 330 * 331 * @param pixels the new size. 332 */ 333 public void setSize(int pixels) { 334 this.size = pixels; 335 } 336 337 /** 338 * Returns the transform. 339 * 340 * @return The transform. 341 */ 342 public AffineTransform getTransform() { 343 return MeterNeedle.transform; 344 } 345 346 /** 347 * Tests another object for equality with this object. 348 * 349 * @param obj the object to test (<code>null</code> permitted). 350 * 351 * @return A boolean. 352 */ 353 public boolean equals(Object obj) { 354 if (obj == this) { 355 return true; 356 } 357 if (!(obj instanceof MeterNeedle)) { 358 return false; 359 } 360 MeterNeedle that = (MeterNeedle) obj; 361 if (!PaintUtilities.equal(this.outlinePaint, that.outlinePaint)) { 362 return false; 363 } 364 if (!ObjectUtilities.equal(this.outlineStroke, that.outlineStroke)) { 365 return false; 366 } 367 if (!PaintUtilities.equal(this.fillPaint, that.fillPaint)) { 368 return false; 369 } 370 if (!PaintUtilities.equal(this.highlightPaint, that.highlightPaint)) { 371 return false; 372 } 373 if (this.size != that.size) { 374 return false; 375 } 376 if (this.rotateX != that.rotateX) { 377 return false; 378 } 379 if (this.rotateY != that.rotateY) { 380 return false; 381 } 382 return true; 383 } 384 385 /** 386 * Provides serialization support. 387 * 388 * @param stream the output stream. 389 * 390 * @throws IOException if there is an I/O error. 391 */ 392 private void writeObject(ObjectOutputStream stream) throws IOException { 393 stream.defaultWriteObject(); 394 SerialUtilities.writeStroke(this.outlineStroke, stream); 395 SerialUtilities.writePaint(this.outlinePaint, stream); 396 SerialUtilities.writePaint(this.fillPaint, stream); 397 SerialUtilities.writePaint(this.highlightPaint, stream); 398 } 399 400 /** 401 * Provides serialization support. 402 * 403 * @param stream the input stream. 404 * 405 * @throws IOException if there is an I/O error. 406 * @throws ClassNotFoundException if there is a classpath problem. 407 */ 408 private void readObject(ObjectInputStream stream) 409 throws IOException, ClassNotFoundException { 410 stream.defaultReadObject(); 411 this.outlineStroke = SerialUtilities.readStroke(stream); 412 this.outlinePaint = SerialUtilities.readPaint(stream); 413 this.fillPaint = SerialUtilities.readPaint(stream); 414 this.highlightPaint = SerialUtilities.readPaint(stream); 415 } 416 417}