001 /* ===========================================================
002 * JFreeChart : a free chart library for the Java(tm) platform
003 * ===========================================================
004 *
005 * (C) Copyright 2000-2008, 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-2008, 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 * 22-Nov-2007 : Implemented hashCode() (DG);
046 *
047 */
048
049 package org.jfree.chart.needle;
050
051 import java.awt.BasicStroke;
052 import java.awt.Color;
053 import java.awt.Graphics2D;
054 import java.awt.Paint;
055 import java.awt.Shape;
056 import java.awt.Stroke;
057 import java.awt.geom.AffineTransform;
058 import java.awt.geom.Point2D;
059 import java.awt.geom.Rectangle2D;
060 import java.io.IOException;
061 import java.io.ObjectInputStream;
062 import java.io.ObjectOutputStream;
063 import java.io.Serializable;
064
065 import org.jfree.chart.HashUtilities;
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 public abstract class MeterNeedle implements Serializable {
075
076 /** For serialization. */
077 private static final long serialVersionUID = 5203064851510951052L;
078
079 /** The outline paint. */
080 private transient Paint outlinePaint = Color.black;
081
082 /** The outline stroke. */
083 private transient Stroke outlineStroke = new BasicStroke(2);
084
085 /** The fill paint. */
086 private transient Paint fillPaint = null;
087
088 /** The highlight paint. */
089 private transient Paint highlightPaint = null;
090
091 /** The size. */
092 private int size = 5;
093
094 /** Scalar to aply to locate the rotation x point. */
095 private double rotateX = 0.5;
096
097 /** Scalar to aply to locate the rotation y point. */
098 private double rotateY = 0.5;
099
100 /** A transform. */
101 protected static AffineTransform transform = new AffineTransform();
102
103 /**
104 * Creates a new needle.
105 */
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 */
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 */
128 public Paint getOutlinePaint() {
129 return this.outlinePaint;
130 }
131
132 /**
133 * Sets the outline paint.
134 *
135 * @param p the new paint.
136 */
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 */
148 public Stroke getOutlineStroke() {
149 return this.outlineStroke;
150 }
151
152 /**
153 * Sets the outline stroke.
154 *
155 * @param s the new stroke.
156 */
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 */
168 public Paint getFillPaint() {
169 return this.fillPaint;
170 }
171
172 /**
173 * Sets the fill paint.
174 *
175 * @param p the fill paint.
176 */
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 */
188 public Paint getHighlightPaint() {
189 return this.highlightPaint;
190 }
191
192 /**
193 * Sets the highlight paint.
194 *
195 * @param p the highlight paint.
196 */
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 */
208 public double getRotateX() {
209 return this.rotateX;
210 }
211
212 /**
213 * Sets the rotateX value.
214 *
215 * @param x the new value.
216 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
326 public int getSize() {
327 return this.size;
328 }
329
330 /**
331 * Sets the size.
332 *
333 * @param pixels the new size.
334 */
335 public void setSize(int pixels) {
336 this.size = pixels;
337 }
338
339 /**
340 * Returns the transform.
341 *
342 * @return The transform.
343 */
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 public boolean equals(Object obj) {
356 if (obj == this) {
357 return true;
358 }
359 if (!(obj instanceof MeterNeedle)) {
360 return false;
361 }
362 MeterNeedle that = (MeterNeedle) obj;
363 if (!PaintUtilities.equal(this.outlinePaint, that.outlinePaint)) {
364 return false;
365 }
366 if (!ObjectUtilities.equal(this.outlineStroke, that.outlineStroke)) {
367 return false;
368 }
369 if (!PaintUtilities.equal(this.fillPaint, that.fillPaint)) {
370 return false;
371 }
372 if (!PaintUtilities.equal(this.highlightPaint, that.highlightPaint)) {
373 return false;
374 }
375 if (this.size != that.size) {
376 return false;
377 }
378 if (this.rotateX != that.rotateX) {
379 return false;
380 }
381 if (this.rotateY != that.rotateY) {
382 return false;
383 }
384 return true;
385 }
386
387 /**
388 * Returns a hash code for this instance.
389 *
390 * @return A hash code.
391 */
392 public int hashCode() {
393 int result = HashUtilities.hashCode(193, this.fillPaint);
394 result = HashUtilities.hashCode(result, this.highlightPaint);
395 result = HashUtilities.hashCode(result, this.outlinePaint);
396 result = HashUtilities.hashCode(result, this.outlineStroke);
397 result = HashUtilities.hashCode(result, this.rotateX);
398 result = HashUtilities.hashCode(result, this.rotateY);
399 result = HashUtilities.hashCode(result, this.size);
400 return result;
401 }
402
403 /**
404 * Provides serialization support.
405 *
406 * @param stream the output stream.
407 *
408 * @throws IOException if there is an I/O error.
409 */
410 private void writeObject(ObjectOutputStream stream) throws IOException {
411 stream.defaultWriteObject();
412 SerialUtilities.writeStroke(this.outlineStroke, stream);
413 SerialUtilities.writePaint(this.outlinePaint, stream);
414 SerialUtilities.writePaint(this.fillPaint, stream);
415 SerialUtilities.writePaint(this.highlightPaint, stream);
416 }
417
418 /**
419 * Provides serialization support.
420 *
421 * @param stream the input stream.
422 *
423 * @throws IOException if there is an I/O error.
424 * @throws ClassNotFoundException if there is a classpath problem.
425 */
426 private void readObject(ObjectInputStream stream)
427 throws IOException, ClassNotFoundException {
428 stream.defaultReadObject();
429 this.outlineStroke = SerialUtilities.readStroke(stream);
430 this.outlinePaint = SerialUtilities.readPaint(stream);
431 this.fillPaint = SerialUtilities.readPaint(stream);
432 this.highlightPaint = SerialUtilities.readPaint(stream);
433 }
434
435 }