1:
98:
99: package ;
100:
101: import ;
102: import ;
103: import ;
104: import ;
105: import ;
106: import ;
107: import ;
108: import ;
109: import ;
110: import ;
111: import ;
112: import ;
113:
114: import ;
115: import ;
116: import ;
117: import ;
118: import ;
119: import ;
120: import ;
121: import ;
122: import ;
123: import ;
124: import ;
125: import ;
126: import ;
127: import ;
128: import ;
129: import ;
130: import ;
131: import ;
132: import ;
133: import ;
134: import ;
135: import ;
136: import ;
137: import ;
138: import ;
139: import ;
140: import ;
141: import ;
142: import ;
143: import ;
144: import ;
145: import ;
146: import ;
147:
148:
154: public abstract class AbstractCategoryItemRenderer extends AbstractRenderer
155: implements CategoryItemRenderer, Cloneable, PublicCloneable, Serializable {
156:
157:
158: private static final long serialVersionUID = 1247553218442497391L;
159:
160:
161: private CategoryPlot plot;
162:
163:
168: private CategoryItemLabelGenerator itemLabelGenerator;
169:
170:
171: private ObjectList itemLabelGeneratorList;
172:
173:
174: private CategoryItemLabelGenerator baseItemLabelGenerator;
175:
176:
181: private CategoryToolTipGenerator toolTipGenerator;
182:
183:
184: private ObjectList toolTipGeneratorList;
185:
186:
187: private CategoryToolTipGenerator baseToolTipGenerator;
188:
189:
194: private CategoryURLGenerator itemURLGenerator;
195:
196:
197: private ObjectList itemURLGeneratorList;
198:
199:
200: private CategoryURLGenerator baseItemURLGenerator;
201:
202:
203: private CategorySeriesLabelGenerator legendItemLabelGenerator;
204:
205:
206: private CategorySeriesLabelGenerator legendItemToolTipGenerator;
207:
208:
209: private CategorySeriesLabelGenerator legendItemURLGenerator;
210:
211:
212: private transient int rowCount;
213:
214:
215: private transient int columnCount;
216:
217:
224: protected AbstractCategoryItemRenderer() {
225: this.itemLabelGenerator = null;
226: this.itemLabelGeneratorList = new ObjectList();
227: this.toolTipGenerator = null;
228: this.toolTipGeneratorList = new ObjectList();
229: this.itemURLGenerator = null;
230: this.itemURLGeneratorList = new ObjectList();
231: this.legendItemLabelGenerator
232: = new StandardCategorySeriesLabelGenerator();
233: }
234:
235:
242: public int getPassCount() {
243: return 1;
244: }
245:
246:
255: public CategoryPlot getPlot() {
256: return this.plot;
257: }
258:
259:
268: public void setPlot(CategoryPlot plot) {
269: if (plot == null) {
270: throw new IllegalArgumentException("Null 'plot' argument.");
271: }
272: this.plot = plot;
273: }
274:
275:
276:
277:
288: public CategoryItemLabelGenerator getItemLabelGenerator(int row,
289: int column) {
290: return getSeriesItemLabelGenerator(row);
291: }
292:
293:
302: public CategoryItemLabelGenerator getSeriesItemLabelGenerator(int series) {
303:
304:
305: if (this.itemLabelGenerator != null) {
306: return this.itemLabelGenerator;
307: }
308:
309:
310: CategoryItemLabelGenerator generator = (CategoryItemLabelGenerator)
311: this.itemLabelGeneratorList.get(series);
312: if (generator == null) {
313: generator = this.baseItemLabelGenerator;
314: }
315: return generator;
316:
317: }
318:
319:
330: public void setItemLabelGenerator(CategoryItemLabelGenerator generator) {
331: this.itemLabelGenerator = generator;
332: notifyListeners(new RendererChangeEvent(this));
333: }
334:
335:
344: public void setSeriesItemLabelGenerator(int series,
345: CategoryItemLabelGenerator generator) {
346: this.itemLabelGeneratorList.set(series, generator);
347: notifyListeners(new RendererChangeEvent(this));
348: }
349:
350:
357: public CategoryItemLabelGenerator getBaseItemLabelGenerator() {
358: return this.baseItemLabelGenerator;
359: }
360:
361:
369: public void setBaseItemLabelGenerator(CategoryItemLabelGenerator generator)
370: {
371: this.baseItemLabelGenerator = generator;
372: notifyListeners(new RendererChangeEvent(this));
373: }
374:
375:
376:
377:
389: public CategoryToolTipGenerator getToolTipGenerator(int row, int column) {
390:
391: CategoryToolTipGenerator result = null;
392: if (this.toolTipGenerator != null) {
393: result = this.toolTipGenerator;
394: }
395: else {
396: result = getSeriesToolTipGenerator(row);
397: if (result == null) {
398: result = this.baseToolTipGenerator;
399: }
400: }
401: return result;
402: }
403:
404:
416: public CategoryToolTipGenerator getToolTipGenerator() {
417: return this.toolTipGenerator;
418: }
419:
420:
434: public void setToolTipGenerator(CategoryToolTipGenerator generator) {
435: this.toolTipGenerator = generator;
436: notifyListeners(new RendererChangeEvent(this));
437: }
438:
439:
449: public CategoryToolTipGenerator getSeriesToolTipGenerator(int series) {
450: return (CategoryToolTipGenerator) this.toolTipGeneratorList.get(series);
451: }
452:
453:
463: public void setSeriesToolTipGenerator(int series,
464: CategoryToolTipGenerator generator) {
465: this.toolTipGeneratorList.set(series, generator);
466: notifyListeners(new RendererChangeEvent(this));
467: }
468:
469:
476: public CategoryToolTipGenerator getBaseToolTipGenerator() {
477: return this.baseToolTipGenerator;
478: }
479:
480:
488: public void setBaseToolTipGenerator(CategoryToolTipGenerator generator) {
489: this.baseToolTipGenerator = generator;
490: notifyListeners(new RendererChangeEvent(this));
491: }
492:
493:
494:
495:
505: public CategoryURLGenerator getItemURLGenerator(int row, int column) {
506: return getSeriesItemURLGenerator(row);
507: }
508:
509:
518: public CategoryURLGenerator getSeriesItemURLGenerator(int series) {
519:
520:
521: if (this.itemURLGenerator != null) {
522: return this.itemURLGenerator;
523: }
524:
525:
526: CategoryURLGenerator generator
527: = (CategoryURLGenerator) this.itemURLGeneratorList.get(series);
528: if (generator == null) {
529: generator = this.baseItemURLGenerator;
530: }
531: return generator;
532:
533: }
534:
535:
545: public void setItemURLGenerator(CategoryURLGenerator generator) {
546: this.itemURLGenerator = generator;
547: notifyListeners(new RendererChangeEvent(this));
548: }
549:
550:
558: public void setSeriesItemURLGenerator(int series,
559: CategoryURLGenerator generator) {
560: this.itemURLGeneratorList.set(series, generator);
561: notifyListeners(new RendererChangeEvent(this));
562: }
563:
564:
571: public CategoryURLGenerator getBaseItemURLGenerator() {
572: return this.baseItemURLGenerator;
573: }
574:
575:
582: public void setBaseItemURLGenerator(CategoryURLGenerator generator) {
583: this.baseItemURLGenerator = generator;
584: notifyListeners(new RendererChangeEvent(this));
585: }
586:
587:
593: public int getRowCount() {
594: return this.rowCount;
595: }
596:
597:
603: public int getColumnCount() {
604: return this.columnCount;
605: }
606:
607:
619: protected CategoryItemRendererState createState(PlotRenderingInfo info) {
620: return new CategoryItemRendererState(info);
621: }
622:
623:
638: public CategoryItemRendererState initialise(Graphics2D g2,
639: Rectangle2D dataArea,
640: CategoryPlot plot,
641: int rendererIndex,
642: PlotRenderingInfo info) {
643:
644: setPlot(plot);
645: CategoryDataset data = plot.getDataset(rendererIndex);
646: if (data != null) {
647: this.rowCount = data.getRowCount();
648: this.columnCount = data.getColumnCount();
649: }
650: else {
651: this.rowCount = 0;
652: this.columnCount = 0;
653: }
654: return createState(info);
655:
656: }
657:
658:
667: public Range findRangeBounds(CategoryDataset dataset) {
668: return DatasetUtilities.findRangeBounds(dataset);
669: }
670:
671:
680: public void drawBackground(Graphics2D g2,
681: CategoryPlot plot,
682: Rectangle2D dataArea) {
683:
684: plot.drawBackground(g2, dataArea);
685:
686: }
687:
688:
697: public void drawOutline(Graphics2D g2,
698: CategoryPlot plot,
699: Rectangle2D dataArea) {
700:
701: plot.drawOutline(g2, dataArea);
702:
703: }
704:
705:
721: public void drawDomainGridline(Graphics2D g2,
722: CategoryPlot plot,
723: Rectangle2D dataArea,
724: double value) {
725:
726: Line2D line = null;
727: PlotOrientation orientation = plot.getOrientation();
728:
729: if (orientation == PlotOrientation.HORIZONTAL) {
730: line = new Line2D.Double(dataArea.getMinX(), value,
731: dataArea.getMaxX(), value);
732: }
733: else if (orientation == PlotOrientation.VERTICAL) {
734: line = new Line2D.Double(value, dataArea.getMinY(), value,
735: dataArea.getMaxY());
736: }
737:
738: Paint paint = plot.getDomainGridlinePaint();
739: if (paint == null) {
740: paint = CategoryPlot.DEFAULT_GRIDLINE_PAINT;
741: }
742: g2.setPaint(paint);
743:
744: Stroke stroke = plot.getDomainGridlineStroke();
745: if (stroke == null) {
746: stroke = CategoryPlot.DEFAULT_GRIDLINE_STROKE;
747: }
748: g2.setStroke(stroke);
749:
750: g2.draw(line);
751:
752: }
753:
754:
767: public void drawRangeGridline(Graphics2D g2,
768: CategoryPlot plot,
769: ValueAxis axis,
770: Rectangle2D dataArea,
771: double value) {
772:
773: Range range = axis.getRange();
774: if (!range.contains(value)) {
775: return;
776: }
777:
778: PlotOrientation orientation = plot.getOrientation();
779: double v = axis.valueToJava2D(value, dataArea, plot.getRangeAxisEdge());
780: Line2D line = null;
781: if (orientation == PlotOrientation.HORIZONTAL) {
782: line = new Line2D.Double(v, dataArea.getMinY(), v,
783: dataArea.getMaxY());
784: }
785: else if (orientation == PlotOrientation.VERTICAL) {
786: line = new Line2D.Double(dataArea.getMinX(), v,
787: dataArea.getMaxX(), v);
788: }
789:
790: Paint paint = plot.getRangeGridlinePaint();
791: if (paint == null) {
792: paint = CategoryPlot.DEFAULT_GRIDLINE_PAINT;
793: }
794: g2.setPaint(paint);
795:
796: Stroke stroke = plot.getRangeGridlineStroke();
797: if (stroke == null) {
798: stroke = CategoryPlot.DEFAULT_GRIDLINE_STROKE;
799: }
800: g2.setStroke(stroke);
801:
802: g2.draw(line);
803:
804: }
805:
806:
818: public void drawDomainMarker(Graphics2D g2,
819: CategoryPlot plot,
820: CategoryAxis axis,
821: CategoryMarker marker,
822: Rectangle2D dataArea) {
823:
824: Comparable category = marker.getKey();
825: CategoryDataset dataset = plot.getDataset(plot.getIndexOf(this));
826: int columnIndex = dataset.getColumnIndex(category);
827: if (columnIndex < 0) {
828: return;
829: }
830:
831: final Composite savedComposite = g2.getComposite();
832: g2.setComposite(AlphaComposite.getInstance(
833: AlphaComposite.SRC_OVER, marker.getAlpha()));
834:
835: PlotOrientation orientation = plot.getOrientation();
836: Rectangle2D bounds = null;
837: if (marker.getDrawAsLine()) {
838: double v = axis.getCategoryMiddle(columnIndex,
839: dataset.getColumnCount(), dataArea,
840: plot.getDomainAxisEdge());
841: Line2D line = null;
842: if (orientation == PlotOrientation.HORIZONTAL) {
843: line = new Line2D.Double(dataArea.getMinX(), v,
844: dataArea.getMaxX(), v);
845: }
846: else if (orientation == PlotOrientation.VERTICAL) {
847: line = new Line2D.Double(v, dataArea.getMinY(), v,
848: dataArea.getMaxY());
849: }
850: g2.setPaint(marker.getPaint());
851: g2.setStroke(marker.getStroke());
852: g2.draw(line);
853: bounds = line.getBounds2D();
854: }
855: else {
856: double v0 = axis.getCategoryStart(columnIndex,
857: dataset.getColumnCount(), dataArea,
858: plot.getDomainAxisEdge());
859: double v1 = axis.getCategoryEnd(columnIndex,
860: dataset.getColumnCount(), dataArea,
861: plot.getDomainAxisEdge());
862: Rectangle2D area = null;
863: if (orientation == PlotOrientation.HORIZONTAL) {
864: area = new Rectangle2D.Double(dataArea.getMinX(), v0,
865: dataArea.getWidth(), (v1 - v0));
866: }
867: else if (orientation == PlotOrientation.VERTICAL) {
868: area = new Rectangle2D.Double(v0, dataArea.getMinY(),
869: (v1 - v0), dataArea.getHeight());
870: }
871: g2.setPaint(marker.getPaint());
872: g2.fill(area);
873: bounds = area;
874: }
875:
876: String label = marker.getLabel();
877: RectangleAnchor anchor = marker.getLabelAnchor();
878: if (label != null) {
879: Font labelFont = marker.getLabelFont();
880: g2.setFont(labelFont);
881: g2.setPaint(marker.getLabelPaint());
882: Point2D coordinates = calculateDomainMarkerTextAnchorPoint(
883: g2, orientation, dataArea, bounds, marker.getLabelOffset(),
884: marker.getLabelOffsetType(), anchor);
885: TextUtilities.drawAlignedString(label, g2,
886: (float) coordinates.getX(), (float) coordinates.getY(),
887: marker.getLabelTextAnchor());
888: }
889: g2.setComposite(savedComposite);
890: }
891:
892:
904: public void drawRangeMarker(Graphics2D g2,
905: CategoryPlot plot,
906: ValueAxis axis,
907: Marker marker,
908: Rectangle2D dataArea) {
909:
910: if (marker instanceof ValueMarker) {
911: ValueMarker vm = (ValueMarker) marker;
912: double value = vm.getValue();
913: Range range = axis.getRange();
914:
915: if (!range.contains(value)) {
916: return;
917: }
918:
919: final Composite savedComposite = g2.getComposite();
920: g2.setComposite(AlphaComposite.getInstance(
921: AlphaComposite.SRC_OVER, marker.getAlpha()));
922:
923: PlotOrientation orientation = plot.getOrientation();
924: double v = axis.valueToJava2D(value, dataArea,
925: plot.getRangeAxisEdge());
926: Line2D line = null;
927: if (orientation == PlotOrientation.HORIZONTAL) {
928: line = new Line2D.Double(v, dataArea.getMinY(), v,
929: dataArea.getMaxY());
930: }
931: else if (orientation == PlotOrientation.VERTICAL) {
932: line = new Line2D.Double(dataArea.getMinX(), v,
933: dataArea.getMaxX(), v);
934: }
935:
936: g2.setPaint(marker.getPaint());
937: g2.setStroke(marker.getStroke());
938: g2.draw(line);
939:
940: String label = marker.getLabel();
941: RectangleAnchor anchor = marker.getLabelAnchor();
942: if (label != null) {
943: Font labelFont = marker.getLabelFont();
944: g2.setFont(labelFont);
945: g2.setPaint(marker.getLabelPaint());
946: Point2D coordinates = calculateRangeMarkerTextAnchorPoint(
947: g2, orientation, dataArea, line.getBounds2D(),
948: marker.getLabelOffset(), LengthAdjustmentType.EXPAND,
949: anchor);
950: TextUtilities.drawAlignedString(label, g2,
951: (float) coordinates.getX(), (float) coordinates.getY(),
952: marker.getLabelTextAnchor());
953: }
954: g2.setComposite(savedComposite);
955: }
956: else if (marker instanceof IntervalMarker) {
957: IntervalMarker im = (IntervalMarker) marker;
958: double start = im.getStartValue();
959: double end = im.getEndValue();
960: Range range = axis.getRange();
961: if (!(range.intersects(start, end))) {
962: return;
963: }
964:
965: final Composite savedComposite = g2.getComposite();
966: g2.setComposite(AlphaComposite.getInstance(
967: AlphaComposite.SRC_OVER, marker.getAlpha()));
968:
969: double start2d = axis.valueToJava2D(start, dataArea,
970: plot.getRangeAxisEdge());
971: double end2d = axis.valueToJava2D(end, dataArea,
972: plot.getRangeAxisEdge());
973: double low = Math.min(start2d, end2d);
974: double high = Math.max(start2d, end2d);
975:
976: PlotOrientation orientation = plot.getOrientation();
977: Rectangle2D rect = null;
978: if (orientation == PlotOrientation.HORIZONTAL) {
979:
980: low = Math.max(low, dataArea.getMinX());
981: high = Math.min(high, dataArea.getMaxX());
982: rect = new Rectangle2D.Double(low,
983: dataArea.getMinY(), high - low,
984: dataArea.getHeight());
985: }
986: else if (orientation == PlotOrientation.VERTICAL) {
987:
988: low = Math.max(low, dataArea.getMinY());
989: high = Math.min(high, dataArea.getMaxY());
990: rect = new Rectangle2D.Double(dataArea.getMinX(),
991: low, dataArea.getWidth(),
992: high - low);
993: }
994: Paint p = marker.getPaint();
995: if (p instanceof GradientPaint) {
996: GradientPaint gp = (GradientPaint) p;
997: GradientPaintTransformer t = im.getGradientPaintTransformer();
998: if (t != null) {
999: gp = t.transform(gp, rect);
1000: }
1001: g2.setPaint(gp);
1002: }
1003: else {
1004: g2.setPaint(p);
1005: }
1006: g2.fill(rect);
1007:
1008:
1009: if (im.getOutlinePaint() != null && im.getOutlineStroke() != null) {
1010: if (orientation == PlotOrientation.VERTICAL) {
1011: Line2D line = new Line2D.Double();
1012: double x0 = dataArea.getMinX();
1013: double x1 = dataArea.getMaxX();
1014: g2.setPaint(im.getOutlinePaint());
1015: g2.setStroke(im.getOutlineStroke());
1016: if (range.contains(start)) {
1017: line.setLine(x0, start2d, x1, start2d);
1018: g2.draw(line);
1019: }
1020: if (range.contains(end)) {
1021: line.setLine(x0, end2d, x1, end2d);
1022: g2.draw(line);
1023: }
1024: }
1025: else {
1026: Line2D line = new Line2D.Double();
1027: double y0 = dataArea.getMinY();
1028: double y1 = dataArea.getMaxY();
1029: g2.setPaint(im.getOutlinePaint());
1030: g2.setStroke(im.getOutlineStroke());
1031: if (range.contains(start)) {
1032: line.setLine(start2d, y0, start2d, y1);
1033: g2.draw(line);
1034: }
1035: if (range.contains(end)) {
1036: line.setLine(end2d, y0, end2d, y1);
1037: g2.draw(line);
1038: }
1039: }
1040: }
1041:
1042: String label = marker.getLabel();
1043: RectangleAnchor anchor = marker.getLabelAnchor();
1044: if (label != null) {
1045: Font labelFont = marker.getLabelFont();
1046: g2.setFont(labelFont);
1047: g2.setPaint(marker.getLabelPaint());
1048: Point2D coordinates = calculateRangeMarkerTextAnchorPoint(
1049: g2, orientation, dataArea, rect,
1050: marker.getLabelOffset(), marker.getLabelOffsetType(),
1051: anchor);
1052: TextUtilities.drawAlignedString(label, g2,
1053: (float) coordinates.getX(), (float) coordinates.getY(),
1054: marker.getLabelTextAnchor());
1055: }
1056: g2.setComposite(savedComposite);
1057: }
1058: }
1059:
1060:
1074: protected Point2D calculateDomainMarkerTextAnchorPoint(Graphics2D g2,
1075: PlotOrientation orientation,
1076: Rectangle2D dataArea,
1077: Rectangle2D markerArea,
1078: RectangleInsets markerOffset,
1079: LengthAdjustmentType labelOffsetType,
1080: RectangleAnchor anchor) {
1081:
1082: Rectangle2D anchorRect = null;
1083: if (orientation == PlotOrientation.HORIZONTAL) {
1084: anchorRect = markerOffset.createAdjustedRectangle(markerArea,
1085: LengthAdjustmentType.CONTRACT, labelOffsetType);
1086: }
1087: else if (orientation == PlotOrientation.VERTICAL) {
1088: anchorRect = markerOffset.createAdjustedRectangle(markerArea,
1089: labelOffsetType, LengthAdjustmentType.CONTRACT);
1090: }
1091: return RectangleAnchor.coordinates(anchorRect, anchor);
1092:
1093: }
1094:
1095:
1108: protected Point2D calculateRangeMarkerTextAnchorPoint(Graphics2D g2,
1109: PlotOrientation orientation,
1110: Rectangle2D dataArea,
1111: Rectangle2D markerArea,
1112: RectangleInsets markerOffset,
1113: LengthAdjustmentType labelOffsetType,
1114: RectangleAnchor anchor) {
1115:
1116: Rectangle2D anchorRect = null;
1117: if (orientation == PlotOrientation.HORIZONTAL) {
1118: anchorRect = markerOffset.createAdjustedRectangle(markerArea,
1119: labelOffsetType, LengthAdjustmentType.CONTRACT);
1120: }
1121: else if (orientation == PlotOrientation.VERTICAL) {
1122: anchorRect = markerOffset.createAdjustedRectangle(markerArea,
1123: LengthAdjustmentType.CONTRACT, labelOffsetType);
1124: }
1125: return RectangleAnchor.coordinates(anchorRect, anchor);
1126:
1127: }
1128:
1129:
1141: public LegendItem getLegendItem(int datasetIndex, int series) {
1142:
1143: CategoryPlot p = getPlot();
1144: if (p == null) {
1145: return null;
1146: }
1147:
1148:
1149: if (!isSeriesVisible(series) || !isSeriesVisibleInLegend(series)) {
1150: return null;
1151: }
1152:
1153: CategoryDataset dataset = p.getDataset(datasetIndex);
1154: String label = this.legendItemLabelGenerator.generateLabel(dataset,
1155: series);
1156: String description = label;
1157: String toolTipText = null;
1158: if (this.legendItemToolTipGenerator != null) {
1159: toolTipText = this.legendItemToolTipGenerator.generateLabel(
1160: dataset, series);
1161: }
1162: String urlText = null;
1163: if (this.legendItemURLGenerator != null) {
1164: urlText = this.legendItemURLGenerator.generateLabel(dataset,
1165: series);
1166: }
1167: Shape shape = lookupSeriesShape(series);
1168: Paint paint = lookupSeriesPaint(series);
1169: Paint outlinePaint = lookupSeriesOutlinePaint(series);
1170: Stroke outlineStroke = lookupSeriesOutlineStroke(series);
1171:
1172: LegendItem item = new LegendItem(label, description, toolTipText,
1173: urlText, shape, paint, outlineStroke, outlinePaint);
1174: item.setSeriesKey(dataset.getRowKey(series));
1175: item.setSeriesIndex(series);
1176: item.setDataset(dataset);
1177: item.setDatasetIndex(datasetIndex);
1178: return item;
1179: }
1180:
1181:
1188: public boolean equals(Object obj) {
1189:
1190: if (obj == this) {
1191: return true;
1192: }
1193: if (!(obj instanceof AbstractCategoryItemRenderer)) {
1194: return false;
1195: }
1196: AbstractCategoryItemRenderer that = (AbstractCategoryItemRenderer) obj;
1197:
1198: if (!ObjectUtilities.equal(this.itemLabelGenerator,
1199: that.itemLabelGenerator)) {
1200: return false;
1201: }
1202: if (!ObjectUtilities.equal(this.itemLabelGeneratorList,
1203: that.itemLabelGeneratorList)) {
1204: return false;
1205: }
1206: if (!ObjectUtilities.equal(this.baseItemLabelGenerator,
1207: that.baseItemLabelGenerator)) {
1208: return false;
1209: }
1210: if (!ObjectUtilities.equal(this.toolTipGenerator,
1211: that.toolTipGenerator)) {
1212: return false;
1213: }
1214: if (!ObjectUtilities.equal(this.toolTipGeneratorList,
1215: that.toolTipGeneratorList)) {
1216: return false;
1217: }
1218: if (!ObjectUtilities.equal(this.baseToolTipGenerator,
1219: that.baseToolTipGenerator)) {
1220: return false;
1221: }
1222: if (!ObjectUtilities.equal(this.itemURLGenerator,
1223: that.itemURLGenerator)) {
1224: return false;
1225: }
1226: if (!ObjectUtilities.equal(this.itemURLGeneratorList,
1227: that.itemURLGeneratorList)) {
1228: return false;
1229: }
1230: if (!ObjectUtilities.equal(this.baseItemURLGenerator,
1231: that.baseItemURLGenerator)) {
1232: return false;
1233: }
1234: if (!ObjectUtilities.equal(this.legendItemLabelGenerator,
1235: that.legendItemLabelGenerator)) {
1236: return false;
1237: }
1238: if (!ObjectUtilities.equal(this.legendItemToolTipGenerator,
1239: that.legendItemToolTipGenerator)) {
1240: return false;
1241: }
1242: if (!ObjectUtilities.equal(this.legendItemURLGenerator,
1243: that.legendItemURLGenerator)) {
1244: return false;
1245: }
1246: return super.equals(obj);
1247: }
1248:
1249:
1254: public int hashCode() {
1255: int result = super.hashCode();
1256: return result;
1257: }
1258:
1259:
1264: public DrawingSupplier getDrawingSupplier() {
1265: DrawingSupplier result = null;
1266: CategoryPlot cp = getPlot();
1267: if (cp != null) {
1268: result = cp.getDrawingSupplier();
1269: }
1270: return result;
1271: }
1272:
1273:
1286: protected void drawItemLabel(Graphics2D g2,
1287: PlotOrientation orientation,
1288: CategoryDataset dataset,
1289: int row, int column,
1290: double x, double y,
1291: boolean negative) {
1292:
1293: CategoryItemLabelGenerator generator
1294: = getItemLabelGenerator(row, column);
1295: if (generator != null) {
1296: Font labelFont = getItemLabelFont(row, column);
1297: Paint paint = getItemLabelPaint(row, column);
1298: g2.setFont(labelFont);
1299: g2.setPaint(paint);
1300: String label = generator.generateLabel(dataset, row, column);
1301: ItemLabelPosition position = null;
1302: if (!negative) {
1303: position = getPositiveItemLabelPosition(row, column);
1304: }
1305: else {
1306: position = getNegativeItemLabelPosition(row, column);
1307: }
1308: Point2D anchorPoint = calculateLabelAnchorPoint(
1309: position.getItemLabelAnchor(), x, y, orientation);
1310: TextUtilities.drawRotatedString(label, g2,
1311: (float) anchorPoint.getX(), (float) anchorPoint.getY(),
1312: position.getTextAnchor(),
1313: position.getAngle(), position.getRotationAnchor());
1314: }
1315:
1316: }
1317:
1318:
1328: public Object clone() throws CloneNotSupportedException {
1329:
1330: AbstractCategoryItemRenderer clone
1331: = (AbstractCategoryItemRenderer) super.clone();
1332:
1333: if (this.itemLabelGenerator != null) {
1334: if (this.itemLabelGenerator instanceof PublicCloneable) {
1335: PublicCloneable pc = (PublicCloneable) this.itemLabelGenerator;
1336: clone.itemLabelGenerator
1337: = (CategoryItemLabelGenerator) pc.clone();
1338: }
1339: else {
1340: throw new CloneNotSupportedException(
1341: "ItemLabelGenerator not cloneable.");
1342: }
1343: }
1344:
1345: if (this.itemLabelGeneratorList != null) {
1346: clone.itemLabelGeneratorList
1347: = (ObjectList) this.itemLabelGeneratorList.clone();
1348: }
1349:
1350: if (this.baseItemLabelGenerator != null) {
1351: if (this.baseItemLabelGenerator instanceof PublicCloneable) {
1352: PublicCloneable pc
1353: = (PublicCloneable) this.baseItemLabelGenerator;
1354: clone.baseItemLabelGenerator
1355: = (CategoryItemLabelGenerator) pc.clone();
1356: }
1357: else {
1358: throw new CloneNotSupportedException(
1359: "ItemLabelGenerator not cloneable.");
1360: }
1361: }
1362:
1363: if (this.toolTipGenerator != null) {
1364: if (this.toolTipGenerator instanceof PublicCloneable) {
1365: PublicCloneable pc = (PublicCloneable) this.toolTipGenerator;
1366: clone.toolTipGenerator = (CategoryToolTipGenerator) pc.clone();
1367: }
1368: else {
1369: throw new CloneNotSupportedException(
1370: "Tool tip generator not cloneable.");
1371: }
1372: }
1373:
1374: if (this.toolTipGeneratorList != null) {
1375: clone.toolTipGeneratorList
1376: = (ObjectList) this.toolTipGeneratorList.clone();
1377: }
1378:
1379: if (this.baseToolTipGenerator != null) {
1380: if (this.baseToolTipGenerator instanceof PublicCloneable) {
1381: PublicCloneable pc
1382: = (PublicCloneable) this.baseToolTipGenerator;
1383: clone.baseToolTipGenerator
1384: = (CategoryToolTipGenerator) pc.clone();
1385: }
1386: else {
1387: throw new CloneNotSupportedException(
1388: "Base tool tip generator not cloneable.");
1389: }
1390: }
1391:
1392: if (this.itemURLGenerator != null) {
1393: if (this.itemURLGenerator instanceof PublicCloneable) {
1394: PublicCloneable pc = (PublicCloneable) this.itemURLGenerator;
1395: clone.itemURLGenerator = (CategoryURLGenerator) pc.clone();
1396: }
1397: else {
1398: throw new CloneNotSupportedException(
1399: "Item URL generator not cloneable.");
1400: }
1401: }
1402:
1403: if (this.itemURLGeneratorList != null) {
1404: clone.itemURLGeneratorList
1405: = (ObjectList) this.itemURLGeneratorList.clone();
1406: }
1407:
1408: if (this.baseItemURLGenerator != null) {
1409: if (this.baseItemURLGenerator instanceof PublicCloneable) {
1410: PublicCloneable pc
1411: = (PublicCloneable) this.baseItemURLGenerator;
1412: clone.baseItemURLGenerator = (CategoryURLGenerator) pc.clone();
1413: }
1414: else {
1415: throw new CloneNotSupportedException(
1416: "Base item URL generator not cloneable.");
1417: }
1418: }
1419:
1420: if (this.legendItemLabelGenerator instanceof PublicCloneable) {
1421: clone.legendItemLabelGenerator = (CategorySeriesLabelGenerator)
1422: ObjectUtilities.clone(this.legendItemLabelGenerator);
1423: }
1424: if (this.legendItemToolTipGenerator instanceof PublicCloneable) {
1425: clone.legendItemToolTipGenerator = (CategorySeriesLabelGenerator)
1426: ObjectUtilities.clone(this.legendItemToolTipGenerator);
1427: }
1428: if (this.legendItemURLGenerator instanceof PublicCloneable) {
1429: clone.legendItemURLGenerator = (CategorySeriesLabelGenerator)
1430: ObjectUtilities.clone(this.legendItemURLGenerator);
1431: }
1432: return clone;
1433: }
1434:
1435:
1443: protected CategoryAxis getDomainAxis(CategoryPlot plot, int index) {
1444: CategoryAxis result = plot.getDomainAxis(index);
1445: if (result == null) {
1446: result = plot.getDomainAxis();
1447: }
1448: return result;
1449: }
1450:
1451:
1459: protected ValueAxis getRangeAxis(CategoryPlot plot, int index) {
1460: ValueAxis result = plot.getRangeAxis(index);
1461: if (result == null) {
1462: result = plot.getRangeAxis();
1463: }
1464: return result;
1465: }
1466:
1467:
1475: public LegendItemCollection getLegendItems() {
1476: if (this.plot == null) {
1477: return new LegendItemCollection();
1478: }
1479: LegendItemCollection result = new LegendItemCollection();
1480: int index = this.plot.getIndexOf(this);
1481: CategoryDataset dataset = this.plot.getDataset(index);
1482: if (dataset != null) {
1483: int seriesCount = dataset.getRowCount();
1484: for (int i = 0; i < seriesCount; i++) {
1485: if (isSeriesVisibleInLegend(i)) {
1486: LegendItem item = getLegendItem(index, i);
1487: if (item != null) {
1488: result.add(item);
1489: }
1490: }
1491: }
1492:
1493: }
1494: return result;
1495: }
1496:
1497:
1504: public CategorySeriesLabelGenerator getLegendItemLabelGenerator() {
1505: return this.legendItemLabelGenerator;
1506: }
1507:
1508:
1516: public void setLegendItemLabelGenerator(
1517: CategorySeriesLabelGenerator generator) {
1518: if (generator == null) {
1519: throw new IllegalArgumentException("Null 'generator' argument.");
1520: }
1521: this.legendItemLabelGenerator = generator;
1522: notifyListeners(new RendererChangeEvent(this));
1523: }
1524:
1525:
1532: public CategorySeriesLabelGenerator getLegendItemToolTipGenerator() {
1533: return this.legendItemToolTipGenerator;
1534: }
1535:
1536:
1544: public void setLegendItemToolTipGenerator(
1545: CategorySeriesLabelGenerator generator) {
1546: this.legendItemToolTipGenerator = generator;
1547: notifyListeners(new RendererChangeEvent(this));
1548: }
1549:
1550:
1557: public CategorySeriesLabelGenerator getLegendItemURLGenerator() {
1558: return this.legendItemURLGenerator;
1559: }
1560:
1561:
1569: public void setLegendItemURLGenerator(
1570: CategorySeriesLabelGenerator generator) {
1571: this.legendItemURLGenerator = generator;
1572: notifyListeners(new RendererChangeEvent(this));
1573: }
1574:
1575:
1584: protected void addItemEntity(EntityCollection entities,
1585: CategoryDataset dataset, int row, int column,
1586: Shape hotspot) {
1587:
1588: String tip = null;
1589: CategoryToolTipGenerator tipster = getToolTipGenerator(row, column);
1590: if (tipster != null) {
1591: tip = tipster.generateToolTip(dataset, row, column);
1592: }
1593: String url = null;
1594: CategoryURLGenerator urlster = getItemURLGenerator(row, column);
1595: if (urlster != null) {
1596: url = urlster.generateURL(dataset, row, column);
1597: }
1598: CategoryItemEntity entity = new CategoryItemEntity(hotspot, tip, url,
1599: dataset, dataset.getRowKey(row), dataset.getColumnKey(column));
1600: entities.add(entity);
1601:
1602: }
1603:
1604:
1605: }