1 /* =========================================================== 2 * JFreeChart : a free chart library for the Java(tm) platform 3 * =========================================================== 4 * 5 * (C) Copyright 2000-2013, by Object Refinery Limited and Contributors. 6 * 7 * Project Info: http://www.jfree.org/jfreechart/index.html 8 * 9 * This library is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU Lesser General Public License as published by 11 * the Free Software Foundation; either version 2.1 of the License, or 12 * (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 17 * License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with this library; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 22 * USA. 23 * 24 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 25 * Other names may be trademarks of their respective owners.] 26 * 27 * ---------------- 28 * MeterNeedle.java 29 * ---------------- 30 * (C) Copyright 2002-2008, by the Australian Antarctic Division and 31 * Contributors. 32 * 33 * Original Author: Bryan Scott (for the Australian Antarctic Division); 34 * Contributor(s): David Gilbert (for Object Refinery Limited); 35 * Nicolas Brodu (for Astrium and EADS Corporate Research 36 * Center); 37 * 38 * Changes: 39 * -------- 40 * 25-Sep-2002 : Version 1, contributed by Bryan Scott (DG); 41 * 07-Nov-2002 : Fixed errors reported by Checkstyle (DG); 42 * 01-Sep-2003 : Implemented Serialization (NB); 43 * 16-Mar-2004 : Changed transform from private to protected (BRS); 44 * 08-Jun-2005 : Fixed equals() method to handle GradientPaint (DG); 45 * 22-Nov-2007 : Implemented hashCode() (DG); 46 * 47 */ 48 49 package org.jfree.chart.needle; 50 51 import java.awt.BasicStroke; 52 import java.awt.Color; 53 import java.awt.Graphics2D; 54 import java.awt.Paint; 55 import java.awt.Shape; 56 import java.awt.Stroke; 57 import java.awt.geom.AffineTransform; 58 import java.awt.geom.Point2D; 59 import java.awt.geom.Rectangle2D; 60 import java.io.IOException; 61 import java.io.ObjectInputStream; 62 import java.io.ObjectOutputStream; 63 import java.io.Serializable; 64 65 import org.jfree.chart.HashUtilities; 66 import org.jfree.io.SerialUtilities; 67 import org.jfree.util.ObjectUtilities; 68 import org.jfree.util.PaintUtilities; 69 70 /** 71 * The base class used to represent the needle on a 72 * {@link org.jfree.chart.plot.CompassPlot}. 73 */ 74 public abstract class MeterNeedle implements Serializable { 75 76 /** For serialization. */ 77 private static final long serialVersionUID = 5203064851510951052L; 78 79 /** The outline paint. */ 80 private transient Paint outlinePaint = Color.black; 81 82 /** The outline stroke. */ 83 private transient Stroke outlineStroke = new BasicStroke(2); 84 85 /** The fill paint. */ 86 private transient Paint fillPaint = null; 87 88 /** The highlight paint. */ 89 private transient Paint highlightPaint = null; 90 91 /** The size. */ 92 private int size = 5; 93 94 /** Scalar to aply to locate the rotation x point. */ 95 private double rotateX = 0.5; 96 97 /** Scalar to aply to locate the rotation y point. */ 98 private double rotateY = 0.5; 99 100 /** A transform. */ 101 protected static AffineTransform transform = new AffineTransform(); 102 103 /** 104 * Creates a new needle. 105 */ MeterNeedle()106 public MeterNeedle() { 107 this(null, null, null); 108 } 109 110 /** 111 * Creates a new needle. 112 * 113 * @param outline the outline paint (<code>null</code> permitted). 114 * @param fill the fill paint (<code>null</code> permitted). 115 * @param highlight the highlight paint (<code>null</code> permitted). 116 */ MeterNeedle(Paint outline, Paint fill, Paint highlight)117 public MeterNeedle(Paint outline, Paint fill, Paint highlight) { 118 this.fillPaint = fill; 119 this.highlightPaint = highlight; 120 this.outlinePaint = outline; 121 } 122 123 /** 124 * Returns the outline paint. 125 * 126 * @return The outline paint. 127 */ getOutlinePaint()128 public Paint getOutlinePaint() { 129 return this.outlinePaint; 130 } 131 132 /** 133 * Sets the outline paint. 134 * 135 * @param p the new paint. 136 */ setOutlinePaint(Paint p)137 public void setOutlinePaint(Paint p) { 138 if (p != null) { 139 this.outlinePaint = p; 140 } 141 } 142 143 /** 144 * Returns the outline stroke. 145 * 146 * @return The outline stroke. 147 */ getOutlineStroke()148 public Stroke getOutlineStroke() { 149 return this.outlineStroke; 150 } 151 152 /** 153 * Sets the outline stroke. 154 * 155 * @param s the new stroke. 156 */ setOutlineStroke(Stroke s)157 public void setOutlineStroke(Stroke s) { 158 if (s != null) { 159 this.outlineStroke = s; 160 } 161 } 162 163 /** 164 * Returns the fill paint. 165 * 166 * @return The fill paint. 167 */ getFillPaint()168 public Paint getFillPaint() { 169 return this.fillPaint; 170 } 171 172 /** 173 * Sets the fill paint. 174 * 175 * @param p the fill paint. 176 */ setFillPaint(Paint p)177 public void setFillPaint(Paint p) { 178 if (p != null) { 179 this.fillPaint = p; 180 } 181 } 182 183 /** 184 * Returns the highlight paint. 185 * 186 * @return The highlight paint. 187 */ getHighlightPaint()188 public Paint getHighlightPaint() { 189 return this.highlightPaint; 190 } 191 192 /** 193 * Sets the highlight paint. 194 * 195 * @param p the highlight paint. 196 */ setHighlightPaint(Paint p)197 public void setHighlightPaint(Paint p) { 198 if (p != null) { 199 this.highlightPaint = p; 200 } 201 } 202 203 /** 204 * Returns the scalar used for determining the rotation x value. 205 * 206 * @return The x rotate scalar. 207 */ getRotateX()208 public double getRotateX() { 209 return this.rotateX; 210 } 211 212 /** 213 * Sets the rotateX value. 214 * 215 * @param x the new value. 216 */ setRotateX(double x)217 public void setRotateX(double x) { 218 this.rotateX = x; 219 } 220 221 /** 222 * Sets the rotateY value. 223 * 224 * @param y the new value. 225 */ setRotateY(double y)226 public void setRotateY(double y) { 227 this.rotateY = y; 228 } 229 230 /** 231 * Returns the scalar used for determining the rotation y value. 232 * 233 * @return The y rotate scalar. 234 */ getRotateY()235 public double getRotateY() { 236 return this.rotateY; 237 } 238 239 /** 240 * Draws the needle. 241 * 242 * @param g2 the graphics device. 243 * @param plotArea the plot area. 244 */ draw(Graphics2D g2, Rectangle2D plotArea)245 public void draw(Graphics2D g2, Rectangle2D plotArea) { 246 draw(g2, plotArea, 0); 247 } 248 249 /** 250 * Draws the needle. 251 * 252 * @param g2 the graphics device. 253 * @param plotArea the plot area. 254 * @param angle the angle. 255 */ draw(Graphics2D g2, Rectangle2D plotArea, double angle)256 public void draw(Graphics2D g2, Rectangle2D plotArea, double angle) { 257 258 Point2D.Double pt = new Point2D.Double(); 259 pt.setLocation( 260 plotArea.getMinX() + this.rotateX * plotArea.getWidth(), 261 plotArea.getMinY() + this.rotateY * plotArea.getHeight() 262 ); 263 draw(g2, plotArea, pt, angle); 264 265 } 266 267 /** 268 * Draws the needle. 269 * 270 * @param g2 the graphics device. 271 * @param plotArea the plot area. 272 * @param rotate the rotation point. 273 * @param angle the angle. 274 */ draw(Graphics2D g2, Rectangle2D plotArea, Point2D rotate, double angle)275 public void draw(Graphics2D g2, Rectangle2D plotArea, Point2D rotate, 276 double angle) { 277 278 Paint savePaint = g2.getColor(); 279 Stroke saveStroke = g2.getStroke(); 280 281 drawNeedle(g2, plotArea, rotate, Math.toRadians(angle)); 282 283 g2.setStroke(saveStroke); 284 g2.setPaint(savePaint); 285 286 } 287 288 /** 289 * Draws the needle. 290 * 291 * @param g2 the graphics device. 292 * @param plotArea the plot area. 293 * @param rotate the rotation point. 294 * @param angle the angle. 295 */ drawNeedle(Graphics2D g2, Rectangle2D plotArea, Point2D rotate, double angle)296 protected abstract void drawNeedle(Graphics2D g2, 297 Rectangle2D plotArea, Point2D rotate, 298 double angle); 299 300 /** 301 * Displays a shape. 302 * 303 * @param g2 the graphics device. 304 * @param shape the shape. 305 */ defaultDisplay(Graphics2D g2, Shape shape)306 protected void defaultDisplay(Graphics2D g2, Shape shape) { 307 308 if (this.fillPaint != null) { 309 g2.setPaint(this.fillPaint); 310 g2.fill(shape); 311 } 312 313 if (this.outlinePaint != null) { 314 g2.setStroke(this.outlineStroke); 315 g2.setPaint(this.outlinePaint); 316 g2.draw(shape); 317 } 318 319 } 320 321 /** 322 * Returns the size. 323 * 324 * @return The size. 325 */ getSize()326 public int getSize() { 327 return this.size; 328 } 329 330 /** 331 * Sets the size. 332 * 333 * @param pixels the new size. 334 */ setSize(int pixels)335 public void setSize(int pixels) { 336 this.size = pixels; 337 } 338 339 /** 340 * Returns the transform. 341 * 342 * @return The transform. 343 */ getTransform()344 public AffineTransform getTransform() { 345 return MeterNeedle.transform; 346 } 347 348 /** 349 * Tests another object for equality with this object. 350 * 351 * @param obj the object to test (<code>null</code> permitted). 352 * 353 * @return A boolean. 354 */ 355 @Override equals(Object obj)356 public boolean equals(Object obj) { 357 if (obj == this) { 358 return true; 359 } 360 if (!(obj instanceof MeterNeedle)) { 361 return false; 362 } 363 MeterNeedle that = (MeterNeedle) obj; 364 if (!PaintUtilities.equal(this.outlinePaint, that.outlinePaint)) { 365 return false; 366 } 367 if (!ObjectUtilities.equal(this.outlineStroke, that.outlineStroke)) { 368 return false; 369 } 370 if (!PaintUtilities.equal(this.fillPaint, that.fillPaint)) { 371 return false; 372 } 373 if (!PaintUtilities.equal(this.highlightPaint, that.highlightPaint)) { 374 return false; 375 } 376 if (this.size != that.size) { 377 return false; 378 } 379 if (this.rotateX != that.rotateX) { 380 return false; 381 } 382 if (this.rotateY != that.rotateY) { 383 return false; 384 } 385 return true; 386 } 387 388 /** 389 * Returns a hash code for this instance. 390 * 391 * @return A hash code. 392 */ 393 @Override hashCode()394 public int hashCode() { 395 int result = HashUtilities.hashCode(193, this.fillPaint); 396 result = HashUtilities.hashCode(result, this.highlightPaint); 397 result = HashUtilities.hashCode(result, this.outlinePaint); 398 result = HashUtilities.hashCode(result, this.outlineStroke); 399 result = HashUtilities.hashCode(result, this.rotateX); 400 result = HashUtilities.hashCode(result, this.rotateY); 401 result = HashUtilities.hashCode(result, this.size); 402 return result; 403 } 404 405 /** 406 * Provides serialization support. 407 * 408 * @param stream the output stream. 409 * 410 * @throws IOException if there is an I/O error. 411 */ writeObject(ObjectOutputStream stream)412 private void writeObject(ObjectOutputStream stream) throws IOException { 413 stream.defaultWriteObject(); 414 SerialUtilities.writeStroke(this.outlineStroke, stream); 415 SerialUtilities.writePaint(this.outlinePaint, stream); 416 SerialUtilities.writePaint(this.fillPaint, stream); 417 SerialUtilities.writePaint(this.highlightPaint, stream); 418 } 419 420 /** 421 * Provides serialization support. 422 * 423 * @param stream the input stream. 424 * 425 * @throws IOException if there is an I/O error. 426 * @throws ClassNotFoundException if there is a classpath problem. 427 */ readObject(ObjectInputStream stream)428 private void readObject(ObjectInputStream stream) 429 throws IOException, ClassNotFoundException { 430 stream.defaultReadObject(); 431 this.outlineStroke = SerialUtilities.readStroke(stream); 432 this.outlinePaint = SerialUtilities.readPaint(stream); 433 this.fillPaint = SerialUtilities.readPaint(stream); 434 this.highlightPaint = SerialUtilities.readPaint(stream); 435 } 436 437 } 438