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