KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > experimental > chart > plot > dial > StandardDialFrame


1 /* ===========================================================
2  * JFreeChart : a free chart library for the Java(tm) platform
3  * ===========================================================
4  *
5  * (C) Copyright 2000-2006, 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  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
25  * in the United States and other countries.]
26  *
27  * ----------------------
28  * StandardDialFrame.java
29  * ----------------------
30  * (C) Copyright 2006, by Object Refinery Limited.
31  *
32  * Original Author: David Gilbert (for Object Refinery Limited);
33  * Contributor(s): -;
34  *
35  * $Id: StandardDialFrame.java,v 1.1.2.3 2006/11/17 11:06:44 mungady Exp $
36  *
37  * Changes
38  * -------
39  * 03-Nov-2006 : Version 1 (DG);
40  *
41  */

42
43 package org.jfree.experimental.chart.plot.dial;
44
45 import java.awt.BasicStroke JavaDoc;
46 import java.awt.Color JavaDoc;
47 import java.awt.Graphics2D JavaDoc;
48 import java.awt.Paint JavaDoc;
49 import java.awt.Shape JavaDoc;
50 import java.awt.Stroke JavaDoc;
51 import java.awt.geom.Arc2D JavaDoc;
52 import java.awt.geom.Area JavaDoc;
53 import java.awt.geom.GeneralPath JavaDoc;
54 import java.awt.geom.Point2D JavaDoc;
55 import java.awt.geom.Rectangle2D JavaDoc;
56 import java.io.IOException JavaDoc;
57 import java.io.ObjectInputStream JavaDoc;
58 import java.io.ObjectOutputStream JavaDoc;
59 import java.io.Serializable JavaDoc;
60
61 import org.jfree.chart.HashUtilities;
62 import org.jfree.io.SerialUtilities;
63 import org.jfree.util.PaintUtilities;
64 import org.jfree.util.PublicCloneable;
65
66 /**
67  * A standard frame for the {@link DialPlot} class.
68  */

69 public class StandardDialFrame extends AbstractDialLayer implements DialFrame,
70         Cloneable JavaDoc, PublicCloneable, Serializable JavaDoc {
71     
72     /**
73      * The color used for the front of the panel. This field is transient
74      * because it requires special handling for serialization.
75      */

76     private transient Paint JavaDoc backgroundPaint;
77     
78     /**
79      * The color used for the border around the window. This field is transient
80      * because it requires special handling for serialization.
81      */

82     private transient Paint JavaDoc foregroundPaint;
83     
84     /**
85      * The stroke for drawing the frame outline. This field is transient
86      * because it requires special handling for serialization.
87      */

88     private transient Stroke JavaDoc stroke;
89        
90     /**
91      * The start angle.
92      */

93     private double startAngle;
94     
95     /**
96      * The end angle.
97      */

98     private double extent;
99     
100     /** The inner radius, relative to the framing rectangle. */
101     private double innerRadius;
102     
103     /** The outer radius, relative to the framing rectangle. */
104     private double outerRadius;
105    
106     /**
107      * Creates a new instance of <code>StandardDialFrame</code> that spans
108      * 180 degrees.
109      */

110     public StandardDialFrame() {
111         this(0, 180);
112     }
113     
114     /**
115      * Creates a new instance of <code>StandardDialFrame</code> that spans
116      * the arc specified.
117      *
118      * @param startAngle the startAngle (in degrees).
119      * @param extent the extent of the arc (in degrees, counter-clockwise).
120      */

121     public StandardDialFrame(double startAngle, double extent) {
122         this.backgroundPaint = Color.gray;
123         this.foregroundPaint = new Color JavaDoc(100, 100, 150);
124         this.stroke = new BasicStroke JavaDoc(2.0f);
125         this.innerRadius = 0.25;
126         this.outerRadius = 0.75;
127         this.startAngle = startAngle;
128         this.extent = extent;
129     }
130     
131     /**
132      * Returns the background paint (never <code>null</code>).
133      *
134      * @return The background paint.
135      *
136      * @see #setBackgroundPaint(Paint)
137      */

138     public Paint JavaDoc getBackgroundPaint() {
139         return this.backgroundPaint;
140     }
141     
142     /**
143      * Sets the background paint.
144      *
145      * @param paint the paint (<code>null</code> not permitted).
146      *
147      * @see #getBackgroundPaint()
148      */

149     public void setBackgroundPaint(Paint JavaDoc paint) {
150         if (paint == null) {
151             throw new IllegalArgumentException JavaDoc("Null 'paint' argument.");
152         }
153         this.backgroundPaint = paint;
154         notifyListeners(new DialLayerChangeEvent(this));
155     }
156     
157     /**
158      * Returns the foreground paint.
159      *
160      * @return The foreground paint (never <code>null</code>).
161      *
162      * @see #setForegroundPaint(Paint)
163      */

164     public Paint JavaDoc getForegroundPaint() {
165         return this.foregroundPaint;
166     }
167     
168     /**
169      * Sets the foreground paint.
170      *
171      * @param paint the paint (<code>null</code> not permitted).
172      *
173      * @see #getForegroundPaint()
174      */

175     public void setForegroundPaint(Paint JavaDoc paint) {
176         if (paint == null) {
177             throw new IllegalArgumentException JavaDoc("Null 'paint' argument.");
178         }
179         this.foregroundPaint = paint;
180         notifyListeners(new DialLayerChangeEvent(this));
181     }
182     
183     /**
184      * Returns the stroke.
185      *
186      * @return The stroke (never <code>null</code>).
187      *
188      * @see #setStroke(Stroke)
189      */

190     public Stroke JavaDoc getStroke() {
191         return this.stroke;
192     }
193     
194     /**
195      * Sets the stroke.
196      *
197      * @param stroke the stroke (<code>null</code> not permitted).
198      *
199      * @see #getStroke()
200      */

201     public void setStroke(Stroke JavaDoc stroke) {
202         if (stroke == null) {
203             throw new IllegalArgumentException JavaDoc("Null 'stroke' argument.");
204         }
205         this.stroke = stroke;
206         notifyListeners(new DialLayerChangeEvent(this));
207     }
208
209     /**
210      * Returns the inner radius, relative to the framing rectangle.
211      *
212      * @return The inner radius.
213      *
214      * @see #setInnerRadius(double)
215      */

216     public double getInnerRadius() {
217         return this.innerRadius;
218     }
219     
220     /**
221      * Sets the inner radius.
222      *
223      * @param radius the inner radius.
224      *
225      * @see #getInnerRadius()
226      */

227     public void setInnerRadius(double radius) {
228         // TODO: validation
229
this.innerRadius = radius;
230         notifyListeners(new DialLayerChangeEvent(this));
231     }
232     
233     /**
234      * Returns the outer radius, relative to the framing rectangle.
235      *
236      * @return The outer radius.
237      *
238      * @see #setOuterRadius(double)
239      */

240     public double getOuterRadius() {
241         return this.outerRadius;
242     }
243     
244     /**
245      * Sets the outer radius.
246      *
247      * @param radius the outer radius.
248      *
249      * @see #getOuterRadius()
250      */

251     public void setOuterRadius(double radius) {
252         // TODO: validation
253
this.outerRadius = radius;
254         notifyListeners(new DialLayerChangeEvent(this));
255     }
256     
257     /**
258      * Returns the start angle.
259      *
260      * @return The start angle.
261      *
262      * @see #setStartAngle(double)
263      */

264     public double getStartAngle() {
265         return this.startAngle;
266     }
267     
268     /**
269      * Sets the start angle.
270      *
271      * @param angle the angle.
272      *
273      * @see #getStartAngle()
274      */

275     public void setStartAngle(double angle) {
276         this.startAngle = angle;
277         notifyListeners(new DialLayerChangeEvent(this));
278     }
279     
280     /**
281      * Returns the extent.
282      *
283      * @return The extent.
284      *
285      * @see #setExtent(double)
286      */

287     public double getExtent() {
288         return this.extent;
289     }
290     
291     /**
292      * Sets the extent.
293      *
294      * @param extent the extent.
295      *
296      * @see #getExtent()
297      */

298     public void setExtent(double extent) {
299         this.extent = extent;
300         notifyListeners(new DialLayerChangeEvent(this));
301     }
302     
303     /**
304      * Returns the shape for the window for this dial. Some dial layers will
305      * request that their drawing be clipped within this window.
306      *
307      * @param frame the reference frame (<code>null</code> not permitted).
308      *
309      * @return The shape of the dial's window.
310      */

311     public Shape JavaDoc getWindow(Rectangle2D JavaDoc frame) {
312         
313         Rectangle2D JavaDoc innerFrame = DialPlot.rectangleByRadius(frame,
314                 this.innerRadius, this.innerRadius);
315         Rectangle2D JavaDoc outerFrame = DialPlot.rectangleByRadius(frame,
316                 this.outerRadius, this.outerRadius);
317         Arc2D JavaDoc inner = new Arc2D.Double JavaDoc(innerFrame, this.startAngle, this.extent,
318                 Arc2D.OPEN);
319         Arc2D JavaDoc outer = new Arc2D.Double JavaDoc(outerFrame, this.startAngle
320                 + this.extent, - this.extent, Arc2D.OPEN);
321         GeneralPath JavaDoc p = new GeneralPath JavaDoc();
322         Point2D JavaDoc point1 = inner.getStartPoint();
323         p.moveTo((float) point1.getX(), (float) point1.getY());
324         p.append(inner, true);
325         p.append(outer, true);
326         p.closePath();
327         return p;
328         
329     }
330     
331     protected Shape JavaDoc getOuterWindow(Rectangle2D JavaDoc frame) {
332         double radiusMargin = 0.02;
333         double angleMargin = 1.5;
334         Rectangle2D JavaDoc innerFrame = DialPlot.rectangleByRadius(frame,
335                 this.innerRadius - radiusMargin, this.innerRadius
336                 - radiusMargin);
337         Rectangle2D JavaDoc outerFrame = DialPlot.rectangleByRadius(frame,
338                 this.outerRadius + radiusMargin, this.outerRadius
339                 + radiusMargin);
340         Arc2D JavaDoc inner = new Arc2D.Double JavaDoc(innerFrame, this.startAngle
341                 - angleMargin, this.extent + 2 * angleMargin, Arc2D.OPEN);
342         Arc2D JavaDoc outer = new Arc2D.Double JavaDoc(outerFrame, this.startAngle
343                 + angleMargin + this.extent, - this.extent - 2 * angleMargin,
344                 Arc2D.OPEN);
345         GeneralPath JavaDoc p = new GeneralPath JavaDoc();
346         Point2D JavaDoc point1 = inner.getStartPoint();
347         p.moveTo((float) point1.getX(), (float) point1.getY());
348         p.append(inner, true);
349         p.append(outer, true);
350         p.closePath();
351         return p;
352         
353     }
354     
355     /**
356      * Draws the frame.
357      *
358      * @param g2 the graphics target.
359      * @param plot the plot.
360      * @param frame the dial's reference frame.
361      * @param view the dial's view rectangle.
362      */

363     public void draw(Graphics2D JavaDoc g2, DialPlot plot, Rectangle2D JavaDoc frame,
364             Rectangle2D JavaDoc view) {
365         
366         Shape JavaDoc window = getWindow(frame);
367         Shape JavaDoc outerWindow = getOuterWindow(frame);
368
369         Area JavaDoc area1 = new Area JavaDoc(outerWindow);
370         Area JavaDoc area2 = new Area JavaDoc(window);
371         area1.subtract(area2);
372         g2.setPaint(Color.lightGray);
373         g2.fill(area1);
374         
375         g2.setStroke(this.stroke);
376         g2.setPaint(this.foregroundPaint);
377         g2.draw(window);
378         g2.draw(outerWindow);
379         
380         
381     }
382
383     /**
384      * Returns <code>false</code> to indicate that this dial layer is not
385      * clipped to the dial window.
386      *
387      * @return <code>false</code>.
388      */

389     public boolean isClippedToWindow() {
390         return false;
391     }
392     
393     /**
394      * Tests this instance for equality with an arbitrary object.
395      *
396      * @param obj the object (<code>null</code> permitted).
397      *
398      * @return A boolean.
399      */

400     public boolean equals(Object JavaDoc obj) {
401         if (obj == this) {
402             return true;
403         }
404         if (!(obj instanceof StandardDialFrame)) {
405             return false;
406         }
407         StandardDialFrame that = (StandardDialFrame) obj;
408         if (!PaintUtilities.equal(this.backgroundPaint, that.backgroundPaint)) {
409             return false;
410         }
411         if (!PaintUtilities.equal(this.foregroundPaint, that.foregroundPaint)) {
412             return false;
413         }
414         if (this.startAngle != that.startAngle) {
415             return false;
416         }
417         if (this.extent != that.extent) {
418             return false;
419         }
420         if (this.innerRadius != that.innerRadius) {
421             return false;
422         }
423         if (this.outerRadius != that.outerRadius) {
424             return false;
425         }
426         if (!this.stroke.equals(that.stroke)) {
427             return false;
428         }
429         return true;
430     }
431     
432     /**
433      * Returns a hash code for this instance.
434      *
435      * @return The hash code.
436      */

437     public int hashCode() {
438         int result = 193;
439         long temp = Double.doubleToLongBits(this.startAngle);
440         result = (int) (temp ^ (temp >>> 32));
441         temp = Double.doubleToLongBits(this.extent);
442         result = (int) (temp ^ (temp >>> 32));
443         temp = Double.doubleToLongBits(this.innerRadius);
444         result = (int) (temp ^ (temp >>> 32));
445         temp = Double.doubleToLongBits(this.outerRadius);
446         result = (int) (temp ^ (temp >>> 32));
447         result = 37 * result + HashUtilities.hashCodeForPaint(
448                 this.backgroundPaint);
449         result = 37 * result + HashUtilities.hashCodeForPaint(
450                 this.foregroundPaint);
451         result = 37 * result + this.stroke.hashCode();
452         return result;
453     }
454     
455     /**
456      * Returns a clone of this instance.
457      *
458      * @return A clone.
459      *
460      * @throws CloneNotSupportedException if any attribute of this instance
461      * cannot be cloned.
462      */

463     public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc {
464         return super.clone();
465     }
466     
467     /**
468      * Provides serialization support.
469      *
470      * @param stream the output stream.
471      *
472      * @throws IOException if there is an I/O error.
473      */

474     private void writeObject(ObjectOutputStream JavaDoc stream) throws IOException JavaDoc {
475         stream.defaultWriteObject();
476         SerialUtilities.writePaint(this.backgroundPaint, stream);
477         SerialUtilities.writePaint(this.foregroundPaint, stream);
478         SerialUtilities.writeStroke(this.stroke, stream);
479     }
480
481     /**
482      * Provides serialization support.
483      *
484      * @param stream the input stream.
485      *
486      * @throws IOException if there is an I/O error.
487      * @throws ClassNotFoundException if there is a classpath problem.
488      */

489     private void readObject(ObjectInputStream JavaDoc stream)
490             throws IOException JavaDoc, ClassNotFoundException JavaDoc {
491         stream.defaultReadObject();
492         this.backgroundPaint = SerialUtilities.readPaint(stream);
493         this.foregroundPaint = SerialUtilities.readPaint(stream);
494         this.stroke = SerialUtilities.readStroke(stream);
495     }
496     
497 }
498
Popular Tags