KickJava   Java API By Example, From Geeks To Geeks.

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


1 /* ======================================
2  * JFreeChart : a free Java chart library
3  * ======================================
4  *
5  * Project Info: http://www.jfree.org/jfreechart/index.html
6  * Project Lead: David Gilbert (david.gilbert@object-refinery.com);
7  *
8  * (C) Copyright 2000-2003, by Object Refinery Limited and Contributors.
9  *
10  * This library is free software; you can redistribute it and/or modify it under the terms
11  * of the GNU Lesser General Public License as published by the Free Software Foundation;
12  * either version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License along with this
19  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20  * Boston, MA 02111-1307, USA.
21  *
22  * ---------------------------------
23  * AbstractCategoryItemRenderer.java
24  * ---------------------------------
25  * (C) Copyright 2002, 2003 by Object Refinery Limited.
26  *
27  * Original Author: David Gilbert (for Object Refinery Limited);
28  * Contributor(s): Richard Atkinson;
29  *
30  * $Id: AbstractCategoryItemRenderer.java,v 1.29 2003/11/05 11:28:36 mungady Exp $
31  *
32  * Changes:
33  * --------
34  * 29-May-2002 : Version 1 (DG);
35  * 06-Jun-2002 : Added accessor methods for the tool tip generator (DG);
36  * 11-Jun-2002 : Made constructors protected (DG);
37  * 26-Jun-2002 : Added axis to initialise method (DG);
38  * 05-Aug-2002 : Added urlGenerator member variable plus accessors (RA);
39  * 22-Aug-2002 : Added categoriesPaint attribute, based on code submitted by Janet Banks.
40  * This can be used when there is only one series, and you want each category
41  * item to have a different color (DG);
42  * 01-Oct-2002 : Fixed errors reported by Checkstyle (DG);
43  * 29-Oct-2002 : Fixed bug where background image for plot was not being drawn (DG);
44  * 05-Nov-2002 : Replaced references to CategoryDataset with TableDataset (DG);
45  * 26-Nov 2002 : Replaced the isStacked() method with getRangeType() (DG);
46  * 09-Jan-2003 : Renamed grid-line methods (DG);
47  * 17-Jan-2003 : Moved plot classes into separate package (DG);
48  * 25-Mar-2003 : Implemented Serializable (DG);
49  * 12-May-2003 : Modified to take into account the plot orientation (DG);
50  * 12-Aug-2003 : Very minor javadoc corrections (DB)
51  * 13-Aug-2003 : Implemented Cloneable (DG);
52  * 16-Sep-2003 : Changed ChartRenderingInfo --> PlotRenderingInfo (DG);
53  * 05-Nov-2003 : Fixed marker rendering bug (833623) (DG);
54  *
55  */

56
57 package org.jfree.chart.renderer;
58
59 import java.awt.Font JavaDoc;
60 import java.awt.FontMetrics JavaDoc;
61 import java.awt.Graphics2D JavaDoc;
62 import java.awt.Paint JavaDoc;
63 import java.awt.Shape JavaDoc;
64 import java.awt.Stroke JavaDoc;
65 import java.awt.font.FontRenderContext JavaDoc;
66 import java.awt.font.LineMetrics JavaDoc;
67 import java.awt.geom.Line2D JavaDoc;
68 import java.awt.geom.Point2D JavaDoc;
69 import java.awt.geom.Rectangle2D JavaDoc;
70 import java.io.Serializable JavaDoc;
71
72 import org.jfree.chart.LegendItem;
73 import org.jfree.chart.Marker;
74 import org.jfree.chart.MarkerLabelPosition;
75 import org.jfree.chart.axis.CategoryAxis;
76 import org.jfree.chart.axis.ValueAxis;
77 import org.jfree.chart.labels.CategoryItemLabelGenerator;
78 import org.jfree.chart.plot.CategoryPlot;
79 import org.jfree.chart.plot.DrawingSupplier;
80 import org.jfree.chart.plot.PlotOrientation;
81 import org.jfree.chart.plot.PlotRenderingInfo;
82 import org.jfree.chart.urls.CategoryURLGenerator;
83 import org.jfree.data.CategoryDataset;
84 import org.jfree.data.Range;
85 import org.jfree.ui.RefineryUtilities;
86 import org.jfree.util.NumberUtils;
87 import org.jfree.util.ObjectList;
88 import org.jfree.util.ObjectUtils;
89
90 /**
91  * An abstract base class that you can use to implement a new {@link CategoryItemRenderer}.
92  * <p>
93  * When you create a new {@link CategoryItemRenderer} you are not required to extend this class,
94  * but it makes the job easier.
95  *
96  * @author David Gilbert
97  */

98 public abstract class AbstractCategoryItemRenderer extends AbstractRenderer
99                                                    implements CategoryItemRenderer,
100                                                               Cloneable JavaDoc,
101                                                               Serializable JavaDoc {
102
103     /** The plot that the renderer is assigned to. */
104     private CategoryPlot plot;
105
106     /** The item label generator for ALL series. */
107     private CategoryItemLabelGenerator itemLabelGenerator;
108
109     /** A list of item label generators (one per series). */
110     private ObjectList itemLabelGeneratorList;
111
112     /** The base item label generator. */
113     private CategoryItemLabelGenerator baseItemLabelGenerator;
114
115     /** The URL generator. */
116     private CategoryURLGenerator itemURLGenerator;
117
118     /** A list of item label generators (one per series). */
119     private ObjectList itemURLGeneratorList;
120
121     /** The base item label generator. */
122     private CategoryURLGenerator baseItemURLGenerator;
123
124     /** The number of rows in the dataset (temporary record). */
125     private transient int rowCount;
126
127     /** The number of columns in the dataset (temporary record). */
128     private transient int columnCount;
129
130     /** The item label anchor offset. */
131     private double itemLabelAnchorOffset = 2.0;
132
133     /**
134      * Creates a new renderer with no tool tip generator and no URL generator.
135      * <P>
136      * The defaults (no tool tip or URL generators) have been chosen to minimise the processing
137      * required to generate a default chart. If you require tool tips or URLs, then you can
138      * easily add the required generators.
139      */

140     protected AbstractCategoryItemRenderer() {
141         this.itemLabelGenerator = null;
142         this.itemLabelGeneratorList = new ObjectList();
143         this.itemURLGenerator = null;
144         this.itemURLGeneratorList = new ObjectList();
145     }
146
147     /**
148      * Returns the plot that the renderer is currently assigned to.
149      *
150      * @return The plot.
151      */

152     public CategoryPlot getPlot() {
153         return this.plot;
154     }
155
156     /**
157      * Sets the plot that the renderer is currently assigned to.
158      *
159      * @param plot the plot.
160      */

161     public void setPlot(CategoryPlot plot) {
162         this.plot = plot;
163     }
164
165     /**
166      * Returns the label generator for a data item. This method just calls the
167      * getSeriesItemLabelGenerator method, but you can override this behaviour if you want to.
168      *
169      * @param row the row index (zero based).
170      * @param column the column index (zero based).
171      *
172      * @return The label generator.
173      */

174     public CategoryItemLabelGenerator getItemLabelGenerator(int row, int column) {
175         return getSeriesItemLabelGenerator(row);
176     }
177
178     /**
179      * Returns the label generator for a series.
180      *
181      * @param series the series index (zero based).
182      *
183      * @return The label generator for the series.
184      */

185     public CategoryItemLabelGenerator getSeriesItemLabelGenerator(int series) {
186
187         // return the generator for ALL series, if there is one...
188
if (this.itemLabelGenerator != null) {
189             return this.itemLabelGenerator;
190         }
191
192         // otherwise look up the generator table
193
CategoryItemLabelGenerator generator
194             = (CategoryItemLabelGenerator) this.itemLabelGeneratorList.get(series);
195         if (generator == null) {
196             generator = this.baseItemLabelGenerator;
197         }
198         return generator;
199
200     }
201
202     /**
203      * Sets the item label generator for ALL series.
204      *
205      * @param generator the generator.
206      */

207     public void setItemLabelGenerator(CategoryItemLabelGenerator generator) {
208         this.itemLabelGenerator = generator;
209     }
210
211     /**
212      * Sets the label generator for a series.
213      *
214      * @param series the series index (zero based).
215      * @param generator the generator.
216      */

217     public void setSeriesItemLabelGenerator(int series, CategoryItemLabelGenerator generator) {
218         this.itemLabelGeneratorList.set(series, generator);
219     }
220
221     /**
222      * Returns the base item label generator.
223      *
224      * @return The base item label generator.
225      */

226     public CategoryItemLabelGenerator getBaseItemLabelGenerator() {
227         return this.baseItemLabelGenerator;
228     }
229
230     /**
231      * Sets the base item label generator.
232      *
233      * @param generator the base item label generator.
234      */

235     public void setBaseItemLabelGenerator(CategoryItemLabelGenerator generator) {
236         this.baseItemLabelGenerator = generator;
237     }
238
239     /**
240      * Returns the URL generator for a data item. This method just calls the
241      * getSeriesItemURLGenerator method, but you can override this behaviour if you want to.
242      *
243      * @param row the row index (zero based).
244      * @param column the column index (zero based).
245      *
246      * @return The URL generator.
247      */

248     public CategoryURLGenerator getItemURLGenerator(int row, int column) {
249         return getSeriesItemURLGenerator(row);
250     }
251
252     /**
253      * Returns the URL generator for a series.
254      *
255      * @param series the series index (zero based).
256      *
257      * @return The URL generator for the series.
258      */

259     public CategoryURLGenerator getSeriesItemURLGenerator(int series) {
260
261         // return the generator for ALL series, if there is one...
262
if (this.itemURLGenerator != null) {
263             return this.itemURLGenerator;
264         }
265
266         // otherwise look up the generator table
267
CategoryURLGenerator generator
268             = (CategoryURLGenerator) this.itemURLGeneratorList.get(series);
269         if (generator == null) {
270             generator = this.baseItemURLGenerator;
271         }
272         return generator;
273
274     }
275
276     /**
277      * Sets the item URL generator for ALL series.
278      *
279      * @param generator the generator.
280      */

281     public void setItemURLGenerator(CategoryURLGenerator generator) {
282         this.itemURLGenerator = generator;
283     }
284
285     /**
286      * Sets the URL generator for a series.
287      *
288      * @param series the series index (zero based).
289      * @param generator the generator.
290      */

291     public void setSeriesItemURLGenerator(int series, CategoryURLGenerator generator) {
292         this.itemURLGeneratorList.set(series, generator);
293     }
294
295     /**
296      * Returns the base item URL generator.
297      *
298      * @return The item URL generator.
299      */

300     public CategoryURLGenerator getBaseItemURLGenerator() {
301         return this.baseItemURLGenerator;
302     }
303
304     /**
305      * Sets the base item URL generator.
306      *
307      * @param generator the item URL generator.
308      */

309     public void setBaseItemURLGenerator(CategoryURLGenerator generator) {
310         this.baseItemURLGenerator = generator;
311     }
312
313     /**
314      * Returns the item label anchor offset.
315      *
316      * @return The offset.
317      */

318     public double getItemLabelAnchorOffset() {
319         return this.itemLabelAnchorOffset;
320     }
321
322     /**
323      * Sets the item label anchor offset.
324      *
325      * @param offset the offset.
326      */

327     public void setItemLabelAnchorOffset(double offset) {
328         this.itemLabelAnchorOffset = offset;
329         firePropertyChanged("ItemLabelAnchorOffset", null, null);
330     }
331
332     /**
333      * Returns the number of rows in the dataset. This value is updated in the
334      * {@link AbstractCategoryItemRenderer#initialise} method.
335      *
336      * @return the row count.
337      */

338     public int getRowCount() {
339         return this.rowCount;
340     }
341
342     /**
343      * Returns the number of columns in the dataset. This value is updated in the
344      * {@link AbstractCategoryItemRenderer#initialise} method.
345      *
346      * @return the column count.
347      */

348     public int getColumnCount() {
349         return this.columnCount;
350     }
351
352     /**
353      * Initialises the renderer and returns a state object that will be used for the
354      * remainder of the drawing process for a single chart. The state object allows
355      * for the fact that the renderer may be used simultaneously by multiple threads (each
356      * thread will work with a separate state object).
357      * <P>
358      * Stores a reference to the {@link PlotRenderingInfo} object (which might be
359      * <code>null</code>), and then sets the useCategoriesPaint flag according to the special case
360      * conditions a) there is only one series and b) the categoriesPaint array is not null.
361      *
362      * @param g2 the graphics device.
363      * @param dataArea the data area.
364      * @param plot the plot.
365      * @param index the secondary index (<code>null</code> for primary renderer).
366      * @param info an object for returning information about the structure of the plot
367      * (<code>null</code> permitted).
368      *
369      * @return The renderer state.
370      *
371      */

372     public CategoryItemRendererState initialise(Graphics2D JavaDoc g2,
373                                                 Rectangle2D JavaDoc dataArea,
374                                                 CategoryPlot plot,
375                                                 Integer JavaDoc index,
376                                                 PlotRenderingInfo info) {
377
378         setPlot(plot);
379         CategoryDataset data = getDataset(plot, index);
380         if (data != null) {
381             this.rowCount = data.getRowCount();
382             this.columnCount = data.getColumnCount();
383         }
384         else {
385             this.rowCount = 0;
386             this.columnCount = 0;
387         }
388         return new CategoryItemRendererState(info);
389
390     }
391
392     /**
393      * Returns the range type for the renderer.
394      * <p>
395      * The default implementation returns <code>STANDARD</code>, subclasses may override this
396      * behaviour.
397      * <p>
398      * The {@link CategoryPlot} uses this information when auto-calculating the range for the axis.
399      *
400      * @return the range type.
401      */

402     public RangeType getRangeType() {
403         return RangeType.STANDARD;
404     }
405
406     /**
407      * Draws a background for the data area. The default implementation just gets the plot to
408      * draw the outline, but some renderers will override this behaviour.
409      *
410      * @param g2 the graphics device.
411      * @param plot the plot.
412      * @param dataArea the data area.
413      */

414     public void drawBackground(Graphics2D JavaDoc g2,
415                                CategoryPlot plot,
416                                Rectangle2D JavaDoc dataArea) {
417
418         plot.drawBackground(g2, dataArea);
419
420     }
421
422     /**
423      * Draws an outline for the data area. The default implementation just gets the plot to
424      * draw the outline, but some renderers will override this behaviour.
425      *
426      * @param g2 the graphics device.
427      * @param plot the plot.
428      * @param dataArea the data area.
429      */

430     public void drawOutline(Graphics2D JavaDoc g2,
431                             CategoryPlot plot,
432                             Rectangle2D JavaDoc dataArea) {
433
434         plot.drawOutline(g2, dataArea);
435
436     }
437
438     /**
439      * Draws a grid line against the domain axis.
440      * <P>
441      * Note that this default implementation assumes that the horizontal axis is the domain axis.
442      * If this is not the case, you will need to override this method.
443      *
444      * @param g2 the graphics device.
445      * @param plot the plot.
446      * @param dataArea the area for plotting data (not yet adjusted for any 3D effect).
447      * @param value the Java2D value at which the grid line should be drawn.
448      */

449     public void drawDomainGridline(Graphics2D JavaDoc g2,
450                                    CategoryPlot plot,
451                                    Rectangle2D JavaDoc dataArea,
452                                    double value) {
453
454         Line2D JavaDoc line = null;
455         PlotOrientation orientation = plot.getOrientation();
456
457         if (orientation == PlotOrientation.HORIZONTAL) {
458             line = new Line2D.Double JavaDoc(dataArea.getMinX(), value, dataArea.getMaxX(), value);
459         }
460         else if (orientation == PlotOrientation.VERTICAL) {
461             line = new Line2D.Double JavaDoc(value, dataArea.getMinY(), value, dataArea.getMaxY());
462         }
463
464         Paint JavaDoc paint = plot.getDomainGridlinePaint();
465         if (paint == null) {
466             paint = CategoryPlot.DEFAULT_GRIDLINE_PAINT;
467         }
468         g2.setPaint(paint);
469
470         Stroke JavaDoc stroke = plot.getDomainGridlineStroke();
471         if (stroke == null) {
472             stroke = CategoryPlot.DEFAULT_GRIDLINE_STROKE;
473         }
474         g2.setStroke(stroke);
475
476         g2.draw(line);
477
478     }
479
480     /**
481      * Draws a grid line against the range axis.
482      *
483      * @param g2 the graphics device.
484      * @param plot the plot.
485      * @param axis the value axis.
486      * @param dataArea the area for plotting data (not yet adjusted for any 3D effect).
487      * @param value the value at which the grid line should be drawn.
488      *
489      */

490     public void drawRangeGridline(Graphics2D JavaDoc g2,
491                                   CategoryPlot plot,
492                                   ValueAxis axis,
493                                   Rectangle2D JavaDoc dataArea,
494                                   double value) {
495
496         Range range = axis.getRange();
497         if (!range.contains(value)) {
498             return;
499         }
500
501         PlotOrientation orientation = plot.getOrientation();
502         double v = axis.translateValueToJava2D(value, dataArea, plot.getRangeAxisEdge());
503         Line2D JavaDoc line = null;
504         if (orientation == PlotOrientation.HORIZONTAL) {
505             line = new Line2D.Double JavaDoc(v, dataArea.getMinY(), v, dataArea.getMaxY());
506         }
507         else if (orientation == PlotOrientation.VERTICAL) {
508             line = new Line2D.Double JavaDoc(dataArea.getMinX(), v, dataArea.getMaxX(), v);
509         }
510
511         Paint JavaDoc paint = plot.getRangeGridlinePaint();
512         if (paint == null) {
513             paint = CategoryPlot.DEFAULT_GRIDLINE_PAINT;
514         }
515         g2.setPaint(paint);
516
517         Stroke JavaDoc stroke = plot.getRangeGridlineStroke();
518         if (stroke == null) {
519             stroke = CategoryPlot.DEFAULT_GRIDLINE_STROKE;
520         }
521         g2.setStroke(stroke);
522
523         g2.draw(line);
524
525     }
526
527     /**
528      * Draws a marker for the range axis.
529      * <P>
530      * A marker is a constant value, usually represented by a line.
531      *
532      * @param g2 the graphics device.
533      * @param plot the plot.
534      * @param axis the range axis.
535      * @param marker the marker to be drawn.
536      * @param dataArea the area inside the axes.
537      */

538     public void drawRangeMarker(Graphics2D JavaDoc g2,
539                                 CategoryPlot plot,
540                                 ValueAxis axis,
541                                 Marker marker,
542                                 Rectangle2D JavaDoc dataArea) {
543
544         double value = marker.getValue();
545         Range range = axis.getRange();
546
547         if (!range.contains(value)) {
548             return;
549         }
550
551         PlotOrientation orientation = plot.getOrientation();
552         double v = axis.translateValueToJava2D(value, dataArea, plot.getRangeAxisEdge());
553         Line2D JavaDoc line = null;
554         if (orientation == PlotOrientation.HORIZONTAL) {
555             line = new Line2D.Double JavaDoc(v, dataArea.getMinY(), v, dataArea.getMaxY());
556         }
557         else if (orientation == PlotOrientation.VERTICAL) {
558             line = new Line2D.Double JavaDoc(dataArea.getMinX(), v, dataArea.getMaxX(), v);
559         }
560
561         g2.setPaint(marker.getOutlinePaint());
562         g2.setStroke(marker.getOutlineStroke());
563         g2.draw(line);
564         
565         String JavaDoc label = marker.getLabel();
566         MarkerLabelPosition position = marker.getLabelPosition();
567         if (label != null) {
568             Font JavaDoc labelFont = marker.getLabelFont();
569             g2.setFont(labelFont);
570             g2.setPaint(marker.getLabelPaint());
571             double[] coordinates = calculateRangeMarkerTextPosition(g2, orientation, dataArea,
572                                                                     v, label, labelFont,
573                                                                position);
574             g2.drawString(label, (int) coordinates[0], (int) coordinates[1]);
575         }
576
577     }
578
579     /**
580      * Calculates the (x, y) coordinates for drawing a marker label.
581      *
582      * @param g2 the graphics device.
583      * @param orientation the plot orientation.
584      * @param dataArea the data area.
585      * @param coordinate the range value (converted to Java 2D space).
586      * @param label the label.
587      * @param font the font.
588      * @param position the label position.
589      *
590      * @return the coordinates for drawing the marker label.
591      */

592     private double[] calculateRangeMarkerTextPosition(Graphics2D JavaDoc g2,
593                                                       PlotOrientation orientation,
594                                                       Rectangle2D JavaDoc dataArea,
595                                                       double coordinate,
596                                                       String JavaDoc label,
597                                                       Font JavaDoc font,
598                                                       MarkerLabelPosition position) {
599                                                      
600         double[] result = new double[2];
601         FontRenderContext JavaDoc frc = g2.getFontRenderContext();
602         FontMetrics JavaDoc fm = g2.getFontMetrics();
603         LineMetrics JavaDoc metrics = font.getLineMetrics(label, frc);
604         Rectangle2D JavaDoc bounds = fm.getStringBounds(label, g2);
605         if (orientation == PlotOrientation.HORIZONTAL) {
606             if (position == MarkerLabelPosition.TOP_LEFT) {
607                 result[0] = coordinate - bounds.getWidth() - 2.0;
608                 result[1] = dataArea.getMinY() + bounds.getHeight();
609             }
610             else if (position == MarkerLabelPosition.TOP_RIGHT) {
611                 result[0] = coordinate + 2.0;
612                 result[1] = dataArea.getMinY() + bounds.getHeight();
613             }
614             else if (position == MarkerLabelPosition.BOTTOM_LEFT) {
615                 result[0] = coordinate - bounds.getWidth() - 2.0;
616                 result[1] = dataArea.getMaxY() - metrics.getDescent() - metrics.getLeading();
617             }
618             else if (position == MarkerLabelPosition.BOTTOM_RIGHT) {
619                 result[0] = coordinate + 2.0;
620                 result[1] = dataArea.getMaxY() - metrics.getDescent() - metrics.getLeading();
621             }
622         }
623         else if (orientation == PlotOrientation.VERTICAL) {
624             if (position == MarkerLabelPosition.TOP_LEFT) {
625                 result[0] = dataArea.getMinX() + 2.0;
626                 result[1] = coordinate - metrics.getDescent() - metrics.getLeading();
627             }
628             else if (position == MarkerLabelPosition.TOP_RIGHT) {
629                 result[0] = dataArea.getMaxX() - bounds.getWidth() - 2.0;
630                 result[1] = coordinate - metrics.getDescent() - metrics.getLeading();
631             }
632             else if (position == MarkerLabelPosition.BOTTOM_LEFT) {
633                 result[0] = dataArea.getMinX() + 2.0;
634                 result[1] = coordinate + bounds.getHeight();
635             }
636             else if (position == MarkerLabelPosition.BOTTOM_RIGHT) {
637                 result[0] = dataArea.getMaxX() - bounds.getWidth() - 2.0;
638                 result[1] = coordinate + bounds.getHeight();
639             }
640         }
641         return result;
642         
643     }
644     
645     /**
646      * Returns a legend item for a series.
647      *
648      * @param datasetIndex the dataset index (zero-based).
649      * @param series the series index (zero-based).
650      *
651      * @return the legend item.
652      */

653     public LegendItem getLegendItem(int datasetIndex, int series) {
654
655         CategoryPlot plot = getPlot();
656         if (plot == null) {
657             return null;
658         }
659
660         CategoryDataset dataset;
661         if (datasetIndex == 0) {
662             dataset = plot.getDataset();
663         }
664         else {
665             dataset = plot.getSecondaryDataset(datasetIndex - 1);
666         }
667         String JavaDoc label = dataset.getRowKey(series).toString();
668         String JavaDoc description = label;
669         Shape JavaDoc shape = getSeriesShape(series);
670         Paint JavaDoc paint = getSeriesPaint(series);
671         Paint JavaDoc outlinePaint = getSeriesOutlinePaint(series);
672         Stroke JavaDoc stroke = getSeriesStroke(series);
673
674         return new LegendItem(label, description,
675                               shape, paint, outlinePaint, stroke);
676
677     }
678
679     /**
680      * Tests this renderer for equality with another object.
681      *
682      * @param obj the object.
683      *
684      * @return <code>true</code> or <code>false</code>.
685      */

686     public boolean equals(Object JavaDoc obj) {
687
688         boolean result = super.equals(obj);
689
690         if (obj instanceof AbstractCategoryItemRenderer) {
691             AbstractCategoryItemRenderer r = (AbstractCategoryItemRenderer) obj;
692
693             boolean b0 = ObjectUtils.equal(this.itemLabelGenerator, r.itemLabelGenerator);
694             boolean b1 = ObjectUtils.equal(this.itemLabelGeneratorList, r.itemLabelGeneratorList);
695             boolean b2 = ObjectUtils.equal(this.baseItemLabelGenerator, r.baseItemLabelGenerator);
696             boolean b3 = ObjectUtils.equal(this.itemURLGenerator, r.itemURLGenerator);
697             boolean b4 = ObjectUtils.equal(this.itemURLGeneratorList, r.itemURLGeneratorList);
698             boolean b5 = ObjectUtils.equal(this.baseItemURLGenerator, r.baseItemURLGenerator);
699             boolean b6 = NumberUtils.equal(this.itemLabelAnchorOffset, r.itemLabelAnchorOffset);
700             
701             result = b0 && b1 && b2 && b3 && b4 && b5 && b6;
702         }
703
704         return result;
705
706     }
707     
708     /**
709      * Returns a hash code for the renderer.
710      *
711      * @return The hash code.
712      */

713     public int hashCode() {
714         int result = super.hashCode();
715         return result;
716     }
717
718     /**
719      * Returns the drawing supplier from the plot.
720      *
721      * @return The drawing supplier (possibly <code>null</code>).
722      */

723     public DrawingSupplier getDrawingSupplier() {
724         DrawingSupplier result = null;
725         CategoryPlot cp = getPlot();
726         if (cp != null) {
727             result = cp.getDrawingSupplier();
728         }
729         return result;
730     }
731
732     /**
733      * Draws an item label.
734      *
735      * @param g2 the graphics device.
736      * @param orientation the orientation.
737      * @param dataset the dataset.
738      * @param row the row.
739      * @param column the column.
740      * @param x the x coordinate.
741      * @param y the y coordinate.
742      * @param negative indicates a negative value (which affects the item label position).
743      */

744     protected void drawItemLabel(Graphics2D JavaDoc g2,
745                                  PlotOrientation orientation,
746                                  CategoryDataset dataset,
747                                  int row, int column,
748                                  double x, double y,
749                                  boolean negative) {
750                                      
751         CategoryItemLabelGenerator generator = getItemLabelGenerator(row, column);
752         if (generator != null) {
753             Font JavaDoc labelFont = getItemLabelFont(row, column);
754             g2.setFont(labelFont);
755             Paint JavaDoc paint = getItemLabelPaint(row, column);
756             g2.setPaint(paint);
757             String JavaDoc label = generator.generateItemLabel(dataset, row, column);
758
759             // get the label anchor..
760
ItemLabelPosition position = null;
761             if (!negative) {
762                 position = getPositiveItemLabelPosition(row, column);
763             }
764             else {
765                 position = getNegativeItemLabelPosition(row, column);
766             }
767
768             // work out the label anchor point...
769
Point2D JavaDoc anchorPoint = calculateLabelAnchorPoint(position.getItemLabelAnchor(),
770                                                             x,
771                                                             y,
772                                                             orientation);
773             RefineryUtilities.drawRotatedString(label, g2,
774                                                (float) anchorPoint.getX(),
775                                                (float) anchorPoint.getY(),
776                                                position.getTextAnchor(),
777                                                position.getRotationAnchor(),
778                                                position.getAngle());
779         }
780
781     }
782
783     /**
784      * Calculates the item label anchor point.
785      *
786      * @param anchor the anchor.
787      * @param x the x coordinate.
788      * @param y the y coordinate.
789      * @param orientation the plot orientation.
790      *
791      * @return The anchor point.
792      */

793     private Point2D JavaDoc calculateLabelAnchorPoint(ItemLabelAnchor anchor,
794                                               double x, double y, PlotOrientation orientation) {
795
796         Point2D JavaDoc result = null;
797
798         if (anchor == ItemLabelAnchor.CENTER) {
799             result = new Point2D.Double JavaDoc(x, y);
800         }
801         else if (anchor == ItemLabelAnchor.INSIDE1) {
802             result = new Point2D.Double JavaDoc(x, y);
803         }
804         else if (anchor == ItemLabelAnchor.INSIDE2) {
805             result = new Point2D.Double JavaDoc(x, y);
806         }
807         else if (anchor == ItemLabelAnchor.INSIDE3) {
808             result = new Point2D.Double JavaDoc(x + this.itemLabelAnchorOffset, y);
809         }
810         else if (anchor == ItemLabelAnchor.INSIDE4) {
811             result = new Point2D.Double JavaDoc(x, y);
812         }
813         else if (anchor == ItemLabelAnchor.INSIDE5) {
814             result = new Point2D.Double JavaDoc(x, y);
815         }
816         else if (anchor == ItemLabelAnchor.INSIDE6) {
817             result = new Point2D.Double JavaDoc(x, y + this.itemLabelAnchorOffset);
818         }
819         else if (anchor == ItemLabelAnchor.INSIDE7) {
820             result = new Point2D.Double JavaDoc(x, y);
821         }
822         else if (anchor == ItemLabelAnchor.INSIDE8) {
823             result = new Point2D.Double JavaDoc(x, y);
824         }
825         else if (anchor == ItemLabelAnchor.INSIDE9) {
826             result = new Point2D.Double JavaDoc(x - this.itemLabelAnchorOffset, y);
827         }
828         else if (anchor == ItemLabelAnchor.INSIDE10) {
829             result = new Point2D.Double JavaDoc(x, y);
830         }
831         else if (anchor == ItemLabelAnchor.INSIDE11) {
832             result = new Point2D.Double JavaDoc(x, y);
833         }
834         else if (anchor == ItemLabelAnchor.INSIDE12) {
835             result = new Point2D.Double JavaDoc(x, y - this.itemLabelAnchorOffset);
836         }
837         else if (anchor == ItemLabelAnchor.OUTSIDE1) {
838             result = new Point2D.Double JavaDoc(x, y);
839         }
840         else if (anchor == ItemLabelAnchor.OUTSIDE2) {
841             result = new Point2D.Double JavaDoc(x, y);
842         }
843         else if (anchor == ItemLabelAnchor.OUTSIDE3) {
844             result = new Point2D.Double JavaDoc(x + 2.0 * this.itemLabelAnchorOffset, y);
845         }
846         else if (anchor == ItemLabelAnchor.OUTSIDE4) {
847             result = new Point2D.Double JavaDoc(x, y);
848         }
849         else if (anchor == ItemLabelAnchor.OUTSIDE5) {
850             result = new Point2D.Double JavaDoc(x, y);
851         }
852         else if (anchor == ItemLabelAnchor.OUTSIDE6) {
853             result = new Point2D.Double JavaDoc(x, y + 2.0 * this.itemLabelAnchorOffset);
854         }
855         else if (anchor == ItemLabelAnchor.OUTSIDE7) {
856             result = new Point2D.Double JavaDoc(x, y);
857         }
858         else if (anchor == ItemLabelAnchor.OUTSIDE8) {
859             result = new Point2D.Double JavaDoc(x, y);
860         }
861         else if (anchor == ItemLabelAnchor.OUTSIDE9) {
862             result = new Point2D.Double JavaDoc(x - 2.0 * this.itemLabelAnchorOffset, y);
863         }
864         else if (anchor == ItemLabelAnchor.OUTSIDE10) {
865             result = new Point2D.Double JavaDoc(x, y);
866         }
867         else if (anchor == ItemLabelAnchor.OUTSIDE11) {
868             result = new Point2D.Double JavaDoc(x, y);
869         }
870         else if (anchor == ItemLabelAnchor.OUTSIDE12) {
871             result = new Point2D.Double JavaDoc(x, y - 2.0 * this.itemLabelAnchorOffset);
872        }
873
874         return result;
875
876     }
877     
878     /**
879      * Returns an independent copy of the renderer.
880      * <p>
881      * The <code>plot</code> reference is shallow copied.
882      *
883      * @return A clone.
884      *
885      * @throws CloneNotSupportedException should not happen.
886      */

887     public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc {
888         AbstractCategoryItemRenderer clone = (AbstractCategoryItemRenderer) super.clone();
889
890         if (this.itemLabelGenerator != null) {
891             clone.itemLabelGenerator = (CategoryItemLabelGenerator) this.itemLabelGenerator.clone();
892         }
893
894         if (this.itemLabelGeneratorList != null) {
895             clone.itemLabelGeneratorList = (ObjectList) this.itemLabelGeneratorList.clone();
896         }
897         
898         if (this.baseItemLabelGenerator != null) {
899             clone.baseItemLabelGenerator
900                 = (CategoryItemLabelGenerator) this.baseItemLabelGenerator.clone();
901         }
902         
903         if (this.itemURLGenerator != null) {
904             clone.itemURLGenerator = (CategoryURLGenerator) this.itemURLGenerator.clone();
905         }
906
907         if (this.itemURLGeneratorList != null) {
908             clone.itemURLGeneratorList = (ObjectList) this.itemURLGeneratorList.clone();
909         }
910
911         if (this.baseItemURLGenerator != null) {
912             clone.baseItemURLGenerator
913                 = (CategoryURLGenerator) this.baseItemURLGenerator.clone();
914         }
915         
916
917         return clone;
918     }
919
920     /**
921      * Returns a domain axis for a plot.
922      *
923      * @param plot the plot.
924      * @param index the axis index (<code>null</code> for the primary axis).
925      *
926      * @return A domain axis.
927      */

928     protected CategoryAxis getDomainAxis(CategoryPlot plot, Integer JavaDoc index) {
929         CategoryAxis result = null;
930         if (index == null) {
931             result = plot.getDomainAxis();
932         }
933         else {
934             result = plot.getSecondaryDomainAxis(index.intValue());
935             if (result == null) {
936                 result = plot.getDomainAxis();
937             }
938         }
939         return result;
940     }
941
942     /**
943      * Returns a range axis for a plot.
944      *
945      * @param plot the plot.
946      * @param index the axis index (<code>null</code> for the primary axis).
947      *
948      * @return A range axis.
949      */

950     protected ValueAxis getRangeAxis(CategoryPlot plot, Integer JavaDoc index) {
951         ValueAxis result = null;
952         if (index == null) {
953             result = plot.getRangeAxis();
954         }
955         else {
956             result = plot.getSecondaryRangeAxis(index.intValue());
957             if (result == null) {
958                 result = plot.getRangeAxis();
959             }
960         }
961         return result;
962     }
963
964     /**
965      * Returns a dataset for a plot.
966      *
967      * @param plot the plot.
968      * @param index the dataset index (<code>null</code> for the primary dataset).
969      *
970      * @return A dataset.
971      */

972     protected CategoryDataset getDataset(CategoryPlot plot, Integer JavaDoc index) {
973         CategoryDataset result = null;
974         if (index == null) {
975             result = plot.getDataset();
976         }
977         else {
978             result = plot.getSecondaryDataset(index.intValue());
979         }
980         return result;
981     }
982     
983 }
984
Popular Tags