KickJava   Java API By Example, From Geeks To Geeks.

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


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  * DialValueIndicator.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: DialValueIndicator.java,v 1.1.2.3 2006/11/07 16:11:12 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.Font JavaDoc;
48 import java.awt.FontMetrics JavaDoc;
49 import java.awt.Graphics2D JavaDoc;
50 import java.awt.Paint JavaDoc;
51 import java.awt.Stroke JavaDoc;
52 import java.awt.geom.Arc2D JavaDoc;
53 import java.awt.geom.Point2D JavaDoc;
54 import java.awt.geom.Rectangle2D JavaDoc;
55 import java.io.IOException JavaDoc;
56 import java.io.ObjectInputStream JavaDoc;
57 import java.io.ObjectOutputStream JavaDoc;
58 import java.io.Serializable JavaDoc;
59 import java.text.DecimalFormat JavaDoc;
60 import java.text.NumberFormat JavaDoc;
61
62 import org.jfree.chart.HashUtilities;
63 import org.jfree.io.SerialUtilities;
64 import org.jfree.text.TextUtilities;
65 import org.jfree.ui.RectangleAnchor;
66 import org.jfree.ui.RectangleInsets;
67 import org.jfree.ui.Size2D;
68 import org.jfree.ui.TextAnchor;
69 import org.jfree.util.PaintUtilities;
70 import org.jfree.util.PublicCloneable;
71
72 /**
73  * A value indicator for a {@link DialPlot}.
74  */

75 public class DialValueIndicator extends AbstractDialLayer implements DialLayer,
76         Cloneable JavaDoc, PublicCloneable, Serializable JavaDoc {
77     
78     /** The dataset index. */
79     private int datasetIndex;
80     
81     /** The angle that defines the anchor point. */
82     private double angle;
83     
84     /** The radius that defines the anchor point. */
85     private double radius;
86     
87     /** The frame anchor. */
88     private RectangleAnchor frameAnchor;
89     
90     /** The template value. */
91     private Number JavaDoc templateValue;
92     
93     /** The formatter. */
94     private NumberFormat JavaDoc formatter;
95
96     /** The font. */
97     private Font JavaDoc font;
98     
99     /** The paint. */
100     private transient Paint JavaDoc paint;
101     
102     /** The background paint. */
103     private transient Paint JavaDoc backgroundPaint;
104     
105     /** The outline stroke. */
106     private transient Stroke JavaDoc outlineStroke;
107     
108     /** The outline paint. */
109     private transient Paint JavaDoc outlinePaint;
110     
111     /** The insets. */
112     private RectangleInsets insets;
113     
114     /** The value anchor. */
115     private RectangleAnchor valueAnchor;
116     
117     /** The text anchor for displaying the value. */
118     private TextAnchor textAnchor;
119     
120     /**
121      * Creates a new instance of <code>DialValueIndicator</code>.
122      *
123      * @param datasetIndex the dataset index.
124      * @param label the label.
125      */

126     public DialValueIndicator(int datasetIndex, String JavaDoc label) {
127         this.datasetIndex = datasetIndex;
128         this.angle = -90.0;
129         this.radius = 0.3;
130         this.frameAnchor = RectangleAnchor.CENTER;
131         this.templateValue = new Double JavaDoc(100.0);
132         this.formatter = new DecimalFormat JavaDoc("0.0");
133         this.font = new Font JavaDoc("Dialog", Font.BOLD, 14);
134         this.paint = Color.black;
135         this.backgroundPaint = Color.white;
136         this.outlineStroke = new BasicStroke JavaDoc(1.0f);
137         this.outlinePaint = Color.blue;
138         this.insets = new RectangleInsets(4, 4, 4, 4);
139         this.valueAnchor = RectangleAnchor.RIGHT;
140         this.textAnchor = TextAnchor.CENTER_RIGHT;
141     }
142     
143     /**
144      * Returns the index of the dataset from which this indicator fetches its
145      * current value.
146      *
147      * @return The dataset index.
148      */

149     public int getDatasetIndex() {
150         return this.datasetIndex;
151     }
152     
153     /**
154      * Sets the dataset index.
155      *
156      * @param index the index.
157      */

158     public void setDatasetIndex(int index) {
159         this.datasetIndex = index;
160     }
161     
162     /**
163      * Returns the angle for the anchor point. The angle is specified in
164      * degrees using the same orientation as Java's <code>Arc2D</code> class.
165      *
166      * @return The angle (in degrees).
167      */

168     public double getAngle() {
169         return this.angle;
170     }
171     
172     /**
173      * Sets the angle for the anchor point and sends a
174      * {@link DialLayerChangeEvent} to all registered listeners.
175      *
176      * @param angle the angle (in degrees).
177      */

178     public void setAngle(double angle) {
179         this.angle = angle;
180         notifyListeners(new DialLayerChangeEvent(this));
181     }
182     
183     /**
184      * Returns the radius.
185      *
186      * @return The radius.
187      */

188     public double getRadius() {
189         return this.radius;
190     }
191     
192     /**
193      * Sets the radius.
194      *
195      * @param radius the radius.
196      */

197     public void setRadius(double radius) {
198         // TODO: validation
199
this.radius = radius;
200         notifyListeners(new DialLayerChangeEvent(this));
201     }
202     
203     /**
204      * Returns the frame anchor.
205      *
206      * @return The frame anchor.
207      */

208     public RectangleAnchor getFrameAnchor() {
209         return this.frameAnchor;
210     }
211     
212     /**
213      * Sets the frame anchor and sends a {@link DialLayerChangeEvent} to all
214      * registered listeners.
215      *
216      * @param anchor the anchor (<code>null</code> not permitted).
217      */

218     public void setFrameAnchor(RectangleAnchor anchor) {
219         if (anchor == null) {
220             throw new IllegalArgumentException JavaDoc("Null 'anchor' argument.");
221         }
222         this.frameAnchor = anchor;
223         notifyListeners(new DialLayerChangeEvent(this));
224     }
225     
226     /**
227      * Returns the template value.
228      *
229      * @return The template value.
230      */

231     public Number JavaDoc getTemplateValue() {
232         return this.templateValue;
233     }
234     
235     /**
236      * Sets the template value and sends a {@link DialLayerChangeEvent} to
237      * all registered listeners.
238      *
239      * @param value the value (<code>null</code> not permitted).
240      */

241     public void setTemplateValue(Number JavaDoc value) {
242         this.templateValue = value;
243         notifyListeners(new DialLayerChangeEvent(this));
244     }
245     
246     /**
247      * Returns the formatter used to format the value.
248      *
249      * @return The formatter (never <code>null</code>).
250      */

251     public NumberFormat JavaDoc getNumberFormat() {
252         return this.formatter;
253     }
254     
255     /**
256      * Sets the formatter used to format the value and sends a
257      * {@link DialLayerChangeEvent} to all registered listeners.
258      *
259      * @param formatter the formatter (<code>null</code> not permitted).
260      */

261     public void setNumberFormat(NumberFormat JavaDoc formatter) {
262         if (formatter == null) {
263             throw new IllegalArgumentException JavaDoc("Null 'formatter' argument.");
264         }
265         this.formatter = formatter;
266         notifyListeners(new DialLayerChangeEvent(this));
267     }
268     
269     /**
270      * Returns the font.
271      *
272      * @return The font (never <code>null</code>).
273      */

274     public Font JavaDoc getFont() {
275         return this.font;
276     }
277     
278     /**
279      * Sets the font and sends a {@link DialLayerChangeEvent} to all registered
280      * listeners.
281      *
282      * @param font the font (<code>null</code> not permitted).
283      */

284     public void setFont(Font JavaDoc font) {
285         if (font == null) {
286             throw new IllegalArgumentException JavaDoc("Null 'font' argument.");
287         }
288         this.font = font;
289         notifyListeners(new DialLayerChangeEvent(this));
290     }
291     
292     /**
293      * Returns the paint.
294      *
295      * @return The paint (never <code>null</code>).
296      */

297     public Paint JavaDoc getPaint() {
298         return this.paint;
299     }
300     
301     /**
302      * Sets the paint and sends a {@link DialLayerChangeEvent} to all
303      * registered listeners.
304      *
305      * @param paint the paint (<code>null</code> not permitted).
306      */

307     public void setPaint(Paint JavaDoc paint) {
308         if (paint == null) {
309             throw new IllegalArgumentException JavaDoc("Null 'paint' argument.");
310         }
311         this.paint = paint;
312         notifyListeners(new DialLayerChangeEvent(this));
313     }
314     
315     /**
316      * Returns the background paint.
317      *
318      * @return The background paint.
319      */

320     public Paint JavaDoc getBackgroundPaint() {
321         return this.backgroundPaint;
322     }
323     
324     /**
325      * Sets the background paint.
326      *
327      * @param paint the paint (<code>null</code> not permitted).
328      */

329     public void setBackgroundPaint(Paint JavaDoc paint) {
330         if (paint == null) {
331             throw new IllegalArgumentException JavaDoc("Null 'paint' argument.");
332         }
333         this.backgroundPaint = paint;
334         notifyListeners(new DialLayerChangeEvent(this));
335     }
336     
337     /**
338      * Returns the outline stroke.
339      *
340      * @return The outline stroke.
341      */

342     public Stroke JavaDoc getOutlineStroke() {
343         return this.outlineStroke;
344     }
345      
346     /**
347      * Sets the outline stroke.
348      *
349      * @param stroke the stroke (<code>null</code> not permitted).
350      */

351     public void setOutlineStroke(Stroke JavaDoc stroke) {
352         if (stroke == null) {
353             throw new IllegalArgumentException JavaDoc("Null 'stroke' argument.");
354         }
355         this.outlineStroke = stroke;
356         notifyListeners(new DialLayerChangeEvent(this));
357     }
358     
359     /**
360      * Returns the outline paint.
361      *
362      * @return The outline paint.
363      */

364     public Paint JavaDoc getOutlinePaint() {
365         return this.outlinePaint;
366     }
367     
368     /**
369      * Sets the outline paint and sends a {@link DialLayerChangeEvent} to all
370      * registered listeners.
371      *
372      * @param paint the paint.
373      */

374     public void setOutlinePaint(Paint JavaDoc paint) {
375         if (paint == null) {
376             throw new IllegalArgumentException JavaDoc("Null 'paint' argument.");
377         }
378         this.outlinePaint = paint;
379         notifyListeners(new DialLayerChangeEvent(this));
380     }
381     
382     /**
383      * Returns the insets.
384      *
385      * @return The insets (never <code>null</code>).
386      */

387     public RectangleInsets getInsets() {
388         return this.insets;
389     }
390     
391     /**
392      * Sets the insets.
393      *
394      * @param insets the insets (<code>null</code> not permitted).
395      */

396     public void setInsets(RectangleInsets insets) {
397         if (insets == null) {
398             throw new IllegalArgumentException JavaDoc("Null 'insets' argument.");
399         }
400         this.insets = insets;
401         notifyListeners(new DialLayerChangeEvent(this));
402     }
403     
404     /**
405      * Returns the value anchor.
406      *
407      * @return The value anchor.
408      */

409     public RectangleAnchor getValueAnchor() {
410         return this.valueAnchor;
411     }
412     
413     /**
414      * Sets the value anchor.
415      *
416      * @param anchor the anchor (<code>null</code> not permitted).
417      */

418     public void setValueAnchor(RectangleAnchor anchor) {
419         if (anchor == null) {
420             throw new IllegalArgumentException JavaDoc("Null 'anchor' argument.");
421         }
422         this.valueAnchor = anchor;
423         notifyListeners(new DialLayerChangeEvent(this));
424     }
425     
426     /**
427      * Returns the text anchor.
428      *
429      * @return The text anchor.
430      */

431     public TextAnchor getTextAnchor() {
432         return this.textAnchor;
433     }
434     
435     /**
436      * Sets the text anchor.
437      *
438      * @param anchor the anchor (<code>null</code> not permitted).
439      */

440     public void setTextAnchor(TextAnchor anchor) {
441         if (anchor == null) {
442             throw new IllegalArgumentException JavaDoc("Null 'anchor' argument.");
443         }
444         this.textAnchor = anchor;
445         notifyListeners(new DialLayerChangeEvent(this));
446     }
447     
448     /**
449      * Returns <code>true</code> to indicate that this layer should be
450      * clipped within the dial window.
451      *
452      * @return <code>true</code>.
453      */

454     public boolean isClippedToWindow() {
455         return true;
456     }
457     
458     /**
459      * Draws the background to the specified graphics device. If the dial
460      * frame specifies a window, the clipping region will already have been
461      * set to this window before this method is called.
462      *
463      * @param g2 the graphics device (<code>null</code> not permitted).
464      * @param plot the plot (ignored here).
465      * @param frame the dial frame (ignored here).
466      * @param view the view rectangle (<code>null</code> not permitted).
467      */

468     public void draw(Graphics2D JavaDoc g2, DialPlot plot, Rectangle2D JavaDoc frame,
469             Rectangle2D JavaDoc view) {
470
471         // work out the anchor point
472
Rectangle2D JavaDoc f = DialPlot.rectangleByRadius(frame, this.radius,
473                 this.radius);
474         Arc2D JavaDoc arc = new Arc2D.Double JavaDoc(f, this.angle, 0.0, Arc2D.OPEN);
475         Point2D JavaDoc pt = arc.getStartPoint();
476         
477         // calculate the bounds of the template value
478
FontMetrics JavaDoc fm = g2.getFontMetrics(this.font);
479         String JavaDoc s = this.formatter.format(this.templateValue);
480         Rectangle2D JavaDoc tb = TextUtilities.getTextBounds(s, g2, fm);
481
482         // align this rectangle to the frameAnchor
483
Rectangle2D JavaDoc bounds = RectangleAnchor.createRectangle(new Size2D(
484                 tb.getWidth(), tb.getHeight()), pt.getX(), pt.getY(),
485                 this.frameAnchor);
486         
487         // add the insets
488
Rectangle2D JavaDoc fb = this.insets.createOutsetRectangle(bounds);
489
490         // draw the background
491
g2.setPaint(this.backgroundPaint);
492         g2.fill(fb);
493
494         // draw the border
495
g2.setStroke(this.outlineStroke);
496         g2.setPaint(this.outlinePaint);
497         g2.draw(fb);
498         
499         
500         // now find the text anchor point
501
double value = plot.getValue(this.datasetIndex);
502         String JavaDoc valueStr = this.formatter.format(value);
503         Point2D JavaDoc pt2 = RectangleAnchor.coordinates(bounds, this.valueAnchor);
504         g2.setPaint(this.paint);
505         g2.setFont(this.font);
506         TextUtilities.drawAlignedString(valueStr, g2, (float) pt2.getX(),
507                 (float) pt2.getY(), this.textAnchor);
508         
509     }
510     
511     /**
512      * Tests this instance for equality with an arbitrary object.
513      *
514      * @param obj the object (<code>null</code> permitted).
515      *
516      * @return A boolean.
517      */

518     public boolean equals(Object JavaDoc obj) {
519         if (obj == this) {
520             return true;
521         }
522         if (!(obj instanceof DialValueIndicator)) {
523             return false;
524         }
525         DialValueIndicator that = (DialValueIndicator) obj;
526         if (this.datasetIndex != that.datasetIndex) {
527             return false;
528         }
529         if (this.angle != that.angle) {
530             return false;
531         }
532         if (this.radius != that.radius) {
533             return false;
534         }
535         if (!this.frameAnchor.equals(that.frameAnchor)) {
536             return false;
537         }
538         if (!this.templateValue.equals(that.templateValue)) {
539             return false;
540         }
541         if (!this.font.equals(that.font)) {
542             return false;
543         }
544         if (!PaintUtilities.equal(this.paint, that.paint)) {
545             return false;
546         }
547         if (!PaintUtilities.equal(this.backgroundPaint, that.backgroundPaint)) {
548             return false;
549         }
550         if (!this.outlineStroke.equals(that.outlineStroke)) {
551             return false;
552         }
553         if (!PaintUtilities.equal(this.outlinePaint, that.outlinePaint)) {
554             return false;
555         }
556         if (!this.insets.equals(that.insets)) {
557             return false;
558         }
559         if (!this.valueAnchor.equals(that.valueAnchor)) {
560             return false;
561         }
562         if (!this.textAnchor.equals(that.textAnchor)) {
563             return false;
564         }
565         
566         return true;
567     }
568     
569     /**
570      * Returns a hash code for this instance.
571      *
572      * @return The hash code.
573      */

574     public int hashCode() {
575         int result = 193;
576         result = 37 * result + HashUtilities.hashCodeForPaint(this.paint);
577         result = 37 * result + HashUtilities.hashCodeForPaint(
578                 this.backgroundPaint);
579         result = 37 * result + HashUtilities.hashCodeForPaint(
580                 this.outlinePaint);
581         result = 37 * result + this.outlineStroke.hashCode();
582         return result;
583     }
584     
585     /**
586      * Returns a clone of this instance.
587      *
588      * @return The clone.
589      *
590      * @throws CloneNotSupportedException if some attribute of this instance
591      * cannot be cloned.
592      */

593     public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc {
594         return super.clone();
595     }
596
597     /**
598      * Provides serialization support.
599      *
600      * @param stream the output stream.
601      *
602      * @throws IOException if there is an I/O error.
603      */

604     private void writeObject(ObjectOutputStream JavaDoc stream) throws IOException JavaDoc {
605         stream.defaultWriteObject();
606         SerialUtilities.writePaint(this.paint, stream);
607         SerialUtilities.writePaint(this.backgroundPaint, stream);
608         SerialUtilities.writePaint(this.outlinePaint, stream);
609         SerialUtilities.writeStroke(this.outlineStroke, stream);
610     }
611
612     /**
613      * Provides serialization support.
614      *
615      * @param stream the input stream.
616      *
617      * @throws IOException if there is an I/O error.
618      * @throws ClassNotFoundException if there is a classpath problem.
619      */

620     private void readObject(ObjectInputStream JavaDoc stream)
621             throws IOException JavaDoc, ClassNotFoundException JavaDoc {
622         stream.defaultReadObject();
623         this.paint = SerialUtilities.readPaint(stream);
624         this.backgroundPaint = SerialUtilities.readPaint(stream);
625         this.outlinePaint = SerialUtilities.readPaint(stream);
626         this.outlineStroke = SerialUtilities.readStroke(stream);
627     }
628
629 }
630
Popular Tags