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