KickJava   Java API By Example, From Geeks To Geeks.

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


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  * LineAndShapeRenderer.java
29  * -------------------------
30  * (C) Copyright 2001-2006, by Object Refinery Limited and Contributors.
31  *
32  * Original Author: David Gilbert (for Object Refinery Limited);
33  * Contributor(s): Mark Watson (www.markwatson.com);
34  * Jeremy Bowman;
35  * Richard Atkinson;
36  * Christian W. Zuckschwerdt;
37  *
38  * $Id: LineAndShapeRenderer.java,v 1.18.2.7 2006/10/06 15:02:16 mungady Exp $
39  *
40  * Changes
41  * -------
42  * 23-Oct-2001 : Version 1 (DG);
43  * 15-Nov-2001 : Modified to allow for null data values (DG);
44  * 16-Jan-2002 : Renamed HorizontalCategoryItemRenderer.java
45  * --> CategoryItemRenderer.java (DG);
46  * 05-Feb-2002 : Changed return type of the drawCategoryItem method from void
47  * to Shape, as part of the tooltips implementation (DG);
48  * 11-May-2002 : Support for value label drawing (JB);
49  * 29-May-2002 : Now extends AbstractCategoryItemRenderer (DG);
50  * 25-Jun-2002 : Removed redundant import (DG);
51  * 05-Aug-2002 : Small modification to drawCategoryItem method to support URLs
52  * for HTML image maps (RA);
53  * 26-Sep-2002 : Fixed errors reported by Checkstyle (DG);
54  * 11-Oct-2002 : Added new constructor to incorporate tool tip and URL
55  * generators (DG);
56  * 24-Oct-2002 : Amendments for changes in CategoryDataset interface and
57  * CategoryToolTipGenerator interface (DG);
58  * 05-Nov-2002 : Base dataset is now TableDataset not CategoryDataset (DG);
59  * 06-Nov-2002 : Renamed drawCategoryItem() --> drawItem() and now using axis
60  * for category spacing (DG);
61  * 17-Jan-2003 : Moved plot classes to a separate package (DG);
62  * 10-Apr-2003 : Changed CategoryDataset to KeyedValues2DDataset in drawItem()
63  * method (DG);
64  * 12-May-2003 : Modified to take into account the plot orientation (DG);
65  * 29-Jul-2003 : Amended code that doesn't compile with JDK 1.2.2 (DG);
66  * 30-Jul-2003 : Modified entity constructor (CZ);
67  * 22-Sep-2003 : Fixed cloning (DG);
68  * 10-Feb-2004 : Small change to drawItem() method to make cut-and-paste
69  * override easier (DG);
70  * 16-Jun-2004 : Fixed bug (id=972454) with label positioning on horizontal
71  * charts (DG);
72  * 15-Oct-2004 : Updated equals() method (DG);
73  * 05-Nov-2004 : Modified drawItem() signature (DG);
74  * 11-Nov-2004 : Now uses ShapeUtilities class to translate shapes (DG);
75  * 27-Jan-2005 : Changed attribute names, modified constructor and removed
76  * constants (DG);
77  * 01-Feb-2005 : Removed unnecessary constants (DG);
78  * 15-Mar-2005 : Fixed bug 1163897, concerning outlines for shapes (DG);
79  * 13-Apr-2005 : Check flags that control series visibility (DG);
80  * 20-Apr-2005 : Use generators for legend labels, tooltips and URLs (DG);
81  * 09-Jun-2005 : Use addItemEntity() method (DG);
82  * ------------- JFREECHART 1.0.x ---------------------------------------------
83  * 25-May-2006 : Added check to drawItem() to detect when both the line and
84  * the shape are not visible (DG);
85  *
86  */

87
88 package org.jfree.chart.renderer.category;
89
90 import java.awt.Graphics2D JavaDoc;
91 import java.awt.Paint JavaDoc;
92 import java.awt.Shape JavaDoc;
93 import java.awt.Stroke JavaDoc;
94 import java.awt.geom.Line2D JavaDoc;
95 import java.awt.geom.Rectangle2D JavaDoc;
96 import java.io.Serializable JavaDoc;
97
98 import org.jfree.chart.LegendItem;
99 import org.jfree.chart.axis.CategoryAxis;
100 import org.jfree.chart.axis.ValueAxis;
101 import org.jfree.chart.entity.EntityCollection;
102 import org.jfree.chart.event.RendererChangeEvent;
103 import org.jfree.chart.plot.CategoryPlot;
104 import org.jfree.chart.plot.PlotOrientation;
105 import org.jfree.data.category.CategoryDataset;
106 import org.jfree.util.BooleanList;
107 import org.jfree.util.BooleanUtilities;
108 import org.jfree.util.ObjectUtilities;
109 import org.jfree.util.PublicCloneable;
110 import org.jfree.util.ShapeUtilities;
111
112 /**
113  * A renderer that draws shapes for each data item, and lines between data
114  * items (for use with the {@link CategoryPlot} class).
115  */

116 public class LineAndShapeRenderer extends AbstractCategoryItemRenderer
117                                   implements Cloneable JavaDoc, PublicCloneable,
118                                              Serializable JavaDoc {
119
120     /** For serialization. */
121     private static final long serialVersionUID = -197749519869226398L;
122     
123     /** A flag that controls whether or not lines are visible for ALL series. */
124     private Boolean JavaDoc linesVisible;
125
126     /**
127      * A table of flags that control (per series) whether or not lines are
128      * visible.
129      */

130     private BooleanList seriesLinesVisible;
131
132     /**
133      * A flag indicating whether or not lines are drawn between non-null
134      * points.
135      */

136     private boolean baseLinesVisible;
137
138     /**
139      * A flag that controls whether or not shapes are visible for ALL series.
140      */

141     private Boolean JavaDoc shapesVisible;
142
143     /**
144      * A table of flags that control (per series) whether or not shapes are
145      * visible.
146      */

147     private BooleanList seriesShapesVisible;
148
149     /** The default value returned by the getShapeVisible() method. */
150     private boolean baseShapesVisible;
151
152     /** A flag that controls whether or not shapes are filled for ALL series. */
153     private Boolean JavaDoc shapesFilled;
154     
155     /**
156      * A table of flags that control (per series) whether or not shapes are
157      * filled.
158      */

159     private BooleanList seriesShapesFilled;
160     
161     /** The default value returned by the getShapeFilled() method. */
162     private boolean baseShapesFilled;
163     
164     /**
165      * A flag that controls whether the fill paint is used for filling
166      * shapes.
167      */

168     private boolean useFillPaint;
169
170     /** A flag that controls whether outlines are drawn for shapes. */
171     private boolean drawOutlines;
172         
173     /**
174      * A flag that controls whether the outline paint is used for drawing shape
175      * outlines - if not, the regular series paint is used.
176      */

177     private boolean useOutlinePaint;
178
179     /**
180      * Creates a renderer with both lines and shapes visible by default.
181      */

182     public LineAndShapeRenderer() {
183         this(true, true);
184     }
185
186     /**
187      * Creates a new renderer with lines and/or shapes visible.
188      *
189      * @param lines draw lines?
190      * @param shapes draw shapes?
191      */

192     public LineAndShapeRenderer(boolean lines, boolean shapes) {
193         super();
194         this.linesVisible = null;
195         this.seriesLinesVisible = new BooleanList();
196         this.baseLinesVisible = lines;
197         this.shapesVisible = null;
198         this.seriesShapesVisible = new BooleanList();
199         this.baseShapesVisible = shapes;
200         this.shapesFilled = null;
201         this.seriesShapesFilled = new BooleanList();
202         this.baseShapesFilled = true;
203         this.useFillPaint = false;
204         this.drawOutlines = true;
205         this.useOutlinePaint = false;
206     }
207     
208     // LINES VISIBLE
209

210     /**
211      * Returns the flag used to control whether or not the line for an item is
212      * visible.
213      *
214      * @param series the series index (zero-based).
215      * @param item the item index (zero-based).
216      *
217      * @return A boolean.
218      */

219     public boolean getItemLineVisible(int series, int item) {
220         Boolean JavaDoc flag = this.linesVisible;
221         if (flag == null) {
222             flag = getSeriesLinesVisible(series);
223         }
224         if (flag != null) {
225             return flag.booleanValue();
226         }
227         else {
228             return this.baseLinesVisible;
229         }
230     }
231
232     /**
233      * Returns a flag that controls whether or not lines are drawn for ALL
234      * series. If this flag is <code>null</code>, then the "per series"
235      * settings will apply.
236      *
237      * @return A flag (possibly <code>null</code>).
238      */

239     public Boolean JavaDoc getLinesVisible() {
240         return this.linesVisible;
241     }
242     
243     /**
244      * Sets a flag that controls whether or not lines are drawn between the
245      * items in ALL series, and sends a {@link RendererChangeEvent} to all
246      * registered listeners. You need to set this to <code>null</code> if you
247      * want the "per series" settings to apply.
248      *
249      * @param visible the flag (<code>null</code> permitted).
250      */

251     public void setLinesVisible(Boolean JavaDoc visible) {
252         this.linesVisible = visible;
253         notifyListeners(new RendererChangeEvent(this));
254     }
255
256     /**
257      * Sets a flag that controls whether or not lines are drawn between the
258      * items in ALL series, and sends a {@link RendererChangeEvent} to all
259      * registered listeners.
260      *
261      * @param visible the flag.
262      */

263     public void setLinesVisible(boolean visible) {
264         setLinesVisible(BooleanUtilities.valueOf(visible));
265     }
266
267     /**
268      * Returns the flag used to control whether or not the lines for a series
269      * are visible.
270      *
271      * @param series the series index (zero-based).
272      *
273      * @return The flag (possibly <code>null</code>).
274      */

275     public Boolean JavaDoc getSeriesLinesVisible(int series) {
276         return this.seriesLinesVisible.getBoolean(series);
277     }
278
279     /**
280      * Sets the 'lines visible' flag for a series.
281      *
282      * @param series the series index (zero-based).
283      * @param flag the flag (<code>null</code> permitted).
284      */

285     public void setSeriesLinesVisible(int series, Boolean JavaDoc flag) {
286         this.seriesLinesVisible.setBoolean(series, flag);
287         notifyListeners(new RendererChangeEvent(this));
288     }
289
290     /**
291      * Sets the 'lines visible' flag for a series.
292      *
293      * @param series the series index (zero-based).
294      * @param visible the flag.
295      */

296     public void setSeriesLinesVisible(int series, boolean visible) {
297         setSeriesLinesVisible(series, BooleanUtilities.valueOf(visible));
298     }
299     
300     /**
301      * Returns the base 'lines visible' attribute.
302      *
303      * @return The base flag.
304      */

305     public boolean getBaseLinesVisible() {
306         return this.baseLinesVisible;
307     }
308
309     /**
310      * Sets the base 'lines visible' flag.
311      *
312      * @param flag the flag.
313      */

314     public void setBaseLinesVisible(boolean flag) {
315         this.baseLinesVisible = flag;
316         notifyListeners(new RendererChangeEvent(this));
317     }
318
319     // SHAPES VISIBLE
320

321     /**
322      * Returns the flag used to control whether or not the shape for an item is
323      * visible.
324      *
325      * @param series the series index (zero-based).
326      * @param item the item index (zero-based).
327      *
328      * @return A boolean.
329      */

330     public boolean getItemShapeVisible(int series, int item) {
331         Boolean JavaDoc flag = this.shapesVisible;
332         if (flag == null) {
333             flag = getSeriesShapesVisible(series);
334         }
335         if (flag != null) {
336             return flag.booleanValue();
337         }
338         else {
339             return this.baseShapesVisible;
340         }
341     }
342
343     /**
344      * Returns the flag that controls whether the shapes are visible for the
345      * items in ALL series.
346      *
347      * @return The flag (possibly <code>null</code>).
348      */

349     public Boolean JavaDoc getShapesVisible() {
350         return this.shapesVisible;
351     }
352     
353     /**
354      * Sets the 'shapes visible' for ALL series and sends a
355      * {@link RendererChangeEvent} to all registered listeners.
356      *
357      * @param visible the flag (<code>null</code> permitted).
358      */

359     public void setShapesVisible(Boolean JavaDoc visible) {
360         this.shapesVisible = visible;
361         notifyListeners(new RendererChangeEvent(this));
362     }
363
364     /**
365      * Sets the 'shapes visible' for ALL series and sends a
366      * {@link RendererChangeEvent} to all registered listeners.
367      *
368      * @param visible the flag.
369      */

370     public void setShapesVisible(boolean visible) {
371         setShapesVisible(BooleanUtilities.valueOf(visible));
372     }
373
374     /**
375      * Returns the flag used to control whether or not the shapes for a series
376      * are visible.
377      *
378      * @param series the series index (zero-based).
379      *
380      * @return A boolean.
381      */

382     public Boolean JavaDoc getSeriesShapesVisible(int series) {
383         return this.seriesShapesVisible.getBoolean(series);
384     }
385
386     /**
387      * Sets the 'shapes visible' flag for a series and sends a
388      * {@link RendererChangeEvent} to all registered listeners.
389      *
390      * @param series the series index (zero-based).
391      * @param visible the flag.
392      */

393     public void setSeriesShapesVisible(int series, boolean visible) {
394         setSeriesShapesVisible(series, BooleanUtilities.valueOf(visible));
395     }
396     
397     /**
398      * Sets the 'shapes visible' flag for a series and sends a
399      * {@link RendererChangeEvent} to all registered listeners.
400      *
401      * @param series the series index (zero-based).
402      * @param flag the flag.
403      */

404     public void setSeriesShapesVisible(int series, Boolean JavaDoc flag) {
405         this.seriesShapesVisible.setBoolean(series, flag);
406         notifyListeners(new RendererChangeEvent(this));
407     }
408
409     /**
410      * Returns the base 'shape visible' attribute.
411      *
412      * @return The base flag.
413      */

414     public boolean getBaseShapesVisible() {
415         return this.baseShapesVisible;
416     }
417
418     /**
419      * Sets the base 'shapes visible' flag.
420      *
421      * @param flag the flag.
422      */

423     public void setBaseShapesVisible(boolean flag) {
424         this.baseShapesVisible = flag;
425         notifyListeners(new RendererChangeEvent(this));
426     }
427
428     /**
429      * Returns <code>true</code> if outlines should be drawn for shapes, and
430      * <code>false</code> otherwise.
431      *
432      * @return A boolean.
433      */

434     public boolean getDrawOutlines() {
435         return this.drawOutlines;
436     }
437     
438     /**
439      * Sets the flag that controls whether outlines are drawn for
440      * shapes, and sends a {@link RendererChangeEvent} to all registered
441      * listeners.
442      * <P>
443      * In some cases, shapes look better if they do NOT have an outline, but
444      * this flag allows you to set your own preference.
445      *
446      * @param flag the flag.
447      */

448     public void setDrawOutlines(boolean flag) {
449         this.drawOutlines = flag;
450         notifyListeners(new RendererChangeEvent(this));
451     }
452     
453     /**
454      * Returns the flag that controls whether the outline paint is used for
455      * shape outlines. If not, the regular series paint is used.
456      *
457      * @return A boolean.
458      */

459     public boolean getUseOutlinePaint() {
460         return this.useOutlinePaint;
461     }
462     
463     /**
464      * Sets the flag that controls whether the outline paint is used for shape
465      * outlines.
466      *
467      * @param use the flag.
468      */

469     public void setUseOutlinePaint(boolean use) {
470         this.useOutlinePaint = use;
471     }
472
473     // SHAPES FILLED
474

475     /**
476      * Returns the flag used to control whether or not the shape for an item
477      * is filled. The default implementation passes control to the
478      * <code>getSeriesShapesFilled</code> method. You can override this method
479      * if you require different behaviour.
480      *
481      * @param series the series index (zero-based).
482      * @param item the item index (zero-based).
483      *
484      * @return A boolean.
485      */

486     public boolean getItemShapeFilled(int series, int item) {
487         return getSeriesShapesFilled(series);
488     }
489
490     /**
491      * Returns the flag used to control whether or not the shapes for a series
492      * are filled.
493      *
494      * @param series the series index (zero-based).
495      *
496      * @return A boolean.
497      */

498     public boolean getSeriesShapesFilled(int series) {
499
500         // return the overall setting, if there is one...
501
if (this.shapesFilled != null) {
502             return this.shapesFilled.booleanValue();
503         }
504
505         // otherwise look up the paint table
506
Boolean JavaDoc flag = this.seriesShapesFilled.getBoolean(series);
507         if (flag != null) {
508             return flag.booleanValue();
509         }
510         else {
511             return this.baseShapesFilled;
512         }
513
514     }
515     
516     /**
517      * Returns the flag that controls whether or not shapes are filled for
518      * ALL series.
519      *
520      * @return A Boolean.
521      */

522     public Boolean JavaDoc getShapesFilled() {
523         return this.shapesFilled;
524     }
525
526     /**
527      * Sets the 'shapes filled' for ALL series.
528      *
529      * @param filled the flag.
530      */

531     public void setShapesFilled(boolean filled) {
532         if (filled) {
533             setShapesFilled(Boolean.TRUE);
534         }
535         else {
536             setShapesFilled(Boolean.FALSE);
537         }
538     }
539     
540     /**
541      * Sets the 'shapes filled' for ALL series.
542      *
543      * @param filled the flag (<code>null</code> permitted).
544      */

545     public void setShapesFilled(Boolean JavaDoc filled) {
546         this.shapesFilled = filled;
547     }
548     
549     /**
550      * Sets the 'shapes filled' flag for a series.
551      *
552      * @param series the series index (zero-based).
553      * @param filled the flag.
554      */

555     public void setSeriesShapesFilled(int series, Boolean JavaDoc filled) {
556         this.seriesShapesFilled.setBoolean(series, filled);
557     }
558
559     /**
560      * Sets the 'shapes filled' flag for a series.
561      *
562      * @param series the series index (zero-based).
563      * @param filled the flag.
564      */

565     public void setSeriesShapesFilled(int series, boolean filled) {
566         this.seriesShapesFilled.setBoolean(
567             series, BooleanUtilities.valueOf(filled)
568         );
569     }
570
571     /**
572      * Returns the base 'shape filled' attribute.
573      *
574      * @return The base flag.
575      */

576     public boolean getBaseShapesFilled() {
577         return this.baseShapesFilled;
578     }
579
580     /**
581      * Sets the base 'shapes filled' flag.
582      *
583      * @param flag the flag.
584      */

585     public void setBaseShapesFilled(boolean flag) {
586         this.baseShapesFilled = flag;
587     }
588
589     /**
590      * Returns <code>true</code> if the renderer should use the fill paint
591      * setting to fill shapes, and <code>false</code> if it should just
592      * use the regular paint.
593      *
594      * @return A boolean.
595      */

596     public boolean getUseFillPaint() {
597         return this.useFillPaint;
598     }
599     
600     /**
601      * Sets the flag that controls whether the fill paint is used to fill
602      * shapes, and sends a {@link RendererChangeEvent} to all
603      * registered listeners.
604      *
605      * @param flag the flag.
606      */

607     public void setUseFillPaint(boolean flag) {
608         this.useFillPaint = flag;
609         notifyListeners(new RendererChangeEvent(this));
610     }
611     
612     /**
613      * Returns a legend item for a series.
614      *
615      * @param datasetIndex the dataset index (zero-based).
616      * @param series the series index (zero-based).
617      *
618      * @return The legend item.
619      */

620     public LegendItem getLegendItem(int datasetIndex, int series) {
621
622         CategoryPlot cp = getPlot();
623         if (cp == null) {
624             return null;
625         }
626
627         if (isSeriesVisible(series) && isSeriesVisibleInLegend(series)) {
628             CategoryDataset dataset;
629             dataset = cp.getDataset(datasetIndex);
630             String JavaDoc label = getLegendItemLabelGenerator().generateLabel(
631                     dataset, series);
632             String JavaDoc description = label;
633             String JavaDoc toolTipText = null;
634             if (getLegendItemToolTipGenerator() != null) {
635                 toolTipText = getLegendItemToolTipGenerator().generateLabel(
636                         dataset, series);
637             }
638             String JavaDoc urlText = null;
639             if (getLegendItemURLGenerator() != null) {
640                 urlText = getLegendItemURLGenerator().generateLabel(
641                         dataset, series);
642             }
643             Shape JavaDoc shape = getSeriesShape(series);
644             Paint JavaDoc paint = getSeriesPaint(series);
645             Paint JavaDoc fillPaint = (this.useFillPaint
646                     ? getItemFillPaint(series, 0) : paint);
647             boolean shapeOutlineVisible = this.drawOutlines;
648             Paint JavaDoc outlinePaint = (this.useOutlinePaint
649                     ? getItemOutlinePaint(series, 0) : paint);
650             Stroke JavaDoc outlineStroke = getSeriesOutlineStroke(series);
651             boolean lineVisible = getItemLineVisible(series, 0);
652             boolean shapeVisible = getItemShapeVisible(series, 0);
653             return new LegendItem(label, description, toolTipText,
654                     urlText, shapeVisible, shape, getItemShapeFilled(series, 0),
655                     fillPaint, shapeOutlineVisible, outlinePaint, outlineStroke,
656                     lineVisible, new Line2D.Double JavaDoc(-7.0, 0.0, 7.0, 0.0),
657                     getItemStroke(series, 0), getItemPaint(series, 0));
658         }
659         return null;
660
661     }
662
663     /**
664      * This renderer uses two passes to draw the data.
665      *
666      * @return The pass count (<code>2</code> for this renderer).
667      */

668     public int getPassCount() {
669         return 2;
670     }
671     
672     /**
673      * Draw a single data item.
674      *
675      * @param g2 the graphics device.
676      * @param state the renderer state.
677      * @param dataArea the area in which the data is drawn.
678      * @param plot the plot.
679      * @param domainAxis the domain axis.
680      * @param rangeAxis the range axis.
681      * @param dataset the dataset.
682      * @param row the row index (zero-based).
683      * @param column the column index (zero-based).
684      * @param pass the pass index.
685      */

686     public void drawItem(Graphics2D JavaDoc g2, CategoryItemRendererState state,
687             Rectangle2D JavaDoc dataArea, CategoryPlot plot, CategoryAxis domainAxis,
688             ValueAxis rangeAxis, CategoryDataset dataset, int row, int column,
689             int pass) {
690
691         // do nothing if item is not visible
692
if (!getItemVisible(row, column)) {
693             return;
694         }
695         
696         // do nothing if both the line and shape are not visible
697
if (!getItemLineVisible(row, column)
698                 && !getItemShapeVisible(row, column)) {
699             return;
700         }
701
702         // nothing is drawn for null...
703
Number JavaDoc v = dataset.getValue(row, column);
704         if (v == null) {
705             return;
706         }
707
708         PlotOrientation orientation = plot.getOrientation();
709
710         // current data point...
711
double x1 = domainAxis.getCategoryMiddle(column, getColumnCount(),
712                 dataArea, plot.getDomainAxisEdge());
713         double value = v.doubleValue();
714         double y1 = rangeAxis.valueToJava2D(value, dataArea,
715                 plot.getRangeAxisEdge());
716
717         if (pass == 0 && getItemLineVisible(row, column)) {
718             if (column != 0) {
719                 Number JavaDoc previousValue = dataset.getValue(row, column - 1);
720                 if (previousValue != null) {
721                     // previous data point...
722
double previous = previousValue.doubleValue();
723                     double x0 = domainAxis.getCategoryMiddle(column - 1,
724                             getColumnCount(), dataArea,
725                             plot.getDomainAxisEdge());
726                     double y0 = rangeAxis.valueToJava2D(previous, dataArea,
727                             plot.getRangeAxisEdge());
728
729                     Line2D JavaDoc line = null;
730                     if (orientation == PlotOrientation.HORIZONTAL) {
731                         line = new Line2D.Double JavaDoc(y0, x0, y1, x1);
732                     }
733                     else if (orientation == PlotOrientation.VERTICAL) {
734                         line = new Line2D.Double JavaDoc(x0, y0, x1, y1);
735                     }
736                     g2.setPaint(getItemPaint(row, column));
737                     g2.setStroke(getItemStroke(row, column));
738                     g2.draw(line);
739                 }
740             }
741         }
742
743         if (pass == 1) {
744             Shape JavaDoc shape = getItemShape(row, column);
745             if (orientation == PlotOrientation.HORIZONTAL) {
746                 shape = ShapeUtilities.createTranslatedShape(shape, y1, x1);
747             }
748             else if (orientation == PlotOrientation.VERTICAL) {
749                 shape = ShapeUtilities.createTranslatedShape(shape, x1, y1);
750             }
751
752             if (getItemShapeVisible(row, column)) {
753                 if (getItemShapeFilled(row, column)) {
754                     if (this.useFillPaint) {
755                         g2.setPaint(getItemFillPaint(row, column));
756                     }
757                     else {
758                         g2.setPaint(getItemPaint(row, column));
759                     }
760                     g2.fill(shape);
761                 }
762                 if (this.drawOutlines) {
763                     if (this.useOutlinePaint) {
764                         g2.setPaint(getItemOutlinePaint(row, column));
765                     }
766                     else {
767                         g2.setPaint(getItemPaint(row, column));
768                     }
769                     g2.setStroke(getItemOutlineStroke(row, column));
770                     g2.draw(shape);
771                 }
772             }
773
774             // draw the item label if there is one...
775
if (isItemLabelVisible(row, column)) {
776                 if (orientation == PlotOrientation.HORIZONTAL) {
777                     drawItemLabel(g2, orientation, dataset, row, column, y1,
778                             x1, (value < 0.0));
779                 }
780                 else if (orientation == PlotOrientation.VERTICAL) {
781                     drawItemLabel(g2, orientation, dataset, row, column, x1,
782                             y1, (value < 0.0));
783                 }
784             }
785
786             // add an item entity, if this information is being collected
787
EntityCollection entities = state.getEntityCollection();
788             if (entities != null) {
789                 addItemEntity(entities, dataset, row, column, shape);
790             }
791         }
792
793     }
794     
795     /**
796      * Tests this renderer for equality with an arbitrary object.
797      *
798      * @param obj the object (<code>null</code> permitted).
799      *
800      * @return A boolean.
801      */

802     public boolean equals(Object JavaDoc obj) {
803
804         if (obj == this) {
805             return true;
806         }
807         if (!(obj instanceof LineAndShapeRenderer)) {
808             return false;
809         }
810         
811         LineAndShapeRenderer that = (LineAndShapeRenderer) obj;
812         if (this.baseLinesVisible != that.baseLinesVisible) {
813             return false;
814         }
815         if (!ObjectUtilities.equal(this.seriesLinesVisible,
816                 that.seriesLinesVisible)) {
817             return false;
818         }
819         if (!ObjectUtilities.equal(this.linesVisible, that.linesVisible)) {
820             return false;
821         }
822         if (this.baseShapesVisible != that.baseShapesVisible) {
823             return false;
824         }
825         if (!ObjectUtilities.equal(this.seriesShapesVisible,
826                 that.seriesShapesVisible)) {
827             return false;
828         }
829         if (!ObjectUtilities.equal(this.shapesVisible, that.shapesVisible)) {
830             return false;
831         }
832         if (!ObjectUtilities.equal(this.shapesFilled, that.shapesFilled)) {
833             return false;
834         }
835         if (!ObjectUtilities.equal(this.seriesShapesFilled,
836                 that.seriesShapesFilled)) {
837             return false;
838         }
839         if (this.baseShapesFilled != that.baseShapesFilled) {
840             return false;
841         }
842         if (this.useOutlinePaint != that.useOutlinePaint) {
843             return false;
844         }
845         if (!super.equals(obj)) {
846             return false;
847         }
848         return true;
849     }
850
851     /**
852      * Returns an independent copy of the renderer.
853      *
854      * @return A clone.
855      *
856      * @throws CloneNotSupportedException should not happen.
857      */

858     public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc {
859         LineAndShapeRenderer clone = (LineAndShapeRenderer) super.clone();
860         clone.seriesLinesVisible
861             = (BooleanList) this.seriesLinesVisible.clone();
862         clone.seriesShapesVisible
863             = (BooleanList) this.seriesLinesVisible.clone();
864         clone.seriesShapesFilled
865             = (BooleanList) this.seriesShapesFilled.clone();
866         return clone;
867     }
868     
869 }
870
Popular Tags