Source Code Cross Referenced for AbstractXYItemRenderer.java in  » Chart » jfreechart » org » jfree » chart » renderer » xy » 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.renderer.xy 
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:         * AbstractXYItemRenderer.java
0029:         * ---------------------------
0030:         * (C) Copyright 2002-2007, by Object Refinery Limited and Contributors.
0031:         *
0032:         * Original Author:  David Gilbert (for Object Refinery Limited);
0033:         * Contributor(s):   Richard Atkinson;
0034:         *                   Focus Computer Services Limited;
0035:         *                   Tim Bardzil;
0036:         *                   Sergei Ivanov;
0037:         *
0038:         * $Id: AbstractXYItemRenderer.java,v 1.26.2.19 2007/06/12 08:39:30 mungady Exp $
0039:         *
0040:         * Changes:
0041:         * --------
0042:         * 15-Mar-2002 : Version 1 (DG);
0043:         * 09-Apr-2002 : Added a getToolTipGenerator() method reflecting the change in
0044:         *               the XYItemRenderer interface (DG);
0045:         * 05-Aug-2002 : Added a urlGenerator member variable to support HTML image
0046:         *               maps (RA);
0047:         * 20-Aug-2002 : Added property change events for the tooltip and URL
0048:         *               generators (DG);
0049:         * 22-Aug-2002 : Moved property change support into AbstractRenderer class (DG);
0050:         * 23-Sep-2002 : Fixed errors reported by Checkstyle tool (DG);
0051:         * 18-Nov-2002 : Added methods for drawing grid lines (DG);
0052:         * 17-Jan-2003 : Moved plot classes into a separate package (DG);
0053:         * 25-Mar-2003 : Implemented Serializable (DG);
0054:         * 01-May-2003 : Modified initialise() return type and drawItem() method
0055:         *               signature (DG);
0056:         * 15-May-2003 : Modified to take into account the plot orientation (DG);
0057:         * 21-May-2003 : Added labels to markers (DG);
0058:         * 05-Jun-2003 : Added domain and range grid bands (sponsored by Focus Computer
0059:         *               Services Ltd) (DG);
0060:         * 27-Jul-2003 : Added getRangeType() to support stacked XY area charts (RA);
0061:         * 31-Jul-2003 : Deprecated all but the default constructor (DG);
0062:         * 13-Aug-2003 : Implemented Cloneable (DG);
0063:         * 16-Sep-2003 : Changed ChartRenderingInfo --> PlotRenderingInfo (DG);
0064:         * 29-Oct-2003 : Added workaround for font alignment in PDF output (DG);
0065:         * 05-Nov-2003 : Fixed marker rendering bug (833623) (DG);
0066:         * 11-Feb-2004 : Updated labelling for markers (DG);
0067:         * 25-Feb-2004 : Added updateCrosshairValues() method.  Moved deprecated code
0068:         *               to bottom of source file (DG);
0069:         * 16-Apr-2004 : Added support for IntervalMarker in drawRangeMarker() method
0070:         *               - thanks to Tim Bardzil (DG);
0071:         * 05-May-2004 : Fixed bug (948310) where interval markers extend beyond axis
0072:         *               range (DG);
0073:         * 03-Jun-2004 : Fixed more bugs in drawing interval markers (DG);
0074:         * 26-Aug-2004 : Added the addEntity() method (DG);
0075:         * 29-Sep-2004 : Added annotation support (with layers) (DG);
0076:         * 30-Sep-2004 : Moved drawRotatedString() from RefineryUtilities -->
0077:         *               TextUtilities (DG);
0078:         * 06-Oct-2004 : Added findDomainBounds() method and renamed
0079:         *               getRangeExtent() --> findRangeBounds() (DG);
0080:         * 07-Jan-2005 : Removed deprecated code (DG);
0081:         * 27-Jan-2005 : Modified getLegendItem() to omit hidden series (DG);
0082:         * 24-Feb-2005 : Added getLegendItems() method (DG);
0083:         * 08-Mar-2005 : Fixed positioning of marker labels (DG);
0084:         * 20-Apr-2005 : Renamed XYLabelGenerator --> XYItemLabelGenerator and
0085:         *               added generators for legend labels, tooltips and URLs (DG);
0086:         * 01-Jun-2005 : Handle one dimension of the marker label adjustment
0087:         *               automatically (DG);
0088:         * ------------- JFREECHART 1.0.x ---------------------------------------------
0089:         * 20-Jul-2006 : Set dataset and series indices in LegendItem (DG);
0090:         * 24-Oct-2006 : Respect alpha setting in markers (see patch 1567843 by Sergei
0091:         *               Ivanov) (DG);
0092:         * 24-Oct-2006 : Added code to draw outlines for interval markers (DG);
0093:         * 24-Nov-2006 : Fixed cloning for legend item generators (DG);
0094:         * 06-Feb-2007 : Added new updateCrosshairValues() method that takes into
0095:         *               account multiple axis plots (see bug 1086307) (DG);
0096:         * 20-Feb-2007 : Fixed equals() method implementation (DG);
0097:         * 01-Mar-2007 : Fixed interval marker drawing (patch 1670686 thanks to 
0098:         *               Sergei Ivanov) (DG);
0099:         * 22-Mar-2007 : Modified the tool tip generator look up (DG);
0100:         * 23-Mar-2007 : Added drawDomainLine() method (DG);
0101:         * 20-Apr-2007 : Updated getLegendItem() for renderer change, and deprecated
0102:         *               itemLabelGenerator and toolTipGenerator override fields (DG);
0103:         * 18-May-2007 : Set dataset and seriesKey for LegendItem (DG);
0104:         *
0105:         */
0106:
0107:        package org.jfree.chart.renderer.xy;
0108:
0109:        import java.awt.AlphaComposite;
0110:        import java.awt.Composite;
0111:        import java.awt.Font;
0112:        import java.awt.GradientPaint;
0113:        import java.awt.Graphics2D;
0114:        import java.awt.Paint;
0115:        import java.awt.Shape;
0116:        import java.awt.Stroke;
0117:        import java.awt.geom.Ellipse2D;
0118:        import java.awt.geom.Line2D;
0119:        import java.awt.geom.Point2D;
0120:        import java.awt.geom.Rectangle2D;
0121:        import java.io.Serializable;
0122:        import java.util.Iterator;
0123:        import java.util.List;
0124:
0125:        import org.jfree.chart.LegendItem;
0126:        import org.jfree.chart.LegendItemCollection;
0127:        import org.jfree.chart.annotations.XYAnnotation;
0128:        import org.jfree.chart.axis.ValueAxis;
0129:        import org.jfree.chart.entity.EntityCollection;
0130:        import org.jfree.chart.entity.XYItemEntity;
0131:        import org.jfree.chart.event.RendererChangeEvent;
0132:        import org.jfree.chart.labels.ItemLabelPosition;
0133:        import org.jfree.chart.labels.StandardXYSeriesLabelGenerator;
0134:        import org.jfree.chart.labels.XYItemLabelGenerator;
0135:        import org.jfree.chart.labels.XYSeriesLabelGenerator;
0136:        import org.jfree.chart.labels.XYToolTipGenerator;
0137:        import org.jfree.chart.plot.CrosshairState;
0138:        import org.jfree.chart.plot.DrawingSupplier;
0139:        import org.jfree.chart.plot.IntervalMarker;
0140:        import org.jfree.chart.plot.Marker;
0141:        import org.jfree.chart.plot.Plot;
0142:        import org.jfree.chart.plot.PlotOrientation;
0143:        import org.jfree.chart.plot.PlotRenderingInfo;
0144:        import org.jfree.chart.plot.ValueMarker;
0145:        import org.jfree.chart.plot.XYPlot;
0146:        import org.jfree.chart.renderer.AbstractRenderer;
0147:        import org.jfree.chart.urls.XYURLGenerator;
0148:        import org.jfree.data.Range;
0149:        import org.jfree.data.general.DatasetUtilities;
0150:        import org.jfree.data.xy.XYDataset;
0151:        import org.jfree.text.TextUtilities;
0152:        import org.jfree.ui.GradientPaintTransformer;
0153:        import org.jfree.ui.Layer;
0154:        import org.jfree.ui.LengthAdjustmentType;
0155:        import org.jfree.ui.RectangleAnchor;
0156:        import org.jfree.ui.RectangleInsets;
0157:        import org.jfree.util.ObjectList;
0158:        import org.jfree.util.ObjectUtilities;
0159:        import org.jfree.util.PublicCloneable;
0160:
0161:        /**
0162:         * A base class that can be used to create new {@link XYItemRenderer}
0163:         * implementations.
0164:         */
0165:        public abstract class AbstractXYItemRenderer extends AbstractRenderer
0166:                implements  XYItemRenderer, Cloneable, Serializable {
0167:
0168:            /** For serialization. */
0169:            private static final long serialVersionUID = 8019124836026607990L;
0170:
0171:            /** The plot. */
0172:            private XYPlot plot;
0173:
0174:            /** 
0175:             * The item label generator for ALL series.
0176:             * 
0177:             * @deprecated This field is redundant, use itemLabelGeneratorList and
0178:             *     baseItemLabelGenerator instead.  Deprecated as of version 1.0.6.
0179:             */
0180:            private XYItemLabelGenerator itemLabelGenerator;
0181:
0182:            /** A list of item label generators (one per series). */
0183:            private ObjectList itemLabelGeneratorList;
0184:
0185:            /** The base item label generator. */
0186:            private XYItemLabelGenerator baseItemLabelGenerator;
0187:
0188:            /** 
0189:             * The tool tip generator for ALL series. 
0190:             * 
0191:             * @deprecated This field is redundant, use tooltipGeneratorList and
0192:             *     baseToolTipGenerator instead.  Deprecated as of version 1.0.6.
0193:             */
0194:            private XYToolTipGenerator toolTipGenerator;
0195:
0196:            /** A list of tool tip generators (one per series). */
0197:            private ObjectList toolTipGeneratorList;
0198:
0199:            /** The base tool tip generator. */
0200:            private XYToolTipGenerator baseToolTipGenerator;
0201:
0202:            /** The URL text generator. */
0203:            private XYURLGenerator urlGenerator;
0204:
0205:            /**
0206:             * Annotations to be drawn in the background layer ('underneath' the data
0207:             * items).
0208:             */
0209:            private List backgroundAnnotations;
0210:
0211:            /**
0212:             * Annotations to be drawn in the foreground layer ('on top' of the data
0213:             * items).
0214:             */
0215:            private List foregroundAnnotations;
0216:
0217:            /** The default radius for the entity 'hotspot' */
0218:            private int defaultEntityRadius;
0219:
0220:            /** The legend item label generator. */
0221:            private XYSeriesLabelGenerator legendItemLabelGenerator;
0222:
0223:            /** The legend item tool tip generator. */
0224:            private XYSeriesLabelGenerator legendItemToolTipGenerator;
0225:
0226:            /** The legend item URL generator. */
0227:            private XYSeriesLabelGenerator legendItemURLGenerator;
0228:
0229:            /**
0230:             * Creates a renderer where the tooltip generator and the URL generator are
0231:             * both <code>null</code>.
0232:             */
0233:            protected AbstractXYItemRenderer() {
0234:                super ();
0235:                this .itemLabelGenerator = null;
0236:                this .itemLabelGeneratorList = new ObjectList();
0237:                this .toolTipGenerator = null;
0238:                this .toolTipGeneratorList = new ObjectList();
0239:                this .urlGenerator = null;
0240:                this .backgroundAnnotations = new java.util.ArrayList();
0241:                this .foregroundAnnotations = new java.util.ArrayList();
0242:                this .defaultEntityRadius = 3;
0243:                this .legendItemLabelGenerator = new StandardXYSeriesLabelGenerator(
0244:                        "{0}");
0245:            }
0246:
0247:            /**
0248:             * Returns the number of passes through the data that the renderer requires
0249:             * in order to draw the chart.  Most charts will require a single pass, but
0250:             * some require two passes.
0251:             *
0252:             * @return The pass count.
0253:             */
0254:            public int getPassCount() {
0255:                return 1;
0256:            }
0257:
0258:            /**
0259:             * Returns the plot that the renderer is assigned to.
0260:             *
0261:             * @return The plot (possibly <code>null</code>).
0262:             */
0263:            public XYPlot getPlot() {
0264:                return this .plot;
0265:            }
0266:
0267:            /**
0268:             * Sets the plot that the renderer is assigned to.
0269:             *
0270:             * @param plot  the plot (<code>null</code> permitted).
0271:             */
0272:            public void setPlot(XYPlot plot) {
0273:                this .plot = plot;
0274:            }
0275:
0276:            /**
0277:             * Initialises the renderer and returns a state object that should be
0278:             * passed to all subsequent calls to the drawItem() method.
0279:             * <P>
0280:             * This method will be called before the first item is rendered, giving the
0281:             * renderer an opportunity to initialise any state information it wants to
0282:             * maintain.  The renderer can do nothing if it chooses.
0283:             *
0284:             * @param g2  the graphics device.
0285:             * @param dataArea  the area inside the axes.
0286:             * @param plot  the plot.
0287:             * @param data  the data.
0288:             * @param info  an optional info collection object to return data back to
0289:             *              the caller.
0290:             *
0291:             * @return The renderer state (never <code>null</code>).
0292:             */
0293:            public XYItemRendererState initialise(Graphics2D g2,
0294:                    Rectangle2D dataArea, XYPlot plot, XYDataset data,
0295:                    PlotRenderingInfo info) {
0296:
0297:                XYItemRendererState state = new XYItemRendererState(info);
0298:                return state;
0299:
0300:            }
0301:
0302:            // ITEM LABEL GENERATOR
0303:
0304:            /**
0305:             * Returns the label generator for a data item.  This implementation simply
0306:             * passes control to the {@link #getSeriesItemLabelGenerator(int)} method.
0307:             * If, for some reason, you want a different generator for individual
0308:             * items, you can override this method.
0309:             *
0310:             * @param series  the series index (zero based).
0311:             * @param item  the item index (zero based).
0312:             *
0313:             * @return The generator (possibly <code>null</code>).
0314:             */
0315:            public XYItemLabelGenerator getItemLabelGenerator(int series,
0316:                    int item) {
0317:                // return the generator for ALL series, if there is one...
0318:                if (this .itemLabelGenerator != null) {
0319:                    return this .itemLabelGenerator;
0320:                }
0321:
0322:                // otherwise look up the generator table
0323:                XYItemLabelGenerator generator = (XYItemLabelGenerator) this .itemLabelGeneratorList
0324:                        .get(series);
0325:                if (generator == null) {
0326:                    generator = this .baseItemLabelGenerator;
0327:                }
0328:                return generator;
0329:            }
0330:
0331:            /**
0332:             * Returns the item label generator for a series.
0333:             *
0334:             * @param series  the series index (zero based).
0335:             *
0336:             * @return The generator (possibly <code>null</code>).
0337:             */
0338:            public XYItemLabelGenerator getSeriesItemLabelGenerator(int series) {
0339:                return (XYItemLabelGenerator) this .itemLabelGeneratorList
0340:                        .get(series);
0341:            }
0342:
0343:            /**
0344:             * Returns the item label generator override.
0345:             * 
0346:             * @return The generator (possibly <code>null</code>).
0347:             * 
0348:             * @since 1.0.5
0349:             * 
0350:             * @see #setItemLabelGenerator(XYItemLabelGenerator)
0351:             * 
0352:             * @deprecated As of version 1.0.6, this override setting should not be
0353:             *     used.  You can use the base setting instead 
0354:             *     ({@link #getBaseItemLabelGenerator()}).
0355:             */
0356:            public XYItemLabelGenerator getItemLabelGenerator() {
0357:                return this .itemLabelGenerator;
0358:            }
0359:
0360:            /**
0361:             * Sets the item label generator for ALL series and sends a
0362:             * {@link RendererChangeEvent} to all registered listeners.
0363:             *
0364:             * @param generator  the generator (<code>null</code> permitted).
0365:             * 
0366:             * @see #getItemLabelGenerator()
0367:             * 
0368:             * @deprecated As of version 1.0.6, this override setting should not be
0369:             *     used.  You can use the base setting instead 
0370:             *     ({@link #setBaseItemLabelGenerator(XYItemLabelGenerator)}).
0371:             */
0372:            public void setItemLabelGenerator(XYItemLabelGenerator generator) {
0373:                this .itemLabelGenerator = generator;
0374:                notifyListeners(new RendererChangeEvent(this ));
0375:            }
0376:
0377:            /**
0378:             * Sets the item label generator for a series and sends a
0379:             * {@link RendererChangeEvent} to all registered listeners.
0380:             *
0381:             * @param series  the series index (zero based).
0382:             * @param generator  the generator (<code>null</code> permitted).
0383:             */
0384:            public void setSeriesItemLabelGenerator(int series,
0385:                    XYItemLabelGenerator generator) {
0386:                this .itemLabelGeneratorList.set(series, generator);
0387:                notifyListeners(new RendererChangeEvent(this ));
0388:            }
0389:
0390:            /**
0391:             * Returns the base item label generator.
0392:             *
0393:             * @return The generator (possibly <code>null</code>).
0394:             */
0395:            public XYItemLabelGenerator getBaseItemLabelGenerator() {
0396:                return this .baseItemLabelGenerator;
0397:            }
0398:
0399:            /**
0400:             * Sets the base item label generator and sends a
0401:             * {@link RendererChangeEvent} to all registered listeners.
0402:             *
0403:             * @param generator  the generator (<code>null</code> permitted).
0404:             */
0405:            public void setBaseItemLabelGenerator(XYItemLabelGenerator generator) {
0406:                this .baseItemLabelGenerator = generator;
0407:                notifyListeners(new RendererChangeEvent(this ));
0408:            }
0409:
0410:            // TOOL TIP GENERATOR
0411:
0412:            /**
0413:             * Returns the tool tip generator for a data item.  If, for some reason, 
0414:             * you want a different generator for individual items, you can override 
0415:             * this method.
0416:             *
0417:             * @param series  the series index (zero based).
0418:             * @param item  the item index (zero based).
0419:             *
0420:             * @return The generator (possibly <code>null</code>).
0421:             */
0422:            public XYToolTipGenerator getToolTipGenerator(int series, int item) {
0423:                // return the generator for ALL series, if there is one...
0424:                if (this .toolTipGenerator != null) {
0425:                    return this .toolTipGenerator;
0426:                }
0427:
0428:                // otherwise look up the generator table
0429:                XYToolTipGenerator generator = (XYToolTipGenerator) this .toolTipGeneratorList
0430:                        .get(series);
0431:                if (generator == null) {
0432:                    generator = this .baseToolTipGenerator;
0433:                }
0434:                return generator;
0435:            }
0436:
0437:            /**
0438:             * Returns the override tool tip generator.
0439:             * 
0440:             * @return The tool tip generator (possible <code>null</code>).
0441:             * 
0442:             * @since 1.0.5
0443:             * 
0444:             * @see #setToolTipGenerator(XYToolTipGenerator)
0445:             * 
0446:             * @deprecated As of version 1.0.6, this override setting should not be
0447:             *     used.  You can use the base setting instead 
0448:             *     ({@link #getBaseToolTipGenerator()}).
0449:             */
0450:            public XYToolTipGenerator getToolTipGenerator() {
0451:                return this .toolTipGenerator;
0452:            }
0453:
0454:            /**
0455:             * Sets the tool tip generator for ALL series and sends a
0456:             * {@link RendererChangeEvent} to all registered listeners.
0457:             *
0458:             * @param generator  the generator (<code>null</code> permitted).
0459:             * 
0460:             * @see #getToolTipGenerator()
0461:             * 
0462:             * @deprecated As of version 1.0.6, this override setting should not be
0463:             *     used.  You can use the base setting instead 
0464:             *     ({@link #setBaseToolTipGenerator(XYToolTipGenerator)}).
0465:             */
0466:            public void setToolTipGenerator(XYToolTipGenerator generator) {
0467:                this .toolTipGenerator = generator;
0468:                notifyListeners(new RendererChangeEvent(this ));
0469:            }
0470:
0471:            /**
0472:             * Returns the tool tip generator for a series.
0473:             *
0474:             * @param series  the series index (zero based).
0475:             *
0476:             * @return The generator (possibly <code>null</code>).
0477:             */
0478:            public XYToolTipGenerator getSeriesToolTipGenerator(int series) {
0479:                return (XYToolTipGenerator) this .toolTipGeneratorList
0480:                        .get(series);
0481:            }
0482:
0483:            /**
0484:             * Sets the tool tip generator for a series and sends a
0485:             * {@link RendererChangeEvent} to all registered listeners.
0486:             *
0487:             * @param series  the series index (zero based).
0488:             * @param generator  the generator (<code>null</code> permitted).
0489:             */
0490:            public void setSeriesToolTipGenerator(int series,
0491:                    XYToolTipGenerator generator) {
0492:                this .toolTipGeneratorList.set(series, generator);
0493:                notifyListeners(new RendererChangeEvent(this ));
0494:            }
0495:
0496:            /**
0497:             * Returns the base tool tip generator.
0498:             *
0499:             * @return The generator (possibly <code>null</code>).
0500:             * 
0501:             * @see #setBaseToolTipGenerator(XYToolTipGenerator)
0502:             */
0503:            public XYToolTipGenerator getBaseToolTipGenerator() {
0504:                return this .baseToolTipGenerator;
0505:            }
0506:
0507:            /**
0508:             * Sets the base tool tip generator and sends a {@link RendererChangeEvent}
0509:             * to all registered listeners.
0510:             *
0511:             * @param generator  the generator (<code>null</code> permitted).
0512:             * 
0513:             * @see #getBaseToolTipGenerator()
0514:             */
0515:            public void setBaseToolTipGenerator(XYToolTipGenerator generator) {
0516:                this .baseToolTipGenerator = generator;
0517:                notifyListeners(new RendererChangeEvent(this ));
0518:            }
0519:
0520:            // URL GENERATOR
0521:
0522:            /**
0523:             * Returns the URL generator for HTML image maps.
0524:             *
0525:             * @return The URL generator (possibly <code>null</code>).
0526:             */
0527:            public XYURLGenerator getURLGenerator() {
0528:                return this .urlGenerator;
0529:            }
0530:
0531:            /**
0532:             * Sets the URL generator for HTML image maps.
0533:             *
0534:             * @param urlGenerator  the URL generator (<code>null</code> permitted).
0535:             */
0536:            public void setURLGenerator(XYURLGenerator urlGenerator) {
0537:                this .urlGenerator = urlGenerator;
0538:                notifyListeners(new RendererChangeEvent(this ));
0539:            }
0540:
0541:            /**
0542:             * Adds an annotation and sends a {@link RendererChangeEvent} to all
0543:             * registered listeners.  The annotation is added to the foreground
0544:             * layer.
0545:             *
0546:             * @param annotation  the annotation (<code>null</code> not permitted).
0547:             */
0548:            public void addAnnotation(XYAnnotation annotation) {
0549:                // defer argument checking
0550:                addAnnotation(annotation, Layer.FOREGROUND);
0551:            }
0552:
0553:            /**
0554:             * Adds an annotation to the specified layer.
0555:             *
0556:             * @param annotation  the annotation (<code>null</code> not permitted).
0557:             * @param layer  the layer (<code>null</code> not permitted).
0558:             */
0559:            public void addAnnotation(XYAnnotation annotation, Layer layer) {
0560:                if (annotation == null) {
0561:                    throw new IllegalArgumentException(
0562:                            "Null 'annotation' argument.");
0563:                }
0564:                if (layer.equals(Layer.FOREGROUND)) {
0565:                    this .foregroundAnnotations.add(annotation);
0566:                    notifyListeners(new RendererChangeEvent(this ));
0567:                } else if (layer.equals(Layer.BACKGROUND)) {
0568:                    this .backgroundAnnotations.add(annotation);
0569:                    notifyListeners(new RendererChangeEvent(this ));
0570:                } else {
0571:                    // should never get here
0572:                    throw new RuntimeException("Unknown layer.");
0573:                }
0574:            }
0575:
0576:            /**
0577:             * Removes the specified annotation and sends a {@link RendererChangeEvent}
0578:             * to all registered listeners.
0579:             *
0580:             * @param annotation  the annotation to remove (<code>null</code> not
0581:             *                    permitted).
0582:             *
0583:             * @return A boolean to indicate whether or not the annotation was
0584:             *         successfully removed.
0585:             */
0586:            public boolean removeAnnotation(XYAnnotation annotation) {
0587:                boolean removed = this .foregroundAnnotations.remove(annotation);
0588:                removed = removed
0589:                        & this .backgroundAnnotations.remove(annotation);
0590:                notifyListeners(new RendererChangeEvent(this ));
0591:                return removed;
0592:            }
0593:
0594:            /**
0595:             * Removes all annotations and sends a {@link RendererChangeEvent}
0596:             * to all registered listeners.
0597:             */
0598:            public void removeAnnotations() {
0599:                this .foregroundAnnotations.clear();
0600:                this .backgroundAnnotations.clear();
0601:                notifyListeners(new RendererChangeEvent(this ));
0602:            }
0603:
0604:            /**
0605:             * Returns the radius of the circle used for the default entity area
0606:             * when no area is specified.
0607:             *
0608:             * @return A radius.
0609:             */
0610:            public int getDefaultEntityRadius() {
0611:                return this .defaultEntityRadius;
0612:            }
0613:
0614:            /**
0615:             * Sets the radius of the circle used for the default entity area
0616:             * when no area is specified.
0617:             *
0618:             * @param radius  the radius.
0619:             */
0620:            public void setDefaultEntityRadius(int radius) {
0621:                this .defaultEntityRadius = radius;
0622:            }
0623:
0624:            /**
0625:             * Returns the legend item label generator.
0626:             *
0627:             * @return The label generator (never <code>null</code>).
0628:             *
0629:             * @see #setLegendItemLabelGenerator(XYSeriesLabelGenerator)
0630:             */
0631:            public XYSeriesLabelGenerator getLegendItemLabelGenerator() {
0632:                return this .legendItemLabelGenerator;
0633:            }
0634:
0635:            /**
0636:             * Sets the legend item label generator and sends a
0637:             * {@link RendererChangeEvent} to all registered listeners.
0638:             *
0639:             * @param generator  the generator (<code>null</code> not permitted).
0640:             *
0641:             * @see #getLegendItemLabelGenerator()
0642:             */
0643:            public void setLegendItemLabelGenerator(
0644:                    XYSeriesLabelGenerator generator) {
0645:                if (generator == null) {
0646:                    throw new IllegalArgumentException(
0647:                            "Null 'generator' argument.");
0648:                }
0649:                this .legendItemLabelGenerator = generator;
0650:                notifyListeners(new RendererChangeEvent(this ));
0651:            }
0652:
0653:            /**
0654:             * Returns the legend item tool tip generator.
0655:             *
0656:             * @return The tool tip generator (possibly <code>null</code>).
0657:             *
0658:             * @see #setLegendItemToolTipGenerator(XYSeriesLabelGenerator)
0659:             */
0660:            public XYSeriesLabelGenerator getLegendItemToolTipGenerator() {
0661:                return this .legendItemToolTipGenerator;
0662:            }
0663:
0664:            /**
0665:             * Sets the legend item tool tip generator and sends a
0666:             * {@link RendererChangeEvent} to all registered listeners.
0667:             *
0668:             * @param generator  the generator (<code>null</code> permitted).
0669:             *
0670:             * @see #getLegendItemToolTipGenerator()
0671:             */
0672:            public void setLegendItemToolTipGenerator(
0673:                    XYSeriesLabelGenerator generator) {
0674:                this .legendItemToolTipGenerator = generator;
0675:                notifyListeners(new RendererChangeEvent(this ));
0676:            }
0677:
0678:            /**
0679:             * Returns the legend item URL generator.
0680:             *
0681:             * @return The URL generator (possibly <code>null</code>).
0682:             *
0683:             * @see #setLegendItemURLGenerator(XYSeriesLabelGenerator)
0684:             */
0685:            public XYSeriesLabelGenerator getLegendItemURLGenerator() {
0686:                return this .legendItemURLGenerator;
0687:            }
0688:
0689:            /**
0690:             * Sets the legend item URL generator and sends a
0691:             * {@link RendererChangeEvent} to all registered listeners.
0692:             *
0693:             * @param generator  the generator (<code>null</code> permitted).
0694:             *
0695:             * @see #getLegendItemURLGenerator()
0696:             */
0697:            public void setLegendItemURLGenerator(
0698:                    XYSeriesLabelGenerator generator) {
0699:                this .legendItemURLGenerator = generator;
0700:                notifyListeners(new RendererChangeEvent(this ));
0701:            }
0702:
0703:            /**
0704:             * Returns the lower and upper bounds (range) of the x-values in the
0705:             * specified dataset.
0706:             *
0707:             * @param dataset  the dataset (<code>null</code> permitted).
0708:             *
0709:             * @return The range (<code>null</code> if the dataset is <code>null</code>
0710:             *         or empty).
0711:             */
0712:            public Range findDomainBounds(XYDataset dataset) {
0713:                if (dataset != null) {
0714:                    return DatasetUtilities.findDomainBounds(dataset, false);
0715:                } else {
0716:                    return null;
0717:                }
0718:            }
0719:
0720:            /**
0721:             * Returns the range of values the renderer requires to display all the
0722:             * items from the specified dataset.
0723:             *
0724:             * @param dataset  the dataset (<code>null</code> permitted).
0725:             *
0726:             * @return The range (<code>null</code> if the dataset is <code>null</code>
0727:             *         or empty).
0728:             */
0729:            public Range findRangeBounds(XYDataset dataset) {
0730:                if (dataset != null) {
0731:                    return DatasetUtilities.findRangeBounds(dataset, false);
0732:                } else {
0733:                    return null;
0734:                }
0735:            }
0736:
0737:            /**
0738:             * Returns a (possibly empty) collection of legend items for the series
0739:             * that this renderer is responsible for drawing.
0740:             *
0741:             * @return The legend item collection (never <code>null</code>).
0742:             */
0743:            public LegendItemCollection getLegendItems() {
0744:                if (this .plot == null) {
0745:                    return new LegendItemCollection();
0746:                }
0747:                LegendItemCollection result = new LegendItemCollection();
0748:                int index = this .plot.getIndexOf(this );
0749:                XYDataset dataset = this .plot.getDataset(index);
0750:                if (dataset != null) {
0751:                    int seriesCount = dataset.getSeriesCount();
0752:                    for (int i = 0; i < seriesCount; i++) {
0753:                        if (isSeriesVisibleInLegend(i)) {
0754:                            LegendItem item = getLegendItem(index, i);
0755:                            if (item != null) {
0756:                                result.add(item);
0757:                            }
0758:                        }
0759:                    }
0760:
0761:                }
0762:                return result;
0763:            }
0764:
0765:            /**
0766:             * Returns a default legend item for the specified series.  Subclasses
0767:             * should override this method to generate customised items.
0768:             *
0769:             * @param datasetIndex  the dataset index (zero-based).
0770:             * @param series  the series index (zero-based).
0771:             *
0772:             * @return A legend item for the series.
0773:             */
0774:            public LegendItem getLegendItem(int datasetIndex, int series) {
0775:                LegendItem result = null;
0776:                XYPlot xyplot = getPlot();
0777:                if (xyplot != null) {
0778:                    XYDataset dataset = xyplot.getDataset(datasetIndex);
0779:                    if (dataset != null) {
0780:                        String label = this .legendItemLabelGenerator
0781:                                .generateLabel(dataset, series);
0782:                        String description = label;
0783:                        String toolTipText = null;
0784:                        if (getLegendItemToolTipGenerator() != null) {
0785:                            toolTipText = getLegendItemToolTipGenerator()
0786:                                    .generateLabel(dataset, series);
0787:                        }
0788:                        String urlText = null;
0789:                        if (getLegendItemURLGenerator() != null) {
0790:                            urlText = getLegendItemURLGenerator()
0791:                                    .generateLabel(dataset, series);
0792:                        }
0793:                        Shape shape = lookupSeriesShape(series);
0794:                        Paint paint = lookupSeriesPaint(series);
0795:                        Paint outlinePaint = lookupSeriesOutlinePaint(series);
0796:                        Stroke outlineStroke = lookupSeriesOutlineStroke(series);
0797:                        result = new LegendItem(label, description,
0798:                                toolTipText, urlText, shape, paint,
0799:                                outlineStroke, outlinePaint);
0800:                        result.setSeriesKey(dataset.getSeriesKey(series));
0801:                        result.setSeriesIndex(series);
0802:                        result.setDataset(dataset);
0803:                        result.setDatasetIndex(datasetIndex);
0804:                    }
0805:                }
0806:                return result;
0807:            }
0808:
0809:            /**
0810:             * Fills a band between two values on the axis.  This can be used to color
0811:             * bands between the grid lines.
0812:             *
0813:             * @param g2  the graphics device.
0814:             * @param plot  the plot.
0815:             * @param axis  the domain axis.
0816:             * @param dataArea  the data area.
0817:             * @param start  the start value.
0818:             * @param end  the end value.
0819:             */
0820:            public void fillDomainGridBand(Graphics2D g2, XYPlot plot,
0821:                    ValueAxis axis, Rectangle2D dataArea, double start,
0822:                    double end) {
0823:
0824:                double x1 = axis.valueToJava2D(start, dataArea, plot
0825:                        .getDomainAxisEdge());
0826:                double x2 = axis.valueToJava2D(end, dataArea, plot
0827:                        .getDomainAxisEdge());
0828:                // TODO: need to change the next line to take account of plot
0829:                //       orientation...
0830:                Rectangle2D band = new Rectangle2D.Double(x1, dataArea
0831:                        .getMinY(), x2 - x1, dataArea.getMaxY()
0832:                        - dataArea.getMinY());
0833:                Paint paint = plot.getDomainTickBandPaint();
0834:
0835:                if (paint != null) {
0836:                    g2.setPaint(paint);
0837:                    g2.fill(band);
0838:                }
0839:
0840:            }
0841:
0842:            /**
0843:             * Fills a band between two values on the range axis.  This can be used to
0844:             * color bands between the grid lines.
0845:             *
0846:             * @param g2  the graphics device.
0847:             * @param plot  the plot.
0848:             * @param axis  the range axis.
0849:             * @param dataArea  the data area.
0850:             * @param start  the start value.
0851:             * @param end  the end value.
0852:             */
0853:            public void fillRangeGridBand(Graphics2D g2, XYPlot plot,
0854:                    ValueAxis axis, Rectangle2D dataArea, double start,
0855:                    double end) {
0856:
0857:                double y1 = axis.valueToJava2D(start, dataArea, plot
0858:                        .getRangeAxisEdge());
0859:                double y2 = axis.valueToJava2D(end, dataArea, plot
0860:                        .getRangeAxisEdge());
0861:                // TODO: need to change the next line to take account of the plot
0862:                //       orientation
0863:                Rectangle2D band = new Rectangle2D.Double(dataArea.getMinX(),
0864:                        y2, dataArea.getWidth(), y1 - y2);
0865:                Paint paint = plot.getRangeTickBandPaint();
0866:
0867:                if (paint != null) {
0868:                    g2.setPaint(paint);
0869:                    g2.fill(band);
0870:                }
0871:
0872:            }
0873:
0874:            /**
0875:             * Draws a grid line against the range axis.
0876:             *
0877:             * @param g2  the graphics device.
0878:             * @param plot  the plot.
0879:             * @param axis  the value axis.
0880:             * @param dataArea  the area for plotting data (not yet adjusted for any
0881:             *                  3D effect).
0882:             * @param value  the value at which the grid line should be drawn.
0883:             */
0884:            public void drawDomainGridLine(Graphics2D g2, XYPlot plot,
0885:                    ValueAxis axis, Rectangle2D dataArea, double value) {
0886:
0887:                Range range = axis.getRange();
0888:                if (!range.contains(value)) {
0889:                    return;
0890:                }
0891:
0892:                PlotOrientation orientation = plot.getOrientation();
0893:                double v = axis.valueToJava2D(value, dataArea, plot
0894:                        .getDomainAxisEdge());
0895:                Line2D line = null;
0896:                if (orientation == PlotOrientation.HORIZONTAL) {
0897:                    line = new Line2D.Double(dataArea.getMinX(), v, dataArea
0898:                            .getMaxX(), v);
0899:                } else if (orientation == PlotOrientation.VERTICAL) {
0900:                    line = new Line2D.Double(v, dataArea.getMinY(), v, dataArea
0901:                            .getMaxY());
0902:                }
0903:
0904:                Paint paint = plot.getDomainGridlinePaint();
0905:                Stroke stroke = plot.getDomainGridlineStroke();
0906:                g2.setPaint(paint != null ? paint : Plot.DEFAULT_OUTLINE_PAINT);
0907:                g2.setStroke(stroke != null ? stroke
0908:                        : Plot.DEFAULT_OUTLINE_STROKE);
0909:                g2.draw(line);
0910:
0911:            }
0912:
0913:            /**
0914:             * Draws a line perpendicular to the domain axis.
0915:             *
0916:             * @param g2  the graphics device.
0917:             * @param plot  the plot.
0918:             * @param axis  the value axis.
0919:             * @param dataArea  the area for plotting data (not yet adjusted for any 3D
0920:             *                  effect).
0921:             * @param value  the value at which the grid line should be drawn.
0922:             * @param paint  the paint.
0923:             * @param stroke  the stroke.
0924:             * 
0925:             * @since 1.0.5
0926:             */
0927:            public void drawDomainLine(Graphics2D g2, XYPlot plot,
0928:                    ValueAxis axis, Rectangle2D dataArea, double value,
0929:                    Paint paint, Stroke stroke) {
0930:
0931:                Range range = axis.getRange();
0932:                if (!range.contains(value)) {
0933:                    return;
0934:                }
0935:
0936:                PlotOrientation orientation = plot.getOrientation();
0937:                Line2D line = null;
0938:                double v = axis.valueToJava2D(value, dataArea, plot
0939:                        .getDomainAxisEdge());
0940:                if (orientation == PlotOrientation.HORIZONTAL) {
0941:                    line = new Line2D.Double(dataArea.getMinX(), v, dataArea
0942:                            .getMaxX(), v);
0943:                } else if (orientation == PlotOrientation.VERTICAL) {
0944:                    line = new Line2D.Double(v, dataArea.getMinY(), v, dataArea
0945:                            .getMaxY());
0946:                }
0947:
0948:                g2.setPaint(paint);
0949:                g2.setStroke(stroke);
0950:                g2.draw(line);
0951:
0952:            }
0953:
0954:            /**
0955:             * Draws a line perpendicular to the range axis.
0956:             *
0957:             * @param g2  the graphics device.
0958:             * @param plot  the plot.
0959:             * @param axis  the value axis.
0960:             * @param dataArea  the area for plotting data (not yet adjusted for any 3D
0961:             *                  effect).
0962:             * @param value  the value at which the grid line should be drawn.
0963:             * @param paint  the paint.
0964:             * @param stroke  the stroke.
0965:             */
0966:            public void drawRangeLine(Graphics2D g2, XYPlot plot,
0967:                    ValueAxis axis, Rectangle2D dataArea, double value,
0968:                    Paint paint, Stroke stroke) {
0969:
0970:                Range range = axis.getRange();
0971:                if (!range.contains(value)) {
0972:                    return;
0973:                }
0974:
0975:                PlotOrientation orientation = plot.getOrientation();
0976:                Line2D line = null;
0977:                double v = axis.valueToJava2D(value, dataArea, plot
0978:                        .getRangeAxisEdge());
0979:                if (orientation == PlotOrientation.HORIZONTAL) {
0980:                    line = new Line2D.Double(v, dataArea.getMinY(), v, dataArea
0981:                            .getMaxY());
0982:                } else if (orientation == PlotOrientation.VERTICAL) {
0983:                    line = new Line2D.Double(dataArea.getMinX(), v, dataArea
0984:                            .getMaxX(), v);
0985:                }
0986:
0987:                g2.setPaint(paint);
0988:                g2.setStroke(stroke);
0989:                g2.draw(line);
0990:
0991:            }
0992:
0993:            /**
0994:             * Draws a vertical line on the chart to represent a 'range marker'.
0995:             *
0996:             * @param g2  the graphics device.
0997:             * @param plot  the plot.
0998:             * @param domainAxis  the domain axis.
0999:             * @param marker  the marker line.
1000:             * @param dataArea  the axis data area.
1001:             */
1002:            public void drawDomainMarker(Graphics2D g2, XYPlot plot,
1003:                    ValueAxis domainAxis, Marker marker, Rectangle2D dataArea) {
1004:
1005:                if (marker instanceof  ValueMarker) {
1006:                    ValueMarker vm = (ValueMarker) marker;
1007:                    double value = vm.getValue();
1008:                    Range range = domainAxis.getRange();
1009:                    if (!range.contains(value)) {
1010:                        return;
1011:                    }
1012:
1013:                    double v = domainAxis.valueToJava2D(value, dataArea, plot
1014:                            .getDomainAxisEdge());
1015:
1016:                    PlotOrientation orientation = plot.getOrientation();
1017:                    Line2D line = null;
1018:                    if (orientation == PlotOrientation.HORIZONTAL) {
1019:                        line = new Line2D.Double(dataArea.getMinX(), v,
1020:                                dataArea.getMaxX(), v);
1021:                    } else if (orientation == PlotOrientation.VERTICAL) {
1022:                        line = new Line2D.Double(v, dataArea.getMinY(), v,
1023:                                dataArea.getMaxY());
1024:                    }
1025:
1026:                    final Composite originalComposite = g2.getComposite();
1027:                    g2.setComposite(AlphaComposite.getInstance(
1028:                            AlphaComposite.SRC_OVER, marker.getAlpha()));
1029:                    g2.setPaint(marker.getPaint());
1030:                    g2.setStroke(marker.getStroke());
1031:                    g2.draw(line);
1032:
1033:                    String label = marker.getLabel();
1034:                    RectangleAnchor anchor = marker.getLabelAnchor();
1035:                    if (label != null) {
1036:                        Font labelFont = marker.getLabelFont();
1037:                        g2.setFont(labelFont);
1038:                        g2.setPaint(marker.getLabelPaint());
1039:                        Point2D coordinates = calculateDomainMarkerTextAnchorPoint(
1040:                                g2, orientation, dataArea, line.getBounds2D(),
1041:                                marker.getLabelOffset(),
1042:                                LengthAdjustmentType.EXPAND, anchor);
1043:                        TextUtilities.drawAlignedString(label, g2,
1044:                                (float) coordinates.getX(), (float) coordinates
1045:                                        .getY(), marker.getLabelTextAnchor());
1046:                    }
1047:                    g2.setComposite(originalComposite);
1048:                } else if (marker instanceof  IntervalMarker) {
1049:                    IntervalMarker im = (IntervalMarker) marker;
1050:                    double start = im.getStartValue();
1051:                    double end = im.getEndValue();
1052:                    Range range = domainAxis.getRange();
1053:                    if (!(range.intersects(start, end))) {
1054:                        return;
1055:                    }
1056:
1057:                    double start2d = domainAxis.valueToJava2D(start, dataArea,
1058:                            plot.getDomainAxisEdge());
1059:                    double end2d = domainAxis.valueToJava2D(end, dataArea, plot
1060:                            .getDomainAxisEdge());
1061:                    double low = Math.min(start2d, end2d);
1062:                    double high = Math.max(start2d, end2d);
1063:
1064:                    PlotOrientation orientation = plot.getOrientation();
1065:                    Rectangle2D rect = null;
1066:                    if (orientation == PlotOrientation.HORIZONTAL) {
1067:                        // clip top and bottom bounds to data area
1068:                        low = Math.max(low, dataArea.getMinY());
1069:                        high = Math.min(high, dataArea.getMaxY());
1070:                        rect = new Rectangle2D.Double(dataArea.getMinX(), low,
1071:                                dataArea.getWidth(), high - low);
1072:                    } else if (orientation == PlotOrientation.VERTICAL) {
1073:                        // clip left and right bounds to data area
1074:                        low = Math.max(low, dataArea.getMinX());
1075:                        high = Math.min(high, dataArea.getMaxX());
1076:                        rect = new Rectangle2D.Double(low, dataArea.getMinY(),
1077:                                high - low, dataArea.getHeight());
1078:                    }
1079:
1080:                    final Composite originalComposite = g2.getComposite();
1081:                    g2.setComposite(AlphaComposite.getInstance(
1082:                            AlphaComposite.SRC_OVER, marker.getAlpha()));
1083:                    Paint p = marker.getPaint();
1084:                    if (p instanceof  GradientPaint) {
1085:                        GradientPaint gp = (GradientPaint) p;
1086:                        GradientPaintTransformer t = im
1087:                                .getGradientPaintTransformer();
1088:                        if (t != null) {
1089:                            gp = t.transform(gp, rect);
1090:                        }
1091:                        g2.setPaint(gp);
1092:                    } else {
1093:                        g2.setPaint(p);
1094:                    }
1095:                    g2.fill(rect);
1096:
1097:                    // now draw the outlines, if visible...
1098:                    if (im.getOutlinePaint() != null
1099:                            && im.getOutlineStroke() != null) {
1100:                        if (orientation == PlotOrientation.VERTICAL) {
1101:                            Line2D line = new Line2D.Double();
1102:                            double y0 = dataArea.getMinY();
1103:                            double y1 = dataArea.getMaxY();
1104:                            g2.setPaint(im.getOutlinePaint());
1105:                            g2.setStroke(im.getOutlineStroke());
1106:                            if (range.contains(start)) {
1107:                                line.setLine(start2d, y0, start2d, y1);
1108:                                g2.draw(line);
1109:                            }
1110:                            if (range.contains(end)) {
1111:                                line.setLine(end2d, y0, end2d, y1);
1112:                                g2.draw(line);
1113:                            }
1114:                        } else { // PlotOrientation.HORIZONTAL
1115:                            Line2D line = new Line2D.Double();
1116:                            double x0 = dataArea.getMinX();
1117:                            double x1 = dataArea.getMaxX();
1118:                            g2.setPaint(im.getOutlinePaint());
1119:                            g2.setStroke(im.getOutlineStroke());
1120:                            if (range.contains(start)) {
1121:                                line.setLine(x0, start2d, x1, start2d);
1122:                                g2.draw(line);
1123:                            }
1124:                            if (range.contains(end)) {
1125:                                line.setLine(x0, end2d, x1, end2d);
1126:                                g2.draw(line);
1127:                            }
1128:                        }
1129:                    }
1130:
1131:                    String label = marker.getLabel();
1132:                    RectangleAnchor anchor = marker.getLabelAnchor();
1133:                    if (label != null) {
1134:                        Font labelFont = marker.getLabelFont();
1135:                        g2.setFont(labelFont);
1136:                        g2.setPaint(marker.getLabelPaint());
1137:                        Point2D coordinates = calculateDomainMarkerTextAnchorPoint(
1138:                                g2, orientation, dataArea, rect, marker
1139:                                        .getLabelOffset(), marker
1140:                                        .getLabelOffsetType(), anchor);
1141:                        TextUtilities.drawAlignedString(label, g2,
1142:                                (float) coordinates.getX(), (float) coordinates
1143:                                        .getY(), marker.getLabelTextAnchor());
1144:                    }
1145:                    g2.setComposite(originalComposite);
1146:
1147:                }
1148:
1149:            }
1150:
1151:            /**
1152:             * Calculates the (x, y) coordinates for drawing a marker label.
1153:             *
1154:             * @param g2  the graphics device.
1155:             * @param orientation  the plot orientation.
1156:             * @param dataArea  the data area.
1157:             * @param markerArea  the rectangle surrounding the marker area.
1158:             * @param markerOffset  the marker label offset.
1159:             * @param labelOffsetType  the label offset type.
1160:             * @param anchor  the label anchor.
1161:             *
1162:             * @return The coordinates for drawing the marker label.
1163:             */
1164:            protected Point2D calculateDomainMarkerTextAnchorPoint(
1165:                    Graphics2D g2, PlotOrientation orientation,
1166:                    Rectangle2D dataArea, Rectangle2D markerArea,
1167:                    RectangleInsets markerOffset,
1168:                    LengthAdjustmentType labelOffsetType, RectangleAnchor anchor) {
1169:
1170:                Rectangle2D anchorRect = null;
1171:                if (orientation == PlotOrientation.HORIZONTAL) {
1172:                    anchorRect = markerOffset.createAdjustedRectangle(
1173:                            markerArea, LengthAdjustmentType.CONTRACT,
1174:                            labelOffsetType);
1175:                } else if (orientation == PlotOrientation.VERTICAL) {
1176:                    anchorRect = markerOffset.createAdjustedRectangle(
1177:                            markerArea, labelOffsetType,
1178:                            LengthAdjustmentType.CONTRACT);
1179:                }
1180:                return RectangleAnchor.coordinates(anchorRect, anchor);
1181:
1182:            }
1183:
1184:            /**
1185:             * Draws a horizontal line across the chart to represent a 'range marker'.
1186:             *
1187:             * @param g2  the graphics device.
1188:             * @param plot  the plot.
1189:             * @param rangeAxis  the range axis.
1190:             * @param marker  the marker line.
1191:             * @param dataArea  the axis data area.
1192:             */
1193:            public void drawRangeMarker(Graphics2D g2, XYPlot plot,
1194:                    ValueAxis rangeAxis, Marker marker, Rectangle2D dataArea) {
1195:
1196:                if (marker instanceof  ValueMarker) {
1197:                    ValueMarker vm = (ValueMarker) marker;
1198:                    double value = vm.getValue();
1199:                    Range range = rangeAxis.getRange();
1200:                    if (!range.contains(value)) {
1201:                        return;
1202:                    }
1203:
1204:                    double v = rangeAxis.valueToJava2D(value, dataArea, plot
1205:                            .getRangeAxisEdge());
1206:                    PlotOrientation orientation = plot.getOrientation();
1207:                    Line2D line = null;
1208:                    if (orientation == PlotOrientation.HORIZONTAL) {
1209:                        line = new Line2D.Double(v, dataArea.getMinY(), v,
1210:                                dataArea.getMaxY());
1211:                    } else if (orientation == PlotOrientation.VERTICAL) {
1212:                        line = new Line2D.Double(dataArea.getMinX(), v,
1213:                                dataArea.getMaxX(), v);
1214:                    }
1215:
1216:                    final Composite originalComposite = g2.getComposite();
1217:                    g2.setComposite(AlphaComposite.getInstance(
1218:                            AlphaComposite.SRC_OVER, marker.getAlpha()));
1219:                    g2.setPaint(marker.getPaint());
1220:                    g2.setStroke(marker.getStroke());
1221:                    g2.draw(line);
1222:
1223:                    String label = marker.getLabel();
1224:                    RectangleAnchor anchor = marker.getLabelAnchor();
1225:                    if (label != null) {
1226:                        Font labelFont = marker.getLabelFont();
1227:                        g2.setFont(labelFont);
1228:                        g2.setPaint(marker.getLabelPaint());
1229:                        Point2D coordinates = calculateRangeMarkerTextAnchorPoint(
1230:                                g2, orientation, dataArea, line.getBounds2D(),
1231:                                marker.getLabelOffset(),
1232:                                LengthAdjustmentType.EXPAND, anchor);
1233:                        TextUtilities.drawAlignedString(label, g2,
1234:                                (float) coordinates.getX(), (float) coordinates
1235:                                        .getY(), marker.getLabelTextAnchor());
1236:                    }
1237:                    g2.setComposite(originalComposite);
1238:                } else if (marker instanceof  IntervalMarker) {
1239:                    IntervalMarker im = (IntervalMarker) marker;
1240:                    double start = im.getStartValue();
1241:                    double end = im.getEndValue();
1242:                    Range range = rangeAxis.getRange();
1243:                    if (!(range.intersects(start, end))) {
1244:                        return;
1245:                    }
1246:
1247:                    double start2d = rangeAxis.valueToJava2D(start, dataArea,
1248:                            plot.getRangeAxisEdge());
1249:                    double end2d = rangeAxis.valueToJava2D(end, dataArea, plot
1250:                            .getRangeAxisEdge());
1251:                    double low = Math.min(start2d, end2d);
1252:                    double high = Math.max(start2d, end2d);
1253:
1254:                    PlotOrientation orientation = plot.getOrientation();
1255:                    Rectangle2D rect = null;
1256:                    if (orientation == PlotOrientation.HORIZONTAL) {
1257:                        // clip left and right bounds to data area
1258:                        low = Math.max(low, dataArea.getMinX());
1259:                        high = Math.min(high, dataArea.getMaxX());
1260:                        rect = new Rectangle2D.Double(low, dataArea.getMinY(),
1261:                                high - low, dataArea.getHeight());
1262:                    } else if (orientation == PlotOrientation.VERTICAL) {
1263:                        // clip top and bottom bounds to data area
1264:                        low = Math.max(low, dataArea.getMinY());
1265:                        high = Math.min(high, dataArea.getMaxY());
1266:                        rect = new Rectangle2D.Double(dataArea.getMinX(), low,
1267:                                dataArea.getWidth(), high - low);
1268:                    }
1269:
1270:                    final Composite originalComposite = g2.getComposite();
1271:                    g2.setComposite(AlphaComposite.getInstance(
1272:                            AlphaComposite.SRC_OVER, marker.getAlpha()));
1273:                    Paint p = marker.getPaint();
1274:                    if (p instanceof  GradientPaint) {
1275:                        GradientPaint gp = (GradientPaint) p;
1276:                        GradientPaintTransformer t = im
1277:                                .getGradientPaintTransformer();
1278:                        if (t != null) {
1279:                            gp = t.transform(gp, rect);
1280:                        }
1281:                        g2.setPaint(gp);
1282:                    } else {
1283:                        g2.setPaint(p);
1284:                    }
1285:                    g2.fill(rect);
1286:
1287:                    // now draw the outlines, if visible...
1288:                    if (im.getOutlinePaint() != null
1289:                            && im.getOutlineStroke() != null) {
1290:                        if (orientation == PlotOrientation.VERTICAL) {
1291:                            Line2D line = new Line2D.Double();
1292:                            double x0 = dataArea.getMinX();
1293:                            double x1 = dataArea.getMaxX();
1294:                            g2.setPaint(im.getOutlinePaint());
1295:                            g2.setStroke(im.getOutlineStroke());
1296:                            if (range.contains(start)) {
1297:                                line.setLine(x0, start2d, x1, start2d);
1298:                                g2.draw(line);
1299:                            }
1300:                            if (range.contains(end)) {
1301:                                line.setLine(x0, end2d, x1, end2d);
1302:                                g2.draw(line);
1303:                            }
1304:                        } else { // PlotOrientation.HORIZONTAL
1305:                            Line2D line = new Line2D.Double();
1306:                            double y0 = dataArea.getMinY();
1307:                            double y1 = dataArea.getMaxY();
1308:                            g2.setPaint(im.getOutlinePaint());
1309:                            g2.setStroke(im.getOutlineStroke());
1310:                            if (range.contains(start)) {
1311:                                line.setLine(start2d, y0, start2d, y1);
1312:                                g2.draw(line);
1313:                            }
1314:                            if (range.contains(end)) {
1315:                                line.setLine(end2d, y0, end2d, y1);
1316:                                g2.draw(line);
1317:                            }
1318:                        }
1319:                    }
1320:
1321:                    String label = marker.getLabel();
1322:                    RectangleAnchor anchor = marker.getLabelAnchor();
1323:                    if (label != null) {
1324:                        Font labelFont = marker.getLabelFont();
1325:                        g2.setFont(labelFont);
1326:                        g2.setPaint(marker.getLabelPaint());
1327:                        Point2D coordinates = calculateRangeMarkerTextAnchorPoint(
1328:                                g2, orientation, dataArea, rect, marker
1329:                                        .getLabelOffset(), marker
1330:                                        .getLabelOffsetType(), anchor);
1331:                        TextUtilities.drawAlignedString(label, g2,
1332:                                (float) coordinates.getX(), (float) coordinates
1333:                                        .getY(), marker.getLabelTextAnchor());
1334:                    }
1335:                    g2.setComposite(originalComposite);
1336:                }
1337:            }
1338:
1339:            /**
1340:             * Calculates the (x, y) coordinates for drawing a marker label.
1341:             *
1342:             * @param g2  the graphics device.
1343:             * @param orientation  the plot orientation.
1344:             * @param dataArea  the data area.
1345:             * @param markerArea  the marker area.
1346:             * @param markerOffset  the marker offset.
1347:             * @param anchor  the label anchor.
1348:             *
1349:             * @return The coordinates for drawing the marker label.
1350:             */
1351:            private Point2D calculateRangeMarkerTextAnchorPoint(Graphics2D g2,
1352:                    PlotOrientation orientation, Rectangle2D dataArea,
1353:                    Rectangle2D markerArea, RectangleInsets markerOffset,
1354:                    LengthAdjustmentType labelOffsetForRange,
1355:                    RectangleAnchor anchor) {
1356:
1357:                Rectangle2D anchorRect = null;
1358:                if (orientation == PlotOrientation.HORIZONTAL) {
1359:                    anchorRect = markerOffset.createAdjustedRectangle(
1360:                            markerArea, labelOffsetForRange,
1361:                            LengthAdjustmentType.CONTRACT);
1362:                } else if (orientation == PlotOrientation.VERTICAL) {
1363:                    anchorRect = markerOffset.createAdjustedRectangle(
1364:                            markerArea, LengthAdjustmentType.CONTRACT,
1365:                            labelOffsetForRange);
1366:                }
1367:                return RectangleAnchor.coordinates(anchorRect, anchor);
1368:
1369:            }
1370:
1371:            /**
1372:             * Returns a clone of the renderer.
1373:             *
1374:             * @return A clone.
1375:             *
1376:             * @throws CloneNotSupportedException if the renderer does not support
1377:             *         cloning.
1378:             */
1379:            protected Object clone() throws CloneNotSupportedException {
1380:                AbstractXYItemRenderer clone = (AbstractXYItemRenderer) super 
1381:                        .clone();
1382:                // 'plot' : just retain reference, not a deep copy
1383:
1384:                if (this .itemLabelGenerator != null
1385:                        && this .itemLabelGenerator instanceof  PublicCloneable) {
1386:                    PublicCloneable pc = (PublicCloneable) this .itemLabelGenerator;
1387:                    clone.itemLabelGenerator = (XYItemLabelGenerator) pc
1388:                            .clone();
1389:                }
1390:                clone.itemLabelGeneratorList = (ObjectList) this .itemLabelGeneratorList
1391:                        .clone();
1392:                if (this .baseItemLabelGenerator != null
1393:                        && this .baseItemLabelGenerator instanceof  PublicCloneable) {
1394:                    PublicCloneable pc = (PublicCloneable) this .baseItemLabelGenerator;
1395:                    clone.baseItemLabelGenerator = (XYItemLabelGenerator) pc
1396:                            .clone();
1397:                }
1398:
1399:                if (this .toolTipGenerator != null
1400:                        && this .toolTipGenerator instanceof  PublicCloneable) {
1401:                    PublicCloneable pc = (PublicCloneable) this .toolTipGenerator;
1402:                    clone.toolTipGenerator = (XYToolTipGenerator) pc.clone();
1403:                }
1404:                clone.toolTipGeneratorList = (ObjectList) this .toolTipGeneratorList
1405:                        .clone();
1406:                if (this .baseToolTipGenerator != null
1407:                        && this .baseToolTipGenerator instanceof  PublicCloneable) {
1408:                    PublicCloneable pc = (PublicCloneable) this .baseToolTipGenerator;
1409:                    clone.baseToolTipGenerator = (XYToolTipGenerator) pc
1410:                            .clone();
1411:                }
1412:
1413:                if (clone.legendItemLabelGenerator instanceof  PublicCloneable) {
1414:                    clone.legendItemLabelGenerator = (XYSeriesLabelGenerator) ObjectUtilities
1415:                            .clone(this .legendItemLabelGenerator);
1416:                }
1417:                if (clone.legendItemToolTipGenerator instanceof  PublicCloneable) {
1418:                    clone.legendItemToolTipGenerator = (XYSeriesLabelGenerator) ObjectUtilities
1419:                            .clone(this .legendItemToolTipGenerator);
1420:                }
1421:                if (clone.legendItemURLGenerator instanceof  PublicCloneable) {
1422:                    clone.legendItemURLGenerator = (XYSeriesLabelGenerator) ObjectUtilities
1423:                            .clone(this .legendItemURLGenerator);
1424:                }
1425:
1426:                clone.foregroundAnnotations = (List) ObjectUtilities
1427:                        .deepClone(this .foregroundAnnotations);
1428:                clone.backgroundAnnotations = (List) ObjectUtilities
1429:                        .deepClone(this .backgroundAnnotations);
1430:
1431:                if (clone.legendItemLabelGenerator instanceof  PublicCloneable) {
1432:                    clone.legendItemLabelGenerator = (XYSeriesLabelGenerator) ObjectUtilities
1433:                            .clone(this .legendItemLabelGenerator);
1434:                }
1435:                if (clone.legendItemToolTipGenerator instanceof  PublicCloneable) {
1436:                    clone.legendItemToolTipGenerator = (XYSeriesLabelGenerator) ObjectUtilities
1437:                            .clone(this .legendItemToolTipGenerator);
1438:                }
1439:                if (clone.legendItemURLGenerator instanceof  PublicCloneable) {
1440:                    clone.legendItemURLGenerator = (XYSeriesLabelGenerator) ObjectUtilities
1441:                            .clone(this .legendItemURLGenerator);
1442:                }
1443:
1444:                return clone;
1445:            }
1446:
1447:            /**
1448:             * Tests this renderer for equality with another object.
1449:             *
1450:             * @param obj  the object (<code>null</code> permitted).
1451:             *
1452:             * @return <code>true</code> or <code>false</code>.
1453:             */
1454:            public boolean equals(Object obj) {
1455:                if (obj == this ) {
1456:                    return true;
1457:                }
1458:                if (!(obj instanceof  AbstractXYItemRenderer)) {
1459:                    return false;
1460:                }
1461:                AbstractXYItemRenderer that = (AbstractXYItemRenderer) obj;
1462:                if (!ObjectUtilities.equal(this .itemLabelGenerator,
1463:                        that.itemLabelGenerator)) {
1464:                    return false;
1465:                }
1466:                if (!this .itemLabelGeneratorList
1467:                        .equals(that.itemLabelGeneratorList)) {
1468:                    return false;
1469:                }
1470:                if (!ObjectUtilities.equal(this .baseItemLabelGenerator,
1471:                        that.baseItemLabelGenerator)) {
1472:                    return false;
1473:                }
1474:                if (!ObjectUtilities.equal(this .toolTipGenerator,
1475:                        that.toolTipGenerator)) {
1476:                    return false;
1477:                }
1478:                if (!this .toolTipGeneratorList
1479:                        .equals(that.toolTipGeneratorList)) {
1480:                    return false;
1481:                }
1482:                if (!ObjectUtilities.equal(this .baseToolTipGenerator,
1483:                        that.baseToolTipGenerator)) {
1484:                    return false;
1485:                }
1486:                if (!ObjectUtilities
1487:                        .equal(this .urlGenerator, that.urlGenerator)) {
1488:                    return false;
1489:                }
1490:                if (!this .foregroundAnnotations
1491:                        .equals(that.foregroundAnnotations)) {
1492:                    return false;
1493:                }
1494:                if (!this .backgroundAnnotations
1495:                        .equals(that.backgroundAnnotations)) {
1496:                    return false;
1497:                }
1498:                if (this .defaultEntityRadius != that.defaultEntityRadius) {
1499:                    return false;
1500:                }
1501:                if (!ObjectUtilities.equal(this .legendItemLabelGenerator,
1502:                        that.legendItemLabelGenerator)) {
1503:                    return false;
1504:                }
1505:                if (!ObjectUtilities.equal(this .legendItemToolTipGenerator,
1506:                        that.legendItemToolTipGenerator)) {
1507:                    return false;
1508:                }
1509:                if (!ObjectUtilities.equal(this .legendItemURLGenerator,
1510:                        that.legendItemURLGenerator)) {
1511:                    return false;
1512:                }
1513:                return super .equals(obj);
1514:            }
1515:
1516:            /**
1517:             * Returns the drawing supplier from the plot.
1518:             *
1519:             * @return The drawing supplier (possibly <code>null</code>).
1520:             */
1521:            public DrawingSupplier getDrawingSupplier() {
1522:                DrawingSupplier result = null;
1523:                XYPlot p = getPlot();
1524:                if (p != null) {
1525:                    result = p.getDrawingSupplier();
1526:                }
1527:                return result;
1528:            }
1529:
1530:            /**
1531:             * Considers the current (x, y) coordinate and updates the crosshair point
1532:             * if it meets the criteria (usually means the (x, y) coordinate is the
1533:             * closest to the anchor point so far).
1534:             *
1535:             * @param crosshairState  the crosshair state (<code>null</code> permitted,
1536:             *                        but the method does nothing in that case).
1537:             * @param x  the x-value (in data space).
1538:             * @param y  the y-value (in data space).
1539:             * @param transX  the x-value translated to Java2D space.
1540:             * @param transY  the y-value translated to Java2D space.
1541:             * @param orientation  the plot orientation (<code>null</code> not
1542:             *                     permitted).
1543:             *
1544:             * @deprecated Use {@link #updateCrosshairValues(CrosshairState, double,
1545:             *         double, int, int, double, double, PlotOrientation)} -- see bug
1546:             *         report 1086307.
1547:             */
1548:            protected void updateCrosshairValues(CrosshairState crosshairState,
1549:                    double x, double y, double transX, double transY,
1550:                    PlotOrientation orientation) {
1551:                updateCrosshairValues(crosshairState, x, y, 0, 0, transX,
1552:                        transY, orientation);
1553:            }
1554:
1555:            /**
1556:             * Considers the current (x, y) coordinate and updates the crosshair point
1557:             * if it meets the criteria (usually means the (x, y) coordinate is the
1558:             * closest to the anchor point so far).
1559:             *
1560:             * @param crosshairState  the crosshair state (<code>null</code> permitted,
1561:             *                        but the method does nothing in that case).
1562:             * @param x  the x-value (in data space).
1563:             * @param y  the y-value (in data space).
1564:             * @param domainAxisIndex  the index of the domain axis for the point.
1565:             * @param rangeAxisIndex  the index of the range axis for the point.
1566:             * @param transX  the x-value translated to Java2D space.
1567:             * @param transY  the y-value translated to Java2D space.
1568:             * @param orientation  the plot orientation (<code>null</code> not
1569:             *                     permitted).
1570:             *
1571:             * @since 1.0.4
1572:             */
1573:            protected void updateCrosshairValues(CrosshairState crosshairState,
1574:                    double x, double y, int domainAxisIndex,
1575:                    int rangeAxisIndex, double transX, double transY,
1576:                    PlotOrientation orientation) {
1577:
1578:                if (orientation == null) {
1579:                    throw new IllegalArgumentException(
1580:                            "Null 'orientation' argument.");
1581:                }
1582:
1583:                if (crosshairState != null) {
1584:                    // do we need to update the crosshair values?
1585:                    if (this .plot.isDomainCrosshairLockedOnData()) {
1586:                        if (this .plot.isRangeCrosshairLockedOnData()) {
1587:                            // both axes
1588:                            crosshairState.updateCrosshairPoint(x, y,
1589:                                    domainAxisIndex, rangeAxisIndex, transX,
1590:                                    transY, orientation);
1591:                        } else {
1592:                            // just the domain axis...
1593:                            crosshairState.updateCrosshairX(x, domainAxisIndex);
1594:                        }
1595:                    } else {
1596:                        if (this .plot.isRangeCrosshairLockedOnData()) {
1597:                            // just the range axis...
1598:                            crosshairState.updateCrosshairY(y, rangeAxisIndex);
1599:                        }
1600:                    }
1601:                }
1602:
1603:            }
1604:
1605:            /**
1606:             * Draws an item label.
1607:             *
1608:             * @param g2  the graphics device.
1609:             * @param orientation  the orientation.
1610:             * @param dataset  the dataset.
1611:             * @param series  the series index (zero-based).
1612:             * @param item  the item index (zero-based).
1613:             * @param x  the x coordinate (in Java2D space).
1614:             * @param y  the y coordinate (in Java2D space).
1615:             * @param negative  indicates a negative value (which affects the item
1616:             *                  label position).
1617:             */
1618:            protected void drawItemLabel(Graphics2D g2,
1619:                    PlotOrientation orientation, XYDataset dataset, int series,
1620:                    int item, double x, double y, boolean negative) {
1621:
1622:                XYItemLabelGenerator generator = getItemLabelGenerator(series,
1623:                        item);
1624:                if (generator != null) {
1625:                    Font labelFont = getItemLabelFont(series, item);
1626:                    Paint paint = getItemLabelPaint(series, item);
1627:                    g2.setFont(labelFont);
1628:                    g2.setPaint(paint);
1629:                    String label = generator.generateLabel(dataset, series,
1630:                            item);
1631:
1632:                    // get the label position..
1633:                    ItemLabelPosition position = null;
1634:                    if (!negative) {
1635:                        position = getPositiveItemLabelPosition(series, item);
1636:                    } else {
1637:                        position = getNegativeItemLabelPosition(series, item);
1638:                    }
1639:
1640:                    // work out the label anchor point...
1641:                    Point2D anchorPoint = calculateLabelAnchorPoint(position
1642:                            .getItemLabelAnchor(), x, y, orientation);
1643:                    TextUtilities.drawRotatedString(label, g2,
1644:                            (float) anchorPoint.getX(), (float) anchorPoint
1645:                                    .getY(), position.getTextAnchor(), position
1646:                                    .getAngle(), position.getRotationAnchor());
1647:                }
1648:
1649:            }
1650:
1651:            /**
1652:             * Draws all the annotations for the specified layer.
1653:             *
1654:             * @param g2  the graphics device.
1655:             * @param dataArea  the data area.
1656:             * @param domainAxis  the domain axis.
1657:             * @param rangeAxis  the range axis.
1658:             * @param layer  the layer.
1659:             * @param info  the plot rendering info.
1660:             */
1661:            public void drawAnnotations(Graphics2D g2, Rectangle2D dataArea,
1662:                    ValueAxis domainAxis, ValueAxis rangeAxis, Layer layer,
1663:                    PlotRenderingInfo info) {
1664:
1665:                Iterator iterator = null;
1666:                if (layer.equals(Layer.FOREGROUND)) {
1667:                    iterator = this .foregroundAnnotations.iterator();
1668:                } else if (layer.equals(Layer.BACKGROUND)) {
1669:                    iterator = this .backgroundAnnotations.iterator();
1670:                } else {
1671:                    // should not get here
1672:                    throw new RuntimeException("Unknown layer.");
1673:                }
1674:                while (iterator.hasNext()) {
1675:                    XYAnnotation annotation = (XYAnnotation) iterator.next();
1676:                    annotation.draw(g2, this .plot, dataArea, domainAxis,
1677:                            rangeAxis, 0, info);
1678:                }
1679:
1680:            }
1681:
1682:            /**
1683:             * Adds an entity to the collection.
1684:             *
1685:             * @param entities  the entity collection being populated.
1686:             * @param area  the entity area (if <code>null</code> a default will be
1687:             *              used).
1688:             * @param dataset  the dataset.
1689:             * @param series  the series.
1690:             * @param item  the item.
1691:             * @param entityX  the entity's center x-coordinate in user space.
1692:             * @param entityY  the entity's center y-coordinate in user space.
1693:             */
1694:            protected void addEntity(EntityCollection entities, Shape area,
1695:                    XYDataset dataset, int series, int item, double entityX,
1696:                    double entityY) {
1697:                if (!getItemCreateEntity(series, item)) {
1698:                    return;
1699:                }
1700:                if (area == null) {
1701:                    area = new Ellipse2D.Double(entityX
1702:                            - this .defaultEntityRadius, entityY
1703:                            - this .defaultEntityRadius,
1704:                            this .defaultEntityRadius * 2,
1705:                            this .defaultEntityRadius * 2);
1706:                }
1707:                String tip = null;
1708:                XYToolTipGenerator generator = getToolTipGenerator(series, item);
1709:                if (generator != null) {
1710:                    tip = generator.generateToolTip(dataset, series, item);
1711:                }
1712:                String url = null;
1713:                if (getURLGenerator() != null) {
1714:                    url = getURLGenerator().generateURL(dataset, series, item);
1715:                }
1716:                XYItemEntity entity = new XYItemEntity(area, dataset, series,
1717:                        item, tip, url);
1718:                entities.add(entity);
1719:            }
1720:
1721:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.