Source Code Cross Referenced for MeterPlot.java in  » Chart » jfreechart » org » jfree » chart » plot » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Chart » jfreechart » org.jfree.chart.plot 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* ===========================================================
0002:         * JFreeChart : a free chart library for the Java(tm) platform
0003:         * ===========================================================
0004:         *
0005:         * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
0006:         *
0007:         * Project Info:  http://www.jfree.org/jfreechart/index.html
0008:         *
0009:         * This library is free software; you can redistribute it and/or modify it 
0010:         * under the terms of the GNU Lesser General Public License as published by 
0011:         * the Free Software Foundation; either version 2.1 of the License, or 
0012:         * (at your option) any later version.
0013:         *
0014:         * This library is distributed in the hope that it will be useful, but 
0015:         * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
0016:         * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
0017:         * License for more details.
0018:         *
0019:         * You should have received a copy of the GNU Lesser General Public
0020:         * License along with this library; if not, write to the Free Software
0021:         * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
0022:         * USA.  
0023:         *
0024:         * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
0025:         * in the United States and other countries.]
0026:         *
0027:         * --------------
0028:         * MeterPlot.java
0029:         * --------------
0030:         * (C) Copyright 2000-2007, by Hari and Contributors.
0031:         *
0032:         * Original Author:  Hari (ourhari@hotmail.com);
0033:         * Contributor(s):   David Gilbert (for Object Refinery Limited);
0034:         *                   Bob Orchard;
0035:         *                   Arnaud Lelievre;
0036:         *                   Nicolas Brodu;
0037:         *                   David Bastend;
0038:         *
0039:         * $Id: MeterPlot.java,v 1.13.2.10 2007/05/18 10:28:21 mungady Exp $
0040:         *
0041:         * Changes
0042:         * -------
0043:         * 01-Apr-2002 : Version 1, contributed by Hari (DG);
0044:         * 23-Apr-2002 : Moved dataset from JFreeChart to Plot (DG);
0045:         * 22-Aug-2002 : Added changes suggest by Bob Orchard, changed Color to Paint 
0046:         *               for consistency, plus added Javadoc comments (DG);
0047:         * 01-Oct-2002 : Fixed errors reported by Checkstyle (DG);
0048:         * 23-Jan-2003 : Removed one constructor (DG);
0049:         * 26-Mar-2003 : Implemented Serializable (DG);
0050:         * 20-Aug-2003 : Changed dataset from MeterDataset --> ValueDataset, added 
0051:         *               equals() method,
0052:         * 08-Sep-2003 : Added internationalization via use of properties 
0053:         *               resourceBundle (RFE 690236) (AL); 
0054:         *               implemented Cloneable, and various other changes (DG);
0055:         * 08-Sep-2003 : Added serialization methods (NB);
0056:         * 11-Sep-2003 : Added cloning support (NB);
0057:         * 16-Sep-2003 : Changed ChartRenderingInfo --> PlotRenderingInfo (DG);
0058:         * 25-Sep-2003 : Fix useless cloning. Correct dataset listener registration in 
0059:         *               constructor. (NB)
0060:         * 29-Oct-2003 : Added workaround for font alignment in PDF output (DG);
0061:         * 17-Jan-2004 : Changed to allow dialBackgroundPaint to be set to null - see 
0062:         *               bug 823628 (DG);
0063:         * 07-Apr-2004 : Changed string bounds calculation (DG);
0064:         * 12-May-2004 : Added tickLabelFormat attribute - see RFE 949566.  Also 
0065:         *               updated the equals() method (DG);
0066:         * 02-Nov-2004 : Added sanity checks for range, and only draw the needle if the 
0067:         *               value is contained within the overall range - see bug report 
0068:         *               1056047 (DG);
0069:         * 11-Jan-2005 : Removed deprecated code in preparation for the 1.0.0 
0070:         *               release (DG);
0071:         * 02-Feb-2005 : Added optional background paint for each region (DG);
0072:         * 22-Mar-2005 : Removed 'normal', 'warning' and 'critical' regions and put in
0073:         *               facility to define an arbitrary number of MeterIntervals,
0074:         *               based on a contribution by David Bastend (DG);
0075:         * 20-Apr-2005 : Small update for change to LegendItem constructors (DG);
0076:         * 05-May-2005 : Updated draw() method parameters (DG);
0077:         * 08-Jun-2005 : Fixed equals() method to handle GradientPaint (DG);
0078:         * 10-Nov-2005 : Added tickPaint, tickSize and valuePaint attributes, and
0079:         *               put value label drawing code into a separate method (DG);
0080:         * ------------- JFREECHART 1.0.x ---------------------------------------------
0081:         * 05-Mar-2007 : Restore clip region correctly (see bug 1667750) (DG);
0082:         * 18-May-2007 : Set dataset for LegendItem (DG);
0083:         * 
0084:         */
0085:
0086:        package org.jfree.chart.plot;
0087:
0088:        import java.awt.AlphaComposite;
0089:        import java.awt.BasicStroke;
0090:        import java.awt.Color;
0091:        import java.awt.Composite;
0092:        import java.awt.Font;
0093:        import java.awt.FontMetrics;
0094:        import java.awt.Graphics2D;
0095:        import java.awt.Paint;
0096:        import java.awt.Polygon;
0097:        import java.awt.Shape;
0098:        import java.awt.Stroke;
0099:        import java.awt.geom.Arc2D;
0100:        import java.awt.geom.Ellipse2D;
0101:        import java.awt.geom.Line2D;
0102:        import java.awt.geom.Point2D;
0103:        import java.awt.geom.Rectangle2D;
0104:        import java.io.IOException;
0105:        import java.io.ObjectInputStream;
0106:        import java.io.ObjectOutputStream;
0107:        import java.io.Serializable;
0108:        import java.text.NumberFormat;
0109:        import java.util.Collections;
0110:        import java.util.Iterator;
0111:        import java.util.List;
0112:        import java.util.ResourceBundle;
0113:
0114:        import org.jfree.chart.LegendItem;
0115:        import org.jfree.chart.LegendItemCollection;
0116:        import org.jfree.chart.event.PlotChangeEvent;
0117:        import org.jfree.data.Range;
0118:        import org.jfree.data.general.DatasetChangeEvent;
0119:        import org.jfree.data.general.ValueDataset;
0120:        import org.jfree.io.SerialUtilities;
0121:        import org.jfree.text.TextUtilities;
0122:        import org.jfree.ui.RectangleInsets;
0123:        import org.jfree.ui.TextAnchor;
0124:        import org.jfree.util.ObjectUtilities;
0125:        import org.jfree.util.PaintUtilities;
0126:
0127:        /**
0128:         * A plot that displays a single value in the form of a needle on a dial.  
0129:         * Defined ranges (for example, 'normal', 'warning' and 'critical') can be
0130:         * highlighted on the dial.
0131:         */
0132:        public class MeterPlot extends Plot implements  Serializable, Cloneable {
0133:
0134:            /** For serialization. */
0135:            private static final long serialVersionUID = 2987472457734470962L;
0136:
0137:            /** The default background paint. */
0138:            static final Paint DEFAULT_DIAL_BACKGROUND_PAINT = Color.black;
0139:
0140:            /** The default needle paint. */
0141:            static final Paint DEFAULT_NEEDLE_PAINT = Color.green;
0142:
0143:            /** The default value font. */
0144:            static final Font DEFAULT_VALUE_FONT = new Font("SansSerif",
0145:                    Font.BOLD, 12);
0146:
0147:            /** The default value paint. */
0148:            static final Paint DEFAULT_VALUE_PAINT = Color.yellow;
0149:
0150:            /** The default meter angle. */
0151:            public static final int DEFAULT_METER_ANGLE = 270;
0152:
0153:            /** The default border size. */
0154:            public static final float DEFAULT_BORDER_SIZE = 3f;
0155:
0156:            /** The default circle size. */
0157:            public static final float DEFAULT_CIRCLE_SIZE = 10f;
0158:
0159:            /** The default label font. */
0160:            public static final Font DEFAULT_LABEL_FONT = new Font("SansSerif",
0161:                    Font.BOLD, 10);
0162:
0163:            /** The dataset (contains a single value). */
0164:            private ValueDataset dataset;
0165:
0166:            /** The dial shape (background shape). */
0167:            private DialShape shape;
0168:
0169:            /** The dial extent (measured in degrees). */
0170:            private int meterAngle;
0171:
0172:            /** The overall range of data values on the dial. */
0173:            private Range range;
0174:
0175:            /** The tick size. */
0176:            private double tickSize;
0177:
0178:            /** The paint used to draw the ticks. */
0179:            private transient Paint tickPaint;
0180:
0181:            /** The units displayed on the dial. */
0182:            private String units;
0183:
0184:            /** The font for the value displayed in the center of the dial. */
0185:            private Font valueFont;
0186:
0187:            /** The paint for the value displayed in the center of the dial. */
0188:            private transient Paint valuePaint;
0189:
0190:            /** A flag that controls whether or not the border is drawn. */
0191:            private boolean drawBorder;
0192:
0193:            /** The outline paint. */
0194:            private transient Paint dialOutlinePaint;
0195:
0196:            /** The paint for the dial background. */
0197:            private transient Paint dialBackgroundPaint;
0198:
0199:            /** The paint for the needle. */
0200:            private transient Paint needlePaint;
0201:
0202:            /** A flag that controls whether or not the tick labels are visible. */
0203:            private boolean tickLabelsVisible;
0204:
0205:            /** The tick label font. */
0206:            private Font tickLabelFont;
0207:
0208:            /** The tick label paint. */
0209:            private transient Paint tickLabelPaint;
0210:
0211:            /** The tick label format. */
0212:            private NumberFormat tickLabelFormat;
0213:
0214:            /** The resourceBundle for the localization. */
0215:            protected static ResourceBundle localizationResources = ResourceBundle
0216:                    .getBundle("org.jfree.chart.plot.LocalizationBundle");
0217:
0218:            /** 
0219:             * A (possibly empty) list of the {@link MeterInterval}s to be highlighted 
0220:             * on the dial. 
0221:             */
0222:            private List intervals;
0223:
0224:            /**
0225:             * Creates a new plot with a default range of <code>0</code> to 
0226:             * <code>100</code> and no value to display.
0227:             */
0228:            public MeterPlot() {
0229:                this (null);
0230:            }
0231:
0232:            /**
0233:             * Creates a new plot that displays the value from the supplied dataset.
0234:             *
0235:             * @param dataset  the dataset (<code>null</code> permitted).
0236:             */
0237:            public MeterPlot(ValueDataset dataset) {
0238:                super ();
0239:                this .shape = DialShape.CIRCLE;
0240:                this .meterAngle = DEFAULT_METER_ANGLE;
0241:                this .range = new Range(0.0, 100.0);
0242:                this .tickSize = 10.0;
0243:                this .tickPaint = Color.white;
0244:                this .units = "Units";
0245:                this .needlePaint = MeterPlot.DEFAULT_NEEDLE_PAINT;
0246:                this .tickLabelsVisible = true;
0247:                this .tickLabelFont = MeterPlot.DEFAULT_LABEL_FONT;
0248:                this .tickLabelPaint = Color.black;
0249:                this .tickLabelFormat = NumberFormat.getInstance();
0250:                this .valueFont = MeterPlot.DEFAULT_VALUE_FONT;
0251:                this .valuePaint = MeterPlot.DEFAULT_VALUE_PAINT;
0252:                this .dialBackgroundPaint = MeterPlot.DEFAULT_DIAL_BACKGROUND_PAINT;
0253:                this .intervals = new java.util.ArrayList();
0254:                setDataset(dataset);
0255:            }
0256:
0257:            /**
0258:             * Returns the dial shape.  The default is {@link DialShape#CIRCLE}).
0259:             * 
0260:             * @return The dial shape (never <code>null</code>).
0261:             * 
0262:             * @see #setDialShape(DialShape)
0263:             */
0264:            public DialShape getDialShape() {
0265:                return this .shape;
0266:            }
0267:
0268:            /**
0269:             * Sets the dial shape and sends a {@link PlotChangeEvent} to all 
0270:             * registered listeners.
0271:             * 
0272:             * @param shape  the shape (<code>null</code> not permitted).
0273:             * 
0274:             * @see #getDialShape()
0275:             */
0276:            public void setDialShape(DialShape shape) {
0277:                if (shape == null) {
0278:                    throw new IllegalArgumentException("Null 'shape' argument.");
0279:                }
0280:                this .shape = shape;
0281:                notifyListeners(new PlotChangeEvent(this ));
0282:            }
0283:
0284:            /**
0285:             * Returns the meter angle in degrees.  This defines, in part, the shape
0286:             * of the dial.  The default is 270 degrees.
0287:             *
0288:             * @return The meter angle (in degrees).
0289:             * 
0290:             * @see #setMeterAngle(int)
0291:             */
0292:            public int getMeterAngle() {
0293:                return this .meterAngle;
0294:            }
0295:
0296:            /**
0297:             * Sets the angle (in degrees) for the whole range of the dial and sends 
0298:             * a {@link PlotChangeEvent} to all registered listeners.
0299:             * 
0300:             * @param angle  the angle (in degrees, in the range 1-360).
0301:             * 
0302:             * @see #getMeterAngle()
0303:             */
0304:            public void setMeterAngle(int angle) {
0305:                if (angle < 1 || angle > 360) {
0306:                    throw new IllegalArgumentException("Invalid 'angle' ("
0307:                            + angle + ")");
0308:                }
0309:                this .meterAngle = angle;
0310:                notifyListeners(new PlotChangeEvent(this ));
0311:            }
0312:
0313:            /**
0314:             * Returns the overall range for the dial.
0315:             * 
0316:             * @return The overall range (never <code>null</code>).
0317:             * 
0318:             * @see #setRange(Range)
0319:             */
0320:            public Range getRange() {
0321:                return this .range;
0322:            }
0323:
0324:            /**
0325:             * Sets the range for the dial and sends a {@link PlotChangeEvent} to all
0326:             * registered listeners.
0327:             * 
0328:             * @param range  the range (<code>null</code> not permitted and zero-length
0329:             *               ranges not permitted).
0330:             *             
0331:             * @see #getRange()
0332:             */
0333:            public void setRange(Range range) {
0334:                if (range == null) {
0335:                    throw new IllegalArgumentException("Null 'range' argument.");
0336:                }
0337:                if (!(range.getLength() > 0.0)) {
0338:                    throw new IllegalArgumentException(
0339:                            "Range length must be positive.");
0340:                }
0341:                this .range = range;
0342:                notifyListeners(new PlotChangeEvent(this ));
0343:            }
0344:
0345:            /**
0346:             * Returns the tick size (the interval between ticks on the dial).
0347:             * 
0348:             * @return The tick size.
0349:             * 
0350:             * @see #setTickSize(double)
0351:             */
0352:            public double getTickSize() {
0353:                return this .tickSize;
0354:            }
0355:
0356:            /**
0357:             * Sets the tick size and sends a {@link PlotChangeEvent} to all 
0358:             * registered listeners.
0359:             * 
0360:             * @param size  the tick size (must be > 0).
0361:             * 
0362:             * @see #getTickSize()
0363:             */
0364:            public void setTickSize(double size) {
0365:                if (size <= 0) {
0366:                    throw new IllegalArgumentException("Requires 'size' > 0.");
0367:                }
0368:                this .tickSize = size;
0369:                notifyListeners(new PlotChangeEvent(this ));
0370:            }
0371:
0372:            /**
0373:             * Returns the paint used to draw the ticks around the dial. 
0374:             * 
0375:             * @return The paint used to draw the ticks around the dial (never 
0376:             *         <code>null</code>).
0377:             *         
0378:             * @see #setTickPaint(Paint)
0379:             */
0380:            public Paint getTickPaint() {
0381:                return this .tickPaint;
0382:            }
0383:
0384:            /**
0385:             * Sets the paint used to draw the tick labels around the dial and sends
0386:             * a {@link PlotChangeEvent} to all registered listeners.
0387:             * 
0388:             * @param paint  the paint (<code>null</code> not permitted).
0389:             * 
0390:             * @see #getTickPaint()
0391:             */
0392:            public void setTickPaint(Paint paint) {
0393:                if (paint == null) {
0394:                    throw new IllegalArgumentException("Null 'paint' argument.");
0395:                }
0396:                this .tickPaint = paint;
0397:                notifyListeners(new PlotChangeEvent(this ));
0398:            }
0399:
0400:            /**
0401:             * Returns a string describing the units for the dial.
0402:             * 
0403:             * @return The units (possibly <code>null</code>).
0404:             * 
0405:             * @see #setUnits(String)
0406:             */
0407:            public String getUnits() {
0408:                return this .units;
0409:            }
0410:
0411:            /**
0412:             * Sets the units for the dial and sends a {@link PlotChangeEvent} to all
0413:             * registered listeners.
0414:             * 
0415:             * @param units  the units (<code>null</code> permitted).
0416:             * 
0417:             * @see #getUnits()
0418:             */
0419:            public void setUnits(String units) {
0420:                this .units = units;
0421:                notifyListeners(new PlotChangeEvent(this ));
0422:            }
0423:
0424:            /**
0425:             * Returns the paint for the needle.
0426:             *
0427:             * @return The paint (never <code>null</code>).
0428:             * 
0429:             * @see #setNeedlePaint(Paint)
0430:             */
0431:            public Paint getNeedlePaint() {
0432:                return this .needlePaint;
0433:            }
0434:
0435:            /**
0436:             * Sets the paint used to display the needle and sends a 
0437:             * {@link PlotChangeEvent} to all registered listeners.
0438:             *
0439:             * @param paint  the paint (<code>null</code> not permitted).
0440:             * 
0441:             * @see #getNeedlePaint()
0442:             */
0443:            public void setNeedlePaint(Paint paint) {
0444:                if (paint == null) {
0445:                    throw new IllegalArgumentException("Null 'paint' argument.");
0446:                }
0447:                this .needlePaint = paint;
0448:                notifyListeners(new PlotChangeEvent(this ));
0449:            }
0450:
0451:            /**
0452:             * Returns the flag that determines whether or not tick labels are visible.
0453:             *
0454:             * @return The flag.
0455:             * 
0456:             * @see #setTickLabelsVisible(boolean)
0457:             */
0458:            public boolean getTickLabelsVisible() {
0459:                return this .tickLabelsVisible;
0460:            }
0461:
0462:            /**
0463:             * Sets the flag that controls whether or not the tick labels are visible
0464:             * and sends a {@link PlotChangeEvent} to all registered listeners.
0465:             *
0466:             * @param visible  the flag.
0467:             * 
0468:             * @see #getTickLabelsVisible()
0469:             */
0470:            public void setTickLabelsVisible(boolean visible) {
0471:                if (this .tickLabelsVisible != visible) {
0472:                    this .tickLabelsVisible = visible;
0473:                    notifyListeners(new PlotChangeEvent(this ));
0474:                }
0475:            }
0476:
0477:            /**
0478:             * Returns the tick label font.
0479:             *
0480:             * @return The font (never <code>null</code>).
0481:             * 
0482:             * @see #setTickLabelFont(Font)
0483:             */
0484:            public Font getTickLabelFont() {
0485:                return this .tickLabelFont;
0486:            }
0487:
0488:            /**
0489:             * Sets the tick label font and sends a {@link PlotChangeEvent} to all 
0490:             * registered listeners.
0491:             *
0492:             * @param font  the font (<code>null</code> not permitted).
0493:             * 
0494:             * @see #getTickLabelFont()
0495:             */
0496:            public void setTickLabelFont(Font font) {
0497:                if (font == null) {
0498:                    throw new IllegalArgumentException("Null 'font' argument.");
0499:                }
0500:                if (!this .tickLabelFont.equals(font)) {
0501:                    this .tickLabelFont = font;
0502:                    notifyListeners(new PlotChangeEvent(this ));
0503:                }
0504:            }
0505:
0506:            /**
0507:             * Returns the tick label paint.
0508:             *
0509:             * @return The paint (never <code>null</code>).
0510:             * 
0511:             * @see #setTickLabelPaint(Paint)
0512:             */
0513:            public Paint getTickLabelPaint() {
0514:                return this .tickLabelPaint;
0515:            }
0516:
0517:            /**
0518:             * Sets the tick label paint and sends a {@link PlotChangeEvent} to all 
0519:             * registered listeners.
0520:             *
0521:             * @param paint  the paint (<code>null</code> not permitted).
0522:             * 
0523:             * @see #getTickLabelPaint()
0524:             */
0525:            public void setTickLabelPaint(Paint paint) {
0526:                if (paint == null) {
0527:                    throw new IllegalArgumentException("Null 'paint' argument.");
0528:                }
0529:                if (!this .tickLabelPaint.equals(paint)) {
0530:                    this .tickLabelPaint = paint;
0531:                    notifyListeners(new PlotChangeEvent(this ));
0532:                }
0533:            }
0534:
0535:            /**
0536:             * Returns the tick label format.
0537:             * 
0538:             * @return The tick label format (never <code>null</code>).
0539:             * 
0540:             * @see #setTickLabelFormat(NumberFormat)
0541:             */
0542:            public NumberFormat getTickLabelFormat() {
0543:                return this .tickLabelFormat;
0544:            }
0545:
0546:            /**
0547:             * Sets the format for the tick labels and sends a {@link PlotChangeEvent} 
0548:             * to all registered listeners.
0549:             * 
0550:             * @param format  the format (<code>null</code> not permitted).
0551:             * 
0552:             * @see #getTickLabelFormat()
0553:             */
0554:            public void setTickLabelFormat(NumberFormat format) {
0555:                if (format == null) {
0556:                    throw new IllegalArgumentException(
0557:                            "Null 'format' argument.");
0558:                }
0559:                this .tickLabelFormat = format;
0560:                notifyListeners(new PlotChangeEvent(this ));
0561:            }
0562:
0563:            /**
0564:             * Returns the font for the value label.
0565:             *
0566:             * @return The font (never <code>null</code>).
0567:             * 
0568:             * @see #setValueFont(Font)
0569:             */
0570:            public Font getValueFont() {
0571:                return this .valueFont;
0572:            }
0573:
0574:            /**
0575:             * Sets the font used to display the value label and sends a 
0576:             * {@link PlotChangeEvent} to all registered listeners.
0577:             *
0578:             * @param font  the font (<code>null</code> not permitted).
0579:             * 
0580:             * @see #getValueFont()
0581:             */
0582:            public void setValueFont(Font font) {
0583:                if (font == null) {
0584:                    throw new IllegalArgumentException("Null 'font' argument.");
0585:                }
0586:                this .valueFont = font;
0587:                notifyListeners(new PlotChangeEvent(this ));
0588:            }
0589:
0590:            /**
0591:             * Returns the paint for the value label.
0592:             *
0593:             * @return The paint (never <code>null</code>).
0594:             * 
0595:             * @see #setValuePaint(Paint)
0596:             */
0597:            public Paint getValuePaint() {
0598:                return this .valuePaint;
0599:            }
0600:
0601:            /**
0602:             * Sets the paint used to display the value label and sends a 
0603:             * {@link PlotChangeEvent} to all registered listeners.
0604:             *
0605:             * @param paint  the paint (<code>null</code> not permitted).
0606:             * 
0607:             * @see #getValuePaint()
0608:             */
0609:            public void setValuePaint(Paint paint) {
0610:                if (paint == null) {
0611:                    throw new IllegalArgumentException("Null 'paint' argument.");
0612:                }
0613:                this .valuePaint = paint;
0614:                notifyListeners(new PlotChangeEvent(this ));
0615:            }
0616:
0617:            /**
0618:             * Returns the paint for the dial background.
0619:             *
0620:             * @return The paint (possibly <code>null</code>).
0621:             * 
0622:             * @see #setDialBackgroundPaint(Paint)
0623:             */
0624:            public Paint getDialBackgroundPaint() {
0625:                return this .dialBackgroundPaint;
0626:            }
0627:
0628:            /**
0629:             * Sets the paint used to fill the dial background.  Set this to 
0630:             * <code>null</code> for no background.
0631:             *
0632:             * @param paint  the paint (<code>null</code> permitted).
0633:             * 
0634:             * @see #getDialBackgroundPaint()
0635:             */
0636:            public void setDialBackgroundPaint(Paint paint) {
0637:                this .dialBackgroundPaint = paint;
0638:                notifyListeners(new PlotChangeEvent(this ));
0639:            }
0640:
0641:            /**
0642:             * Returns a flag that controls whether or not a rectangular border is 
0643:             * drawn around the plot area.
0644:             *
0645:             * @return A flag.
0646:             * 
0647:             * @see #setDrawBorder(boolean)
0648:             */
0649:            public boolean getDrawBorder() {
0650:                return this .drawBorder;
0651:            }
0652:
0653:            /**
0654:             * Sets the flag that controls whether or not a rectangular border is drawn
0655:             * around the plot area and sends a {@link PlotChangeEvent} to all 
0656:             * registered listeners.
0657:             *
0658:             * @param draw  the flag.
0659:             * 
0660:             * @see #getDrawBorder()
0661:             */
0662:            public void setDrawBorder(boolean draw) {
0663:                // TODO: fix output when this flag is set to true
0664:                this .drawBorder = draw;
0665:                notifyListeners(new PlotChangeEvent(this ));
0666:            }
0667:
0668:            /**
0669:             * Returns the dial outline paint.
0670:             *
0671:             * @return The paint.
0672:             * 
0673:             * @see #setDialOutlinePaint(Paint)
0674:             */
0675:            public Paint getDialOutlinePaint() {
0676:                return this .dialOutlinePaint;
0677:            }
0678:
0679:            /**
0680:             * Sets the dial outline paint and sends a {@link PlotChangeEvent} to all
0681:             * registered listeners.
0682:             *
0683:             * @param paint  the paint.
0684:             * 
0685:             * @see #getDialOutlinePaint()
0686:             */
0687:            public void setDialOutlinePaint(Paint paint) {
0688:                this .dialOutlinePaint = paint;
0689:                notifyListeners(new PlotChangeEvent(this ));
0690:            }
0691:
0692:            /**
0693:             * Returns the dataset for the plot.
0694:             * 
0695:             * @return The dataset (possibly <code>null</code>).
0696:             * 
0697:             * @see #setDataset(ValueDataset)
0698:             */
0699:            public ValueDataset getDataset() {
0700:                return this .dataset;
0701:            }
0702:
0703:            /**
0704:             * Sets the dataset for the plot, replacing the existing dataset if there 
0705:             * is one, and triggers a {@link PlotChangeEvent}.
0706:             * 
0707:             * @param dataset  the dataset (<code>null</code> permitted).
0708:             * 
0709:             * @see #getDataset()
0710:             */
0711:            public void setDataset(ValueDataset dataset) {
0712:
0713:                // if there is an existing dataset, remove the plot from the list of 
0714:                // change listeners...
0715:                ValueDataset existing = this .dataset;
0716:                if (existing != null) {
0717:                    existing.removeChangeListener(this );
0718:                }
0719:
0720:                // set the new dataset, and register the chart as a change listener...
0721:                this .dataset = dataset;
0722:                if (dataset != null) {
0723:                    setDatasetGroup(dataset.getGroup());
0724:                    dataset.addChangeListener(this );
0725:                }
0726:
0727:                // send a dataset change event to self...
0728:                DatasetChangeEvent event = new DatasetChangeEvent(this , dataset);
0729:                datasetChanged(event);
0730:
0731:            }
0732:
0733:            /**
0734:             * Returns an unmodifiable list of the intervals for the plot.
0735:             * 
0736:             * @return A list.
0737:             * 
0738:             * @see #addInterval(MeterInterval)
0739:             */
0740:            public List getIntervals() {
0741:                return Collections.unmodifiableList(this .intervals);
0742:            }
0743:
0744:            /**
0745:             * Adds an interval and sends a {@link PlotChangeEvent} to all registered
0746:             * listeners.
0747:             * 
0748:             * @param interval  the interval (<code>null</code> not permitted).
0749:             * 
0750:             * @see #getIntervals()
0751:             * @see #clearIntervals()
0752:             */
0753:            public void addInterval(MeterInterval interval) {
0754:                if (interval == null) {
0755:                    throw new IllegalArgumentException(
0756:                            "Null 'interval' argument.");
0757:                }
0758:                this .intervals.add(interval);
0759:                notifyListeners(new PlotChangeEvent(this ));
0760:            }
0761:
0762:            /**
0763:             * Clears the intervals for the plot and sends a {@link PlotChangeEvent} to
0764:             * all registered listeners.
0765:             * 
0766:             * @see #addInterval(MeterInterval)
0767:             */
0768:            public void clearIntervals() {
0769:                this .intervals.clear();
0770:                notifyListeners(new PlotChangeEvent(this ));
0771:            }
0772:
0773:            /**
0774:             * Returns an item for each interval.
0775:             *
0776:             * @return A collection of legend items.
0777:             */
0778:            public LegendItemCollection getLegendItems() {
0779:                LegendItemCollection result = new LegendItemCollection();
0780:                Iterator iterator = this .intervals.iterator();
0781:                while (iterator.hasNext()) {
0782:                    MeterInterval mi = (MeterInterval) iterator.next();
0783:                    Paint color = mi.getBackgroundPaint();
0784:                    if (color == null) {
0785:                        color = mi.getOutlinePaint();
0786:                    }
0787:                    LegendItem item = new LegendItem(mi.getLabel(), mi
0788:                            .getLabel(), null, null, new Rectangle2D.Double(
0789:                            -4.0, -4.0, 8.0, 8.0), color);
0790:                    item.setDataset(getDataset());
0791:                    result.add(item);
0792:                }
0793:                return result;
0794:            }
0795:
0796:            /**
0797:             * Draws the plot on a Java 2D graphics device (such as the screen or a 
0798:             * printer).
0799:             *
0800:             * @param g2  the graphics device.
0801:             * @param area  the area within which the plot should be drawn.
0802:             * @param anchor  the anchor point (<code>null</code> permitted).
0803:             * @param parentState  the state from the parent plot, if there is one.
0804:             * @param info  collects info about the drawing.
0805:             */
0806:            public void draw(Graphics2D g2, Rectangle2D area, Point2D anchor,
0807:                    PlotState parentState, PlotRenderingInfo info) {
0808:
0809:                if (info != null) {
0810:                    info.setPlotArea(area);
0811:                }
0812:
0813:                // adjust for insets...
0814:                RectangleInsets insets = getInsets();
0815:                insets.trim(area);
0816:
0817:                area.setRect(area.getX() + 4, area.getY() + 4,
0818:                        area.getWidth() - 8, area.getHeight() - 8);
0819:
0820:                // draw the background
0821:                if (this .drawBorder) {
0822:                    drawBackground(g2, area);
0823:                }
0824:
0825:                // adjust the plot area by the interior spacing value
0826:                double gapHorizontal = (2 * DEFAULT_BORDER_SIZE);
0827:                double gapVertical = (2 * DEFAULT_BORDER_SIZE);
0828:                double meterX = area.getX() + gapHorizontal / 2;
0829:                double meterY = area.getY() + gapVertical / 2;
0830:                double meterW = area.getWidth() - gapHorizontal;
0831:                double meterH = area.getHeight()
0832:                        - gapVertical
0833:                        + ((this .meterAngle <= 180)
0834:                                && (this .shape != DialShape.CIRCLE) ? area
0835:                                .getHeight() / 1.25 : 0);
0836:
0837:                double min = Math.min(meterW, meterH) / 2;
0838:                meterX = (meterX + meterX + meterW) / 2 - min;
0839:                meterY = (meterY + meterY + meterH) / 2 - min;
0840:                meterW = 2 * min;
0841:                meterH = 2 * min;
0842:
0843:                Rectangle2D meterArea = new Rectangle2D.Double(meterX, meterY,
0844:                        meterW, meterH);
0845:
0846:                Rectangle2D.Double originalArea = new Rectangle2D.Double(
0847:                        meterArea.getX() - 4, meterArea.getY() - 4, meterArea
0848:                                .getWidth() + 8, meterArea.getHeight() + 8);
0849:
0850:                double meterMiddleX = meterArea.getCenterX();
0851:                double meterMiddleY = meterArea.getCenterY();
0852:
0853:                // plot the data (unless the dataset is null)...
0854:                ValueDataset data = getDataset();
0855:                if (data != null) {
0856:                    double dataMin = this .range.getLowerBound();
0857:                    double dataMax = this .range.getUpperBound();
0858:
0859:                    Shape savedClip = g2.getClip();
0860:                    g2.clip(originalArea);
0861:                    Composite originalComposite = g2.getComposite();
0862:                    g2.setComposite(AlphaComposite.getInstance(
0863:                            AlphaComposite.SRC_OVER, getForegroundAlpha()));
0864:
0865:                    if (this .dialBackgroundPaint != null) {
0866:                        fillArc(g2, originalArea, dataMin, dataMax,
0867:                                this .dialBackgroundPaint, true);
0868:                    }
0869:                    drawTicks(g2, meterArea, dataMin, dataMax);
0870:                    drawArcForInterval(g2, meterArea, new MeterInterval("",
0871:                            this .range, this .dialOutlinePaint, new BasicStroke(
0872:                                    1.0f), null));
0873:
0874:                    Iterator iterator = this .intervals.iterator();
0875:                    while (iterator.hasNext()) {
0876:                        MeterInterval interval = (MeterInterval) iterator
0877:                                .next();
0878:                        drawArcForInterval(g2, meterArea, interval);
0879:                    }
0880:
0881:                    Number n = data.getValue();
0882:                    if (n != null) {
0883:                        double value = n.doubleValue();
0884:                        drawValueLabel(g2, meterArea);
0885:
0886:                        if (this .range.contains(value)) {
0887:                            g2.setPaint(this .needlePaint);
0888:                            g2.setStroke(new BasicStroke(2.0f));
0889:
0890:                            double radius = (meterArea.getWidth() / 2)
0891:                                    + DEFAULT_BORDER_SIZE + 15;
0892:                            double valueAngle = valueToAngle(value);
0893:                            double valueP1 = meterMiddleX
0894:                                    + (radius * Math.cos(Math.PI
0895:                                            * (valueAngle / 180)));
0896:                            double valueP2 = meterMiddleY
0897:                                    - (radius * Math.sin(Math.PI
0898:                                            * (valueAngle / 180)));
0899:
0900:                            Polygon arrow = new Polygon();
0901:                            if ((valueAngle > 135 && valueAngle < 225)
0902:                                    || (valueAngle < 45 && valueAngle > -45)) {
0903:
0904:                                double valueP3 = (meterMiddleY - DEFAULT_CIRCLE_SIZE / 4);
0905:                                double valueP4 = (meterMiddleY + DEFAULT_CIRCLE_SIZE / 4);
0906:                                arrow.addPoint((int) meterMiddleX,
0907:                                        (int) valueP3);
0908:                                arrow.addPoint((int) meterMiddleX,
0909:                                        (int) valueP4);
0910:
0911:                            } else {
0912:                                arrow
0913:                                        .addPoint(
0914:                                                (int) (meterMiddleX - DEFAULT_CIRCLE_SIZE / 4),
0915:                                                (int) meterMiddleY);
0916:                                arrow
0917:                                        .addPoint(
0918:                                                (int) (meterMiddleX + DEFAULT_CIRCLE_SIZE / 4),
0919:                                                (int) meterMiddleY);
0920:                            }
0921:                            arrow.addPoint((int) valueP1, (int) valueP2);
0922:                            g2.fill(arrow);
0923:
0924:                            Ellipse2D circle = new Ellipse2D.Double(
0925:                                    meterMiddleX - DEFAULT_CIRCLE_SIZE / 2,
0926:                                    meterMiddleY - DEFAULT_CIRCLE_SIZE / 2,
0927:                                    DEFAULT_CIRCLE_SIZE, DEFAULT_CIRCLE_SIZE);
0928:                            g2.fill(circle);
0929:                        }
0930:                    }
0931:
0932:                    g2.setClip(savedClip);
0933:                    g2.setComposite(originalComposite);
0934:
0935:                }
0936:                if (this .drawBorder) {
0937:                    drawOutline(g2, area);
0938:                }
0939:
0940:            }
0941:
0942:            /**
0943:             * Draws the arc to represent an interval.
0944:             *
0945:             * @param g2  the graphics device.
0946:             * @param meterArea  the drawing area.
0947:             * @param interval  the interval.
0948:             */
0949:            protected void drawArcForInterval(Graphics2D g2,
0950:                    Rectangle2D meterArea, MeterInterval interval) {
0951:
0952:                double minValue = interval.getRange().getLowerBound();
0953:                double maxValue = interval.getRange().getUpperBound();
0954:                Paint outlinePaint = interval.getOutlinePaint();
0955:                Stroke outlineStroke = interval.getOutlineStroke();
0956:                Paint backgroundPaint = interval.getBackgroundPaint();
0957:
0958:                if (backgroundPaint != null) {
0959:                    fillArc(g2, meterArea, minValue, maxValue, backgroundPaint,
0960:                            false);
0961:                }
0962:                if (outlinePaint != null) {
0963:                    if (outlineStroke != null) {
0964:                        drawArc(g2, meterArea, minValue, maxValue,
0965:                                outlinePaint, outlineStroke);
0966:                    }
0967:                    drawTick(g2, meterArea, minValue, true);
0968:                    drawTick(g2, meterArea, maxValue, true);
0969:                }
0970:            }
0971:
0972:            /**
0973:             * Draws an arc.
0974:             *
0975:             * @param g2  the graphics device.
0976:             * @param area  the plot area.
0977:             * @param minValue  the minimum value.
0978:             * @param maxValue  the maximum value.
0979:             * @param paint  the paint.
0980:             * @param stroke  the stroke.
0981:             */
0982:            protected void drawArc(Graphics2D g2, Rectangle2D area,
0983:                    double minValue, double maxValue, Paint paint, Stroke stroke) {
0984:
0985:                double startAngle = valueToAngle(maxValue);
0986:                double endAngle = valueToAngle(minValue);
0987:                double extent = endAngle - startAngle;
0988:
0989:                double x = area.getX();
0990:                double y = area.getY();
0991:                double w = area.getWidth();
0992:                double h = area.getHeight();
0993:                g2.setPaint(paint);
0994:                g2.setStroke(stroke);
0995:
0996:                if (paint != null && stroke != null) {
0997:                    Arc2D.Double arc = new Arc2D.Double(x, y, w, h, startAngle,
0998:                            extent, Arc2D.OPEN);
0999:                    g2.setPaint(paint);
1000:                    g2.setStroke(stroke);
1001:                    g2.draw(arc);
1002:                }
1003:
1004:            }
1005:
1006:            /**
1007:             * Fills an arc on the dial between the given values.
1008:             *
1009:             * @param g2  the graphics device.
1010:             * @param area  the plot area.
1011:             * @param minValue  the minimum data value.
1012:             * @param maxValue  the maximum data value.
1013:             * @param paint  the background paint (<code>null</code> not permitted).
1014:             * @param dial  a flag that indicates whether the arc represents the whole 
1015:             *              dial.
1016:             */
1017:            protected void fillArc(Graphics2D g2, Rectangle2D area,
1018:                    double minValue, double maxValue, Paint paint, boolean dial) {
1019:                if (paint == null) {
1020:                    throw new IllegalArgumentException("Null 'paint' argument");
1021:                }
1022:                double startAngle = valueToAngle(maxValue);
1023:                double endAngle = valueToAngle(minValue);
1024:                double extent = endAngle - startAngle;
1025:
1026:                double x = area.getX();
1027:                double y = area.getY();
1028:                double w = area.getWidth();
1029:                double h = area.getHeight();
1030:                int joinType = Arc2D.OPEN;
1031:                if (this .shape == DialShape.PIE) {
1032:                    joinType = Arc2D.PIE;
1033:                } else if (this .shape == DialShape.CHORD) {
1034:                    if (dial && this .meterAngle > 180) {
1035:                        joinType = Arc2D.CHORD;
1036:                    } else {
1037:                        joinType = Arc2D.PIE;
1038:                    }
1039:                } else if (this .shape == DialShape.CIRCLE) {
1040:                    joinType = Arc2D.PIE;
1041:                    if (dial) {
1042:                        extent = 360;
1043:                    }
1044:                } else {
1045:                    throw new IllegalStateException("DialShape not recognised.");
1046:                }
1047:
1048:                g2.setPaint(paint);
1049:                Arc2D.Double arc = new Arc2D.Double(x, y, w, h, startAngle,
1050:                        extent, joinType);
1051:                g2.fill(arc);
1052:            }
1053:
1054:            /**
1055:             * Translates a data value to an angle on the dial.
1056:             *
1057:             * @param value  the value.
1058:             *
1059:             * @return The angle on the dial.
1060:             */
1061:            public double valueToAngle(double value) {
1062:                value = value - this .range.getLowerBound();
1063:                double baseAngle = 180 + ((this .meterAngle - 180) / 2);
1064:                return baseAngle
1065:                        - ((value / this .range.getLength()) * this .meterAngle);
1066:            }
1067:
1068:            /**
1069:             * Draws the ticks that subdivide the overall range.
1070:             *
1071:             * @param g2  the graphics device.
1072:             * @param meterArea  the meter area.
1073:             * @param minValue  the minimum value.
1074:             * @param maxValue  the maximum value.
1075:             */
1076:            protected void drawTicks(Graphics2D g2, Rectangle2D meterArea,
1077:                    double minValue, double maxValue) {
1078:                for (double v = minValue; v <= maxValue; v += this .tickSize) {
1079:                    drawTick(g2, meterArea, v);
1080:                }
1081:            }
1082:
1083:            /**
1084:             * Draws a tick.
1085:             *
1086:             * @param g2  the graphics device.
1087:             * @param meterArea  the meter area.
1088:             * @param value  the value.
1089:             */
1090:            protected void drawTick(Graphics2D g2, Rectangle2D meterArea,
1091:                    double value) {
1092:                drawTick(g2, meterArea, value, false);
1093:            }
1094:
1095:            /**
1096:             * Draws a tick on the dial.
1097:             *
1098:             * @param g2  the graphics device.
1099:             * @param meterArea  the meter area.
1100:             * @param value  the tick value.
1101:             * @param label  a flag that controls whether or not a value label is drawn.
1102:             */
1103:            protected void drawTick(Graphics2D g2, Rectangle2D meterArea,
1104:                    double value, boolean label) {
1105:
1106:                double valueAngle = valueToAngle(value);
1107:
1108:                double meterMiddleX = meterArea.getCenterX();
1109:                double meterMiddleY = meterArea.getCenterY();
1110:
1111:                g2.setPaint(this .tickPaint);
1112:                g2.setStroke(new BasicStroke(2.0f));
1113:
1114:                double valueP2X = 0;
1115:                double valueP2Y = 0;
1116:
1117:                double radius = (meterArea.getWidth() / 2)
1118:                        + DEFAULT_BORDER_SIZE;
1119:                double radius1 = radius - 15;
1120:
1121:                double valueP1X = meterMiddleX
1122:                        + (radius * Math.cos(Math.PI * (valueAngle / 180)));
1123:                double valueP1Y = meterMiddleY
1124:                        - (radius * Math.sin(Math.PI * (valueAngle / 180)));
1125:
1126:                valueP2X = meterMiddleX
1127:                        + (radius1 * Math.cos(Math.PI * (valueAngle / 180)));
1128:                valueP2Y = meterMiddleY
1129:                        - (radius1 * Math.sin(Math.PI * (valueAngle / 180)));
1130:
1131:                Line2D.Double line = new Line2D.Double(valueP1X, valueP1Y,
1132:                        valueP2X, valueP2Y);
1133:                g2.draw(line);
1134:
1135:                if (this .tickLabelsVisible && label) {
1136:
1137:                    String tickLabel = this .tickLabelFormat.format(value);
1138:                    g2.setFont(this .tickLabelFont);
1139:                    g2.setPaint(this .tickLabelPaint);
1140:
1141:                    FontMetrics fm = g2.getFontMetrics();
1142:                    Rectangle2D tickLabelBounds = TextUtilities.getTextBounds(
1143:                            tickLabel, g2, fm);
1144:
1145:                    double x = valueP2X;
1146:                    double y = valueP2Y;
1147:                    if (valueAngle == 90 || valueAngle == 270) {
1148:                        x = x - tickLabelBounds.getWidth() / 2;
1149:                    } else if (valueAngle < 90 || valueAngle > 270) {
1150:                        x = x - tickLabelBounds.getWidth();
1151:                    }
1152:                    if ((valueAngle > 135 && valueAngle < 225)
1153:                            || valueAngle > 315 || valueAngle < 45) {
1154:                        y = y - tickLabelBounds.getHeight() / 2;
1155:                    } else {
1156:                        y = y + tickLabelBounds.getHeight() / 2;
1157:                    }
1158:                    g2.drawString(tickLabel, (float) x, (float) y);
1159:                }
1160:            }
1161:
1162:            /**
1163:             * Draws the value label just below the center of the dial.
1164:             * 
1165:             * @param g2  the graphics device.
1166:             * @param area  the plot area.
1167:             */
1168:            protected void drawValueLabel(Graphics2D g2, Rectangle2D area) {
1169:                g2.setFont(this .valueFont);
1170:                g2.setPaint(this .valuePaint);
1171:                String valueStr = "No value";
1172:                if (this .dataset != null) {
1173:                    Number n = this .dataset.getValue();
1174:                    if (n != null) {
1175:                        valueStr = this .tickLabelFormat.format(n.doubleValue())
1176:                                + " " + this .units;
1177:                    }
1178:                }
1179:                float x = (float) area.getCenterX();
1180:                float y = (float) area.getCenterY() + DEFAULT_CIRCLE_SIZE;
1181:                TextUtilities.drawAlignedString(valueStr, g2, x, y,
1182:                        TextAnchor.TOP_CENTER);
1183:            }
1184:
1185:            /**
1186:             * Returns a short string describing the type of plot.
1187:             *
1188:             * @return A string describing the type of plot.
1189:             */
1190:            public String getPlotType() {
1191:                return localizationResources.getString("Meter_Plot");
1192:            }
1193:
1194:            /**
1195:             * A zoom method that does nothing.  Plots are required to support the 
1196:             * zoom operation.  In the case of a meter plot, it doesn't make sense to 
1197:             * zoom in or out, so the method is empty.
1198:             *
1199:             * @param percent   The zoom percentage.
1200:             */
1201:            public void zoom(double percent) {
1202:                // intentionally blank
1203:            }
1204:
1205:            /**
1206:             * Tests the plot for equality with an arbitrary object.  Note that the 
1207:             * dataset is ignored for the purposes of testing equality.
1208:             * 
1209:             * @param obj  the object (<code>null</code> permitted).
1210:             * 
1211:             * @return A boolean.
1212:             */
1213:            public boolean equals(Object obj) {
1214:                if (obj == this ) {
1215:                    return true;
1216:                }
1217:                if (!(obj instanceof  MeterPlot)) {
1218:                    return false;
1219:                }
1220:                if (!super .equals(obj)) {
1221:                    return false;
1222:                }
1223:                MeterPlot that = (MeterPlot) obj;
1224:                if (!ObjectUtilities.equal(this .units, that.units)) {
1225:                    return false;
1226:                }
1227:                if (!ObjectUtilities.equal(this .range, that.range)) {
1228:                    return false;
1229:                }
1230:                if (!ObjectUtilities.equal(this .intervals, that.intervals)) {
1231:                    return false;
1232:                }
1233:                if (!PaintUtilities.equal(this .dialOutlinePaint,
1234:                        that.dialOutlinePaint)) {
1235:                    return false;
1236:                }
1237:                if (this .shape != that.shape) {
1238:                    return false;
1239:                }
1240:                if (!PaintUtilities.equal(this .dialBackgroundPaint,
1241:                        that.dialBackgroundPaint)) {
1242:                    return false;
1243:                }
1244:                if (!PaintUtilities.equal(this .needlePaint, that.needlePaint)) {
1245:                    return false;
1246:                }
1247:                if (!ObjectUtilities.equal(this .valueFont, that.valueFont)) {
1248:                    return false;
1249:                }
1250:                if (!PaintUtilities.equal(this .valuePaint, that.valuePaint)) {
1251:                    return false;
1252:                }
1253:                if (!PaintUtilities.equal(this .tickPaint, that.tickPaint)) {
1254:                    return false;
1255:                }
1256:                if (this .tickSize != that.tickSize) {
1257:                    return false;
1258:                }
1259:                if (this .tickLabelsVisible != that.tickLabelsVisible) {
1260:                    return false;
1261:                }
1262:                if (!ObjectUtilities.equal(this .tickLabelFont,
1263:                        that.tickLabelFont)) {
1264:                    return false;
1265:                }
1266:                if (!PaintUtilities.equal(this .tickLabelPaint,
1267:                        that.tickLabelPaint)) {
1268:                    return false;
1269:                }
1270:                if (!ObjectUtilities.equal(this .tickLabelFormat,
1271:                        that.tickLabelFormat)) {
1272:                    return false;
1273:                }
1274:                if (this .drawBorder != that.drawBorder) {
1275:                    return false;
1276:                }
1277:                if (this .meterAngle != that.meterAngle) {
1278:                    return false;
1279:                }
1280:                return true;
1281:            }
1282:
1283:            /**
1284:             * Provides serialization support.
1285:             *
1286:             * @param stream  the output stream.
1287:             *
1288:             * @throws IOException  if there is an I/O error.
1289:             */
1290:            private void writeObject(ObjectOutputStream stream)
1291:                    throws IOException {
1292:                stream.defaultWriteObject();
1293:                SerialUtilities.writePaint(this .dialBackgroundPaint, stream);
1294:                SerialUtilities.writePaint(this .needlePaint, stream);
1295:                SerialUtilities.writePaint(this .valuePaint, stream);
1296:                SerialUtilities.writePaint(this .tickPaint, stream);
1297:                SerialUtilities.writePaint(this .tickLabelPaint, stream);
1298:            }
1299:
1300:            /**
1301:             * Provides serialization support.
1302:             *
1303:             * @param stream  the input stream.
1304:             *
1305:             * @throws IOException  if there is an I/O error.
1306:             * @throws ClassNotFoundException  if there is a classpath problem.
1307:             */
1308:            private void readObject(ObjectInputStream stream)
1309:                    throws IOException, ClassNotFoundException {
1310:                stream.defaultReadObject();
1311:                this .dialBackgroundPaint = SerialUtilities.readPaint(stream);
1312:                this .needlePaint = SerialUtilities.readPaint(stream);
1313:                this .valuePaint = SerialUtilities.readPaint(stream);
1314:                this .tickPaint = SerialUtilities.readPaint(stream);
1315:                this .tickLabelPaint = SerialUtilities.readPaint(stream);
1316:                if (this .dataset != null) {
1317:                    this .dataset.addChangeListener(this );
1318:                }
1319:            }
1320:
1321:            /** 
1322:             * Returns an independent copy (clone) of the plot.  The dataset is NOT 
1323:             * cloned - both the original and the clone will have a reference to the
1324:             * same dataset.
1325:             * 
1326:             * @return A clone.
1327:             * 
1328:             * @throws CloneNotSupportedException if some component of the plot cannot
1329:             *         be cloned.
1330:             */
1331:            public Object clone() throws CloneNotSupportedException {
1332:                MeterPlot clone = (MeterPlot) super .clone();
1333:                clone.tickLabelFormat = (NumberFormat) this .tickLabelFormat
1334:                        .clone();
1335:                // the following relies on the fact that the intervals are immutable
1336:                clone.intervals = new java.util.ArrayList(this.intervals);
1337:                if (clone.dataset != null) {
1338:                    clone.dataset.addChangeListener(clone);
1339:                }
1340:                return clone;
1341:            }
1342:
1343:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.