KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > chart > renderer > xy > AbstractXYItemRenderer


1 /* ===========================================================
2  * JFreeChart : a free chart library for the Java(tm) platform
3  * ===========================================================
4  *
5  * (C) Copyright 2000-2006, by Object Refinery Limited and Contributors.
6  *
7  * Project Info: http://www.jfree.org/jfreechart/index.html
8  *
9  * This library is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22  * USA.
23  *
24  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
25  * in the United States and other countries.]
26  *
27  * ---------------------------
28  * AbstractXYItemRenderer.java
29  * ---------------------------
30  * (C) Copyright 2002-2006, by Object Refinery Limited and Contributors.
31  *
32  * Original Author: David Gilbert (for Object Refinery Limited);
33  * Contributor(s): Richard Atkinson;
34  * Focus Computer Services Limited;
35  * Tim Bardzil;
36  * Sergei Ivanov;
37  *
38  * $Id: AbstractXYItemRenderer.java,v 1.26.2.8 2006/10/24 15:39:20 mungady Exp $
39  *
40  * Changes:
41  * --------
42  * 15-Mar-2002 : Version 1 (DG);
43  * 09-Apr-2002 : Added a getToolTipGenerator() method reflecting the change in
44  * the XYItemRenderer interface (DG);
45  * 05-Aug-2002 : Added a urlGenerator member variable to support HTML image
46  * maps (RA);
47  * 20-Aug-2002 : Added property change events for the tooltip and URL
48  * generators (DG);
49  * 22-Aug-2002 : Moved property change support into AbstractRenderer class (DG);
50  * 23-Sep-2002 : Fixed errors reported by Checkstyle tool (DG);
51  * 18-Nov-2002 : Added methods for drawing grid lines (DG);
52  * 17-Jan-2003 : Moved plot classes into a separate package (DG);
53  * 25-Mar-2003 : Implemented Serializable (DG);
54  * 01-May-2003 : Modified initialise() return type and drawItem() method
55  * signature (DG);
56  * 15-May-2003 : Modified to take into account the plot orientation (DG);
57  * 21-May-2003 : Added labels to markers (DG);
58  * 05-Jun-2003 : Added domain and range grid bands (sponsored by Focus Computer
59  * Services Ltd) (DG);
60  * 27-Jul-2003 : Added getRangeType() to support stacked XY area charts (RA);
61  * 31-Jul-2003 : Deprecated all but the default constructor (DG);
62  * 13-Aug-2003 : Implemented Cloneable (DG);
63  * 16-Sep-2003 : Changed ChartRenderingInfo --> PlotRenderingInfo (DG);
64  * 29-Oct-2003 : Added workaround for font alignment in PDF output (DG);
65  * 05-Nov-2003 : Fixed marker rendering bug (833623) (DG);
66  * 11-Feb-2004 : Updated labelling for markers (DG);
67  * 25-Feb-2004 : Added updateCrosshairValues() method. Moved deprecated code
68  * to bottom of source file (DG);
69  * 16-Apr-2004 : Added support for IntervalMarker in drawRangeMarker() method
70  * - thanks to Tim Bardzil (DG);
71  * 05-May-2004 : Fixed bug (948310) where interval markers extend beyond axis
72  * range (DG);
73  * 03-Jun-2004 : Fixed more bugs in drawing interval markers (DG);
74  * 26-Aug-2004 : Added the addEntity() method (DG);
75  * 29-Sep-2004 : Added annotation support (with layers) (DG);
76  * 30-Sep-2004 : Moved drawRotatedString() from RefineryUtilities -->
77  * TextUtilities (DG);
78  * 06-Oct-2004 : Added findDomainBounds() method and renamed
79  * getRangeExtent() --> findRangeBounds() (DG);
80  * 07-Jan-2005 : Removed deprecated code (DG);
81  * 27-Jan-2005 : Modified getLegendItem() to omit hidden series (DG);
82  * 24-Feb-2005 : Added getLegendItems() method (DG);
83  * 08-Mar-2005 : Fixed positioning of marker labels (DG);
84  * 20-Apr-2005 : Renamed XYLabelGenerator --> XYItemLabelGenerator and
85  * added generators for legend labels, tooltips and URLs (DG);
86  * 01-Jun-2005 : Handle one dimension of the marker label adjustment
87  * automatically (DG);
88  * ------------- JFREECHART 1.0.x ---------------------------------------------
89  * 20-Jul-2006 : Set dataset and series indices in LegendItem (DG);
90  * 24-Oct-2006 : Respect alpha setting in markers (see patch 1567843 by Sergei
91  * Ivanov) (DG);
92  * 24-Oct-2006 : Added code to draw outlines for interval markers (DG);
93  *
94  */

95
96 package org.jfree.chart.renderer.xy;
97
98 import java.awt.AlphaComposite JavaDoc;
99 import java.awt.Composite JavaDoc;
100 import java.awt.Font JavaDoc;
101 import java.awt.GradientPaint JavaDoc;
102 import java.awt.Graphics2D JavaDoc;
103 import java.awt.Paint JavaDoc;
104 import java.awt.Shape JavaDoc;
105 import java.awt.Stroke JavaDoc;
106 import java.awt.geom.Ellipse2D JavaDoc;
107 import java.awt.geom.Line2D JavaDoc;
108 import java.awt.geom.Point2D JavaDoc;
109 import java.awt.geom.Rectangle2D JavaDoc;
110 import java.io.Serializable JavaDoc;
111 import java.util.Iterator JavaDoc;
112 import java.util.List JavaDoc;
113
114 import org.jfree.chart.LegendItem;
115 import org.jfree.chart.LegendItemCollection;
116 import org.jfree.chart.annotations.XYAnnotation;
117 import org.jfree.chart.axis.ValueAxis;
118 import org.jfree.chart.entity.EntityCollection;
119 import org.jfree.chart.entity.XYItemEntity;
120 import org.jfree.chart.event.RendererChangeEvent;
121 import org.jfree.chart.labels.ItemLabelPosition;
122 import org.jfree.chart.labels.StandardXYSeriesLabelGenerator;
123 import org.jfree.chart.labels.XYItemLabelGenerator;
124 import org.jfree.chart.labels.XYSeriesLabelGenerator;
125 import org.jfree.chart.labels.XYToolTipGenerator;
126 import org.jfree.chart.plot.CrosshairState;
127 import org.jfree.chart.plot.DrawingSupplier;
128 import org.jfree.chart.plot.IntervalMarker;
129 import org.jfree.chart.plot.Marker;
130 import org.jfree.chart.plot.Plot;
131 import org.jfree.chart.plot.PlotOrientation;
132 import org.jfree.chart.plot.PlotRenderingInfo;
133 import org.jfree.chart.plot.ValueMarker;
134 import org.jfree.chart.plot.XYPlot;
135 import org.jfree.chart.renderer.AbstractRenderer;
136 import org.jfree.chart.urls.XYURLGenerator;
137 import org.jfree.data.Range;
138 import org.jfree.data.general.DatasetUtilities;
139 import org.jfree.data.xy.XYDataset;
140 import org.jfree.text.TextUtilities;
141 import org.jfree.ui.GradientPaintTransformer;
142 import org.jfree.ui.Layer;
143 import org.jfree.ui.LengthAdjustmentType;
144 import org.jfree.ui.RectangleAnchor;
145 import org.jfree.ui.RectangleInsets;
146 import org.jfree.util.ObjectList;
147 import org.jfree.util.ObjectUtilities;
148 import org.jfree.util.PublicCloneable;
149
150 /**
151  * A base class that can be used to create new {@link XYItemRenderer}
152  * implementations.
153  */

154 public abstract class AbstractXYItemRenderer extends AbstractRenderer
155                                              implements XYItemRenderer,
156                                                         Cloneable JavaDoc,
157                                                         Serializable JavaDoc {
158
159     /** For serialization. */
160     private static final long serialVersionUID = 8019124836026607990L;
161     
162     /** The plot. */
163     private XYPlot plot;
164     
165     /** The item label generator for ALL series. */
166     private XYItemLabelGenerator itemLabelGenerator;
167
168     /** A list of item label generators (one per series). */
169     private ObjectList itemLabelGeneratorList;
170
171     /** The base item label generator. */
172     private XYItemLabelGenerator baseItemLabelGenerator;
173
174     /** The tool tip generator for ALL series. */
175     private XYToolTipGenerator toolTipGenerator;
176
177     /** A list of tool tip generators (one per series). */
178     private ObjectList toolTipGeneratorList;
179
180     /** The base tool tip generator. */
181     private XYToolTipGenerator baseToolTipGenerator;
182
183     /** The URL text generator. */
184     private XYURLGenerator urlGenerator;
185     
186     /**
187      * Annotations to be drawn in the background layer ('underneath' the data
188      * items).
189      */

190     private List JavaDoc backgroundAnnotations;
191     
192     /**
193      * Annotations to be drawn in the foreground layer ('on top' of the data
194      * items).
195      */

196     private List JavaDoc foregroundAnnotations;
197     
198     private int defaultEntityRadius;
199     
200     private XYSeriesLabelGenerator legendItemLabelGenerator;
201     
202     private XYSeriesLabelGenerator legendItemToolTipGenerator;
203     
204     private XYSeriesLabelGenerator legendItemURLGenerator;
205
206     /**
207      * Creates a renderer where the tooltip generator and the URL generator are
208      * both <code>null</code>.
209      */

210     protected AbstractXYItemRenderer() {
211         this.itemLabelGenerator = null;
212         this.itemLabelGeneratorList = new ObjectList();
213         this.toolTipGenerator = null;
214         this.toolTipGeneratorList = new ObjectList();
215         this.urlGenerator = null;
216         this.backgroundAnnotations = new java.util.ArrayList JavaDoc();
217         this.foregroundAnnotations = new java.util.ArrayList JavaDoc();
218         this.defaultEntityRadius = 3;
219         this.legendItemLabelGenerator
220             = new StandardXYSeriesLabelGenerator("{0}");
221     }
222
223     /**
224      * Returns the number of passes through the data that the renderer requires
225      * in order to draw the chart. Most charts will require a single pass, but
226      * some require two passes.
227      *
228      * @return The pass count.
229      */

230     public int getPassCount() {
231         return 1;
232     }
233
234     /**
235      * Returns the plot that the renderer is assigned to.
236      *
237      * @return The plot.
238      */

239     public XYPlot getPlot() {
240         return this.plot;
241     }
242
243     /**
244      * Sets the plot that the renderer is assigned to.
245      *
246      * @param plot the plot.
247      */

248     public void setPlot(XYPlot plot) {
249         this.plot = plot;
250     }
251
252     /**
253      * Initialises the renderer and returns a state object that should be
254      * passed to all subsequent calls to the drawItem() method.
255      * <P>
256      * This method will be called before the first item is rendered, giving the
257      * renderer an opportunity to initialise any state information it wants to
258      * maintain. The renderer can do nothing if it chooses.
259      *
260      * @param g2 the graphics device.
261      * @param dataArea the area inside the axes.
262      * @param plot the plot.
263      * @param data the data.
264      * @param info an optional info collection object to return data back to
265      * the caller.
266      *
267      * @return The renderer state (never <code>null</code>).
268      */

269     public XYItemRendererState initialise(Graphics2D JavaDoc g2,
270                                           Rectangle2D JavaDoc dataArea,
271                                           XYPlot plot,
272                                           XYDataset data,
273                                           PlotRenderingInfo info) {
274
275         XYItemRendererState state = new XYItemRendererState(info);
276         return state;
277
278     }
279
280     // ITEM LABEL GENERATOR
281

282     /**
283      * Returns the label generator for a data item. This implementation simply
284      * passes control to the {@link #getSeriesItemLabelGenerator(int)} method.
285      * If, for some reason, you want a different generator for individual
286      * items, you can override this method.
287      *
288      * @param row the row index (zero based).
289      * @param column the column index (zero based).
290      *
291      * @return The generator (possibly <code>null</code>).
292      */

293     public XYItemLabelGenerator getItemLabelGenerator(int row, int column) {
294         return getSeriesItemLabelGenerator(row);
295     }
296
297     /**
298      * Returns the item label generator for a series.
299      *
300      * @param series the series index (zero based).
301      *
302      * @return The generator (possibly <code>null</code>).
303      */

304     public XYItemLabelGenerator getSeriesItemLabelGenerator(int series) {
305
306         // return the generator for ALL series, if there is one...
307
if (this.itemLabelGenerator != null) {
308             return this.itemLabelGenerator;
309         }
310
311         // otherwise look up the generator table
312
XYItemLabelGenerator generator
313             = (XYItemLabelGenerator) this.itemLabelGeneratorList.get(series);
314         if (generator == null) {
315             generator = this.baseItemLabelGenerator;
316         }
317         return generator;
318
319     }
320
321     /**
322      * Sets the item label generator for ALL series and sends a
323      * {@link RendererChangeEvent} to all registered listeners.
324      *
325      * @param generator the generator (<code>null</code> permitted).
326      */

327     public void setItemLabelGenerator(XYItemLabelGenerator generator) {
328         this.itemLabelGenerator = generator;
329         notifyListeners(new RendererChangeEvent(this));
330     }
331
332     /**
333      * Sets the item label generator for a series and sends a
334      * {@link RendererChangeEvent} to all registered listeners.
335      *
336      * @param series the series index (zero based).
337      * @param generator the generator (<code>null</code> permitted).
338      */

339     public void setSeriesItemLabelGenerator(int series,
340                                             XYItemLabelGenerator generator) {
341         this.itemLabelGeneratorList.set(series, generator);
342         notifyListeners(new RendererChangeEvent(this));
343     }
344
345     /**
346      * Returns the base item label generator.
347      *
348      * @return The generator (possibly <code>null</code>).
349      */

350     public XYItemLabelGenerator getBaseItemLabelGenerator() {
351         return this.baseItemLabelGenerator;
352     }
353
354     /**
355      * Sets the base item label generator and sends a
356      * {@link RendererChangeEvent} to all registered listeners.
357      *
358      * @param generator the generator (<code>null</code> permitted).
359      */

360     public void setBaseItemLabelGenerator(XYItemLabelGenerator generator) {
361         this.baseItemLabelGenerator = generator;
362         notifyListeners(new RendererChangeEvent(this));
363     }
364
365     // TOOL TIP GENERATOR
366

367     /**
368      * Returns the tool tip generator for a data item. This implementation
369      * simply passes control to the getSeriesToolTipGenerator() method. If,
370      * for some reason, you want a different generator for individual items,
371      * you can override this method.
372      *
373      * @param row the row index (zero based).
374      * @param column the column index (zero based).
375      *
376      * @return The generator (possibly <code>null</code>).
377      */

378     public XYToolTipGenerator getToolTipGenerator(int row, int column) {
379         return getSeriesToolTipGenerator(row);
380     }
381
382     /**
383      * Returns the tool tip generator for a series.
384      *
385      * @param series the series index (zero based).
386      *
387      * @return The generator (possibly <code>null</code>).
388      */

389     public XYToolTipGenerator getSeriesToolTipGenerator(int series) {
390
391         // return the generator for ALL series, if there is one...
392
if (this.toolTipGenerator != null) {
393             return this.toolTipGenerator;
394         }
395
396         // otherwise look up the generator table
397
XYToolTipGenerator generator
398             = (XYToolTipGenerator) this.toolTipGeneratorList.get(series);
399         if (generator == null) {
400             generator = this.baseToolTipGenerator;
401         }
402         return generator;
403
404     }
405
406     /**
407      * Sets the tool tip generator for ALL series and sends a
408      * {@link RendererChangeEvent} to all registered listeners.
409      *
410      * @param generator the generator (<code>null</code> permitted).
411      */

412     public void setToolTipGenerator(XYToolTipGenerator generator) {
413         this.toolTipGenerator = generator;
414         notifyListeners(new RendererChangeEvent(this));
415     }
416
417     /**
418      * Sets the tool tip generator for a series and sends a
419      * {@link RendererChangeEvent} to all registered listeners.
420      *
421      * @param series the series index (zero based).
422      * @param generator the generator (<code>null</code> permitted).
423      */

424     public void setSeriesToolTipGenerator(int series,
425                                           XYToolTipGenerator generator) {
426         this.toolTipGeneratorList.set(series, generator);
427         notifyListeners(new RendererChangeEvent(this));
428     }
429
430     /**
431      * Returns the base tool tip generator.
432      *
433      * @return The generator (possibly <code>null</code>).
434      */

435     public XYToolTipGenerator getBaseToolTipGenerator() {
436         return this.baseToolTipGenerator;
437     }
438
439     /**
440      * Sets the base tool tip generator and sends a {@link RendererChangeEvent}
441      * to all registered listeners.
442      *
443      * @param generator the generator (<code>null</code> permitted).
444      */

445     public void setBaseToolTipGenerator(XYToolTipGenerator generator) {
446         this.baseToolTipGenerator = generator;
447         notifyListeners(new RendererChangeEvent(this));
448     }
449
450     // URL GENERATOR
451

452     /**
453      * Returns the URL generator for HTML image maps.
454      *
455      * @return The URL generator (possibly <code>null</code>).
456      */

457     public XYURLGenerator getURLGenerator() {
458         return this.urlGenerator;
459     }
460
461     /**
462      * Sets the URL generator for HTML image maps.
463      *
464      * @param urlGenerator the URL generator (<code>null</code> permitted).
465      */

466     public void setURLGenerator(XYURLGenerator urlGenerator) {
467         this.urlGenerator = urlGenerator;
468         notifyListeners(new RendererChangeEvent(this));
469     }
470
471     /**
472      * Adds an annotation and sends a {@link RendererChangeEvent} to all
473      * registered listeners. The annotation is added to the foreground
474      * layer.
475      *
476      * @param annotation the annotation (<code>null</code> not permitted).
477      */

478     public void addAnnotation(XYAnnotation annotation) {
479         // defer argument checking
480
addAnnotation(annotation, Layer.FOREGROUND);
481     }
482     
483     /**
484      * Adds an annotation to the specified layer.
485      *
486      * @param annotation the annotation (<code>null</code> not permitted).
487      * @param layer the layer (<code>null</code> not permitted).
488      */

489     public void addAnnotation(XYAnnotation annotation, Layer layer) {
490         if (annotation == null) {
491             throw new IllegalArgumentException JavaDoc("Null 'annotation' argument.");
492         }
493         if (layer.equals(Layer.FOREGROUND)) {
494             this.foregroundAnnotations.add(annotation);
495             notifyListeners(new RendererChangeEvent(this));
496         }
497         else if (layer.equals(Layer.BACKGROUND)) {
498             this.backgroundAnnotations.add(annotation);
499             notifyListeners(new RendererChangeEvent(this));
500         }
501         else {
502             // should never get here
503
throw new RuntimeException JavaDoc("Unknown layer.");
504         }
505     }
506     /**
507      * Removes the specified annotation and sends a {@link RendererChangeEvent}
508      * to all registered listeners.
509      *
510      * @param annotation the annotation to remove (<code>null</code> not
511      * permitted).
512      *
513      * @return A boolean to indicate whether or not the annotation was
514      * successfully removed.
515      */

516     public boolean removeAnnotation(XYAnnotation annotation) {
517         boolean removed = this.foregroundAnnotations.remove(annotation);
518         removed = removed & this.backgroundAnnotations.remove(annotation);
519         notifyListeners(new RendererChangeEvent(this));
520         return removed;
521     }
522     
523     /**
524      * Removes all annotations and sends a {@link RendererChangeEvent}
525      * to all registered listeners.
526      */

527     public void removeAnnotations() {
528         this.foregroundAnnotations.clear();
529         this.backgroundAnnotations.clear();
530         notifyListeners(new RendererChangeEvent(this));
531     }
532     
533     /**
534      * Returns the radius of the circle used for the default entity area
535      * when no area is specified.
536      *
537      * @return A radius.
538      */

539     public int getDefaultEntityRadius() {
540         return this.defaultEntityRadius;
541     }
542     
543     /**
544      * Sets the radius of the circle used for the default entity area
545      * when no area is specified.
546      *
547      * @param radius the radius.
548      */

549     public void setDefaultEntityRadius(int radius) {
550         this.defaultEntityRadius = radius;
551     }
552     
553     /**
554      * Returns the legend item label generator.
555      *
556      * @return The label generator (never <code>null</code>).
557      */

558     public XYSeriesLabelGenerator getLegendItemLabelGenerator() {
559         return this.legendItemLabelGenerator;
560     }
561     
562     /**
563      * Sets the legend item label generator.
564      *
565      * @param generator the generator (<code>null</code> not permitted).
566      */

567     public void setLegendItemLabelGenerator(XYSeriesLabelGenerator generator) {
568         if (generator == null) {
569             throw new IllegalArgumentException JavaDoc("Null 'generator' argument.");
570         }
571         this.legendItemLabelGenerator = generator;
572     }
573     
574     /**
575      * Returns the legend item tool tip generator.
576      *
577      * @return The tool tip generator (possibly <code>null</code>).
578      */

579     public XYSeriesLabelGenerator getLegendItemToolTipGenerator() {
580         return this.legendItemToolTipGenerator;
581     }
582     
583     /**
584      * Sets the legend item tool tip generator.
585      *
586      * @param generator the generator (<code>null</code> permitted).
587      */

588     public void setLegendItemToolTipGenerator(XYSeriesLabelGenerator generator)
589     {
590         this.legendItemToolTipGenerator = generator;
591     }
592     
593     /**
594      * Returns the legend item URL generator.
595      *
596      * @return The URL generator (possibly <code>null</code>).
597      */

598     public XYSeriesLabelGenerator getLegendItemURLGenerator() {
599         return this.legendItemURLGenerator;
600     }
601     
602     /**
603      * Sets the legend item URL generator.
604      *
605      * @param generator the generator (<code>null</code> permitted).
606      */

607     public void setLegendItemURLGenerator(XYSeriesLabelGenerator generator)
608     {
609         this.legendItemURLGenerator = generator;
610     }
611     
612     /**
613      * Returns the lower and upper bounds (range) of the x-values in the
614      * specified dataset.
615      *
616      * @param dataset the dataset (<code>null</code> permitted).
617      *
618      * @return The range (<code>null</code> if the dataset is <code>null</code>
619      * or empty).
620      */

621     public Range findDomainBounds(XYDataset dataset) {
622         if (dataset != null) {
623             return DatasetUtilities.findDomainBounds(dataset, false);
624         }
625         else {
626             return null;
627         }
628     }
629
630     /**
631      * Returns the range of values the renderer requires to display all the
632      * items from the specified dataset.
633      *
634      * @param dataset the dataset (<code>null</code> permitted).
635      *
636      * @return The range (<code>null</code> if the dataset is <code>null</code>
637      * or empty).
638      */

639     public Range findRangeBounds(XYDataset dataset) {
640         if (dataset != null) {
641             return DatasetUtilities.findRangeBounds(dataset, false);
642         }
643         else {
644             return null;
645         }
646     }
647
648     /**
649      * Returns a (possibly empty) collection of legend items for the series
650      * that this renderer is responsible for drawing.
651      *
652      * @return The legend item collection (never <code>null</code>).
653      */

654     public LegendItemCollection getLegendItems() {
655         if (this.plot == null) {
656             return new LegendItemCollection();
657         }
658         LegendItemCollection result = new LegendItemCollection();
659         int index = this.plot.getIndexOf(this);
660         XYDataset dataset = this.plot.getDataset(index);
661         if (dataset != null) {
662             int seriesCount = dataset.getSeriesCount();
663             for (int i = 0; i < seriesCount; i++) {
664                 if (isSeriesVisibleInLegend(i)) {
665                     LegendItem item = getLegendItem(index, i);
666                     if (item != null) {
667                         result.add(item);
668                     }
669                 }
670             }
671    
672         }
673         return result;
674     }
675
676     /**
677      * Returns a default legend item for the specified series. Subclasses
678      * should override this method to generate customised items.
679      *
680      * @param datasetIndex the dataset index (zero-based).
681      * @param series the series index (zero-based).
682      *
683      * @return A legend item for the series.
684      */

685     public LegendItem getLegendItem(int datasetIndex, int series) {
686         LegendItem result = null;
687         XYPlot xyplot = getPlot();
688         if (xyplot != null) {
689             XYDataset dataset = xyplot.getDataset(datasetIndex);
690             if (dataset != null) {
691                 String JavaDoc label = this.legendItemLabelGenerator.generateLabel(
692                         dataset, series);
693                 String JavaDoc description = label;
694                 String JavaDoc toolTipText = null;
695                 if (getLegendItemToolTipGenerator() != null) {
696                     toolTipText = getLegendItemToolTipGenerator().generateLabel(
697                             dataset, series);
698                 }
699                 String JavaDoc urlText = null;
700                 if (getLegendItemURLGenerator() != null) {
701                     urlText = getLegendItemURLGenerator().generateLabel(
702                             dataset, series);
703                 }
704                 Shape JavaDoc shape = getSeriesShape(series);
705                 Paint JavaDoc paint = getSeriesPaint(series);
706                 Paint JavaDoc outlinePaint = getSeriesOutlinePaint(series);
707                 Stroke JavaDoc outlineStroke = getSeriesOutlineStroke(series);
708                 result = new LegendItem(label, description, toolTipText,
709                         urlText, shape, paint, outlineStroke, outlinePaint);
710                 result.setSeriesIndex(series);
711                 result.setDatasetIndex(datasetIndex);
712             }
713         }
714         return result;
715     }
716
717     /**
718      * Fills a band between two values on the axis. This can be used to color
719      * bands between the grid lines.
720      *
721      * @param g2 the graphics device.
722      * @param plot the plot.
723      * @param axis the domain axis.
724      * @param dataArea the data area.
725      * @param start the start value.
726      * @param end the end value.
727      */

728     public void fillDomainGridBand(Graphics2D JavaDoc g2,
729                                    XYPlot plot,
730                                    ValueAxis axis,
731                                    Rectangle2D JavaDoc dataArea,
732                                    double start, double end) {
733
734         double x1 = axis.valueToJava2D(start, dataArea,
735                 plot.getDomainAxisEdge());
736         double x2 = axis.valueToJava2D(end, dataArea,
737                 plot.getDomainAxisEdge());
738         // TODO: need to change the next line to take account of plot
739
// orientation...
740
Rectangle2D JavaDoc band = new Rectangle2D.Double JavaDoc(x1, dataArea.getMinY(),
741                 x2 - x1, dataArea.getMaxY() - dataArea.getMinY());
742         Paint JavaDoc paint = plot.getDomainTickBandPaint();
743
744         if (paint != null) {
745             g2.setPaint(paint);
746             g2.fill(band);
747         }
748
749     }
750
751     /**
752      * Fills a band between two values on the range axis. This can be used to
753      * color bands between the grid lines.
754      *
755      * @param g2 the graphics device.
756      * @param plot the plot.
757      * @param axis the range axis.
758      * @param dataArea the data area.
759      * @param start the start value.
760      * @param end the end value.
761      */

762     public void fillRangeGridBand(Graphics2D JavaDoc g2,
763                                   XYPlot plot,
764                                   ValueAxis axis,
765                                   Rectangle2D JavaDoc dataArea,
766                                   double start, double end) {
767
768         double y1 = axis.valueToJava2D(start, dataArea,
769                 plot.getRangeAxisEdge());
770         double y2 = axis.valueToJava2D(end, dataArea, plot.getRangeAxisEdge());
771         // TODO: need to change the next line to take account of the plot
772
// orientation
773
Rectangle2D JavaDoc band = new Rectangle2D.Double JavaDoc(dataArea.getMinX(), y2,
774                 dataArea.getWidth(), y1 - y2);
775         Paint JavaDoc paint = plot.getRangeTickBandPaint();
776
777         if (paint != null) {
778             g2.setPaint(paint);
779             g2.fill(band);
780         }
781
782     }
783
784     /**
785      * Draws a grid line against the range axis.
786      *
787      * @param g2 the graphics device.
788      * @param plot the plot.
789      * @param axis the value axis.
790      * @param dataArea the area for plotting data (not yet adjusted for any
791      * 3D effect).
792      * @param value the value at which the grid line should be drawn.
793      */

794     public void drawDomainGridLine(Graphics2D JavaDoc g2,
795                                    XYPlot plot,
796                                    ValueAxis axis,
797                                    Rectangle2D JavaDoc dataArea,
798                                    double value) {
799
800         Range range = axis.getRange();
801         if (!range.contains(value)) {
802             return;
803         }
804
805         PlotOrientation orientation = plot.getOrientation();
806         double v = axis.valueToJava2D(value, dataArea,
807                 plot.getDomainAxisEdge());
808         Line2D JavaDoc line = null;
809         if (orientation == PlotOrientation.HORIZONTAL) {
810             line = new Line2D.Double JavaDoc(dataArea.getMinX(), v,
811                     dataArea.getMaxX(), v);
812         }
813         else if (orientation == PlotOrientation.VERTICAL) {
814             line = new Line2D.Double JavaDoc(v, dataArea.getMinY(), v,
815                     dataArea.getMaxY());
816         }
817
818         Paint JavaDoc paint = plot.getDomainGridlinePaint();
819         Stroke JavaDoc stroke = plot.getDomainGridlineStroke();
820         g2.setPaint(paint != null ? paint : Plot.DEFAULT_OUTLINE_PAINT);
821         g2.setStroke(stroke != null ? stroke : Plot.DEFAULT_OUTLINE_STROKE);
822         g2.draw(line);
823
824     }
825
826     /**
827      * Draws a line perpendicular to the range axis.
828      *
829      * @param g2 the graphics device.
830      * @param plot the plot.
831      * @param axis the value axis.
832      * @param dataArea the area for plotting data (not yet adjusted for any 3D
833      * effect).
834      * @param value the value at which the grid line should be drawn.
835      * @param paint the paint.
836      * @param stroke the stroke.
837      */

838     public void drawRangeLine(Graphics2D JavaDoc g2,
839                               XYPlot plot,
840                               ValueAxis axis,
841                               Rectangle2D JavaDoc dataArea,
842                               double value,
843                               Paint JavaDoc paint,
844                               Stroke JavaDoc stroke) {
845
846         Range range = axis.getRange();
847         if (!range.contains(value)) {
848             return;
849         }
850
851         PlotOrientation orientation = plot.getOrientation();
852         Line2D JavaDoc line = null;
853         double v = axis.valueToJava2D(value, dataArea, plot.getRangeAxisEdge());
854         if (orientation == PlotOrientation.HORIZONTAL) {
855             line = new Line2D.Double JavaDoc(v, dataArea.getMinY(), v,
856                     dataArea.getMaxY());
857         }
858         else if (orientation == PlotOrientation.VERTICAL) {
859             line = new Line2D.Double JavaDoc(dataArea.getMinX(), v,
860                     dataArea.getMaxX(), v);
861         }
862         
863         g2.setPaint(paint);
864         g2.setStroke(stroke);
865         g2.draw(line);
866
867     }
868
869