Source Code Cross Referenced for JFreeChart.java in  » Chart » jfreechart » org » jfree » chart » 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 
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:         * JFreeChart.java
0029:         * ---------------
0030:         * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
0031:         *
0032:         * Original Author:  David Gilbert (for Object Refinery Limited);
0033:         * Contributor(s):   Andrzej Porebski;
0034:         *                   David Li;
0035:         *                   Wolfgang Irler;
0036:         *                   Christian W. Zuckschwerdt;
0037:         *                   Klaus Rheinwald;
0038:         *                   Nicolas Brodu;
0039:         *                   
0040:         * NOTE: The above list of contributors lists only the people that have
0041:         * contributed to this source file (JFreeChart.java) - for a list of ALL
0042:         * contributors to the project, please see the README.txt file.
0043:         *
0044:         * $Id: JFreeChart.java,v 1.34.2.21 2007/06/05 15:41:38 mungady Exp $
0045:         *
0046:         * Changes (from 20-Jun-2001)
0047:         * --------------------------
0048:         * 20-Jun-2001 : Modifications submitted by Andrzej Porebski for legend 
0049:         *               placement;
0050:         * 21-Jun-2001 : Removed JFreeChart parameter from Plot constructors (DG);
0051:         * 22-Jun-2001 : Multiple titles added (original code by David Berry, with 
0052:         *               reworkings by DG);
0053:         * 18-Sep-2001 : Updated header (DG);
0054:         * 15-Oct-2001 : Moved data source classes into new package 
0055:         *               com.jrefinery.data.* (DG);
0056:         * 18-Oct-2001 : New factory method for creating VerticalXYBarChart (DG);
0057:         * 19-Oct-2001 : Moved series paint and stroke methods to the Plot class (DG);
0058:         *               Moved static chart creation methods to new ChartFactory 
0059:         *               class (DG);
0060:         * 22-Oct-2001 : Renamed DataSource.java --> Dataset.java etc. (DG);
0061:         *               Fixed bug where chart isn't registered with the dataset (DG);
0062:         * 07-Nov-2001 : Fixed bug where null title in constructor causes 
0063:         *               exception (DG);
0064:         *               Tidied up event notification code (DG);
0065:         * 17-Nov-2001 : Added getLegendItemCount() method (DG);
0066:         * 21-Nov-2001 : Set clipping in draw method to ensure that nothing gets drawn 
0067:         *               outside the chart area (DG);
0068:         * 11-Dec-2001 : Added the createBufferedImage() method, taken from the 
0069:         *               JFreeChartServletDemo class (DG);
0070:         * 13-Dec-2001 : Added tooltips (DG);
0071:         * 16-Jan-2002 : Added handleClick() method (DG);
0072:         * 22-Jan-2002 : Fixed bug correlating legend labels with pie data (DG);
0073:         * 05-Feb-2002 : Removed redundant tooltips code (DG);
0074:         * 19-Feb-2002 : Added accessor methods for the backgroundImage and 
0075:         *               backgroundImageAlpha attributes (DG);
0076:         * 21-Feb-2002 : Added static fields for INFO, COPYRIGHT, LICENCE, CONTRIBUTORS
0077:         *               and LIBRARIES.  These can be used to display information about
0078:         *               JFreeChart (DG);
0079:         * 06-Mar-2002 : Moved constants to JFreeChartConstants interface (DG);
0080:         * 18-Apr-2002 : PieDataset is no longer sorted (oldman);
0081:         * 23-Apr-2002 : Moved dataset to the Plot class (DG);
0082:         * 13-Jun-2002 : Added an extra draw() method (DG);
0083:         * 25-Jun-2002 : Implemented the Drawable interface and removed redundant 
0084:         *               imports (DG);
0085:         * 26-Jun-2002 : Added another createBufferedImage() method (DG);
0086:         * 18-Sep-2002 : Fixed issues reported by Checkstyle (DG);
0087:         * 23-Sep-2002 : Added new contributor (DG);
0088:         * 28-Oct-2002 : Created main title and subtitle list to replace existing title
0089:         *               list (DG);
0090:         * 08-Jan-2003 : Added contributor (DG);
0091:         * 17-Jan-2003 : Added new constructor (DG);
0092:         * 22-Jan-2003 : Added ChartColor class by Cameron Riley, and background image 
0093:         *               alignment code by Christian W. Zuckschwerdt (DG);
0094:         * 11-Feb-2003 : Added flag to allow suppression of chart change events, based 
0095:         *               on a suggestion by Klaus Rheinwald (DG);
0096:         * 04-Mar-2003 : Added small fix for suppressed chart change events (see bug id
0097:         *               690865) (DG);
0098:         * 10-Mar-2003 : Added Benoit Xhenseval to contributors (DG);
0099:         * 26-Mar-2003 : Implemented Serializable (DG);
0100:         * 15-Jul-2003 : Added an optional border for the chart (DG);
0101:         * 11-Sep-2003 : Took care of listeners while cloning (NB);
0102:         * 16-Sep-2003 : Changed ChartRenderingInfo --> PlotRenderingInfo (DG);
0103:         * 22-Sep-2003 : Added nullpointer checks.
0104:         * 25-Sep-2003 : Added nullpointer checks too (NB).
0105:         * 03-Dec-2003 : Legends are now registered by this class instead of using the 
0106:         *               old constructor way (TM);
0107:         * 03-Dec-2003 : Added anchorPoint to draw() method (DG);
0108:         * 08-Jan-2004 : Reworked title code, introducing line wrapping (DG);
0109:         * 09-Feb-2004 : Created additional createBufferedImage() method (DG);
0110:         * 05-Apr-2004 : Added new createBufferedImage() method (DG);
0111:         * 27-May-2004 : Moved constants from JFreeChartConstants.java back to this 
0112:         *               class (DG);
0113:         * 25-Nov-2004 : Updates for changes to Title class (DG);
0114:         * 06-Jan-2005 : Change lookup for default background color (DG);
0115:         * 31-Jan-2005 : Added Don Elliott to contributors (DG);
0116:         * 02-Feb-2005 : Added clearSubtitles() method (DG);
0117:         * 03-Feb-2005 : Added Mofeed Shahin to contributors (DG);
0118:         * 08-Feb-2005 : Updated for RectangleConstraint changes (DG);
0119:         * 28-Mar-2005 : Renamed Legend --> OldLegend (DG);
0120:         * 12-Apr-2005 : Added methods to access legend(s) in subtitle list (DG);
0121:         * 13-Apr-2005 : Added removeLegend() and removeSubtitle() methods (DG);
0122:         * 20-Apr-2005 : Modified to collect chart entities from titles and 
0123:         *               subtitles (DG);
0124:         * 26-Apr-2005 : Removed LOGGER (DG);
0125:         * 06-Jun-2005 : Added addLegend() method and padding attribute, fixed equals() 
0126:         *               method (DG);
0127:         * 24-Nov-2005 : Removed OldLegend and related code - don't want to support
0128:         *               this in 1.0.0 final (DG);
0129:         * ------------- JFREECHART 1.0.x ---------------------------------------------
0130:         * 27-Jan-2006 : Updated version number (DG);
0131:         * 07-Dec-2006 : Added some missing credits (DG);
0132:         * 17-Jan-2007 : Added Darren Jung to contributor list (DG);
0133:         * 05-Mar-2007 : Added Sergei Ivanov to the contributor list (DG);
0134:         * 16-Mar-2007 : Modified initial legend border (DG);
0135:         * 22-Mar-2007 : New methods for text anti-aliasing (DG);
0136:         * 16-May-2007 : Fixed argument check in getSubtitle(), copy list in 
0137:         *               get/setSubtitles(), and added new addSubtitle(int, Title) 
0138:         *               method (DG);
0139:         * 05-Jun-2007 : Add change listener to default legend (DG);
0140:         * 
0141:         */
0142:
0143:        package org.jfree.chart;
0144:
0145:        import java.awt.AlphaComposite;
0146:        import java.awt.BasicStroke;
0147:        import java.awt.Color;
0148:        import java.awt.Composite;
0149:        import java.awt.Font;
0150:        import java.awt.Graphics2D;
0151:        import java.awt.Image;
0152:        import java.awt.Paint;
0153:        import java.awt.RenderingHints;
0154:        import java.awt.Shape;
0155:        import java.awt.Stroke;
0156:        import java.awt.geom.AffineTransform;
0157:        import java.awt.geom.Point2D;
0158:        import java.awt.geom.Rectangle2D;
0159:        import java.awt.image.BufferedImage;
0160:        import java.io.IOException;
0161:        import java.io.ObjectInputStream;
0162:        import java.io.ObjectOutputStream;
0163:        import java.io.Serializable;
0164:        import java.net.URL;
0165:        import java.util.ArrayList;
0166:        import java.util.Arrays;
0167:        import java.util.Iterator;
0168:        import java.util.List;
0169:        import java.util.ResourceBundle;
0170:
0171:        import javax.swing.ImageIcon;
0172:        import javax.swing.UIManager;
0173:        import javax.swing.event.EventListenerList;
0174:
0175:        import org.jfree.JCommon;
0176:        import org.jfree.chart.block.BlockParams;
0177:        import org.jfree.chart.block.EntityBlockResult;
0178:        import org.jfree.chart.block.LengthConstraintType;
0179:        import org.jfree.chart.block.LineBorder;
0180:        import org.jfree.chart.block.RectangleConstraint;
0181:        import org.jfree.chart.entity.EntityCollection;
0182:        import org.jfree.chart.event.ChartChangeEvent;
0183:        import org.jfree.chart.event.ChartChangeListener;
0184:        import org.jfree.chart.event.ChartProgressEvent;
0185:        import org.jfree.chart.event.ChartProgressListener;
0186:        import org.jfree.chart.event.PlotChangeEvent;
0187:        import org.jfree.chart.event.PlotChangeListener;
0188:        import org.jfree.chart.event.TitleChangeEvent;
0189:        import org.jfree.chart.event.TitleChangeListener;
0190:        import org.jfree.chart.plot.CategoryPlot;
0191:        import org.jfree.chart.plot.Plot;
0192:        import org.jfree.chart.plot.PlotRenderingInfo;
0193:        import org.jfree.chart.plot.XYPlot;
0194:        import org.jfree.chart.title.LegendTitle;
0195:        import org.jfree.chart.title.TextTitle;
0196:        import org.jfree.chart.title.Title;
0197:        import org.jfree.data.Range;
0198:        import org.jfree.io.SerialUtilities;
0199:        import org.jfree.ui.Align;
0200:        import org.jfree.ui.Drawable;
0201:        import org.jfree.ui.HorizontalAlignment;
0202:        import org.jfree.ui.RectangleEdge;
0203:        import org.jfree.ui.RectangleInsets;
0204:        import org.jfree.ui.Size2D;
0205:        import org.jfree.ui.VerticalAlignment;
0206:        import org.jfree.ui.about.Contributor;
0207:        import org.jfree.ui.about.Licences;
0208:        import org.jfree.ui.about.ProjectInfo;
0209:        import org.jfree.util.ObjectUtilities;
0210:        import org.jfree.util.PaintUtilities;
0211:
0212:        /**
0213:         * A chart class implemented using the Java 2D APIs.  The current version
0214:         * supports bar charts, line charts, pie charts and xy plots (including time
0215:         * series data).
0216:         * <P>
0217:         * JFreeChart coordinates several objects to achieve its aim of being able to
0218:         * draw a chart on a Java 2D graphics device: a list of {@link Title} objects
0219:         * (which often includes the chart's legend), a {@link Plot} and a 
0220:         * {@link org.jfree.data.general.Dataset} (the plot in turn manages a 
0221:         * domain axis and a range axis).
0222:         * <P>
0223:         * You should use a {@link ChartPanel} to display a chart in a GUI.
0224:         * <P>
0225:         * The {@link ChartFactory} class contains static methods for creating 
0226:         * 'ready-made' charts.
0227:         *
0228:         * @see ChartPanel
0229:         * @see ChartFactory
0230:         * @see Title
0231:         * @see Plot
0232:         */
0233:        public class JFreeChart implements  Drawable, TitleChangeListener,
0234:                PlotChangeListener, Serializable, Cloneable {
0235:
0236:            /** For serialization. */
0237:            private static final long serialVersionUID = -3470703747817429120L;
0238:
0239:            /** Information about the project. */
0240:            public static final ProjectInfo INFO = new JFreeChartInfo();
0241:
0242:            /** The default font for titles. */
0243:            public static final Font DEFAULT_TITLE_FONT = new Font("SansSerif",
0244:                    Font.BOLD, 18);
0245:
0246:            /** The default background color. */
0247:            public static final Paint DEFAULT_BACKGROUND_PAINT = UIManager
0248:                    .getColor("Panel.background");
0249:
0250:            /** The default background image. */
0251:            public static final Image DEFAULT_BACKGROUND_IMAGE = null;
0252:
0253:            /** The default background image alignment. */
0254:            public static final int DEFAULT_BACKGROUND_IMAGE_ALIGNMENT = Align.FIT;
0255:
0256:            /** The default background image alpha. */
0257:            public static final float DEFAULT_BACKGROUND_IMAGE_ALPHA = 0.5f;
0258:
0259:            /** 
0260:             * Rendering hints that will be used for chart drawing.  This should never
0261:             * be <code>null</code>. 
0262:             */
0263:            private transient RenderingHints renderingHints;
0264:
0265:            /** A flag that controls whether or not the chart border is drawn. */
0266:            private boolean borderVisible;
0267:
0268:            /** The stroke used to draw the chart border (if visible). */
0269:            private transient Stroke borderStroke;
0270:
0271:            /** The paint used to draw the chart border (if visible). */
0272:            private transient Paint borderPaint;
0273:
0274:            /** The padding between the chart border and the chart drawing area. */
0275:            private RectangleInsets padding;
0276:
0277:            /** The chart title (optional). */
0278:            private TextTitle title;
0279:
0280:            /** 
0281:             * The chart subtitles (zero, one or many).  This field should never be
0282:             * <code>null</code>.
0283:             */
0284:            private List subtitles;
0285:
0286:            /** Draws the visual representation of the data. */
0287:            private Plot plot;
0288:
0289:            /** Paint used to draw the background of the chart. */
0290:            private transient Paint backgroundPaint;
0291:
0292:            /** An optional background image for the chart. */
0293:            private transient Image backgroundImage; // todo: not serialized yet
0294:
0295:            /** The alignment for the background image. */
0296:            private int backgroundImageAlignment = Align.FIT;
0297:
0298:            /** The alpha transparency for the background image. */
0299:            private float backgroundImageAlpha = 0.5f;
0300:
0301:            /** Storage for registered change listeners. */
0302:            private transient EventListenerList changeListeners;
0303:
0304:            /** Storage for registered progress listeners. */
0305:            private transient EventListenerList progressListeners;
0306:
0307:            /** 
0308:             * A flag that can be used to enable/disable notification of chart change 
0309:             * events. 
0310:             */
0311:            private boolean notify;
0312:
0313:            /**
0314:             * Creates a new chart based on the supplied plot.  The chart will have
0315:             * a legend added automatically, but no title (although you can easily add
0316:             * one later).  
0317:             * <br><br>
0318:             * Note that the  {@link ChartFactory} class contains a range 
0319:             * of static methods that will return ready-made charts, and often this
0320:             * is a more convenient way to create charts than using this constructor.
0321:             *
0322:             * @param plot  the plot (<code>null</code> not permitted).
0323:             */
0324:            public JFreeChart(Plot plot) {
0325:                this (null, null, plot, true);
0326:            }
0327:
0328:            /**
0329:             * Creates a new chart with the given title and plot.  A default font 
0330:             * (@link DEFAULT_TITLE_FONT) is used for the title, and the chart will 
0331:             * have a legend added automatically.  
0332:             * <br><br>
0333:             * Note that the  {@link ChartFactory} class contains a range 
0334:             * of static methods that will return ready-made charts, and often this
0335:             * is a more convenient way to create charts than using this constructor.
0336:             *
0337:             * @param title  the chart title (<code>null</code> permitted).
0338:             * @param plot  the plot (<code>null</code> not permitted).
0339:             */
0340:            public JFreeChart(String title, Plot plot) {
0341:                this (title, JFreeChart.DEFAULT_TITLE_FONT, plot, true);
0342:            }
0343:
0344:            /**
0345:             * Creates a new chart with the given title and plot.  The 
0346:             * <code>createLegend</code> argument specifies whether or not a legend
0347:             * should be added to the chart.  
0348:             * <br><br>
0349:             * Note that the  {@link ChartFactory} class contains a range 
0350:             * of static methods that will return ready-made charts, and often this
0351:             * is a more convenient way to create charts than using this constructor.
0352:             *
0353:             * @param title  the chart title (<code>null</code> permitted).
0354:             * @param titleFont  the font for displaying the chart title 
0355:             *                   (<code>null</code> permitted).
0356:             * @param plot  controller of the visual representation of the data 
0357:             *              (<code>null</code> not permitted).
0358:             * @param createLegend  a flag indicating whether or not a legend should   
0359:             *                      be created for the chart.
0360:             */
0361:            public JFreeChart(String title, Font titleFont, Plot plot,
0362:                    boolean createLegend) {
0363:
0364:                if (plot == null) {
0365:                    throw new NullPointerException("Null 'plot' argument.");
0366:                }
0367:
0368:                // create storage for listeners...
0369:                this .progressListeners = new EventListenerList();
0370:                this .changeListeners = new EventListenerList();
0371:                this .notify = true; // default is to notify listeners when the 
0372:                // chart changes
0373:
0374:                this .renderingHints = new RenderingHints(
0375:                        RenderingHints.KEY_ANTIALIASING,
0376:                        RenderingHints.VALUE_ANTIALIAS_ON);
0377:
0378:                this .borderVisible = false;
0379:                this .borderStroke = new BasicStroke(1.0f);
0380:                this .borderPaint = Color.black;
0381:
0382:                this .padding = RectangleInsets.ZERO_INSETS;
0383:
0384:                this .plot = plot;
0385:                plot.addChangeListener(this );
0386:
0387:                this .subtitles = new ArrayList();
0388:
0389:                // create a legend, if requested...
0390:                if (createLegend) {
0391:                    LegendTitle legend = new LegendTitle(this .plot);
0392:                    legend.setMargin(new RectangleInsets(1.0, 1.0, 1.0, 1.0));
0393:                    legend.setFrame(new LineBorder());
0394:                    legend.setBackgroundPaint(Color.white);
0395:                    legend.setPosition(RectangleEdge.BOTTOM);
0396:                    this .subtitles.add(legend);
0397:                    legend.addChangeListener(this );
0398:                }
0399:
0400:                // add the chart title, if one has been specified...
0401:                if (title != null) {
0402:                    if (titleFont == null) {
0403:                        titleFont = DEFAULT_TITLE_FONT;
0404:                    }
0405:                    this .title = new TextTitle(title, titleFont);
0406:                    this .title.addChangeListener(this );
0407:                }
0408:
0409:                this .backgroundPaint = DEFAULT_BACKGROUND_PAINT;
0410:
0411:                this .backgroundImage = DEFAULT_BACKGROUND_IMAGE;
0412:                this .backgroundImageAlignment = DEFAULT_BACKGROUND_IMAGE_ALIGNMENT;
0413:                this .backgroundImageAlpha = DEFAULT_BACKGROUND_IMAGE_ALPHA;
0414:
0415:            }
0416:
0417:            /**
0418:             * Returns the collection of rendering hints for the chart.
0419:             *
0420:             * @return The rendering hints for the chart (never <code>null</code>).
0421:             * 
0422:             * @see #setRenderingHints(RenderingHints)
0423:             */
0424:            public RenderingHints getRenderingHints() {
0425:                return this .renderingHints;
0426:            }
0427:
0428:            /**
0429:             * Sets the rendering hints for the chart.  These will be added (using the 
0430:             * Graphics2D.addRenderingHints() method) near the start of the 
0431:             * JFreeChart.draw() method.
0432:             *
0433:             * @param renderingHints  the rendering hints (<code>null</code> not 
0434:             *                        permitted).
0435:             *                        
0436:             * @see #getRenderingHints()
0437:             */
0438:            public void setRenderingHints(RenderingHints renderingHints) {
0439:                if (renderingHints == null) {
0440:                    throw new NullPointerException(
0441:                            "RenderingHints given are null");
0442:                }
0443:                this .renderingHints = renderingHints;
0444:                fireChartChanged();
0445:            }
0446:
0447:            /**
0448:             * Returns a flag that controls whether or not a border is drawn around the
0449:             * outside of the chart.
0450:             *
0451:             * @return A boolean.
0452:             * 
0453:             * @see #setBorderVisible(boolean)
0454:             */
0455:            public boolean isBorderVisible() {
0456:                return this .borderVisible;
0457:            }
0458:
0459:            /**
0460:             * Sets a flag that controls whether or not a border is drawn around the 
0461:             * outside of the chart.
0462:             *
0463:             * @param visible  the flag.
0464:             * 
0465:             * @see #isBorderVisible()
0466:             */
0467:            public void setBorderVisible(boolean visible) {
0468:                this .borderVisible = visible;
0469:                fireChartChanged();
0470:            }
0471:
0472:            /**
0473:             * Returns the stroke used to draw the chart border (if visible).
0474:             *
0475:             * @return The border stroke.
0476:             * 
0477:             * @see #setBorderStroke(Stroke)
0478:             */
0479:            public Stroke getBorderStroke() {
0480:                return this .borderStroke;
0481:            }
0482:
0483:            /**
0484:             * Sets the stroke used to draw the chart border (if visible).
0485:             *
0486:             * @param stroke  the stroke.
0487:             * 
0488:             * @see #getBorderStroke()
0489:             */
0490:            public void setBorderStroke(Stroke stroke) {
0491:                this .borderStroke = stroke;
0492:                fireChartChanged();
0493:            }
0494:
0495:            /**
0496:             * Returns the paint used to draw the chart border (if visible).
0497:             *
0498:             * @return The border paint.
0499:             * 
0500:             * @see #setBorderPaint(Paint)
0501:             */
0502:            public Paint getBorderPaint() {
0503:                return this .borderPaint;
0504:            }
0505:
0506:            /**
0507:             * Sets the paint used to draw the chart border (if visible).
0508:             *
0509:             * @param paint  the paint.
0510:             * 
0511:             * @see #getBorderPaint()
0512:             */
0513:            public void setBorderPaint(Paint paint) {
0514:                this .borderPaint = paint;
0515:                fireChartChanged();
0516:            }
0517:
0518:            /**
0519:             * Returns the padding between the chart border and the chart drawing area.
0520:             * 
0521:             * @return The padding (never <code>null</code>).
0522:             * 
0523:             * @see #setPadding(RectangleInsets)
0524:             */
0525:            public RectangleInsets getPadding() {
0526:                return this .padding;
0527:            }
0528:
0529:            /**
0530:             * Sets the padding between the chart border and the chart drawing area,
0531:             * and sends a {@link ChartChangeEvent} to all registered listeners.
0532:             * 
0533:             * @param padding  the padding (<code>null</code> not permitted).
0534:             * 
0535:             * @see #getPadding()
0536:             */
0537:            public void setPadding(RectangleInsets padding) {
0538:                if (padding == null) {
0539:                    throw new IllegalArgumentException(
0540:                            "Null 'padding' argument.");
0541:                }
0542:                this .padding = padding;
0543:                notifyListeners(new ChartChangeEvent(this ));
0544:            }
0545:
0546:            /**
0547:             * Returns the main chart title.  Very often a chart will have just one
0548:             * title, so we make this case simple by providing accessor methods for
0549:             * the main title.  However, multiple titles are supported - see the
0550:             * {@link #addSubtitle(Title)} method.
0551:             *
0552:             * @return The chart title (possibly <code>null</code>).
0553:             * 
0554:             * @see #setTitle(TextTitle)
0555:             */
0556:            public TextTitle getTitle() {
0557:                return this .title;
0558:            }
0559:
0560:            /**
0561:             * Sets the main title for the chart and sends a {@link ChartChangeEvent} 
0562:             * to all registered listeners.  If you do not want a title for the 
0563:             * chart, set it to <code>null</code>.  If you want more than one title on
0564:             * a chart, use the {@link #addSubtitle(Title)} method.
0565:             *
0566:             * @param title  the title (<code>null</code> permitted).
0567:             * 
0568:             * @see #getTitle()
0569:             */
0570:            public void setTitle(TextTitle title) {
0571:                this .title = title;
0572:                fireChartChanged();
0573:            }
0574:
0575:            /**
0576:             * Sets the chart title and sends a {@link ChartChangeEvent} to all 
0577:             * registered listeners.  This is a convenience method that ends up calling 
0578:             * the {@link #setTitle(TextTitle)} method.  If there is an existing title,
0579:             * its text is updated, otherwise a new title using the default font is 
0580:             * added to the chart.  If <code>text</code> is <code>null</code> the chart
0581:             * title is set to <code>null</code>.
0582:             *
0583:             * @param text  the title text (<code>null</code> permitted).
0584:             * 
0585:             * @see #getTitle()
0586:             */
0587:            public void setTitle(String text) {
0588:                if (text != null) {
0589:                    if (this .title == null) {
0590:                        setTitle(new TextTitle(text,
0591:                                JFreeChart.DEFAULT_TITLE_FONT));
0592:                    } else {
0593:                        this .title.setText(text);
0594:                    }
0595:                } else {
0596:                    setTitle((TextTitle) null);
0597:                }
0598:            }
0599:
0600:            /**
0601:             * Adds a legend to the plot and sends a {@link ChartChangeEvent} to all
0602:             * registered listeners.
0603:             * 
0604:             * @param legend  the legend (<code>null</code> not permitted).
0605:             * 
0606:             * @see #removeLegend()
0607:             */
0608:            public void addLegend(LegendTitle legend) {
0609:                addSubtitle(legend);
0610:            }
0611:
0612:            /**
0613:             * Returns the legend for the chart, if there is one.  Note that a chart
0614:             * can have more than one legend - this method returns the first.
0615:             * 
0616:             * @return The legend (possibly <code>null</code>).
0617:             * 
0618:             * @see #getLegend(int)
0619:             */
0620:            public LegendTitle getLegend() {
0621:                return getLegend(0);
0622:            }
0623:
0624:            /**
0625:             * Returns the nth legend for a chart, or <code>null</code>.
0626:             * 
0627:             * @param index  the legend index (zero-based).
0628:             * 
0629:             * @return The legend (possibly <code>null</code>).
0630:             * 
0631:             * @see #addLegend(LegendTitle)
0632:             */
0633:            public LegendTitle getLegend(int index) {
0634:                int seen = 0;
0635:                Iterator iterator = this .subtitles.iterator();
0636:                while (iterator.hasNext()) {
0637:                    Title subtitle = (Title) iterator.next();
0638:                    if (subtitle instanceof  LegendTitle) {
0639:                        if (seen == index) {
0640:                            return (LegendTitle) subtitle;
0641:                        } else {
0642:                            seen++;
0643:                        }
0644:                    }
0645:                }
0646:                return null;
0647:            }
0648:
0649:            /**
0650:             * Removes the first legend in the chart and sends a 
0651:             * {@link ChartChangeEvent} to all registered listeners.
0652:             * 
0653:             * @see #getLegend()
0654:             */
0655:            public void removeLegend() {
0656:                removeSubtitle(getLegend());
0657:            }
0658:
0659:            /**
0660:             * Returns the list of subtitles for the chart.
0661:             *
0662:             * @return The subtitle list (possibly empty, but never <code>null</code>).
0663:             * 
0664:             * @see #setSubtitles(List)
0665:             */
0666:            public List getSubtitles() {
0667:                return new ArrayList(this .subtitles);
0668:            }
0669:
0670:            /**
0671:             * Sets the title list for the chart (completely replaces any existing 
0672:             * titles) and sends a {@link ChartChangeEvent} to all registered 
0673:             * listeners.
0674:             *
0675:             * @param subtitles  the new list of subtitles (<code>null</code> not 
0676:             *                   permitted).
0677:             *                   
0678:             * @see #getSubtitles()
0679:             */
0680:            public void setSubtitles(List subtitles) {
0681:                if (subtitles == null) {
0682:                    throw new NullPointerException("Null 'subtitles' argument.");
0683:                }
0684:                setNotify(false);
0685:                clearSubtitles();
0686:                Iterator iterator = subtitles.iterator();
0687:                while (iterator.hasNext()) {
0688:                    Title t = (Title) iterator.next();
0689:                    if (t != null) {
0690:                        addSubtitle(t);
0691:                    }
0692:                }
0693:                setNotify(true); // this fires a ChartChangeEvent
0694:            }
0695:
0696:            /**
0697:             * Returns the number of titles for the chart.
0698:             *
0699:             * @return The number of titles for the chart.
0700:             * 
0701:             * @see #getSubtitles()
0702:             */
0703:            public int getSubtitleCount() {
0704:                return this .subtitles.size();
0705:            }
0706:
0707:            /**
0708:             * Returns a chart subtitle.
0709:             *
0710:             * @param index  the index of the chart subtitle (zero based).
0711:             *
0712:             * @return A chart subtitle.
0713:             * 
0714:             * @see #addSubtitle(Title)
0715:             */
0716:            public Title getSubtitle(int index) {
0717:                if ((index < 0) || (index >= getSubtitleCount())) {
0718:                    throw new IllegalArgumentException("Index out of range.");
0719:                }
0720:                return (Title) this .subtitles.get(index);
0721:            }
0722:
0723:            /**
0724:             * Adds a chart subtitle, and notifies registered listeners that the chart 
0725:             * has been modified.
0726:             *
0727:             * @param subtitle  the subtitle (<code>null</code> not permitted).
0728:             * 
0729:             * @see #getSubtitle(int)
0730:             */
0731:            public void addSubtitle(Title subtitle) {
0732:                if (subtitle == null) {
0733:                    throw new IllegalArgumentException(
0734:                            "Null 'subtitle' argument.");
0735:                }
0736:                this .subtitles.add(subtitle);
0737:                subtitle.addChangeListener(this );
0738:                fireChartChanged();
0739:            }
0740:
0741:            /**
0742:             * Adds a subtitle at a particular position in the subtitle list, and sends
0743:             * a {@link ChartChangeEvent} to all registered listeners.
0744:             * 
0745:             * @param index  the index (in the range 0 to {@link #getSubtitleCount()}).
0746:             * @param subtitle  the subtitle to add (<code>null</code> not permitted).
0747:             * 
0748:             * @since 1.0.6
0749:             */
0750:            public void addSubtitle(int index, Title subtitle) {
0751:                if (index < 0 || index > getSubtitleCount()) {
0752:                    throw new IllegalArgumentException(
0753:                            "The 'index' argument is out of range.");
0754:                }
0755:                if (subtitle == null) {
0756:                    throw new IllegalArgumentException(
0757:                            "Null 'subtitle' argument.");
0758:                }
0759:                this .subtitles.add(index, subtitle);
0760:                subtitle.addChangeListener(this );
0761:                fireChartChanged();
0762:            }
0763:
0764:            /**
0765:             * Clears all subtitles from the chart and sends a {@link ChartChangeEvent}
0766:             * to all registered listeners.
0767:             * 
0768:             * @see #addSubtitle(Title)
0769:             */
0770:            public void clearSubtitles() {
0771:                Iterator iterator = this .subtitles.iterator();
0772:                while (iterator.hasNext()) {
0773:                    Title t = (Title) iterator.next();
0774:                    t.removeChangeListener(this );
0775:                }
0776:                this .subtitles.clear();
0777:                fireChartChanged();
0778:            }
0779:
0780:            /**
0781:             * Removes the specified subtitle and sends a {@link ChartChangeEvent} to
0782:             * all registered listeners.
0783:             * 
0784:             * @param title  the title.
0785:             * 
0786:             * @see #addSubtitle(Title)
0787:             */
0788:            public void removeSubtitle(Title title) {
0789:                this .subtitles.remove(title);
0790:                fireChartChanged();
0791:            }
0792:
0793:            /**
0794:             * Returns the plot for the chart.  The plot is a class responsible for
0795:             * coordinating the visual representation of the data, including the axes
0796:             * (if any).
0797:             *
0798:             * @return The plot.
0799:             */
0800:            public Plot getPlot() {
0801:                return this .plot;
0802:            }
0803:
0804:            /**
0805:             * Returns the plot cast as a {@link CategoryPlot}.
0806:             * <p>
0807:             * NOTE: if the plot is not an instance of {@link CategoryPlot}, then a
0808:             * <code>ClassCastException</code> is thrown.
0809:             *
0810:             * @return The plot.
0811:             * 
0812:             * @see #getPlot()
0813:             */
0814:            public CategoryPlot getCategoryPlot() {
0815:                return (CategoryPlot) this .plot;
0816:            }
0817:
0818:            /**
0819:             * Returns the plot cast as an {@link XYPlot}.
0820:             * <p>
0821:             * NOTE: if the plot is not an instance of {@link XYPlot}, then a
0822:             * <code>ClassCastException</code> is thrown.
0823:             *
0824:             * @return The plot.
0825:             * 
0826:             * @see #getPlot()
0827:             */
0828:            public XYPlot getXYPlot() {
0829:                return (XYPlot) this .plot;
0830:            }
0831:
0832:            /**
0833:             * Returns a flag that indicates whether or not anti-aliasing is used when
0834:             * the chart is drawn.
0835:             *
0836:             * @return The flag.
0837:             * 
0838:             * @see #setAntiAlias(boolean)
0839:             */
0840:            public boolean getAntiAlias() {
0841:                Object val = this .renderingHints
0842:                        .get(RenderingHints.KEY_ANTIALIASING);
0843:                return RenderingHints.VALUE_ANTIALIAS_ON.equals(val);
0844:            }
0845:
0846:            /**
0847:             * Sets a flag that indicates whether or not anti-aliasing is used when the
0848:             * chart is drawn.
0849:             * <P>
0850:             * Anti-aliasing usually improves the appearance of charts, but is slower.
0851:             *
0852:             * @param flag  the new value of the flag.
0853:             * 
0854:             * @see #getAntiAlias()
0855:             */
0856:            public void setAntiAlias(boolean flag) {
0857:
0858:                Object val = this .renderingHints
0859:                        .get(RenderingHints.KEY_ANTIALIASING);
0860:                if (val == null) {
0861:                    val = RenderingHints.VALUE_ANTIALIAS_DEFAULT;
0862:                }
0863:                if (!flag && RenderingHints.VALUE_ANTIALIAS_OFF.equals(val)
0864:                        || flag
0865:                        && RenderingHints.VALUE_ANTIALIAS_ON.equals(val)) {
0866:                    // no change, do nothing
0867:                    return;
0868:                }
0869:                if (flag) {
0870:                    this .renderingHints.put(RenderingHints.KEY_ANTIALIASING,
0871:                            RenderingHints.VALUE_ANTIALIAS_ON);
0872:                } else {
0873:                    this .renderingHints.put(RenderingHints.KEY_ANTIALIASING,
0874:                            RenderingHints.VALUE_ANTIALIAS_OFF);
0875:                }
0876:                fireChartChanged();
0877:
0878:            }
0879:
0880:            /**
0881:             * Returns the current value stored in the rendering hints table for
0882:             * {@link RenderingHints#KEY_TEXT_ANTIALIASING}.
0883:             * 
0884:             * @return The hint value (possibly <code>null</code>).
0885:             * 
0886:             * @since 1.0.5
0887:             * 
0888:             * @see #setTextAntiAlias(Object)
0889:             */
0890:            public Object getTextAntiAlias() {
0891:                return this .renderingHints
0892:                        .get(RenderingHints.KEY_TEXT_ANTIALIASING);
0893:            }
0894:
0895:            /**
0896:             * Sets the value in the rendering hints table for 
0897:             * {@link RenderingHints#KEY_TEXT_ANTIALIASING} to either
0898:             * {@link RenderingHints#VALUE_TEXT_ANTIALIAS_ON} or
0899:             * {@link RenderingHints#VALUE_TEXT_ANTIALIAS_OFF}, then sends a 
0900:             * {@link ChartChangeEvent} to all registered listeners.
0901:             * 
0902:             * @param flag
0903:             * 
0904:             * @since 1.0.5
0905:             * 
0906:             * @see #getTextAntiAlias()
0907:             * @see #setTextAntiAlias(Object)
0908:             */
0909:            public void setTextAntiAlias(boolean flag) {
0910:                if (flag) {
0911:                    setTextAntiAlias(RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
0912:                } else {
0913:                    setTextAntiAlias(RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
0914:                }
0915:            }
0916:
0917:            /**
0918:             * Sets the value in the rendering hints table for 
0919:             * {@link RenderingHints#KEY_TEXT_ANTIALIASING} and sends a 
0920:             * {@link ChartChangeEvent} to all registered listeners.
0921:             * 
0922:             * @param val  the new value (<code>null</code> permitted).
0923:             * 
0924:             * @since 1.0.5
0925:             * 
0926:             * @see #getTextAntiAlias()
0927:             * @see #setTextAntiAlias(boolean)
0928:             */
0929:            public void setTextAntiAlias(Object val) {
0930:                this .renderingHints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
0931:                        val);
0932:                this .notifyListeners(new ChartChangeEvent(this ));
0933:            }
0934:
0935:            /**
0936:             * Returns the paint used for the chart background.
0937:             *
0938:             * @return The paint (possibly <code>null</code>).
0939:             * 
0940:             * @see #setBackgroundPaint(Paint)
0941:             */
0942:            public Paint getBackgroundPaint() {
0943:                return this .backgroundPaint;
0944:            }
0945:
0946:            /**
0947:             * Sets the paint used to fill the chart background and sends a 
0948:             * {@link ChartChangeEvent} to all registered listeners.
0949:             *
0950:             * @param paint  the paint (<code>null</code> permitted).
0951:             * 
0952:             * @see #getBackgroundPaint()
0953:             */
0954:            public void setBackgroundPaint(Paint paint) {
0955:
0956:                if (this .backgroundPaint != null) {
0957:                    if (!this .backgroundPaint.equals(paint)) {
0958:                        this .backgroundPaint = paint;
0959:                        fireChartChanged();
0960:                    }
0961:                } else {
0962:                    if (paint != null) {
0963:                        this .backgroundPaint = paint;
0964:                        fireChartChanged();
0965:                    }
0966:                }
0967:
0968:            }
0969:
0970:            /**
0971:             * Returns the background image for the chart, or <code>null</code> if 
0972:             * there is no image.
0973:             *
0974:             * @return The image (possibly <code>null</code>).
0975:             * 
0976:             * @see #setBackgroundImage(Image)
0977:             */
0978:            public Image getBackgroundImage() {
0979:                return this .backgroundImage;
0980:            }
0981:
0982:            /**
0983:             * Sets the background image for the chart and sends a 
0984:             * {@link ChartChangeEvent} to all registered listeners.
0985:             *
0986:             * @param image  the image (<code>null</code> permitted).
0987:             * 
0988:             * @see #getBackgroundImage()
0989:             */
0990:            public void setBackgroundImage(Image image) {
0991:
0992:                if (this .backgroundImage != null) {
0993:                    if (!this .backgroundImage.equals(image)) {
0994:                        this .backgroundImage = image;
0995:                        fireChartChanged();
0996:                    }
0997:                } else {
0998:                    if (image != null) {
0999:                        this .backgroundImage = image;
1000:                        fireChartChanged();
1001:                    }
1002:                }
1003:
1004:            }
1005:
1006:            /**
1007:             * Returns the background image alignment. Alignment constants are defined 
1008:             * in the <code>org.jfree.ui.Align</code> class in the JCommon class 
1009:             * library.
1010:             *
1011:             * @return The alignment.
1012:             * 
1013:             * @see #setBackgroundImageAlignment(int)
1014:             */
1015:            public int getBackgroundImageAlignment() {
1016:                return this .backgroundImageAlignment;
1017:            }
1018:
1019:            /**
1020:             * Sets the background alignment.  Alignment options are defined by the 
1021:             * {@link org.jfree.ui.Align} class.
1022:             *
1023:             * @param alignment  the alignment.
1024:             * 
1025:             * @see #getBackgroundImageAlignment()
1026:             */
1027:            public void setBackgroundImageAlignment(int alignment) {
1028:                if (this .backgroundImageAlignment != alignment) {
1029:                    this .backgroundImageAlignment = alignment;
1030:                    fireChartChanged();
1031:                }
1032:            }
1033:
1034:            /**
1035:             * Returns the alpha-transparency for the chart's background image.
1036:             *
1037:             * @return The alpha-transparency.
1038:             * 
1039:             * @see #setBackgroundImageAlpha(float)
1040:             */
1041:            public float getBackgroundImageAlpha() {
1042:                return this .backgroundImageAlpha;
1043:            }
1044:
1045:            /**
1046:             * Sets the alpha-transparency for the chart's background image.
1047:             * Registered listeners are notified that the chart has been changed.
1048:             *
1049:             * @param alpha  the alpha value.
1050:             * 
1051:             * @see #getBackgroundImageAlpha()
1052:             */
1053:            public void setBackgroundImageAlpha(float alpha) {
1054:
1055:                if (this .backgroundImageAlpha != alpha) {
1056:                    this .backgroundImageAlpha = alpha;
1057:                    fireChartChanged();
1058:                }
1059:
1060:            }
1061:
1062:            /**
1063:             * Returns a flag that controls whether or not change events are sent to 
1064:             * registered listeners.
1065:             *
1066:             * @return A boolean.
1067:             * 
1068:             * @see #setNotify(boolean)
1069:             */
1070:            public boolean isNotify() {
1071:                return this .notify;
1072:            }
1073:
1074:            /**
1075:             * Sets a flag that controls whether or not listeners receive 
1076:             * {@link ChartChangeEvent} notifications.
1077:             *
1078:             * @param notify  a boolean.
1079:             * 
1080:             * @see #isNotify()
1081:             */
1082:            public void setNotify(boolean notify) {
1083:                this .notify = notify;
1084:                // if the flag is being set to true, there may be queued up changes...
1085:                if (notify) {
1086:                    notifyListeners(new ChartChangeEvent(this ));
1087:                }
1088:            }
1089:
1090:            /**
1091:             * Draws the chart on a Java 2D graphics device (such as the screen or a
1092:             * printer).
1093:             * <P>
1094:             * This method is the focus of the entire JFreeChart library.
1095:             *
1096:             * @param g2  the graphics device.
1097:             * @param area  the area within which the chart should be drawn.
1098:             */
1099:            public void draw(Graphics2D g2, Rectangle2D area) {
1100:                draw(g2, area, null, null);
1101:            }
1102:
1103:            /**
1104:             * Draws the chart on a Java 2D graphics device (such as the screen or a
1105:             * printer).  This method is the focus of the entire JFreeChart library.
1106:             *
1107:             * @param g2  the graphics device.
1108:             * @param area  the area within which the chart should be drawn.
1109:             * @param info  records info about the drawing (null means collect no info).
1110:             */
1111:            public void draw(Graphics2D g2, Rectangle2D area,
1112:                    ChartRenderingInfo info) {
1113:                draw(g2, area, null, info);
1114:            }
1115:
1116:            /**
1117:             * Draws the chart on a Java 2D graphics device (such as the screen or a
1118:             * printer).
1119:             * <P>
1120:             * This method is the focus of the entire JFreeChart library.
1121:             *
1122:             * @param g2  the graphics device.
1123:             * @param chartArea  the area within which the chart should be drawn.
1124:             * @param anchor  the anchor point (in Java2D space) for the chart 
1125:             *                (<code>null</code> permitted).
1126:             * @param info  records info about the drawing (null means collect no info).
1127:             */
1128:            public void draw(Graphics2D g2, Rectangle2D chartArea,
1129:                    Point2D anchor, ChartRenderingInfo info) {
1130:
1131:                notifyListeners(new ChartProgressEvent(this , this ,
1132:                        ChartProgressEvent.DRAWING_STARTED, 0));
1133:
1134:                // record the chart area, if info is requested...
1135:                if (info != null) {
1136:                    info.clear();
1137:                    info.setChartArea(chartArea);
1138:                }
1139:
1140:                // ensure no drawing occurs outside chart area...
1141:                Shape savedClip = g2.getClip();
1142:                g2.clip(chartArea);
1143:
1144:                g2.addRenderingHints(this .renderingHints);
1145:
1146:                // draw the chart background...
1147:                if (this .backgroundPaint != null) {
1148:                    g2.setPaint(this .backgroundPaint);
1149:                    g2.fill(chartArea);
1150:                }
1151:
1152:                if (this .backgroundImage != null) {
1153:                    Composite originalComposite = g2.getComposite();
1154:                    g2
1155:                            .setComposite(AlphaComposite.getInstance(
1156:                                    AlphaComposite.SRC_OVER,
1157:                                    this .backgroundImageAlpha));
1158:                    Rectangle2D dest = new Rectangle2D.Double(0.0, 0.0,
1159:                            this .backgroundImage.getWidth(null),
1160:                            this .backgroundImage.getHeight(null));
1161:                    Align.align(dest, chartArea, this .backgroundImageAlignment);
1162:                    g2.drawImage(this .backgroundImage, (int) dest.getX(),
1163:                            (int) dest.getY(), (int) dest.getWidth(),
1164:                            (int) dest.getHeight(), null);
1165:                    g2.setComposite(originalComposite);
1166:                }
1167:
1168:                if (isBorderVisible()) {
1169:                    Paint paint = getBorderPaint();
1170:                    Stroke stroke = getBorderStroke();
1171:                    if (paint != null && stroke != null) {
1172:                        Rectangle2D borderArea = new Rectangle2D.Double(
1173:                                chartArea.getX(), chartArea.getY(), chartArea
1174:                                        .getWidth() - 1.0, chartArea
1175:                                        .getHeight() - 1.0);
1176:                        g2.setPaint(paint);
1177:                        g2.setStroke(stroke);
1178:                        g2.draw(borderArea);
1179:                    }
1180:                }
1181:
1182:                // draw the title and subtitles...
1183:                Rectangle2D nonTitleArea = new Rectangle2D.Double();
1184:                nonTitleArea.setRect(chartArea);
1185:                this .padding.trim(nonTitleArea);
1186:
1187:                EntityCollection entities = null;
1188:                if (info != null) {
1189:                    entities = info.getEntityCollection();
1190:                }
1191:                if (this .title != null) {
1192:                    EntityCollection e = drawTitle(this .title, g2,
1193:                            nonTitleArea, (entities != null));
1194:                    if (e != null) {
1195:                        entities.addAll(e);
1196:                    }
1197:                }
1198:
1199:                Iterator iterator = this .subtitles.iterator();
1200:                while (iterator.hasNext()) {
1201:                    Title currentTitle = (Title) iterator.next();
1202:                    EntityCollection e = drawTitle(currentTitle, g2,
1203:                            nonTitleArea, (entities != null));
1204:                    if (e != null) {
1205:                        entities.addAll(e);
1206:                    }
1207:                }
1208:
1209:                Rectangle2D plotArea = nonTitleArea;
1210:
1211:                // draw the plot (axes and data visualisation)
1212:                PlotRenderingInfo plotInfo = null;
1213:                if (info != null) {
1214:                    plotInfo = info.getPlotInfo();
1215:                }
1216:                this .plot.draw(g2, plotArea, anchor, null, plotInfo);
1217:
1218:                g2.setClip(savedClip);
1219:
1220:                notifyListeners(new ChartProgressEvent(this , this ,
1221:                        ChartProgressEvent.DRAWING_FINISHED, 100));
1222:            }
1223:
1224:            /**
1225:             * Creates a rectangle that is aligned to the frame.
1226:             * 
1227:             * @param dimensions
1228:             * @param frame
1229:             * @param hAlign
1230:             * @param vAlign
1231:             * 
1232:             * @return A rectangle.
1233:             */
1234:            private Rectangle2D createAlignedRectangle2D(Size2D dimensions,
1235:                    Rectangle2D frame, HorizontalAlignment hAlign,
1236:                    VerticalAlignment vAlign) {
1237:                double x = Double.NaN;
1238:                double y = Double.NaN;
1239:                if (hAlign == HorizontalAlignment.LEFT) {
1240:                    x = frame.getX();
1241:                } else if (hAlign == HorizontalAlignment.CENTER) {
1242:                    x = frame.getCenterX() - (dimensions.width / 2.0);
1243:                } else if (hAlign == HorizontalAlignment.RIGHT) {
1244:                    x = frame.getMaxX() - dimensions.width;
1245:                }
1246:                if (vAlign == VerticalAlignment.TOP) {
1247:                    y = frame.getY();
1248:                } else if (vAlign == VerticalAlignment.CENTER) {
1249:                    y = frame.getCenterY() - (dimensions.height / 2.0);
1250:                } else if (vAlign == VerticalAlignment.BOTTOM) {
1251:                    y = frame.getMaxY() - dimensions.height;
1252:                }
1253:
1254:                return new Rectangle2D.Double(x, y, dimensions.width,
1255:                        dimensions.height);
1256:            }
1257:
1258:            /**
1259:             * Draws a title.  The title should be drawn at the top, bottom, left or 
1260:             * right of the specified area, and the area should be updated to reflect 
1261:             * the amount of space used by the title.
1262:             *
1263:             * @param t  the title (<code>null</code> not permitted).
1264:             * @param g2  the graphics device (<code>null</code> not permitted).
1265:             * @param area  the chart area, excluding any existing titles 
1266:             *              (<code>null</code> not permitted).
1267:             * @param entities  a flag that controls whether or not an entity 
1268:             *                  collection is returned for the title.
1269:             * 
1270:             * @return An entity collection for the title (possibly <code>null</code>).
1271:             */
1272:            protected EntityCollection drawTitle(Title t, Graphics2D g2,
1273:                    Rectangle2D area, boolean entities) {
1274:
1275:                if (t == null) {
1276:                    throw new IllegalArgumentException("Null 't' argument.");
1277:                }
1278:                if (area == null) {
1279:                    throw new IllegalArgumentException("Null 'area' argument.");
1280:                }
1281:                Rectangle2D titleArea = new Rectangle2D.Double();
1282:                RectangleEdge position = t.getPosition();
1283:                double ww = area.getWidth();
1284:                if (ww <= 0.0) {
1285:                    return null;
1286:                }
1287:                double hh = area.getHeight();
1288:                if (hh <= 0.0) {
1289:                    return null;
1290:                }
1291:                RectangleConstraint constraint = new RectangleConstraint(ww,
1292:                        new Range(0.0, ww), LengthConstraintType.RANGE, hh,
1293:                        new Range(0.0, hh), LengthConstraintType.RANGE);
1294:                Object retValue = null;
1295:                BlockParams p = new BlockParams();
1296:                p.setGenerateEntities(entities);
1297:                if (position == RectangleEdge.TOP) {
1298:                    Size2D size = t.arrange(g2, constraint);
1299:                    titleArea = createAlignedRectangle2D(size, area, t
1300:                            .getHorizontalAlignment(), VerticalAlignment.TOP);
1301:                    retValue = t.draw(g2, titleArea, p);
1302:                    area.setRect(area.getX(), Math.min(area.getY()
1303:                            + size.height, area.getMaxY()), area.getWidth(),
1304:                            Math.max(area.getHeight() - size.height, 0));
1305:                } else if (position == RectangleEdge.BOTTOM) {
1306:                    Size2D size = t.arrange(g2, constraint);
1307:                    titleArea = createAlignedRectangle2D(size, area, t
1308:                            .getHorizontalAlignment(), VerticalAlignment.BOTTOM);
1309:                    retValue = t.draw(g2, titleArea, p);
1310:                    area.setRect(area.getX(), area.getY(), area.getWidth(),
1311:                            area.getHeight() - size.height);
1312:                } else if (position == RectangleEdge.RIGHT) {
1313:                    Size2D size = t.arrange(g2, constraint);
1314:                    titleArea = createAlignedRectangle2D(size, area,
1315:                            HorizontalAlignment.RIGHT, t.getVerticalAlignment());
1316:                    retValue = t.draw(g2, titleArea, p);
1317:                    area.setRect(area.getX(), area.getY(), area.getWidth()
1318:                            - size.width, area.getHeight());
1319:                }
1320:
1321:                else if (position == RectangleEdge.LEFT) {
1322:                    Size2D size = t.arrange(g2, constraint);
1323:                    titleArea = createAlignedRectangle2D(size, area,
1324:                            HorizontalAlignment.LEFT, t.getVerticalAlignment());
1325:                    retValue = t.draw(g2, titleArea, p);
1326:                    area.setRect(area.getX() + size.width, area.getY(), area
1327:                            .getWidth()
1328:                            - size.width, area.getHeight());
1329:                } else {
1330:                    throw new RuntimeException("Unrecognised title position.");
1331:                }
1332:                EntityCollection result = null;
1333:                if (retValue instanceof  EntityBlockResult) {
1334:                    EntityBlockResult ebr = (EntityBlockResult) retValue;
1335:                    result = ebr.getEntityCollection();
1336:                }
1337:                return result;
1338:            }
1339:
1340:            /**
1341:             * Creates and returns a buffered image into which the chart has been drawn.
1342:             *
1343:             * @param width  the width.
1344:             * @param height  the height.
1345:             *
1346:             * @return A buffered image.
1347:             */
1348:            public BufferedImage createBufferedImage(int width, int height) {
1349:                return createBufferedImage(width, height, null);
1350:            }
1351:
1352:            /**
1353:             * Creates and returns a buffered image into which the chart has been drawn.
1354:             *
1355:             * @param width  the width.
1356:             * @param height  the height.
1357:             * @param info  carries back chart state information (<code>null</code> 
1358:             *              permitted).
1359:             *
1360:             * @return A buffered image.
1361:             */
1362:            public BufferedImage createBufferedImage(int width, int height,
1363:                    ChartRenderingInfo info) {
1364:                return createBufferedImage(width, height,
1365:                        BufferedImage.TYPE_INT_RGB, info);
1366:            }
1367:
1368:            /**
1369:             * Creates and returns a buffered image into which the chart has been drawn.
1370:             *
1371:             * @param width  the width.
1372:             * @param height  the height.
1373:             * @param imageType  the image type.
1374:             * @param info  carries back chart state information (<code>null</code> 
1375:             *              permitted).
1376:             *
1377:             * @return A buffered image.
1378:             */
1379:            public BufferedImage createBufferedImage(int width, int height,
1380:                    int imageType, ChartRenderingInfo info) {
1381:                BufferedImage image = new BufferedImage(width, height,
1382:                        imageType);
1383:                Graphics2D g2 = image.createGraphics();
1384:                draw(g2, new Rectangle2D.Double(0, 0, width, height), null,
1385:                        info);
1386:                g2.dispose();
1387:                return image;
1388:            }
1389:
1390:            /**
1391:             * Creates and returns a buffered image into which the chart has been drawn.
1392:             *
1393:             * @param imageWidth  the image width.
1394:             * @param imageHeight  the image height.
1395:             * @param drawWidth  the width for drawing the chart (will be scaled to 
1396:             *                   fit image).
1397:             * @param drawHeight  the height for drawing the chart (will be scaled to 
1398:             *                    fit image).
1399:             * @param info  optional object for collection chart dimension and entity 
1400:             *              information.
1401:             *
1402:             * @return A buffered image.
1403:             */
1404:            public BufferedImage createBufferedImage(int imageWidth,
1405:                    int imageHeight, double drawWidth, double drawHeight,
1406:                    ChartRenderingInfo info) {
1407:
1408:                BufferedImage image = new BufferedImage(imageWidth,
1409:                        imageHeight, BufferedImage.TYPE_INT_RGB);
1410:                Graphics2D g2 = image.createGraphics();
1411:                double scaleX = imageWidth / drawWidth;
1412:                double scaleY = imageHeight / drawHeight;
1413:                AffineTransform st = AffineTransform.getScaleInstance(scaleX,
1414:                        scaleY);
1415:                g2.transform(st);
1416:                draw(g2, new Rectangle2D.Double(0, 0, drawWidth, drawHeight),
1417:                        null, info);
1418:                g2.dispose();
1419:                return image;
1420:
1421:            }
1422:
1423:            /**
1424:             * Handles a 'click' on the chart.
1425:             * <P>
1426:             * JFreeChart is not a UI component, so some other object (e.g. ChartPanel)
1427:             * needs to capture the click event and pass it onto the JFreeChart object.
1428:             * If you are not using JFreeChart in a client application, then this
1429:             * method is not required (and hopefully it doesn't get in the way).
1430:             *
1431:             * @param x  x-coordinate of the click (in Java2D space).
1432:             * @param y  y-coordinate of the click (in Java2D space).
1433:             * @param info  contains chart dimension and entity information.
1434:             */
1435:            public void handleClick(int x, int y, ChartRenderingInfo info) {
1436:
1437:                // pass the click on to the plot...
1438:                // rely on the plot to post a plot change event and redraw the chart...
1439:                this .plot.handleClick(x, y, info.getPlotInfo());
1440:
1441:            }
1442:
1443:            /**
1444:             * Registers an object for notification of changes to the chart.
1445:             *
1446:             * @param listener  the listener (<code>null</code> not permitted).
1447:             * 
1448:             * @see #removeChangeListener(ChartChangeListener)
1449:             */
1450:            public void addChangeListener(ChartChangeListener listener) {
1451:                if (listener == null) {
1452:                    throw new IllegalArgumentException(
1453:                            "Null 'listener' argument.");
1454:                }
1455:                this .changeListeners.add(ChartChangeListener.class, listener);
1456:            }
1457:
1458:            /**
1459:             * Deregisters an object for notification of changes to the chart.
1460:             *
1461:             * @param listener  the listener (<code>null</code> not permitted)
1462:             * 
1463:             * @see #addChangeListener(ChartChangeListener)
1464:             */
1465:            public void removeChangeListener(ChartChangeListener listener) {
1466:                if (listener == null) {
1467:                    throw new IllegalArgumentException(
1468:                            "Null 'listener' argument.");
1469:                }
1470:                this .changeListeners
1471:                        .remove(ChartChangeListener.class, listener);
1472:            }
1473:
1474:            /**
1475:             * Sends a default {@link ChartChangeEvent} to all registered listeners.
1476:             * <P>
1477:             * This method is for convenience only.
1478:             */
1479:            public void fireChartChanged() {
1480:                ChartChangeEvent event = new ChartChangeEvent(this );
1481:                notifyListeners(event);
1482:            }
1483:
1484:            /**
1485:             * Sends a {@link ChartChangeEvent} to all registered listeners.
1486:             *
1487:             * @param event  information about the event that triggered the 
1488:             *               notification.
1489:             */
1490:            protected void notifyListeners(ChartChangeEvent event) {
1491:                if (this .notify) {
1492:                    Object[] listeners = this .changeListeners.getListenerList();
1493:                    for (int i = listeners.length - 2; i >= 0; i -= 2) {
1494:                        if (listeners[i] == ChartChangeListener.class) {
1495:                            ((ChartChangeListener) listeners[i + 1])
1496:                                    .chartChanged(event);
1497:                        }
1498:                    }
1499:                }
1500:            }
1501:
1502:            /**
1503:             * Registers an object for notification of progress events relating to the 
1504:             * chart.
1505:             *
1506:             * @param listener  the object being registered.
1507:             * 
1508:             * @see #removeProgressListener(ChartProgressListener)
1509:             */
1510:            public void addProgressListener(ChartProgressListener listener) {
1511:                this .progressListeners.add(ChartProgressListener.class,
1512:                        listener);
1513:            }
1514:
1515:            /**
1516:             * Deregisters an object for notification of changes to the chart.
1517:             *
1518:             * @param listener  the object being deregistered.
1519:             * 
1520:             * @see #addProgressListener(ChartProgressListener)
1521:             */
1522:            public void removeProgressListener(ChartProgressListener listener) {
1523:                this .progressListeners.remove(ChartProgressListener.class,
1524:                        listener);
1525:            }
1526:
1527:            /**
1528:             * Sends a {@link ChartProgressEvent} to all registered listeners.
1529:             *
1530:             * @param event  information about the event that triggered the 
1531:             *               notification.
1532:             */
1533:            protected void notifyListeners(ChartProgressEvent event) {
1534:
1535:                Object[] listeners = this .progressListeners.getListenerList();
1536:                for (int i = listeners.length - 2; i >= 0; i -= 2) {
1537:                    if (listeners[i] == ChartProgressListener.class) {
1538:                        ((ChartProgressListener) listeners[i + 1])
1539:                                .chartProgress(event);
1540:                    }
1541:                }
1542:
1543:            }
1544:
1545:            /**
1546:             * Receives notification that a chart title has changed, and passes this
1547:             * on to registered listeners.
1548:             *
1549:             * @param event  information about the chart title change.
1550:             */
1551:            public void titleChanged(TitleChangeEvent event) {
1552:                event.setChart(this );
1553:                notifyListeners(event);
1554:            }
1555:
1556:            /**
1557:             * Receives notification that the plot has changed, and passes this on to
1558:             * registered listeners.
1559:             *
1560:             * @param event  information about the plot change.
1561:             */
1562:            public void plotChanged(PlotChangeEvent event) {
1563:                event.setChart(this );
1564:                notifyListeners(event);
1565:            }
1566:
1567:            /**
1568:             * Tests this chart for equality with another object.
1569:             *
1570:             * @param obj  the object (<code>null</code> permitted).
1571:             *
1572:             * @return A boolean.
1573:             */
1574:            public boolean equals(Object obj) {
1575:                if (obj == this ) {
1576:                    return true;
1577:                }
1578:                if (!(obj instanceof  JFreeChart)) {
1579:                    return false;
1580:                }
1581:                JFreeChart that = (JFreeChart) obj;
1582:                if (!this .renderingHints.equals(that.renderingHints)) {
1583:                    return false;
1584:                }
1585:                if (this .borderVisible != that.borderVisible) {
1586:                    return false;
1587:                }
1588:                if (!ObjectUtilities
1589:                        .equal(this .borderStroke, that.borderStroke)) {
1590:                    return false;
1591:                }
1592:                if (!PaintUtilities.equal(this .borderPaint, that.borderPaint)) {
1593:                    return false;
1594:                }
1595:                if (!this .padding.equals(that.padding)) {
1596:                    return false;
1597:                }
1598:                if (!ObjectUtilities.equal(this .title, that.title)) {
1599:                    return false;
1600:                }
1601:                if (!ObjectUtilities.equal(this .subtitles, that.subtitles)) {
1602:                    return false;
1603:                }
1604:                if (!ObjectUtilities.equal(this .plot, that.plot)) {
1605:                    return false;
1606:                }
1607:                if (!PaintUtilities.equal(this .backgroundPaint,
1608:                        that.backgroundPaint)) {
1609:                    return false;
1610:                }
1611:                if (!ObjectUtilities.equal(this .backgroundImage,
1612:                        that.backgroundImage)) {
1613:                    return false;
1614:                }
1615:                if (this .backgroundImageAlignment != that.backgroundImageAlignment) {
1616:                    return false;
1617:                }
1618:                if (this .backgroundImageAlpha != that.backgroundImageAlpha) {
1619:                    return false;
1620:                }
1621:                if (this .notify != that.notify) {
1622:                    return false;
1623:                }
1624:                return true;
1625:            }
1626:
1627:            /**
1628:             * Provides serialization support.
1629:             *
1630:             * @param stream  the output stream.
1631:             *
1632:             * @throws IOException  if there is an I/O error.
1633:             */
1634:            private void writeObject(ObjectOutputStream stream)
1635:                    throws IOException {
1636:                stream.defaultWriteObject();
1637:                SerialUtilities.writeStroke(this .borderStroke, stream);
1638:                SerialUtilities.writePaint(this .borderPaint, stream);
1639:                SerialUtilities.writePaint(this .backgroundPaint, stream);
1640:            }
1641:
1642:            /**
1643:             * Provides serialization support.
1644:             *
1645:             * @param stream  the input stream.
1646:             *
1647:             * @throws IOException  if there is an I/O error.
1648:             * @throws ClassNotFoundException  if there is a classpath problem.
1649:             */
1650:            private void readObject(ObjectInputStream stream)
1651:                    throws IOException, ClassNotFoundException {
1652:                stream.defaultReadObject();
1653:                this .borderStroke = SerialUtilities.readStroke(stream);
1654:                this .borderPaint = SerialUtilities.readPaint(stream);
1655:                this .backgroundPaint = SerialUtilities.readPaint(stream);
1656:                this .progressListeners = new EventListenerList();
1657:                this .changeListeners = new EventListenerList();
1658:                this .renderingHints = new RenderingHints(
1659:                        RenderingHints.KEY_ANTIALIASING,
1660:                        RenderingHints.VALUE_ANTIALIAS_ON);
1661:
1662:                // register as a listener with sub-components...
1663:                if (this .title != null) {
1664:                    this .title.addChangeListener(this );
1665:                }
1666:
1667:                for (int i = 0; i < getSubtitleCount(); i++) {
1668:                    getSubtitle(i).addChangeListener(this );
1669:                }
1670:                this .plot.addChangeListener(this );
1671:            }
1672:
1673:            /**
1674:             * Prints information about JFreeChart to standard output.
1675:             *
1676:             * @param args  no arguments are honored.
1677:             */
1678:            public static void main(String[] args) {
1679:                System.out.println(JFreeChart.INFO.toString());
1680:            }
1681:
1682:            /**
1683:             * Clones the object, and takes care of listeners.
1684:             * Note: caller shall register its own listeners on cloned graph.
1685:             * 
1686:             * @return A clone.
1687:             * 
1688:             * @throws CloneNotSupportedException if the chart is not cloneable.
1689:             */
1690:            public Object clone() throws CloneNotSupportedException {
1691:                JFreeChart chart = (JFreeChart) super .clone();
1692:
1693:                chart.renderingHints = (RenderingHints) this .renderingHints
1694:                        .clone();
1695:                // private boolean borderVisible;
1696:                // private transient Stroke borderStroke;
1697:                // private transient Paint borderPaint;
1698:
1699:                if (this .title != null) {
1700:                    chart.title = (TextTitle) this .title.clone();
1701:                    chart.title.addChangeListener(chart);
1702:                }
1703:
1704:                chart.subtitles = new ArrayList();
1705:                for (int i = 0; i < getSubtitleCount(); i++) {
1706:                    Title subtitle = (Title) getSubtitle(i).clone();
1707:                    chart.subtitles.add(subtitle);
1708:                    subtitle.addChangeListener(chart);
1709:                }
1710:
1711:                if (this .plot != null) {
1712:                    chart.plot = (Plot) this .plot.clone();
1713:                    chart.plot.addChangeListener(chart);
1714:                }
1715:
1716:                chart.progressListeners = new EventListenerList();
1717:                chart.changeListeners = new EventListenerList();
1718:                return chart;
1719:            }
1720:
1721:        }
1722:
1723:        /**
1724:         * Information about the JFreeChart project.  One instance of this class is 
1725:         * assigned to <code>JFreeChart.INFO<code>.
1726:         */
1727:        class JFreeChartInfo extends ProjectInfo {
1728:
1729:            /** 
1730:             * Default constructor. 
1731:             */
1732:            public JFreeChartInfo() {
1733:
1734:                // get a locale-specific resource bundle...
1735:                String baseResourceClass = "org.jfree.chart.resources.JFreeChartResources";
1736:                ResourceBundle resources = ResourceBundle
1737:                        .getBundle(baseResourceClass);
1738:
1739:                setName(resources.getString("project.name"));
1740:                setVersion(resources.getString("project.version"));
1741:                setInfo(resources.getString("project.info"));
1742:                setCopyright(resources.getString("project.copyright"));
1743:                setLogo(null); // load only when required
1744:                setLicenceName("LGPL");
1745:                setLicenceText(Licences.getInstance().getLGPL());
1746:
1747:                setContributors(Arrays
1748:                        .asList(new Contributor[] {
1749:                                new Contributor("Eric Alexander", "-"),
1750:                                new Contributor("Richard Atkinson",
1751:                                        "richard_c_atkinson@ntlworld.com"),
1752:                                new Contributor("David Basten", "-"),
1753:                                new Contributor("David Berry", "-"),
1754:                                new Contributor("Chris Boek", "-"),
1755:                                new Contributor("Zoheb Borbora", "-"),
1756:                                new Contributor("Anthony Boulestreau", "-"),
1757:                                new Contributor("Jeremy Bowman", "-"),
1758:                                new Contributor("Nicolas Brodu", "-"),
1759:                                new Contributor("Jody Brownell", "-"),
1760:                                new Contributor("David Browning", "-"),
1761:                                new Contributor("Soren Caspersen", "-"),
1762:                                new Contributor("Chuanhao Chiu", "-"),
1763:                                new Contributor("Brian Cole", "-"),
1764:                                new Contributor("Pascal Collet", "-"),
1765:                                new Contributor("Martin Cordova", "-"),
1766:                                new Contributor("Paolo Cova", "-"),
1767:                                new Contributor("Mike Duffy", "-"),
1768:                                new Contributor("Don Elliott", "-"),
1769:                                new Contributor("Jonathan Gabbai", "-"),
1770:                                new Contributor("David Gilbert",
1771:                                        "david.gilbert@object-refinery.com"),
1772:                                new Contributor("Serge V. Grachov", "-"),
1773:                                new Contributor("Daniel Gredler", "-"),
1774:                                new Contributor("Hans-Jurgen Greiner", "-"),
1775:                                new Contributor("Joao Guilherme Del Valle", "-"),
1776:                                new Contributor("Aiman Han", "-"),
1777:                                new Contributor("Cameron Hayne", "-"),
1778:                                new Contributor("Jon Iles", "-"),
1779:                                new Contributor("Wolfgang Irler", "-"),
1780:                                new Contributor("Sergei Ivanov", "-"),
1781:                                new Contributor("Adriaan Joubert", "-"),
1782:                                new Contributor("Darren Jung", "-"),
1783:                                new Contributor("Xun Kang", "-"),
1784:                                new Contributor("Bill Kelemen", "-"),
1785:                                new Contributor("Norbert Kiesel", "-"),
1786:                                new Contributor("Gideon Krause", "-"),
1787:                                new Contributor("Pierre-Marie Le Biot", "-"),
1788:                                new Contributor("Arnaud Lelievre", "-"),
1789:                                new Contributor("Wolfgang Lenhard", "-"),
1790:                                new Contributor("David Li", "-"),
1791:                                new Contributor("Yan Liu", "-"),
1792:                                new Contributor("Tin Luu", "-"),
1793:                                new Contributor("Craig MacFarlane", "-"),
1794:                                new Contributor("Achilleus Mantzios", "-"),
1795:                                new Contributor("Thomas Meier", "-"),
1796:                                new Contributor("Jim Moore", "-"),
1797:                                new Contributor("Jonathan Nash", "-"),
1798:                                new Contributor("Barak Naveh", "-"),
1799:                                new Contributor("David M. O'Donnell", "-"),
1800:                                new Contributor("Krzysztof Paz", "-"),
1801:                                new Contributor("Tomer Peretz", "-"),
1802:                                new Contributor("Xavier Poinsard", "-"),
1803:                                new Contributor("Andrzej Porebski", "-"),
1804:                                new Contributor("Viktor Rajewski", "-"),
1805:                                new Contributor("Eduardo Ramalho", "-"),
1806:                                new Contributor("Michael Rauch", "-"),
1807:                                new Contributor("Cameron Riley", "-"),
1808:                                new Contributor("Klaus Rheinwald", "-"),
1809:                                new Contributor("Dan Rivett",
1810:                                        "d.rivett@ukonline.co.uk"),
1811:                                new Contributor("Scott Sams", "-"),
1812:                                new Contributor("Michel Santos", "-"),
1813:                                new Contributor("Thierry Saura", "-"),
1814:                                new Contributor("Andreas Schneider", "-"),
1815:                                new Contributor("Jean-Luc SCHWAB", "-"),
1816:                                new Contributor("Bryan Scott", "-"),
1817:                                new Contributor("Tobias Selb", "-"),
1818:                                new Contributor("Mofeed Shahin", "-"),
1819:                                new Contributor("Pady Srinivasan", "-"),
1820:                                new Contributor("Greg Steckman", "-"),
1821:                                new Contributor("Roger Studner", "-"),
1822:                                new Contributor("Irv Thomae", "-"),
1823:                                new Contributor("Eric Thomas", "-"),
1824:                                new Contributor("Rich Unger", "-"),
1825:                                new Contributor("Daniel van Enckevort", "-"),
1826:                                new Contributor("Laurence Vanhelsuwe", "-"),
1827:                                new Contributor("Sylvain Vieujot", "-"),
1828:                                new Contributor("Jelai Wang", "-"),
1829:                                new Contributor("Mark Watson",
1830:                                        "www.markwatson.com"),
1831:                                new Contributor("Alex Weber", "-"),
1832:                                new Contributor("Matthew Wright", "-"),
1833:                                new Contributor("Benoit Xhenseval", "-"),
1834:                                new Contributor("Christian W. Zuckschwerdt",
1835:                                        "Christian.Zuckschwerdt@Informatik.Uni-Oldenburg.de"),
1836:                                new Contributor("Hari", "-"),
1837:                                new Contributor("Sam (oldman)", "-"), }));
1838:
1839:                addLibrary(JCommon.INFO);
1840:
1841:            }
1842:
1843:            /**
1844:             * Returns the JFreeChart logo (a picture of a gorilla).
1845:             *
1846:             * @return The JFreeChart logo.
1847:             */
1848:            public Image getLogo() {
1849:
1850:                Image logo = super .getLogo();
1851:                if (logo == null) {
1852:                    URL imageURL = this .getClass().getClassLoader()
1853:                            .getResource("org/jfree/chart/gorilla.jpg");
1854:                    if (imageURL != null) {
1855:                        ImageIcon temp = new ImageIcon(imageURL);
1856:                        // use ImageIcon because it waits for the image to load...
1857:                        logo = temp.getImage();
1858:                        setLogo(logo);
1859:                    }
1860:                }
1861:                return logo;
1862:
1863:            }
1864:
1865:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.