KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > chart > renderer > category > AbstractCategoryItemRenderer


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  * AbstractCategoryItemRenderer.java
29  * ---------------------------------
30  * (C) Copyright 2002-2006, by Object Refinery Limited.
31  *
32  * Original Author: David Gilbert (for Object Refinery Limited);
33  * Contributor(s): Richard Atkinson;
34  *
35  * $Id: AbstractCategoryItemRenderer.java,v 1.17.2.9 2006/10/24 15:10:23 mungady Exp $
36  *
37  * Changes:
38  * --------
39  * 29-May-2002 : Version 1 (DG);
40  * 06-Jun-2002 : Added accessor methods for the tool tip generator (DG);
41  * 11-Jun-2002 : Made constructors protected (DG);
42  * 26-Jun-2002 : Added axis to initialise method (DG);
43  * 05-Aug-2002 : Added urlGenerator member variable plus accessors (RA);
44  * 22-Aug-2002 : Added categoriesPaint attribute, based on code submitted by
45  * Janet Banks. This can be used when there is only one series,
46  * and you want each category item to have a different color (DG);
47  * 01-Oct-2002 : Fixed errors reported by Checkstyle (DG);
48  * 29-Oct-2002 : Fixed bug where background image for plot was not being
49  * drawn (DG);
50  * 05-Nov-2002 : Replaced references to CategoryDataset with TableDataset (DG);
51  * 26-Nov 2002 : Replaced the isStacked() method with getRangeType() (DG);
52  * 09-Jan-2003 : Renamed grid-line methods (DG);
53  * 17-Jan-2003 : Moved plot classes into separate package (DG);
54  * 25-Mar-2003 : Implemented Serializable (DG);
55  * 12-May-2003 : Modified to take into account the plot orientation (DG);
56  * 12-Aug-2003 : Very minor javadoc corrections (DB)
57  * 13-Aug-2003 : Implemented Cloneable (DG);
58  * 16-Sep-2003 : Changed ChartRenderingInfo --> PlotRenderingInfo (DG);
59  * 05-Nov-2003 : Fixed marker rendering bug (833623) (DG);
60  * 21-Jan-2004 : Update for renamed method in ValueAxis (DG);
61  * 11-Feb-2004 : Modified labelling for markers (DG);
62  * 12-Feb-2004 : Updated clone() method (DG);
63  * 15-Apr-2004 : Created a new CategoryToolTipGenerator interface (DG);
64  * 05-May-2004 : Fixed bug (948310) where interval markers extend outside axis
65  * range (DG);
66  * 14-Jun-2004 : Fixed bug in drawRangeMarker() method - now uses 'paint' and
67  * 'stroke' rather than 'outlinePaint' and 'outlineStroke' (DG);
68  * 15-Jun-2004 : Interval markers can now use GradientPaint (DG);
69  * 30-Sep-2004 : Moved drawRotatedString() from RefineryUtilities
70  * --> TextUtilities (DG);
71  * 01-Oct-2004 : Fixed bug 1029697, problem with label alignment in
72  * drawRangeMarker() method (DG);
73  * 07-Jan-2005 : Renamed getRangeExtent() --> findRangeBounds() (DG);
74  * 21-Jan-2005 : Modified return type of calculateRangeMarkerTextAnchorPoint()
75  * method (DG);
76  * 08-Mar-2005 : Fixed positioning of marker labels (DG);
77  * 20-Apr-2005 : Added legend label, tooltip and URL generators (DG);
78  * 01-Jun-2005 : Handle one dimension of the marker label adjustment
79  * automatically (DG);
80  * 09-Jun-2005 : Added utility method for adding an item entity (DG);
81  * ------------- JFREECHART 1.0.x ---------------------------------------------
82  * 01-Mar-2006 : Updated getLegendItems() to check seriesVisibleInLegend
83  * flags (DG);
84  * 20-Jul-2006 : Set dataset and series indices in LegendItem (DG);
85  * 23-Oct-2006 : Draw outlines for interval markers (DG);
86  * 24-Oct-2006 : Respect alpha setting in markers, as suggested by Sergei
87  * Ivanov in patch 1567843 (DG);
88  *
89  */

90
91 package org.jfree.chart.renderer.category;
92
93 import java.awt.AlphaComposite JavaDoc;
94 import java.awt.Composite JavaDoc;
95 import java.awt.Font JavaDoc;
96 import java.awt.GradientPaint JavaDoc;
97 import java.awt.Graphics2D JavaDoc;
98 import java.awt.Paint JavaDoc;
99 import java.awt.Shape JavaDoc;
100 import java.awt.Stroke JavaDoc;
101 import java.awt.geom.Line2D JavaDoc;
102 import java.awt.geom.Point2D JavaDoc;
103 import java.awt.geom.Rectangle2D JavaDoc;
104 import java.io.Serializable JavaDoc;
105
106 import org.jfree.chart.LegendItem;
107 import org.jfree.chart.LegendItemCollection;
108 import org.jfree.chart.axis.CategoryAxis;
109 import org.jfree.chart.axis.ValueAxis;
110 import org.jfree.chart.entity.CategoryItemEntity;
111 import org.jfree.chart.entity.EntityCollection;
112 import org.jfree.chart.event.RendererChangeEvent;
113 import org.jfree.chart.labels.CategoryItemLabelGenerator;
114 import org.jfree.chart.labels.CategorySeriesLabelGenerator;
115 import org.jfree.chart.labels.CategoryToolTipGenerator;
116 import org.jfree.chart.labels.ItemLabelPosition;
117 import org.jfree.chart.labels.StandardCategorySeriesLabelGenerator;
118 import org.jfree.chart.plot.CategoryMarker;
119 import org.jfree.chart.plot.CategoryPlot;
120 import org.jfree.chart.plot.DrawingSupplier;
121 import org.jfree.chart.plot.IntervalMarker;
122 import org.jfree.chart.plot.Marker;
123 import org.jfree.chart.plot.PlotOrientation;
124 import org.jfree.chart.plot.PlotRenderingInfo;
125 import org.jfree.chart.plot.ValueMarker;
126 import org.jfree.chart.renderer.AbstractRenderer;
127 import org.jfree.chart.urls.CategoryURLGenerator;
128 import org.jfree.data.Range;
129 import org.jfree.data.category.CategoryDataset;
130 import org.jfree.data.general.DatasetUtilities;
131 import org.jfree.text.TextUtilities;
132 import org.jfree.ui.GradientPaintTransformer;
133 import org.jfree.ui.LengthAdjustmentType;
134 import org.jfree.ui.RectangleAnchor;
135 import org.jfree.ui.RectangleInsets;
136 import org.jfree.util.ObjectList;
137 import org.jfree.util.ObjectUtilities;
138 import org.jfree.util.PublicCloneable;
139
140 /**
141  * An abstract base class that you can use to implement a new
142  * {@link CategoryItemRenderer}. When you create a new
143  * {@link CategoryItemRenderer} you are not required to extend this class,
144  * but it makes the job easier.
145  */

146 public abstract class AbstractCategoryItemRenderer extends AbstractRenderer
147     implements CategoryItemRenderer, Cloneable JavaDoc, PublicCloneable, Serializable JavaDoc {
148
149     /** For serialization. */
150     private static final long serialVersionUID = 1247553218442497391L;
151     
152     /** The plot that the renderer is assigned to. */
153     private CategoryPlot plot;
154
155     /** The item label generator for ALL series. */
156     private CategoryItemLabelGenerator itemLabelGenerator;
157
158     /** A list of item label generators (one per series). */
159     private ObjectList itemLabelGeneratorList;
160
161     /** The base item label generator. */
162     private CategoryItemLabelGenerator baseItemLabelGenerator;
163
164     /** The tool tip generator for ALL series. */
165     private CategoryToolTipGenerator toolTipGenerator;
166
167     /** A list of tool tip generators (one per series). */
168     private ObjectList toolTipGeneratorList;
169
170     /** The base tool tip generator. */
171     private CategoryToolTipGenerator baseToolTipGenerator;
172
173     /** The URL generator. */
174     private CategoryURLGenerator itemURLGenerator;
175
176     /** A list of item label generators (one per series). */
177     private ObjectList itemURLGeneratorList;
178
179     /** The base item label generator. */
180     private CategoryURLGenerator baseItemURLGenerator;
181
182     /** The legend item label generator. */
183     private CategorySeriesLabelGenerator legendItemLabelGenerator;
184     
185     /** The legend item tool tip generator. */
186     private CategorySeriesLabelGenerator legendItemToolTipGenerator;
187
188     /** The legend item URL generator. */
189     private CategorySeriesLabelGenerator legendItemURLGenerator;
190     
191     /** The number of rows in the dataset (temporary record). */
192     private transient int rowCount;
193
194     /** The number of columns in the dataset (temporary record). */
195     private transient int columnCount;
196
197     /**
198      * Creates a new renderer with no tool tip generator and no URL generator.
199      * The defaults (no tool tip or URL generators) have been chosen to
200      * minimise the processing required to generate a default chart. If you
201      * require tool tips or URLs, then you can easily add the required
202      * generators.
203      */

204     protected AbstractCategoryItemRenderer() {
205         this.itemLabelGenerator = null;
206         this.itemLabelGeneratorList = new ObjectList();
207         this.toolTipGenerator = null;
208         this.toolTipGeneratorList = new ObjectList();
209         this.itemURLGenerator = null;
210         this.itemURLGeneratorList = new ObjectList();
211         this.legendItemLabelGenerator
212             = new StandardCategorySeriesLabelGenerator();
213     }
214     
215     /**
216      * Returns the number of passes through the dataset required by the
217      * renderer. This method returns <code>1</code>, subclasses should
218      * override if they need more passes.
219      *
220      * @return The pass count.
221      */

222     public int getPassCount() {
223         return 1;
224     }
225
226     /**
227      * Returns the plot that the renderer has been assigned to (where
228      * <code>null</code> indicates that the renderer is not currently assigned
229      * to a plot).
230      *
231      * @return The plot (possibly <code>null</code>).
232      */

233     public CategoryPlot getPlot() {
234         return this.plot;
235     }
236
237     /**
238      * Sets the plot that the renderer has been assigned to. This method is
239      * usually called by the {@link CategoryPlot}, in normal usage you
240      * shouldn't need to call this method directly.
241      *
242      * @param plot the plot (<code>null</code> not permitted).
243      */

244     public void setPlot(CategoryPlot plot) {
245         if (plot == null) {
246             throw new IllegalArgumentException JavaDoc("Null 'plot' argument.");
247         }
248         this.plot = plot;
249     }
250     
251     // ITEM LABEL GENERATOR
252

253     /**
254      * Returns the item label generator for a data item. This implementation
255      * simply passes control to the {@link #getSeriesItemLabelGenerator(int)}
256      * method. If, for some reason, you want a different generator for
257      * individual items, you can override this method.
258      *
259      * @param row the row index (zero based).
260      * @param column the column index (zero based).
261      *
262      * @return The generator (possibly <code>null</code>).
263      */

264     public CategoryItemLabelGenerator getItemLabelGenerator(int row,
265             int column) {
266         return getSeriesItemLabelGenerator(row);
267     }
268
269     /**
270      * Returns the item label generator for a series.
271      *
272      * @param series the series index (zero based).
273      *
274      * @return The generator (possibly <code>null</code>).
275      */

276     public CategoryItemLabelGenerator getSeriesItemLabelGenerator(int series) {
277
278         // return the generator for ALL series, if there is one...
279
if (this.itemLabelGenerator != null) {
280             return this.itemLabelGenerator;
281         }
282
283         // otherwise look up the generator table
284
CategoryItemLabelGenerator generator = (CategoryItemLabelGenerator)
285             this.itemLabelGeneratorList.get(series);
286         if (generator == null) {
287             generator = this.baseItemLabelGenerator;
288         }
289         return generator;
290
291     }
292
293     /**
294      * Sets the item label generator for ALL series and sends a
295      * {@link RendererChangeEvent} to all registered listeners.
296      *
297      * @param generator the generator (<code>null</code> permitted).
298      */

299     public void setItemLabelGenerator(CategoryItemLabelGenerator generator) {
300         this.itemLabelGenerator = generator;
301         notifyListeners(new RendererChangeEvent(this));
302     }
303
304     /**
305      * Sets the item label generator for a series and sends a
306      * {@link RendererChangeEvent} to all registered listeners.
307      *
308      * @param series the series index (zero based).
309      * @param generator the generator (<code>null</code> permitted).
310      */

311     public void setSeriesItemLabelGenerator(int series,
312                                         CategoryItemLabelGenerator generator) {
313         this.itemLabelGeneratorList.set(series, generator);
314         notifyListeners(new RendererChangeEvent(this));
315     }
316
317     /**
318      * Returns the base item label generator.
319      *
320      * @return The generator (possibly <code>null</code>).
321      */

322     public CategoryItemLabelGenerator getBaseItemLabelGenerator() {
323         return this.baseItemLabelGenerator;
324     }
325
326     /**
327      * Sets the base item label generator and sends a
328      * {@link RendererChangeEvent} to all registered listeners.
329      *
330      * @param generator the generator (<code>null</code> permitted).
331      */

332     public void setBaseItemLabelGenerator(CategoryItemLabelGenerator generator)
333     {
334         this.baseItemLabelGenerator = generator;
335         notifyListeners(new RendererChangeEvent(this));
336     }
337
338     // TOOL TIP GENERATOR
339

340     /**
341      * Returns the tool tip generator that should be used for the specified
342      * item. This method looks up the generator using the "three-layer"
343      * approach outlined in the general description of this interface. You
344      * can override this method if you want to return a different generator per
345      * item.
346      *
347      * @param row the row index (zero-based).
348      * @param column the column index (zero-based).
349      *
350      * @return The generator (possibly <code>null</code>).
351      */

352     public CategoryToolTipGenerator getToolTipGenerator(int row, int column) {
353
354         CategoryToolTipGenerator result = null;
355         if (this.toolTipGenerator != null) {
356             result = this.toolTipGenerator;
357         }
358         else {
359             result = getSeriesToolTipGenerator(row);
360             if (result == null) {
361                 result = this.baseToolTipGenerator;
362             }
363         }
364         return result;
365     }
366
367     /**
368      * Returns the tool tip generator that will be used for ALL items in the
369      * dataset (the "layer 0" generator).
370      *
371      * @return A tool tip generator (possibly <code>null</code>).
372      */

373     public CategoryToolTipGenerator getToolTipGenerator() {
374         return this.toolTipGenerator;
375     }
376     
377     /**
378      * Sets the tool tip generator for ALL series and sends a
379      * {@link org.jfree.chart.event.RendererChangeEvent} to all registered
380      * listeners.
381      *
382      * @param generator the generator (<code>null</code> permitted).
383      */

384     public void setToolTipGenerator(CategoryToolTipGenerator generator) {
385         this.toolTipGenerator = generator;
386         notifyListeners(new RendererChangeEvent(this));
387     }
388
389     /**
390      * Returns the tool tip generator for the specified series (a "layer 1"
391      * generator).
392      *
393      * @param series the series index (zero-based).
394      *
395      * @return The tool tip generator (possibly <code>null</code>).
396      */

397     public CategoryToolTipGenerator getSeriesToolTipGenerator(int series) {
398         return (CategoryToolTipGenerator) this.toolTipGeneratorList.get(series);
399     }
400
401     /**
402      * Sets the tool tip generator for a series and sends a
403      * {@link org.jfree.chart.event.RendererChangeEvent} to all registered
404      * listeners.
405      *
406      * @param series the series index (zero-based).
407      * @param generator the generator (<code>null</code> permitted).
408      */

409     public void setSeriesToolTipGenerator(int series,
410                                           CategoryToolTipGenerator generator) {
411         this.toolTipGeneratorList.set(series, generator);
412         notifyListeners(new RendererChangeEvent(this));
413     }
414
415     /**
416      * Returns the base tool tip generator (the "layer 2" generator).
417      *
418      * @return The tool tip generator (possibly <code>null</code>).
419      */

420     public CategoryToolTipGenerator getBaseToolTipGenerator() {
421         return this.baseToolTipGenerator;
422     }
423
424     /**
425      * Sets the base tool tip generator and sends a
426      * {@link org.jfree.chart.event.RendererChangeEvent} to all registered
427      * listeners.
428      *
429      * @param generator the generator (<code>null</code> permitted).
430      */

431     public void setBaseToolTipGenerator(CategoryToolTipGenerator generator) {
432         this.baseToolTipGenerator = generator;
433         notifyListeners(new RendererChangeEvent(this));
434     }
435
436     // URL GENERATOR
437

438     /**
439      * Returns the URL generator for a data item. This method just calls the
440      * getSeriesItemURLGenerator method, but you can override this behaviour if
441      * you want to.
442      *
443      * @param row the row index (zero based).
444      * @param column the column index (zero based).
445      *
446      * @return The URL generator.
447      */

448     public CategoryURLGenerator getItemURLGenerator(int row, int column) {
449         return getSeriesItemURLGenerator(row);
450     }
451
452     /**
453      * Returns the URL generator for a series.
454      *
455      * @param series the series index (zero based).
456      *
457      * @return The URL generator for the series.
458      */

459     public CategoryURLGenerator getSeriesItemURLGenerator(int series) {
460
461         // return the generator for ALL series, if there is one...
462
if (this.itemURLGenerator != null) {
463             return this.itemURLGenerator;
464         }
465
466         // otherwise look up the generator table
467
CategoryURLGenerator generator
468             = (CategoryURLGenerator) this.itemURLGeneratorList.get(series);
469         if (generator == null) {
470             generator = this.baseItemURLGenerator;
471         }
472         return generator;
473
474     }
475
476     /**
477      * Sets the item URL generator for ALL series.
478      *
479      * @param generator the generator.
480      */

481     public void setItemURLGenerator(CategoryURLGenerator generator) {
482         this.itemURLGenerator = generator;
483     }
484
485     /**
486      * Sets the URL generator for a series.
487      *
488      * @param series the series index (zero based).
489      * @param generator the generator.
490      */

491     public void setSeriesItemURLGenerator(int series,
492                                           CategoryURLGenerator generator) {
493         this.itemURLGeneratorList.set(series, generator);
494     }
495
496     /**
497      * Returns the base item URL generator.
498      *
499      * @return The item URL generator.
500      */

501     public CategoryURLGenerator getBaseItemURLGenerator() {
502         return this.baseItemURLGenerator;
503     }
504
505     /**
506      * Sets the base item URL generator.
507      *
508      * @param generator the item URL generator.
509      */

510     public void setBaseItemURLGenerator(CategoryURLGenerator generator) {
511         this.baseItemURLGenerator = generator;
512     }
513
514     /**
515      * Returns the number of rows in the dataset. This value is updated in the
516      * {@link AbstractCategoryItemRenderer#initialise} method.
517      *
518      * @return The row count.
519      */

520     public int getRowCount() {
521         return this.rowCount;
522     }
523
524     /**
525      * Returns the number of columns in the dataset. This value is updated in
526      * the {@link AbstractCategoryItemRenderer#initialise} method.
527      *
528      * @return The column count.
529      */

530     public int getColumnCount() {
531         return this.columnCount;
532     }
533
534     /**
535      * Initialises the renderer and returns a state object that will be used
536      * for the remainder of the drawing process for a single chart. The state
537      * object allows for the fact that the renderer may be used simultaneously
538      * by multiple threads (each thread will work with a separate state object).
539      * <P>
540      * Stores a reference to the {@link PlotRenderingInfo} object (which might
541      * be <code>null</code>), and then sets the useCategoriesPaint flag
542      * according to the special case conditions a) there is only one series
543      * and b) the categoriesPaint array is not null.
544      *
545      * @param g2 the graphics device.
546      * @param dataArea the data area.
547      * @param plot the plot.
548      * @param rendererIndex the renderer index.
549      * @param info an object for returning information about the structure of
550      * the plot (<code>null</code> permitted).
551      *
552      * @return The renderer state.
553      *
554      */

555     public CategoryItemRendererState initialise(Graphics2D JavaDoc g2,
556                                                 Rectangle2D JavaDoc dataArea,
557                                                 CategoryPlot plot,
558                                                 int rendererIndex,
559                                                 PlotRenderingInfo info) {
560
561         setPlot(plot);
562         CategoryDataset data = plot.getDataset(rendererIndex);
563         if (data != null) {
564             this.rowCount = data.getRowCount();
565             this.columnCount = data.getColumnCount();
566         }
567         else {
568             this.rowCount = 0;
569             this.columnCount = 0;
570         }
571         return new CategoryItemRendererState(info);
572
573     }
574
575     /**
576      * Returns the range of values the renderer requires to display all the
577      * items from the specified dataset.
578      *
579      * @param dataset the dataset (<code>null</code> permitted).
580      *
581      * @return The range (or <code>null</code> if the dataset is
582      * <code>null</code> or empty).
583      */

584     public Range findRangeBounds(CategoryDataset dataset) {
585         return DatasetUtilities.findRangeBounds(dataset);
586     }
587
588     /**
589      * Draws a background for the data area. The default implementation just
590      * gets the plot to draw the outline, but some renderers will override this
591      * behaviour.
592      *
593      * @param g2 the graphics device.
594      * @param plot the plot.
595      * @param dataArea the data area.
596      */

597     public void drawBackground(Graphics2D JavaDoc g2,
598                                CategoryPlot plot,
599                                Rectangle2D JavaDoc dataArea) {
600
601         plot.drawBackground(g2, dataArea);
602
603     }
604
605     /**
606      * Draws an outline for the data area. The default implementation just
607      * gets the plot to draw the outline, but some renderers will override this
608      * behaviour.
609      *
610      * @param g2 the graphics device.
611      * @param plot the plot.
612      * @param dataArea the data area.
613      */

614     public void drawOutline(Graphics2D JavaDoc g2,
615                             CategoryPlot plot,
616                             Rectangle2D JavaDoc dataArea) {
617
618         plot.drawOutline(g2, dataArea);
619
620     }
621
622     /**
623      * Draws a grid line against the domain axis.
624      * <P>
625      * Note that this default implementation assumes that the horizontal axis
626      * is the domain axis. If this is not the case, you will need to override
627      * this method.
628      *
629      * @param g2 the graphics device.
630      * @param plot the plot.
631      * @param dataArea the area for plotting data (not yet adjusted for any
632      * 3D effect).
633      * @param value the Java2D value at which the grid line should be drawn.
634      */

635     public void drawDomainGridline(Graphics2D JavaDoc g2,
636                                    CategoryPlot plot,
637                                    Rectangle2D JavaDoc dataArea,
638                                    double value) {
639
640         Line2D JavaDoc line = null;
641         PlotOrientation orientation = plot.getOrientation();
642
643         if (orientation == PlotOrientation.HORIZONTAL) {
644             line = new Line2D.Double JavaDoc(dataArea.getMinX(), value,
645                     dataArea.getMaxX(), value);
646         }
647         else if (orientation == PlotOrientation.VERTICAL) {
648             line = new Line2D.Double JavaDoc(value, dataArea.getMinY(), value,
649                     dataArea.getMaxY());
650         }
651
652         Paint JavaDoc paint = plot.getDomainGridlinePaint();
653         if (paint == null) {
654             paint = CategoryPlot.DEFAULT_GRIDLINE_PAINT;
655         }
656         g2.setPaint(paint);
657
658         Stroke JavaDoc stroke = plot.getDomainGridlineStroke();
659         if (stroke == null) {
660             stroke = CategoryPlot.DEFAULT_GRIDLINE_STROKE;
661         }
662         g2.setStroke(stroke);
663
664         g2.draw(line);
665
666     }
667
668     /**
669      * Draws a grid line against the range axis.
670      *
671      * @param g2 the graphics device.
672      * @param plot the plot.
673      * @param axis the value axis.
674      * @param dataArea the area for plotting data (not yet adjusted for any
675      * 3D effect).
676      * @param value the value at which the grid line should be drawn.
677      *
678      */

679     public void drawRangeGridline(Graphics2D JavaDoc g2,
680                                   CategoryPlot plot,
681                                   ValueAxis axis,
682                                   Rectangle2D JavaDoc dataArea,
683                                   double value) {
684
685         Range range = axis.getRange();
686         if (!range.contains(value)) {
687             return;
688         }
689
690         PlotOrientation orientation = plot.getOrientation();
691         double v = axis.valueToJava2D(value, dataArea, plot.getRangeAxisEdge());
692         Line2D JavaDoc line = null;
693         if (orientation == PlotOrientation.HORIZONTAL) {
694             line = new Line2D.Double JavaDoc(v, dataArea.getMinY(), v,
695                     dataArea.getMaxY());
696         }
697         else if (orientation == PlotOrientation.VERTICAL) {
698             line = new Line2D.Double JavaDoc(dataArea.getMinX(), v,
699                     dataArea.getMaxX(), v);
700         }
701
702         Paint JavaDoc paint = plot.getRangeGridlinePaint();
703         if (paint == null) {
704             paint = CategoryPlot.DEFAULT_GRIDLINE_PAINT;
705         }
706         g2.setPaint(paint);
707
708         Stroke JavaDoc stroke = plot.getRangeGridlineStroke();
709         if (stroke == null) {
710             stroke = CategoryPlot.DEFAULT_GRIDLINE_STROKE;
711         }
712         g2.setStroke(stroke);
713
714         g2.draw(line);
715
716     }
717
718     /**
719      * Draws a marker for the domain axis.
720      *
721      * @param g2 the graphics device (not <code>null</code>).
722      * @param plot the plot (not <code>null</code>).
723      * @param axis the range axis (not <code>null</code>).
724      * @param marker the marker to be drawn (not <code>null</code>).
725      * @param dataArea the area inside the axes (not <code>null</code>).
726      */

727     public void drawDomainMarker(Graphics2D JavaDoc g2,
728                                  CategoryPlot plot,
729                                  CategoryAxis axis,
730                                  CategoryMarker marker,
731                                  Rectangle2D JavaDoc dataArea) {
732
733         Comparable JavaDoc category = marker.getKey();
734         CategoryDataset dataset = plot.getDataset(plot.getIndexOf(this));
735         int columnIndex = dataset.getColumnIndex(category);
736         if (columnIndex < 0) {
737             return;
738         }
739
740         final Composite JavaDoc savedComposite = g2.getComposite();
741         g2.setComposite(AlphaComposite.getInstance(
742                 AlphaComposite.SRC_OVER, marker.getAlpha()));
743         
744         PlotOrientation orientation = plot.getOrientation();
745         Rectangle2D JavaDoc bounds = null;
746         if (marker.getDrawAsLine()) {
747             double v = axis.getCategoryMiddle(columnIndex,
748                     dataset.getColumnCount(), dataArea,
749                     plot.getDomainAxisEdge());
750             Line2D JavaDoc line = null;
751             if (orientation == PlotOrientation.HORIZONTAL) {
752                 line = new Line2D.Double JavaDoc(dataArea.getMinX(), v,
753                         dataArea.getMaxX(), v);
754             }
755             else if (orientation == PlotOrientation.VERTICAL) {
756                 line = new Line2D.Double JavaDoc(v, dataArea.getMinY(), v,
757                         dataArea.getMaxY());
758             }
759             g2.setPaint(marker.getPaint());
760             g2.setStroke(marker.getStroke());
761             g2.draw(line);
762             bounds = line.getBounds2D();
763         }
764         else {
765             double v0 = axis.getCategoryStart(columnIndex,
766                     dataset.getColumnCount(), dataArea,
767                     plot.getDomainAxisEdge());
768             double v1 = axis.getCategoryEnd(columnIndex,
769                     dataset.getColumnCount(), dataArea,
770                     plot.getDomainAxisEdge());
771             Rectangle2D JavaDoc area = null;
772             if (orientation == PlotOrientation.HORIZONTAL) {
773                 area = new Rectangle2D.Double JavaDoc(dataArea.getMinX(), v0,
774                         dataArea.getWidth(), (v1 - v0));
775             }
776             else if (orientation == PlotOrientation.VERTICAL) {
777                 area = new Rectangle2D.Double JavaDoc(v0, dataArea.getMinY(),
778                         (v1 - v0), dataArea.getHeight());
779             }
780             g2.setPaint(marker.getPaint());
781             g2.fill(area);
782             bounds = area;
783         }
784         
785         String JavaDoc label = marker.getLabel();
786         RectangleAnchor anchor = marker.getLabelAnchor();
787         if (label != null) {
788             Font JavaDoc labelFont = marker.getLabelFont();
789             g2.setFont(labelFont);
790             g2.setPaint(marker.getLabelPaint());
791             Point2D JavaDoc coordinates = calculateDomainMarkerTextAnchorPoint(
792                     g2, orientation, dataArea, bounds, marker.getLabelOffset(),
793                     marker.getLabelOffsetType(), anchor);
794             TextUtilities.drawAlignedString(label, g2,
795                     (float) coordinates.getX(), (float) coordinates.getY(),
796                     marker.getLabelTextAnchor());
797         }
798         g2.setComposite(savedComposite);
799     }
800
801     /**
802      * Draws a marker for the range axis.
803      *
804      * @param g2 the graphics device (not <code>null</code>).
805      * @param plot the plot (not <code>null</code>).
806      * @param axis the range axis (not <code>null</code>).
807      * @param marker the marker to be drawn (not <code>null</code>).
808      * @param dataArea the area inside the axes (not <code>null</code>).
809      */

810     public void drawRangeMarker(Graphics2D JavaDoc g2,
811                                 CategoryPlot plot,
812                                 ValueAxis axis,
813                                 Marker marker,
814                                 Rectangle2D JavaDoc dataArea) {
815
816         if (marker instanceof ValueMarker) {
817             ValueMarker vm = (ValueMarker) marker;
818             double value = vm.getValue();
819             Range range = axis.getRange();
820
821             if (!range.contains(value)) {
822                 return;
823             }
824
825             final Composite JavaDoc savedComposite = g2.getComposite();
826             g2.setComposite(AlphaComposite.getInstance(
827                     AlphaComposite.SRC_OVER, marker.getAlpha()));
828
829             PlotOrientation orientation = plot.getOrientation();
830             double v = axis.valueToJava2D(value, dataArea,
831                     plot.getRangeAxisEdge());
832             Line2D JavaDoc line = null;
833             if (orientation == PlotOrientation.HORIZONTAL) {
834                 line = new Line2D.Double JavaDoc(v, dataArea.getMinY(), v,
835                         dataArea.getMaxY());
836             }
837             else if (orientation == PlotOrientation.VERTICAL) {
838                 line = new Line2D.Double JavaDoc(dataArea.getMinX(), v,
839                         dataArea.getMaxX(), v);
840             }
841
842             g2.setPaint(marker.getPaint());
843             g2.setStroke(marker.getStroke());
844             g2.draw(line);
845         
846             String JavaDoc label = marker.getLabel();
847             RectangleAnchor anchor = marker.getLabelAnchor();
848             if (label != null) {
849                 Font JavaDoc labelFont = marker.getLabelFont();
850                 g2.setFont(labelFont);
851                 g2.setPaint(marker.getLabelPaint());
852                 Point2D JavaDoc coordinates = calculateRangeMarkerTextAnchorPoint(
853                         g2, orientation, dataArea, line.getBounds2D(),
854                         marker.getLabelOffset(), LengthAdjustmentType.EXPAND,
855                         anchor);
856                 TextUtilities.drawAlignedString(label, g2,
857                         (float) coordinates.getX(), (float) coordinates.getY(),
858                         marker.getLabelTextAnchor());
859             }
860             g2.setComposite(savedComposite);
861         }
862         else if (marker instanceof IntervalMarker) {
863             
864             IntervalMarker im = (IntervalMarker) marker;
865             double start = im.getStartValue();
866             double end = im.getEndValue();
867             Range range = axis.getRange();
868             if (!(range.intersects(start, end))) {
869                 return;
870             }
871             
872             final Composite JavaDoc savedComposite = g2.getComposite();
873             g2.setComposite(AlphaComposite.getInstance(
874                     AlphaComposite.SRC_OVER, marker.getAlpha()));
875
876             double start2d = axis.valueToJava2D(start, dataArea,
877                     plot.getRangeAxisEdge());
878             double end2d = axis.valueToJava2D(end, dataArea,
879                     plot.getRangeAxisEdge());
880             
881             PlotOrientation orientation = plot.getOrientation();
882             Rectangle2D JavaDoc rect = null;
883             if (orientation == PlotOrientation.HORIZONTAL) {
884                 rect = new Rectangle2D.Double JavaDoc(Math.min(start2d, end2d),
885                         dataArea.getMinY(), Math.abs(end2d - start2d),
886                         dataArea.getHeight());
887             }
888             else if (orientation == PlotOrientation.VERTICAL) {
889                 rect = new Rectangle2D.Double JavaDoc(dataArea.getMinX(),
890                         Math.min(start2d, end2d), dataArea.getWidth(),
891                         Math.abs(end2d - start2d));
892             }
893             Paint JavaDoc p = marker.getPaint();
894             if (p instanceof GradientPaint JavaDoc) {
895                 GradientPaint JavaDoc gp = (GradientPaint JavaDoc) p;
896                 GradientPaintTransformer t = im.getGradientPaintTransformer();
897                 if (t != null) {
898                     gp = t.transform(gp, rect);
899                 }
900                 g2.setPaint(gp);
901             }
902             else {
903                 g2.setPaint(p);
904             }
905             g2.fill(rect);
906             
907             // now draw the outlines, if visible...
908
if (im.getOutlinePaint() != null && im.getOutlineStroke() != null) {
909                 double x0 = rect.getMinX();
910                 double x1 = rect.getMaxX();
911                 double y0 = rect.getMinY();
912                 double y1 = rect.getMaxY();
913                 if (orientation == PlotOrientation.VERTICAL) {
914                     Line2D JavaDoc line = new Line2D.Double JavaDoc(x0, y0, x1, y0);
915                     g2.setPaint(im.getOutlinePaint());
916                     g2.setStroke(im.getOutlineStroke());
917                     g2.draw(line);
918                     line.setLine(x0, y1, x1, y1);
919                     g2.draw(line);
920                 }
921                 else { // PlotOrientation.HORIZONTAL
922
Line2D JavaDoc line = new Line2D.Double JavaDoc(x0, y0, x0, y1);
923                     g2.setPaint(im.getOutlinePaint());
924                     g2.setStroke(im.getOutlineStroke());
925                     g2.draw(line);
926                     line.setLine(x1, y0, x1, y1);
927                     g2.draw(line);
928                 }
929             }
930
931             String JavaDoc label = marker.getLabel();
932             RectangleAnchor anchor = marker.getLabelAnchor();
933             if (label != null) {
934                 Font JavaDoc labelFont = marker.getLabelFont();
935                 g2.setFont(labelFont);
936                 g2.setPaint(marker.getLabelPaint());
937                 Point2D JavaDoc coordinates = calculateRangeMarkerTextAnchorPoint(
938                         g2, orientation, dataArea, rect,
939                         marker.getLabelOffset(), marker.getLabelOffsetType(),
940                         anchor);
941                 TextUtilities.drawAlignedString(label, g2,
942                         (float) coordinates.getX(), (float) coordinates.getY(),
943                         marker.getLabelTextAnchor());
944             }
945             g2.setComposite(savedComposite);
946             
947         }
948
949     }
950
951     /**
952      * Calculates the (x, y) coordinates for drawing the label for a marker on
953      * the range axis.
954      *
955      * @param g2 the graphics device.
956      * @param orientation the plot orientation.
957      * @param dataArea the data area.
958      * @param markerArea the rectangle surrounding the marker.
959      * @param markerOffset the marker offset.
960      * @param labelOffsetType the label offset type.
961      * @param anchor the label anchor.
962      *
963      * @return The coordinates for drawing the marker label.
964      */

965     protected Point2D JavaDoc calculateDomainMarkerTextAnchorPoint(Graphics2D JavaDoc g2,
966                                       PlotOrientation orientation,
967                                       Rectangle2D JavaDoc dataArea,
968                                       Rectangle2D JavaDoc markerArea,
969                                       RectangleInsets markerOffset,
970                                       LengthAdjustmentType labelOffsetType,
971                                       RectangleAnchor anchor) {
972                                                      
973         Rectangle2D JavaDoc anchorRect = null;
974         if (orientation == PlotOrientation.HORIZONTAL) {
975             anchorRect = markerOffset.createAdjustedRectangle(markerArea,
976                     LengthAdjustmentType.CONTRACT, labelOffsetType);
977         }
978         else if (orientation == PlotOrientation.VERTICAL) {
979             anchorRect = markerOffset.createAdjustedRectangle(markerArea,
980                     labelOffsetType, LengthAdjustmentType.CONTRACT);
981         }
982         return RectangleAnchor.coordinates(anchorRect, anchor);
983         
984     }
985
986     /**
987      * Calculates the (x, y) coordinates for drawing a marker label.
988      *
989      * @param g2 the graphics device.
990      * @param orientation the plot orientation.
991      * @param dataArea the data area.
992      * @param markerArea the rectangle surrounding the marker.
993      * @param markerOffset the marker offset.
994      * @param labelOffsetType the label offset type.
995      * @param anchor the label anchor.
996      *
997      * @return The coordinates for drawing the marker label.
998      */

999     protected Point2D JavaDoc calculateRangeMarkerTextAnchorPoint(Graphics2D JavaDoc g2,
1000                                      PlotOrientation orientation,
1001                                      Rectangle2D JavaDoc dataArea,
1002                                      Rectangle2D JavaDoc markerArea,
1003                                      RectangleInsets markerOffset,
1004                                      LengthAdjustmentType labelOffsetType,
1005                                      RectangleAnchor anchor) {
1006                                                     
1007        Rectangle2D JavaDoc anchorRect = null;
1008        if (orientation == PlotOrientation.HORIZONTAL) {
1009            anchorRect = markerOffset.createAdjustedRectangle(markerArea,
1010                    labelOffsetType, LengthAdjustmentType.CONTRACT);
1011        }
1012        else if (orientation == PlotOrientation.VERTICAL) {
1013            anchorRect = markerOffset.createAdjustedRectangle(markerArea,
1014                    LengthAdjustmentType.CONTRACT, labelOffsetType);
1015        }
1016        return RectangleAnchor.coordinates(anchorRect, anchor);
1017        
1018    }
1019    
1020    /**
1021     * Returns a legend item for a series.
1022     *
1023     * @param datasetIndex the dataset index (zero-based).
1024     * @param series the series index (zero-based).
1025     *
1026     * @return The legend item.
1027     */

1028    public LegendItem getLegendItem(int datasetIndex, int series) {
1029
1030        CategoryPlot p = getPlot();
1031        if (p == null) {
1032            return null;
1033        }
1034
1035        CategoryDataset dataset;
1036        dataset = p.getDataset(datasetIndex);
1037        String JavaDoc label = this.legendItemLabelGenerator.generateLabel(dataset,
1038                series);
1039        String JavaDoc description = label;
1040        String JavaDoc toolTipText = null;
1041        if (this.legendItemToolTipGenerator != null) {
1042            toolTipText = this.legendItemToolTipGenerator.generateLabel(
1043                    dataset, series);
1044        }
1045        String JavaDoc urlText = null;
1046        if (this.legendItemURLGenerator != null) {
1047            urlText = this.legendItemURLGenerator.generateLabel(dataset,
1048                    series);
1049        }
1050        Shape JavaDoc shape = getSeriesShape(series);
1051        Paint JavaDoc paint = getSeriesPaint(series);
1052        Paint JavaDoc outlinePaint = getSeriesOutlinePaint(series);
1053        Stroke JavaDoc outlineStroke = getSeriesOutlineStroke(series);
1054     
1055        LegendItem item = new LegendItem(label, description, toolTipText,
1056                urlText, shape, paint, outlineStroke, outlinePaint);
1057        item.setSeriesIndex(series);
1058        item.setDatasetIndex(datasetIndex);
1059        return item;
1060    }
1061
1062    /**
1063     * Tests this renderer for equality with another object.
1064     *
1065     * @param obj the object.
1066     *
1067     * @return <code>true</code> or <code>false</code>.
1068     */

1069    public boolean equals(Object JavaDoc obj) {
1070
1071        if (obj == this) {
1072            return true;
1073        }
1074        if (!(obj instanceof AbstractCategoryItemRenderer)) {
1075            return false;
1076        }
1077        if (!super.equals(obj)) {
1078            return false;
1079        }
1080
1081        AbstractCategoryItemRenderer that = (AbstractCategoryItemRenderer) obj;
1082
1083        if (!ObjectUtilities.equal(this.itemLabelGenerator,
1084                that.itemLabelGenerator)) {
1085            return false;
1086        }
1087        if (!ObjectUtilities.equal(this.itemLabelGeneratorList,
1088                that.itemLabelGeneratorList)) {
1089            return false;
1090        }
1091        if (!ObjectUtilities.equal(this.baseItemLabelGenerator,
1092                that.baseItemLabelGenerator)) {
1093            return false;
1094        }
1095        if (!ObjectUtilities.equal(this.toolTipGenerator,
1096                that.toolTipGenerator)) {
1097            return false;
1098        }
1099        if (!ObjectUtilities.equal(this.toolTipGeneratorList,
1100                that.toolTipGeneratorList)) {
1101            return false;
1102        }
1103        if (!ObjectUtilities.equal(this.baseToolTipGenerator,
1104                that.baseToolTipGenerator)) {
1105            return false;
1106        }
1107        if (!ObjectUtilities.equal(this.itemURLGenerator,
1108                that.itemURLGenerator)) {
1109            return false;
1110        }
1111        if (!ObjectUtilities.equal(this.itemURLGeneratorList,
1112                that.itemURLGeneratorList)) {
1113            return false;
1114        }
1115        if (!ObjectUtilities.equal(this.baseItemURLGenerator,
1116                that.baseItemURLGenerator)) {
1117            return false;
1118        }
1119
1120        return true;
1121
1122    }
1123    
1124    /**
1125     * Returns a hash code for the renderer.
1126     *
1127     * @return The hash code.
1128     */

1129    public int hashCode() {
1130        int result = super.hashCode();
1131        return result;
1132    }
1133
1134    /**
1135     * Returns the drawing supplier from the plot.
1136     *
1137     * @return The drawing supplier (possibly <code>null</code>).
1138     */

1139    public DrawingSupplier getDrawingSupplier() {
1140        DrawingSupplier result = null;
1141        CategoryPlot cp = getPlot();
1142        if (cp != null) {
1143            result = cp.getDrawingSupplier();
1144        }
1145        return result;
1146    }
1147
1148    /**
1149     * Draws an item label.
1150     *
1151     * @param g2 the graphics device.
1152     * @param orientation the orientation.
1153     * @param dataset the dataset.
1154     * @param row the row.
1155     * @param column the column.
1156     * @param x the x coordinate (in Java2D space).
1157     * @param y the y coordinate (in Java2D space).
1158     * @param negative indicates a negative value (which affects the item
1159     * label position).
1160     */

1161    protected void drawItemLabel(Graphics2D JavaDoc g2,
1162                                 PlotOrientation orientation,
1163                                 CategoryDataset dataset,
1164                                 int row, int column,
1165                                 double x, double y,
1166                                 boolean negative) {
1167                                     
1168        CategoryItemLabelGenerator generator
1169            = getItemLabelGenerator(row, column);
1170        if (generator != null) {
1171            Font JavaDoc labelFont = getItemLabelFont(row, column);
1172            Paint JavaDoc paint = getItemLabelPaint(row, column);
1173            g2.setFont(labelFont);
1174            g2.setPaint(paint);
1175            String JavaDoc label = generator.generateLabel(dataset, row, column);
1176            ItemLabelPosition position = null;
1177            if (!negative) {
1178                position = getPositiveItemLabelPosition(row, column);
1179            }
1180            else {
1181                position = getNegativeItemLabelPosition(row, column);
1182            }
1183            Point2D JavaDoc anchorPoint = calculateLabelAnchorPoint(
1184                    position.getItemLabelAnchor(), x, y, orientation);
1185            TextUtilities.drawRotatedString(label, g2,
1186                    (float) anchorPoint.getX(), (float) anchorPoint.getY(),
1187                    position.getTextAnchor(),
1188                    position.getAngle(), position.getRotationAnchor());
1189        }
1190
1191    }
1192    
1193    /**
1194     * Returns an independent copy of the renderer. The <code>plot</code>
1195     * reference is shallow copied.
1196     *
1197     * @return A clone.
1198     *
1199     * @throws CloneNotSupportedException can be thrown if one of the objects
1200     * belonging to the renderer does not support cloning (for example,
1201     * an item label generator).
1202     */

1203    public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc {
1204        
1205        AbstractCategoryItemRenderer clone
1206            = (AbstractCategoryItemRenderer) super.clone();
1207
1208        if (this.itemLabelGenerator != null) {
1209            if (this.itemLabelGenerator instanceof PublicCloneable) {
1210                PublicCloneable pc = (PublicCloneable) this.itemLabelGenerator;
1211                clone.itemLabelGenerator
1212                    = (CategoryItemLabelGenerator) pc.clone();
1213            }
1214            else {
1215                throw new CloneNotSupportedException JavaDoc(
1216                    "ItemLabelGenerator not cloneable."
1217                );
1218            }
1219        }
1220
1221        if (this.itemLabelGeneratorList != null) {
1222            clone.itemLabelGeneratorList
1223                = (ObjectList) this.itemLabelGeneratorList.clone();
1224        }
1225        
1226        if (this.baseItemLabelGenerator != null) {
1227            if (this.baseItemLabelGenerator instanceof PublicCloneable) {
1228                PublicCloneable pc
1229                    = (PublicCloneable) this.baseItemLabelGenerator;
1230                clone.baseItemLabelGenerator
1231                    = (CategoryItemLabelGenerator) pc.clone();
1232            }
1233            else {
1234                throw new CloneNotSupportedException JavaDoc(
1235                    "ItemLabelGenerator not cloneable."
1236                );
1237            }
1238        }
1239        
1240        if (this.toolTipGenerator != null) {
1241            if (this.toolTipGenerator instanceof PublicCloneable) {
1242                PublicCloneable pc = (PublicCloneable) this.toolTipGenerator;
1243                clone.toolTipGenerator = (CategoryToolTipGenerator) pc.clone();
1244            }
1245            else {
1246                throw new CloneNotSupportedException JavaDoc(
1247                        "Tool tip generator not cloneable.");
1248            }
1249        }
1250
1251        if (this.toolTipGeneratorList != null) {
1252            clone.toolTipGeneratorList
1253                = (ObjectList) this.toolTipGeneratorList.clone();
1254        }
1255        
1256        if (this.baseToolTipGenerator != null) {
1257            if (this.baseToolTipGenerator instanceof PublicCloneable) {
1258                PublicCloneable pc
1259                    = (PublicCloneable) this.baseToolTipGenerator;
1260                clone.baseToolTipGenerator
1261                    = (CategoryToolTipGenerator) pc.clone();
1262            }
1263            else {
1264                throw new CloneNotSupportedException JavaDoc(
1265                        "Base tool tip generator not cloneable.");
1266            }
1267        }
1268        
1269        if (this.itemURLGenerator != null) {
1270            if (this.itemURLGenerator instanceof PublicCloneable) {
1271                PublicCloneable pc = (PublicCloneable) this.itemURLGenerator;
1272                clone.itemURLGenerator = (CategoryURLGenerator) pc.clone();
1273            }
1274            else {
1275                throw new CloneNotSupportedException JavaDoc(
1276                        "Item URL generator not cloneable.");
1277            }
1278        }
1279
1280        if (this.itemURLGeneratorList != null) {
1281            clone.itemURLGeneratorList
1282                = (ObjectList) this.itemURLGeneratorList.clone();
1283        }
1284
1285        if (this.baseItemURLGenerator != null) {
1286            if (this.baseItemURLGenerator instanceof PublicCloneable) {
1287                PublicCloneable pc
1288                    = (PublicCloneable) this.baseItemURLGenerator;
1289                clone.baseItemURLGenerator = (CategoryURLGenerator) pc.clone();
1290            }
1291            else {
1292                throw new CloneNotSupportedException JavaDoc(
1293                        "Base item URL generator not cloneable.");
1294            }
1295        }
1296        
1297        return clone;
1298    }
1299
1300    /**
1301     * Returns a domain axis for a plot.
1302     *
1303     * @param plot the plot.
1304     * @param index the axis index.
1305     *
1306     * @return A domain axis.
1307     */

1308    protected CategoryAxis getDomainAxis(CategoryPlot plot, int index) {
1309        CategoryAxis result = plot.getDomainAxis(index);
1310        if (result == null) {
1311            result = plot.getDomainAxis();
1312        }
1313        return result;
1314    }
1315
1316    /**
1317     * Returns a range axis for a plot.
1318     *
1319     * @param plot the plot.
1320     * @param index the axis index (<code>null</code> for the primary axis).
1321     *
1322     * @return A range axis.
1323     */

1324    protected ValueAxis getRangeAxis(CategoryPlot plot, int index) {
1325        ValueAxis result = plot.getRangeAxis(index);
1326        if (result == null) {
1327            result = plot.getRangeAxis();
1328        }
1329        return result;
1330    }
1331    
1332    /**
1333     * Returns a (possibly empty) collection of legend items for the series
1334     * that this renderer is responsible for drawing.
1335     *
1336     * @return The legend item collection (never <code>null</code>).
1337     */

1338    public LegendItemCollection getLegendItems() {
1339        if (this.plot == null) {
1340            return new LegendItemCollection();
1341        }
1342        LegendItemCollection result = new LegendItemCollection();
1343        int index = this.plot.getIndexOf(this);
1344        CategoryDataset dataset = this.plot.getDataset(index);
1345        if (dataset != null) {
1346            int seriesCount = dataset.getRowCount();
1347            for (int i = 0; i < seriesCount; i++) {
1348                if (isSeriesVisibleInLegend(i)) {
1349                    LegendItem item = getLegendItem(index, i);
1350                    if (item != null) {
1351                        result.add(item);
1352                    }
1353                }
1354            }
1355   
1356        }
1357        return result;
1358    }
1359    
1360    /**
1361     * Returns the legend item label generator.
1362     *
1363     * @return The label generator (never <code>null</code>).
1364     */

1365    public CategorySeriesLabelGenerator getLegendItemLabelGenerator() {
1366        return this.legendItemLabelGenerator;
1367    }
1368    
1369    /**
1370     * Sets the legend item label generator.
1371     *
1372     * @param generator the generator (<code>null</code> not permitted).
1373     */

1374    public void setLegendItemLabelGenerator(
1375            CategorySeriesLabelGenerator generator) {
1376        if (generator == null) {
1377            throw new IllegalArgumentException JavaDoc("Null 'generator' argument.");
1378        }
1379        this.legendItemLabelGenerator = generator;
1380    }
1381    
1382    /**
1383     * Returns the legend item tool tip generator.
1384     *
1385     * @return The tool tip generator (possibly <code>null</code>).
1386     */

1387    public CategorySeriesLabelGenerator getLegendItemToolTipGenerator() {
1388        return this.legendItemToolTipGenerator;
1389    }
1390    
1391    /**
1392     * Sets the legend item tool tip generator.
1393     *
1394     * @param generator the generator (<code>null</code> permitted).
1395     */

1396    public void setLegendItemToolTipGenerator(
1397            CategorySeriesLabelGenerator generator) {
1398        this.legendItemToolTipGenerator = generator;
1399    }
1400
1401    /**
1402     * Returns the legend item URL generator.
1403     *
1404     * @return The URL generator (possibly <code>null</code>).
1405     */

1406    public CategorySeriesLabelGenerator getLegendItemURLGenerator() {
1407        return this.legendItemURLGenerator;
1408    }
1409    
1410    /**
1411     * Sets the legend item URL generator.
1412     *
1413     * @param generator the generator (<code>null</code> permitted).
1414     */

1415    public void setLegendItemURLGenerator(
1416            CategorySeriesLabelGenerator generator) {
1417        this.legendItemURLGenerator = generator;
1418    }
1419    
1420    /**
1421     * Adds an entity with the specified hotspot, but only if an entity
1422     * collection is accessible via the renderer state.
1423     *
1424     * @param entities the entity collection.
1425     * @param dataset the dataset.
1426     * @param row the row index.
1427     * @param column the column index.
1428     * @param hotspot the hotspot.
1429     */

1430    protected void addItemEntity(EntityCollection entities,
1431                                 CategoryDataset dataset, int row, int column,
1432                                 Shape JavaDoc hotspot) {
1433
1434        String JavaDoc tip = null;
1435        CategoryToolTipGenerator tipster = getToolTipGenerator(row, column);
1436        if (tipster != null) {
1437            tip = tipster.generateToolTip(dataset, row, column);
1438        }
1439        String JavaDoc url = null;
1440        CategoryURLGenerator urlster = getItemURLGenerator(row, column);
1441        if (urlster != null) {
1442            url = urlster.generateURL(dataset, row, column);
1443        }
1444        CategoryItemEntity entity = new CategoryItemEntity(hotspot, tip, url,
1445                dataset, row, dataset.getColumnKey(column), column);
1446        entities.add(entity);
1447    
1448    }
1449
1450}
1451
Popular Tags