1:
152:
153: package ;
154:
155: import ;
156: import ;
157: import ;
158: import ;
159: import ;
160: import ;
161: import ;
162: import ;
163: import ;
164: import ;
165: import ;
166: import ;
167: import ;
168: import ;
169: import ;
170: import ;
171: import ;
172: import ;
173: import ;
174: import ;
175: import ;
176: import ;
177: import ;
178: import ;
179: import ;
180:
181: import ;
182: import ;
183: import ;
184: import ;
185: import ;
186: import ;
187: import ;
188: import ;
189: import ;
190: import ;
191: import ;
192: import ;
193: import ;
194: import ;
195: import ;
196: import ;
197: import ;
198: import ;
199: import ;
200: import ;
201: import ;
202: import ;
203: import ;
204: import ;
205: import ;
206: import ;
207: import ;
208: import ;
209: import ;
210: import ;
211: import ;
212: import ;
213:
214:
218: public class CategoryPlot extends Plot
219: implements ValueAxisPlot,
220: Zoomable,
221: RendererChangeListener,
222: Cloneable, PublicCloneable, Serializable {
223:
224:
225: private static final long serialVersionUID = -3537691700434728188L;
226:
227:
231: public static final boolean DEFAULT_DOMAIN_GRIDLINES_VISIBLE = false;
232:
233:
237: public static final boolean DEFAULT_RANGE_GRIDLINES_VISIBLE = true;
238:
239:
240: public static final Stroke DEFAULT_GRIDLINE_STROKE = new BasicStroke(0.5f,
241: BasicStroke.CAP_BUTT,
242: BasicStroke.JOIN_BEVEL,
243: 0.0f,
244: new float[] {2.0f, 2.0f},
245: 0.0f);
246:
247:
248: public static final Paint DEFAULT_GRIDLINE_PAINT = Color.lightGray;
249:
250:
251: public static final Font DEFAULT_VALUE_LABEL_FONT
252: = new Font("SansSerif", Font.PLAIN, 10);
253:
254:
259: public static final boolean DEFAULT_CROSSHAIR_VISIBLE = false;
260:
261:
266: public static final Stroke DEFAULT_CROSSHAIR_STROKE
267: = DEFAULT_GRIDLINE_STROKE;
268:
269:
274: public static final Paint DEFAULT_CROSSHAIR_PAINT = Color.blue;
275:
276:
277: protected static ResourceBundle localizationResources
278: = ResourceBundle.getBundle("org.jfree.chart.plot.LocalizationBundle");
279:
280:
281: private PlotOrientation orientation;
282:
283:
284: private RectangleInsets axisOffset;
285:
286:
287: private ObjectList domainAxes;
288:
289:
290: private ObjectList domainAxisLocations;
291:
292:
296: private boolean drawSharedDomainAxis;
297:
298:
299: private ObjectList rangeAxes;
300:
301:
302: private ObjectList rangeAxisLocations;
303:
304:
305: private ObjectList datasets;
306:
307:
308: private ObjectList datasetToDomainAxisMap;
309:
310:
311: private ObjectList datasetToRangeAxisMap;
312:
313:
314: private ObjectList renderers;
315:
316:
317: private DatasetRenderingOrder renderingOrder
318: = DatasetRenderingOrder.REVERSE;
319:
320:
324: private SortOrder columnRenderingOrder = SortOrder.ASCENDING;
325:
326:
330: private SortOrder rowRenderingOrder = SortOrder.ASCENDING;
331:
332:
336: private boolean domainGridlinesVisible;
337:
338:
339: private CategoryAnchor domainGridlinePosition;
340:
341:
342: private transient Stroke domainGridlineStroke;
343:
344:
345: private transient Paint domainGridlinePaint;
346:
347:
351: private boolean rangeGridlinesVisible;
352:
353:
354: private transient Stroke rangeGridlineStroke;
355:
356:
357: private transient Paint rangeGridlinePaint;
358:
359:
360: private double anchorValue;
361:
362:
363: private boolean rangeCrosshairVisible;
364:
365:
366: private double rangeCrosshairValue;
367:
368:
369: private transient Stroke rangeCrosshairStroke;
370:
371:
372: private transient Paint rangeCrosshairPaint;
373:
374:
378: private boolean rangeCrosshairLockedOnData = true;
379:
380:
381: private Map foregroundDomainMarkers;
382:
383:
384: private Map backgroundDomainMarkers;
385:
386:
387: private Map foregroundRangeMarkers;
388:
389:
390: private Map backgroundRangeMarkers;
391:
392:
397: private List annotations;
398:
399:
403: private int weight;
404:
405:
406: private AxisSpace fixedDomainAxisSpace;
407:
408:
409: private AxisSpace fixedRangeAxisSpace;
410:
411:
415: private LegendItemCollection fixedLegendItems;
416:
417:
420: public CategoryPlot() {
421: this(null, null, null, null);
422: }
423:
424:
433: public CategoryPlot(CategoryDataset dataset,
434: CategoryAxis domainAxis,
435: ValueAxis rangeAxis,
436: CategoryItemRenderer renderer) {
437:
438: super();
439:
440: this.orientation = PlotOrientation.VERTICAL;
441:
442:
443: this.domainAxes = new ObjectList();
444: this.domainAxisLocations = new ObjectList();
445: this.rangeAxes = new ObjectList();
446: this.rangeAxisLocations = new ObjectList();
447:
448: this.datasetToDomainAxisMap = new ObjectList();
449: this.datasetToRangeAxisMap = new ObjectList();
450:
451: this.renderers = new ObjectList();
452:
453: this.datasets = new ObjectList();
454: this.datasets.set(0, dataset);
455: if (dataset != null) {
456: dataset.addChangeListener(this);
457: }
458:
459: this.axisOffset = RectangleInsets.ZERO_INSETS;
460:
461: setDomainAxisLocation(AxisLocation.BOTTOM_OR_LEFT, false);
462: setRangeAxisLocation(AxisLocation.TOP_OR_LEFT, false);
463:
464: this.renderers.set(0, renderer);
465: if (renderer != null) {
466: renderer.setPlot(this);
467: renderer.addChangeListener(this);
468: }
469:
470: this.domainAxes.set(0, domainAxis);
471: this.mapDatasetToDomainAxis(0, 0);
472: if (domainAxis != null) {
473: domainAxis.setPlot(this);
474: domainAxis.addChangeListener(this);
475: }
476: this.drawSharedDomainAxis = false;
477:
478: this.rangeAxes.set(0, rangeAxis);
479: this.mapDatasetToRangeAxis(0, 0);
480: if (rangeAxis != null) {
481: rangeAxis.setPlot(this);
482: rangeAxis.addChangeListener(this);
483: }
484:
485: configureDomainAxes();
486: configureRangeAxes();
487:
488: this.domainGridlinesVisible = DEFAULT_DOMAIN_GRIDLINES_VISIBLE;
489: this.domainGridlinePosition = CategoryAnchor.MIDDLE;
490: this.domainGridlineStroke = DEFAULT_GRIDLINE_STROKE;
491: this.domainGridlinePaint = DEFAULT_GRIDLINE_PAINT;
492:
493: this.rangeGridlinesVisible = DEFAULT_RANGE_GRIDLINES_VISIBLE;
494: this.rangeGridlineStroke = DEFAULT_GRIDLINE_STROKE;
495: this.rangeGridlinePaint = DEFAULT_GRIDLINE_PAINT;
496:
497: this.foregroundDomainMarkers = new HashMap();
498: this.backgroundDomainMarkers = new HashMap();
499: this.foregroundRangeMarkers = new HashMap();
500: this.backgroundRangeMarkers = new HashMap();
501:
502: Marker baseline = new ValueMarker(0.0, new Color(0.8f, 0.8f, 0.8f,
503: 0.5f), new BasicStroke(1.0f), new Color(0.85f, 0.85f, 0.95f,
504: 0.5f), new BasicStroke(1.0f), 0.6f);
505: addRangeMarker(baseline, Layer.BACKGROUND);
506:
507: this.anchorValue = 0.0;
508:
509: this.rangeCrosshairVisible = DEFAULT_CROSSHAIR_VISIBLE;
510: this.rangeCrosshairValue = 0.0;
511: this.rangeCrosshairStroke = DEFAULT_CROSSHAIR_STROKE;
512: this.rangeCrosshairPaint = DEFAULT_CROSSHAIR_PAINT;
513:
514: this.annotations = new java.util.ArrayList();
515:
516: }
517:
518:
523: public String getPlotType() {
524: return localizationResources.getString("Category_Plot");
525: }
526:
527:
534: public PlotOrientation getOrientation() {
535: return this.orientation;
536: }
537:
538:
546: public void setOrientation(PlotOrientation orientation) {
547: if (orientation == null) {
548: throw new IllegalArgumentException("Null 'orientation' argument.");
549: }
550: this.orientation = orientation;
551: notifyListeners(new PlotChangeEvent(this));
552: }
553:
554:
561: public RectangleInsets getAxisOffset() {
562: return this.axisOffset;
563: }
564:
565:
573: public void setAxisOffset(RectangleInsets offset) {
574: if (offset == null) {
575: throw new IllegalArgumentException("Null 'offset' argument.");
576: }
577: this.axisOffset = offset;
578: notifyListeners(new PlotChangeEvent(this));
579: }
580:
581:
590: public CategoryAxis getDomainAxis() {
591: return getDomainAxis(0);
592: }
593:
594:
603: public CategoryAxis getDomainAxis(int index) {
604: CategoryAxis result = null;
605: if (index < this.domainAxes.size()) {
606: result = (CategoryAxis) this.domainAxes.get(index);
607: }
608: if (result == null) {
609: Plot parent = getParent();
610: if (parent instanceof CategoryPlot) {
611: CategoryPlot cp = (CategoryPlot) parent;
612: result = cp.getDomainAxis(index);
613: }
614: }
615: return result;
616: }
617:
618:
626: public void setDomainAxis(CategoryAxis axis) {
627: setDomainAxis(0, axis);
628: }
629:
630:
639: public void setDomainAxis(int index, CategoryAxis axis) {
640: setDomainAxis(index, axis, true);
641: }
642:
643:
651: public void setDomainAxis(int index, CategoryAxis axis, boolean notify) {
652: CategoryAxis existing = (CategoryAxis) this.domainAxes.get(index);
653: if (existing != null) {
654: existing.removeChangeListener(this);
655: }
656: if (axis != null) {
657: axis.setPlot(this);
658: }
659: this.domainAxes.set(index, axis);
660: if (axis != null) {
661: axis.configure();
662: axis.addChangeListener(this);
663: }
664: if (notify) {
665: notifyListeners(new PlotChangeEvent(this));
666: }
667: }
668:
669:
677: public void setDomainAxes(CategoryAxis[] axes) {
678: for (int i = 0; i < axes.length; i++) {
679: setDomainAxis(i, axes[i], false);
680: }
681: notifyListeners(new PlotChangeEvent(this));
682: }
683:
684:
694: public int getDomainAxisIndex(CategoryAxis axis) {
695: return this.domainAxes.indexOf(axis);
696: }
697:
698:
705: public AxisLocation getDomainAxisLocation() {
706: return getDomainAxisLocation(0);
707: }
708:
709:
718: public AxisLocation getDomainAxisLocation(int index) {
719: AxisLocation result = null;
720: if (index < this.domainAxisLocations.size()) {
721: result = (AxisLocation) this.domainAxisLocations.get(index);
722: }
723: if (result == null) {
724: result = AxisLocation.getOpposite(getDomainAxisLocation(0));
725: }
726: return result;
727: }
728:
729:
738: public void setDomainAxisLocation(AxisLocation location) {
739:
740: setDomainAxisLocation(0, location, true);
741: }
742:
743:
750: public void setDomainAxisLocation(AxisLocation location, boolean notify) {
751:
752: setDomainAxisLocation(0, location, notify);
753: }
754:
755:
765: public void setDomainAxisLocation(int index, AxisLocation location) {
766:
767: setDomainAxisLocation(index, location, true);
768: }
769:
770:
783: public void setDomainAxisLocation(int index, AxisLocation location,
784: boolean notify) {
785: if (index == 0 && location == null) {
786: throw new IllegalArgumentException(
787: "Null 'location' for index 0 not permitted.");
788: }
789: this.domainAxisLocations.set(index, location);
790: if (notify) {
791: notifyListeners(new PlotChangeEvent(this));
792: }
793: }
794:
795:
801: public RectangleEdge getDomainAxisEdge() {
802: return getDomainAxisEdge(0);
803: }
804:
805:
812: public RectangleEdge getDomainAxisEdge(int index) {
813: RectangleEdge result = null;
814: AxisLocation location = getDomainAxisLocation(index);
815: if (location != null) {
816: result = Plot.resolveDomainAxisLocation(location, this.orientation);
817: }
818: else {
819: result = RectangleEdge.opposite(getDomainAxisEdge(0));
820: }
821: return result;
822: }
823:
824:
829: public int getDomainAxisCount() {
830: return this.domainAxes.size();
831: }
832:
833:
837: public void clearDomainAxes() {
838: for (int i = 0; i < this.domainAxes.size(); i++) {
839: CategoryAxis axis = (CategoryAxis) this.domainAxes.get(i);
840: if (axis != null) {
841: axis.removeChangeListener(this);
842: }
843: }
844: this.domainAxes.clear();
845: notifyListeners(new PlotChangeEvent(this));
846: }
847:
848:
851: public void configureDomainAxes() {
852: for (int i = 0; i < this.domainAxes.size(); i++) {
853: CategoryAxis axis = (CategoryAxis) this.domainAxes.get(i);
854: if (axis != null) {
855: axis.configure();
856: }
857: }
858: }
859:
860:
867: public ValueAxis getRangeAxis() {
868: return getRangeAxis(0);
869: }
870:
871:
878: public ValueAxis getRangeAxis(int index) {
879: ValueAxis result = null;
880: if (index < this.rangeAxes.size()) {
881: result = (ValueAxis) this.rangeAxes.get(index);
882: }
883: if (result == null) {
884: Plot parent = getParent();
885: if (parent instanceof CategoryPlot) {
886: CategoryPlot cp = (CategoryPlot) parent;
887: result = cp.getRangeAxis(index);
888: }
889: }
890: return result;
891: }
892:
893:
899: public void setRangeAxis(ValueAxis axis) {
900: setRangeAxis(0, axis);
901: }
902:
903:
910: public void setRangeAxis(int index, ValueAxis axis) {
911: setRangeAxis(index, axis, true);
912: }
913:
914:
922: public void setRangeAxis(int index, ValueAxis axis, boolean notify) {
923: ValueAxis existing = (ValueAxis) this.rangeAxes.get(index);
924: if (existing != null) {
925: existing.removeChangeListener(this);
926: }
927: if (axis != null) {
928: axis.setPlot(this);
929: }
930: this.rangeAxes.set(index, axis);
931: if (axis != null) {
932: axis.configure();
933: axis.addChangeListener(this);
934: }
935: if (notify) {
936: notifyListeners(new PlotChangeEvent(this));
937: }
938: }
939:
940:
948: public void setRangeAxes(ValueAxis[] axes) {
949: for (int i = 0; i < axes.length; i++) {
950: setRangeAxis(i, axes[i], false);
951: }
952: notifyListeners(new PlotChangeEvent(this));
953: }
954:
955:
960: public AxisLocation getRangeAxisLocation() {
961: return getRangeAxisLocation(0);
962: }
963:
964:
973: public AxisLocation getRangeAxisLocation(int index) {
974: AxisLocation result = null;
975: if (index < this.rangeAxisLocations.size()) {
976: result = (AxisLocation) this.rangeAxisLocations.get(index);
977: }
978: if (result == null) {
979: result = AxisLocation.getOpposite(getRangeAxisLocation(0));
980: }
981: return result;
982: }
983:
984:
993: public void setRangeAxisLocation(AxisLocation location) {
994:
995: setRangeAxisLocation(location, true);
996: }
997:
998:
1007: public void setRangeAxisLocation(AxisLocation location, boolean notify) {
1008: setRangeAxisLocation(0, location, notify);
1009: }
1010:
1011:
1021: public void setRangeAxisLocation(int index, AxisLocation location) {
1022: setRangeAxisLocation(index, location, true);
1023: }
1024:
1025:
1036: public void setRangeAxisLocation(int index, AxisLocation location,
1037: boolean notify) {
1038: if (index == 0 && location == null) {
1039: throw new IllegalArgumentException(
1040: "Null 'location' for index 0 not permitted.");
1041: }
1042: this.rangeAxisLocations.set(index, location);
1043: if (notify) {
1044: notifyListeners(new PlotChangeEvent(this));
1045: }
1046: }
1047:
1048:
1053: public RectangleEdge getRangeAxisEdge() {
1054: return getRangeAxisEdge(0);
1055: }
1056:
1057:
1064: public RectangleEdge getRangeAxisEdge(int index) {
1065: AxisLocation location = getRangeAxisLocation(index);
1066: RectangleEdge result = Plot.resolveRangeAxisLocation(location,
1067: this.orientation);
1068: if (result == null) {
1069: result = RectangleEdge.opposite(getRangeAxisEdge(0));
1070: }
1071: return result;
1072: }
1073:
1074:
1079: public int getRangeAxisCount() {
1080: return this.rangeAxes.size();
1081: }
1082:
1083:
1087: public void clearRangeAxes() {
1088: for (int i = 0; i < this.rangeAxes.size(); i++) {
1089: ValueAxis axis = (ValueAxis) this.rangeAxes.get(i);
1090: if (axis != null) {
1091: axis.removeChangeListener(this);
1092: }
1093: }
1094: this.rangeAxes.clear();
1095: notifyListeners(new PlotChangeEvent(this));
1096: }
1097:
1098:
1101: public void configureRangeAxes() {
1102: for (int i = 0; i < this.rangeAxes.size(); i++) {
1103: ValueAxis axis = (ValueAxis) this.rangeAxes.get(i);
1104: if (axis != null) {
1105: axis.configure();
1106: }
1107: }
1108: }
1109:
1110:
1117: public CategoryDataset getDataset() {
1118: return getDataset(0);
1119: }
1120:
1121:
1130: public CategoryDataset getDataset(int index) {
1131: CategoryDataset result = null;
1132: if (this.datasets.size() > index) {
1133: result = (CategoryDataset) this.datasets.get(index);
1134: }
1135: return result;
1136: }
1137:
1138:
1149: public void setDataset(CategoryDataset dataset) {
1150: setDataset(0, dataset);
1151: }
1152:
1153:
1161: public void setDataset(int index, CategoryDataset dataset) {
1162:
1163: CategoryDataset existing = (CategoryDataset) this.datasets.get(index);
1164: if (existing != null) {
1165: existing.removeChangeListener(this);
1166: }
1167: this.datasets.set(index, dataset);
1168: if (dataset != null) {
1169: dataset.addChangeListener(this);
1170: }
1171:
1172:
1173: DatasetChangeEvent event = new DatasetChangeEvent(this, dataset);
1174: datasetChanged(event);
1175:
1176: }
1177:
1178:
1185: public int getDatasetCount() {
1186: return this.datasets.size();
1187: }
1188:
1189:
1197: public void mapDatasetToDomainAxis(int index, int axisIndex) {
1198: this.datasetToDomainAxisMap.set(index, new Integer(axisIndex));
1199:
1200: datasetChanged(new DatasetChangeEvent(this, getDataset(index)));
1201: }
1202:
1203:
1213: public CategoryAxis getDomainAxisForDataset(int index) {
1214: CategoryAxis result = getDomainAxis();
1215: Integer axisIndex = (Integer) this.datasetToDomainAxisMap.get(index);
1216: if (axisIndex != null) {
1217: result = getDomainAxis(axisIndex.intValue());
1218: }
1219: return result;
1220: }
1221:
1222:
1230: public void mapDatasetToRangeAxis(int index, int axisIndex) {
1231: this.datasetToRangeAxisMap.set(index, new Integer(axisIndex));
1232:
1233: datasetChanged(new DatasetChangeEvent(this, getDataset(index)));
1234: }
1235:
1236:
1246: public ValueAxis getRangeAxisForDataset(int index) {
1247: ValueAxis result = getRangeAxis();
1248: Integer axisIndex = (Integer) this.datasetToRangeAxisMap.get(index);
1249: if (axisIndex != null) {
1250: result = getRangeAxis(axisIndex.intValue());
1251: }
1252: return result;
1253: }
1254:
1255:
1262: public CategoryItemRenderer getRenderer() {
1263: return getRenderer(0);
1264: }
1265:
1266:
1275: public CategoryItemRenderer getRenderer(int index) {
1276: CategoryItemRenderer result = null;
1277: if (this.renderers.size() > index) {
1278: result = (CategoryItemRenderer) this.renderers.get(index);
1279: }
1280: return result;
1281: }
1282:
1283:
1292: public void setRenderer(CategoryItemRenderer renderer) {
1293: setRenderer(0, renderer, true);
1294: }
1295:
1296:
1313: public void setRenderer(CategoryItemRenderer renderer, boolean notify) {
1314: setRenderer(0, renderer, notify);
1315: }
1316:
1317:
1327: public void setRenderer(int index, CategoryItemRenderer renderer) {
1328: setRenderer(index, renderer, true);
1329: }
1330:
1331:
1341: public void setRenderer(int index, CategoryItemRenderer renderer,
1342: boolean notify) {
1343:
1344:
1345: CategoryItemRenderer existing
1346: = (CategoryItemRenderer) this.renderers.get(index);
1347: if (existing != null) {
1348: existing.removeChangeListener(this);
1349: }
1350:
1351:
1352: this.renderers.set(index, renderer);
1353: if (renderer != null) {
1354: renderer.setPlot(this);
1355: renderer.addChangeListener(this);
1356: }
1357:
1358: configureDomainAxes();
1359: configureRangeAxes();
1360:
1361: if (notify) {
1362: notifyListeners(new PlotChangeEvent(this));
1363: }
1364: }
1365:
1366:
1372: public void setRenderers(CategoryItemRenderer[] renderers) {
1373: for (int i = 0; i < renderers.length; i++) {
1374: setRenderer(i, renderers[i], false);
1375: }
1376: notifyListeners(new PlotChangeEvent(this));
1377: }
1378:
1379:
1387: public CategoryItemRenderer getRendererForDataset(CategoryDataset dataset) {
1388: CategoryItemRenderer result = null;
1389: for (int i = 0; i < this.datasets.size(); i++) {
1390: if (this.datasets.get(i) == dataset) {
1391: result = (CategoryItemRenderer) this.renderers.get(i);
1392: break;
1393: }
1394: }
1395: return result;
1396: }
1397:
1398:
1406: public int getIndexOf(CategoryItemRenderer renderer) {
1407: return this.renderers.indexOf(renderer);
1408: }
1409:
1410:
1417: public DatasetRenderingOrder getDatasetRenderingOrder() {
1418: return this.renderingOrder;
1419: }
1420:
1421:
1431: public void setDatasetRenderingOrder(DatasetRenderingOrder order) {
1432: if (order == null) {
1433: throw new IllegalArgumentException("Null 'order' argument.");
1434: }
1435: this.renderingOrder = order;
1436: notifyListeners(new PlotChangeEvent(this));
1437: }
1438:
1439:
1447: public SortOrder getColumnRenderingOrder() {
1448: return this.columnRenderingOrder;
1449: }
1450:
1451:
1462: public void setColumnRenderingOrder(SortOrder order) {
1463: if (order == null) {
1464: throw new IllegalArgumentException("Null 'order' argument.");
1465: }
1466: this.columnRenderingOrder = order;
1467: notifyListeners(new PlotChangeEvent(this));
1468: }
1469:
1470:
1478: public SortOrder getRowRenderingOrder() {
1479: return this.rowRenderingOrder;
1480: }
1481:
1482:
1493: public void setRowRenderingOrder(SortOrder order) {
1494: if (order == null) {
1495: throw new IllegalArgumentException("Null 'order' argument.");
1496: }
1497: this.rowRenderingOrder = order;
1498: notifyListeners(new PlotChangeEvent(this));
1499: }
1500:
1501:
1508: public boolean isDomainGridlinesVisible() {
1509: return this.domainGridlinesVisible;
1510: }
1511:
1512:
1523: public void setDomainGridlinesVisible(boolean visible) {
1524: if (this.domainGridlinesVisible != visible) {
1525: this.domainGridlinesVisible = visible;
1526: notifyListeners(new PlotChangeEvent(this));
1527: }
1528: }
1529:
1530:
1537: public CategoryAnchor getDomainGridlinePosition() {
1538: return this.domainGridlinePosition;
1539: }
1540:
1541:
1549: public void setDomainGridlinePosition(CategoryAnchor position) {
1550: if (position == null) {
1551: throw new IllegalArgumentException("Null 'position' argument.");
1552: }
1553: this.domainGridlinePosition = position;
1554: notifyListeners(new PlotChangeEvent(this));
1555: }
1556:
1557:
1564: public Stroke getDomainGridlineStroke() {
1565: return this.domainGridlineStroke;
1566: }
1567:
1568:
1576: public void setDomainGridlineStroke(Stroke stroke) {
1577: if (stroke == null) {
1578: throw new IllegalArgumentException("Null 'stroke' not permitted.");
1579: }
1580: this.domainGridlineStroke = stroke;
1581: notifyListeners(new PlotChangeEvent(this));
1582: }
1583:
1584:
1591: public Paint getDomainGridlinePaint() {
1592: return this.domainGridlinePaint;
1593: }
1594:
1595:
1603: public void setDomainGridlinePaint(Paint paint) {
1604: if (paint == null) {
1605: throw new IllegalArgumentException("Null 'paint' argument.");
1606: }
1607: this.domainGridlinePaint = paint;
1608: notifyListeners(new PlotChangeEvent(this));
1609: }
1610:
1611:
1618: public boolean isRangeGridlinesVisible() {
1619: return this.rangeGridlinesVisible;
1620: }
1621:
1622:
1631: public void setRangeGridlinesVisible(boolean visible) {
1632: if (this.rangeGridlinesVisible != visible) {
1633: this.rangeGridlinesVisible = visible;
1634: notifyListeners(new PlotChangeEvent(this));
1635: }
1636: }
1637:
1638:
1645: public Stroke getRangeGridlineStroke() {
1646: return this.rangeGridlineStroke;
1647: }
1648:
1649:
1657: public void setRangeGridlineStroke(Stroke stroke) {
1658: if (stroke == null) {
1659: throw new IllegalArgumentException("Null 'stroke' argument.");
1660: }
1661: this.rangeGridlineStroke = stroke;
1662: notifyListeners(new PlotChangeEvent(this));
1663: }
1664:
1665:
1672: public Paint getRangeGridlinePaint() {
1673: return this.rangeGridlinePaint;
1674: }
1675:
1676:
1684: public void setRangeGridlinePaint(Paint paint) {
1685: if (paint == null) {
1686: throw new IllegalArgumentException("Null 'paint' argument.");
1687: }
1688: this.rangeGridlinePaint = paint;
1689: notifyListeners(new PlotChangeEvent(this));
1690: }
1691:
1692:
1699: public LegendItemCollection getFixedLegendItems() {
1700: return this.fixedLegendItems;
1701: }
1702:
1703:
1712: public void setFixedLegendItems(LegendItemCollection items) {
1713: this.fixedLegendItems = items;
1714: notifyListeners(new PlotChangeEvent(this));
1715: }
1716:
1717:
1724: public LegendItemCollection getLegendItems() {
1725: LegendItemCollection result = this.fixedLegendItems;
1726: if (result == null) {
1727: result = new LegendItemCollection();
1728:
1729: int count = this.datasets.size();
1730: for (int datasetIndex = 0; datasetIndex < count; datasetIndex++) {
1731: CategoryDataset dataset = getDataset(datasetIndex);
1732: if (dataset != null) {
1733: CategoryItemRenderer renderer = getRenderer(datasetIndex);
1734: if (renderer != null) {
1735: int seriesCount = dataset.getRowCount();
1736: for (int i = 0; i < seriesCount; i++) {
1737: LegendItem item = renderer.getLegendItem(
1738: datasetIndex, i);
1739: if (item != null) {
1740: result.add(item);
1741: }
1742: }
1743: }
1744: }
1745: }
1746: }
1747: return result;
1748: }
1749:
1750:
1758: public void handleClick(int x, int y, PlotRenderingInfo info) {
1759:
1760: Rectangle2D dataArea = info.getDataArea();
1761: if (dataArea.contains(x, y)) {
1762:
1763: double java2D = 0.0;
1764: if (this.orientation == PlotOrientation.HORIZONTAL) {
1765: java2D = x;
1766: }
1767: else if (this.orientation == PlotOrientation.VERTICAL) {
1768: java2D = y;
1769: }
1770: RectangleEdge edge = Plot.resolveRangeAxisLocation(
1771: getRangeAxisLocation(), this.orientation);
1772: double value = getRangeAxis().java2DToValue(
1773: java2D, info.getDataArea(), edge);
1774: setAnchorValue(value);
1775: setRangeCrosshairValue(value);
1776: }
1777:
1778: }
1779:
1780:
1789: public void zoom(double percent) {
1790:
1791: if (percent > 0.0) {
1792: double range = getRangeAxis().getRange().getLength();
1793: double scaledRange = range * percent;
1794: getRangeAxis().setRange(this.anchorValue - scaledRange / 2.0,
1795: this.anchorValue + scaledRange / 2.0);
1796: }
1797: else {
1798: getRangeAxis().setAutoRange(true);
1799: }
1800:
1801: }
1802:
1803:
1810: public void datasetChanged(DatasetChangeEvent event) {
1811:
1812: int count = this.rangeAxes.size();
1813: for (int axisIndex = 0; axisIndex < count; axisIndex++) {
1814: ValueAxis yAxis = getRangeAxis(axisIndex);
1815: if (yAxis != null) {
1816: yAxis.configure();
1817: }
1818: }
1819: if (getParent() != null) {
1820: getParent().datasetChanged(event);
1821: }
1822: else {
1823: PlotChangeEvent e = new PlotChangeEvent(this);
1824: e.setType(ChartChangeEventType.DATASET_UPDATED);
1825: notifyListeners(e);
1826: }
1827:
1828: }
1829:
1830:
1835: public void rendererChanged(RendererChangeEvent event) {
1836: Plot parent = getParent();
1837: if (parent != null) {
1838: if (parent instanceof RendererChangeListener) {
1839: RendererChangeListener rcl = (RendererChangeListener) parent;
1840: rcl.rendererChanged(event);
1841: }
1842: else {
1843:
1844:
1845: throw new RuntimeException(
1846: "The renderer has changed and I don't know what to do!");
1847: }
1848: }
1849: else {
1850: configureRangeAxes();
1851: PlotChangeEvent e = new PlotChangeEvent(this);
1852: notifyListeners(e);
1853: }
1854: }
1855:
1856:
1864: public void addDomainMarker(CategoryMarker marker) {
1865: addDomainMarker(marker, Layer.FOREGROUND);
1866: }
1867:
1868:
1878: public void addDomainMarker(CategoryMarker marker, Layer layer) {
1879: addDomainMarker(0, marker, layer);
1880: }
1881:
1882:
1892: public void addDomainMarker(int index, CategoryMarker marker, Layer layer) {
1893: if (marker == null) {
1894: throw new IllegalArgumentException("Null 'marker' not permitted.");
1895: }
1896: if (layer == null) {
1897: throw new IllegalArgumentException("Null 'layer' not permitted.");
1898: }
1899: Collection markers;
1900: if (layer == Layer.FOREGROUND) {
1901: markers = (Collection) this.foregroundDomainMarkers.get(
1902: new Integer(index));
1903: if (markers == null) {
1904: markers = new java.util.ArrayList();
1905: this.foregroundDomainMarkers.put(new Integer(index), markers);
1906: }
1907: markers.add(marker);
1908: }
1909: else if (layer == Layer.BACKGROUND) {
1910: markers = (Collection) this.backgroundDomainMarkers.get(
1911: new Integer(index));
1912: if (markers == null) {
1913: markers = new java.util.ArrayList();
1914: this.backgroundDomainMarkers.put(new Integer(index), markers);
1915: }
1916: markers.add(marker);
1917: }
1918: marker.addChangeListener(this);
1919: notifyListeners(new PlotChangeEvent(this));
1920: }
1921:
1922:
1928: public void clearDomainMarkers() {
1929: if (this.backgroundDomainMarkers != null) {
1930: Set keys = this.backgroundDomainMarkers.keySet();
1931: Iterator iterator = keys.iterator();
1932: while (iterator.hasNext()) {
1933: Integer key = (Integer) iterator.next();
1934: clearDomainMarkers(key.intValue());
1935: }
1936: this.backgroundDomainMarkers.clear();
1937: }
1938: if (this.foregroundDomainMarkers != null) {
1939: Set keys = this.foregroundDomainMarkers.keySet();
1940: Iterator iterator = keys.iterator();
1941: while (iterator.hasNext()) {
1942: Integer key = (Integer) iterator.next();
1943: clearDomainMarkers(key.intValue());
1944: }
1945: this.foregroundDomainMarkers.clear();
1946: }
1947: notifyListeners(new PlotChangeEvent(this));
1948: }
1949:
1950:
1957: public Collection getDomainMarkers(Layer layer) {
1958: return getDomainMarkers(0, layer);
1959: }
1960:
1961:
1970: public Collection getDomainMarkers(int index, Layer layer) {
1971: Collection result = null;
1972: Integer key = new Integer(index);
1973: if (layer == Layer.FOREGROUND) {
1974: result = (Collection) this.foregroundDomainMarkers.get(key);
1975: }
1976: else if (layer == Layer.BACKGROUND) {
1977: result = (Collection) this.backgroundDomainMarkers.get(key);
1978: }
1979: if (result != null) {
1980: result = Collections.unmodifiableCollection(result);
1981: }
1982: return result;
1983: }
1984:
1985:
1992: public void clearDomainMarkers(int index) {
1993: Integer key = new Integer(index);
1994: if (this.backgroundDomainMarkers != null) {
1995: Collection markers
1996: = (Collection) this.backgroundDomainMarkers.get(key);
1997: if (markers != null) {
1998: Iterator iterator = markers.iterator();
1999: while (iterator.hasNext()) {
2000: Marker m = (Marker) iterator.next();
2001: m.removeChangeListener(this);
2002: }
2003: markers.clear();
2004: }
2005: }
2006: if (this.foregroundDomainMarkers != null) {
2007: Collection markers
2008: = (Collection) this.foregroundDomainMarkers.get(key);
2009: if (markers != null) {
2010: Iterator iterator = markers.iterator();
2011: while (iterator.hasNext()) {
2012: Marker m = (Marker) iterator.next();
2013: m.removeChangeListener(this);
2014: }
2015: markers.clear();
2016: }
2017: }
2018: notifyListeners(new PlotChangeEvent(this));
2019: }
2020:
2021:
2029: public void addRangeMarker(Marker marker) {
2030: addRangeMarker(marker, Layer.FOREGROUND);
2031: }
2032:
2033:
2043: public void addRangeMarker(Marker marker, Layer layer) {
2044: addRangeMarker(0, marker, layer);
2045: }
2046:
2047:
2057: public void addRangeMarker(int index, Marker marker, Layer layer) {
2058: Collection markers;
2059: if (layer == Layer.FOREGROUND) {
2060: markers = (Collection) this.foregroundRangeMarkers.get(
2061: new Integer(index));
2062: if (markers == null) {
2063: markers = new java.util.ArrayList();
2064: this.foregroundRangeMarkers.put(new Integer(index), markers);
2065: }
2066: markers.add(marker);
2067: }
2068: else if (layer == Layer.BACKGROUND) {
2069: markers = (Collection) this.backgroundRangeMarkers.get(
2070: new Integer(index));
2071: if (markers == null) {
2072: markers = new java.util.ArrayList();
2073: this.backgroundRangeMarkers.put(new Integer(index), markers);
2074: }
2075: markers.add(marker);
2076: }
2077: marker.addChangeListener(this);
2078: notifyListeners(new PlotChangeEvent(this));
2079: }
2080:
2081:
2087: public void clearRangeMarkers() {
2088: if (this.backgroundRangeMarkers != null) {
2089: Set keys = this.backgroundRangeMarkers.keySet();
2090: Iterator iterator = keys.iterator();
2091: while (iterator.hasNext()) {
2092: Integer key = (Integer) iterator.next();
2093: clearRangeMarkers(key.intValue());
2094: }
2095: this.backgroundRangeMarkers.clear();
2096: }
2097: if (this.foregroundRangeMarkers != null) {
2098: Set keys = this.foregroundRangeMarkers.keySet();
2099: Iterator iterator = keys.iterator();
2100: while (iterator.hasNext()) {
2101: Integer key = (Integer) iterator.next();
2102: clearRangeMarkers(key.intValue());
2103: }
2104: this.foregroundRangeMarkers.clear();
2105: }
2106: notifyListeners(new PlotChangeEvent(this));
2107: }
2108:
2109:
2118: public Collection getRangeMarkers(Layer layer) {
2119: return getRangeMarkers(0, layer);
2120: }
2121:
2122:
2131: public Collection getRangeMarkers(int index, Layer layer) {
2132: Collection result = null;
2133: Integer key = new Integer(index);
2134: if (layer == Layer.FOREGROUND) {
2135: result = (Collection) this.foregroundRangeMarkers.get(key);
2136: }
2137: else if (layer == Layer.BACKGROUND) {
2138: result = (Collection) this.backgroundRangeMarkers.get(key);
2139: }
2140: if (result != null) {
2141: result = Collections.unmodifiableCollection(result);
2142: }
2143: return result;
2144: }
2145:
2146:
2153: public void clearRangeMarkers(int index) {
2154: Integer key = new Integer(index);
2155: if (this.backgroundRangeMarkers != null) {
2156: Collection markers
2157: = (Collection) this.backgroundRangeMarkers.get(key);
2158: if (markers != null) {
2159: Iterator iterator = markers.iterator();
2160: while (iterator.hasNext()) {
2161: Marker m = (Marker) iterator.next();
2162: m.removeChangeListener(this);
2163: }
2164: markers.clear();
2165: }
2166: }
2167: if (this.foregroundRangeMarkers != null) {
2168: Collection markers
2169: = (Collection) this.foregroundRangeMarkers.get(key);
2170: if (markers != null) {
2171: Iterator iterator = markers.iterator();
2172: while (iterator.hasNext()) {
2173: Marker m = (Marker) iterator.next();
2174: m.removeChangeListener(this);
2175: }
2176: markers.clear();
2177: }
2178: }
2179: notifyListeners(new PlotChangeEvent(this));
2180: }
2181:
2182:
2189: public boolean isRangeCrosshairVisible() {
2190: return this.rangeCrosshairVisible;
2191: }
2192:
2193:
2200: public void setRangeCrosshairVisible(boolean flag) {
2201: if (this.rangeCrosshairVisible != flag) {
2202: this.rangeCrosshairVisible = flag;
2203: notifyListeners(new PlotChangeEvent(this));
2204: }
2205: }
2206:
2207:
2215: public boolean isRangeCrosshairLockedOnData() {
2216: return this.rangeCrosshairLockedOnData;
2217: }
2218:
2219:
2227: public void setRangeCrosshairLockedOnData(boolean flag) {
2228:
2229: if (this.rangeCrosshairLockedOnData != flag) {
2230: this.rangeCrosshairLockedOnData = flag;
2231: notifyListeners(new PlotChangeEvent(this));
2232: }
2233:
2234: }
2235:
2236:
2243: public double getRangeCrosshairValue() {
2244: return this.rangeCrosshairValue;
2245: }
2246:
2247:
2257: public void setRangeCrosshairValue(double value) {
2258: setRangeCrosshairValue(value, true);
2259: }
2260:
2261:
2272: public void setRangeCrosshairValue(double value, boolean notify) {
2273: this.rangeCrosshairValue = value;
2274: if (isRangeCrosshairVisible() && notify) {
2275: notifyListeners(new PlotChangeEvent(this));
2276: }
2277: }
2278:
2279:
2289: public Stroke getRangeCrosshairStroke() {
2290: return this.rangeCrosshairStroke;
2291: }
2292:
2293:
2303: public void setRangeCrosshairStroke(Stroke stroke) {
2304: if (stroke == null) {
2305: throw new IllegalArgumentException("Null 'stroke' argument.");
2306: }
2307: this.rangeCrosshairStroke = stroke;
2308: notifyListeners(new PlotChangeEvent(this));
2309: }
2310:
2311:
2320: public Paint getRangeCrosshairPaint() {
2321: return this.rangeCrosshairPaint;
2322: }
2323:
2324:
2332: public void setRangeCrosshairPaint(Paint paint) {
2333: if (paint == null) {
2334: throw new IllegalArgumentException("Null 'paint' argument.");
2335: }
2336: this.rangeCrosshairPaint = paint;
2337: notifyListeners(new PlotChangeEvent(this));
2338: }
2339:
2340:
2345: public List getAnnotations() {
2346: return this.annotations;
2347: }
2348:
2349:
2357: public void addAnnotation(CategoryAnnotation annotation) {
2358: if (annotation == null) {
2359: throw new IllegalArgumentException("Null 'annotation' argument.");
2360: }
2361: this.annotations.add(annotation);
2362: notifyListeners(new PlotChangeEvent(this));
2363: }
2364:
2365:
2375: public boolean removeAnnotation(CategoryAnnotation annotation) {
2376: if (annotation == null) {
2377: throw new IllegalArgumentException("Null 'annotation' argument.");
2378: }
2379: boolean removed = this.annotations.remove(annotation);
2380: if (removed) {
2381: notifyListeners(new PlotChangeEvent(this));
2382: }
2383: return removed;
2384: }
2385:
2386:
2390: public void clearAnnotations() {
2391: this.annotations.clear();
2392: notifyListeners(new PlotChangeEvent(this));
2393: }
2394:
2395:
2404: protected AxisSpace calculateDomainAxisSpace(Graphics2D g2,
2405: Rectangle2D plotArea,
2406: AxisSpace space) {
2407:
2408: if (space == null) {
2409: space = new AxisSpace();
2410: }
2411:
2412:
2413: if (this.fixedDomainAxisSpace != null) {
2414: if (this.orientation == PlotOrientation.HORIZONTAL) {
2415: space.ensureAtLeast(
2416: this.fixedDomainAxisSpace.getLeft(), RectangleEdge.LEFT);
2417: space.ensureAtLeast(this.fixedDomainAxisSpace.getRight(),
2418: RectangleEdge.RIGHT);
2419: }
2420: else if (this.orientation == PlotOrientation.VERTICAL) {
2421: space.ensureAtLeast(this.fixedDomainAxisSpace.getTop(),
2422: RectangleEdge.TOP);
2423: space.ensureAtLeast(this.fixedDomainAxisSpace.getBottom(),
2424: RectangleEdge.BOTTOM);
2425: }
2426: }
2427: else {
2428:
2429: RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(
2430: getDomainAxisLocation(), this.orientation);
2431: if (this.drawSharedDomainAxis) {
2432: space = getDomainAxis().reserveSpace(g2, this, plotArea,
2433: domainEdge, space);
2434: }
2435:
2436:
2437: for (int i = 0; i < this.domainAxes.size(); i++) {
2438: Axis xAxis = (Axis) this.domainAxes.get(i);
2439: if (xAxis != null) {
2440: RectangleEdge edge = getDomainAxisEdge(i);
2441: space = xAxis.reserveSpace(g2, this, plotArea, edge, space);
2442: }
2443: }
2444: }
2445:
2446: return space;
2447:
2448: }
2449:
2450:
2459: protected AxisSpace calculateRangeAxisSpace(Graphics2D g2,
2460: Rectangle2D plotArea,
2461: AxisSpace space) {
2462:
2463: if (space == null) {
2464: space = new AxisSpace();
2465: }
2466:
2467:
2468: if (this.fixedRangeAxisSpace != null) {
2469: if (this.orientation == PlotOrientation.HORIZONTAL) {
2470: space.ensureAtLeast(this.fixedRangeAxisSpace.getTop(),
2471: RectangleEdge.TOP);
2472: space.ensureAtLeast(this.fixedRangeAxisSpace.getBottom(),
2473: RectangleEdge.BOTTOM);
2474: }
2475: else if (this.orientation == PlotOrientation.VERTICAL) {
2476: space.ensureAtLeast(this.fixedRangeAxisSpace.getLeft(),
2477: RectangleEdge.LEFT);
2478: space.ensureAtLeast(this.fixedRangeAxisSpace.getRight(),
2479: RectangleEdge.RIGHT);
2480: }
2481: }
2482: else {
2483:
2484: for (int i = 0; i < this.rangeAxes.size(); i++) {
2485: Axis yAxis = (Axis) this.rangeAxes.get(i);
2486: if (yAxis != null) {
2487: RectangleEdge edge = getRangeAxisEdge(i);
2488: space = yAxis.reserveSpace(g2, this, plotArea, edge, space);
2489: }
2490: }
2491: }
2492: return space;
2493:
2494: }
2495:
2496:
2504: protected AxisSpace calculateAxisSpace(Graphics2D g2,
2505: Rectangle2D plotArea) {
2506: AxisSpace space = new AxisSpace();
2507: space = calculateRangeAxisSpace(g2, plotArea, space);
2508: space = calculateDomainAxisSpace(g2, plotArea, space);
2509: return space;
2510: }
2511:
2512:
2528: public void draw(Graphics2D g2, Rectangle2D area,
2529: Point2D anchor,
2530: PlotState parentState,
2531: PlotRenderingInfo state) {
2532:
2533:
2534: boolean b1 = (area.getWidth() <= MINIMUM_WIDTH_TO_DRAW);
2535: boolean b2 = (area.getHeight() <= MINIMUM_HEIGHT_TO_DRAW);
2536: if (b1 || b2) {
2537: return;
2538: }
2539:
2540:
2541: if (state == null) {
2542:
2543:
2544:
2545: state = new PlotRenderingInfo(null);
2546: }
2547: state.setPlotArea(area);
2548:
2549:
2550: RectangleInsets insets = getInsets();
2551: insets.trim(area);
2552:
2553:
2554: AxisSpace space = calculateAxisSpace(g2, area);
2555: Rectangle2D dataArea = space.shrink(area, null);
2556: this.axisOffset.trim(dataArea);
2557:
2558: state.setDataArea(dataArea);
2559:
2560:
2561:
2562: if (getRenderer() != null) {
2563: getRenderer().drawBackground(g2, this, dataArea);
2564: }
2565: else {
2566: drawBackground(g2, dataArea);
2567: }
2568:
2569: Map axisStateMap = drawAxes(g2, area, dataArea, state);
2570:
2571:
2572: Shape savedClip = g2.getClip();
2573: g2.clip(dataArea);
2574:
2575: drawDomainGridlines(g2, dataArea);
2576:
2577: AxisState rangeAxisState = (AxisState) axisStateMap.get(getRangeAxis());
2578: if (rangeAxisState == null) {
2579: if (parentState != null) {
2580: rangeAxisState = (AxisState) parentState.getSharedAxisStates()
2581: .get(getRangeAxis());
2582: }
2583: }
2584: if (rangeAxisState != null) {
2585: drawRangeGridlines(g2, dataArea, rangeAxisState.getTicks());
2586: }
2587:
2588:
2589: for (int i = 0; i < this.renderers.size(); i++) {
2590: drawDomainMarkers(g2, dataArea, i, Layer.BACKGROUND);
2591: }
2592: for (int i = 0; i < this.renderers.size(); i++) {
2593: drawRangeMarkers(g2, dataArea, i, Layer.BACKGROUND);
2594: }
2595:
2596:
2597: boolean foundData = false;
2598:
2599:
2600: Composite originalComposite = g2.getComposite();
2601: g2.setComposite(AlphaComposite.getInstance(
2602: AlphaComposite.SRC_OVER, getForegroundAlpha()));
2603:
2604: DatasetRenderingOrder order = getDatasetRenderingOrder();
2605: if (order == DatasetRenderingOrder.FORWARD) {
2606: for (int i = 0; i < this.datasets.size(); i++) {
2607: foundData = render(g2, dataArea, i, state) || foundData;
2608: }
2609: }
2610: else {
2611: for (int i = this.datasets.size() - 1; i >= 0; i--) {
2612: foundData = render(g2, dataArea, i, state) || foundData;
2613: }
2614: }
2615:
2616: for (int i = 0; i < this.renderers.size(); i++) {
2617: drawDomainMarkers(g2, dataArea, i, Layer.FOREGROUND);
2618: }
2619: for (int i = 0; i < this.renderers.size(); i++) {
2620: drawRangeMarkers(g2, dataArea, i, Layer.FOREGROUND);
2621: }
2622:
2623:
2624: drawAnnotations(g2, dataArea);
2625:
2626: g2.setClip(savedClip);
2627: g2.setComposite(originalComposite);
2628:
2629: if (!foundData) {
2630: drawNoDataMessage(g2, dataArea);
2631: }
2632:
2633:
2634: if (isRangeCrosshairVisible()) {
2635:
2636: drawRangeCrosshair(g2, dataArea, getOrientation(),
2637: getRangeCrosshairValue(), getRangeAxis(),
2638: getRangeCrosshairStroke(), getRangeCrosshairPaint());
2639: }
2640:
2641:
2642: if (getRenderer() != null) {
2643: getRenderer().drawOutline(g2, this, dataArea);
2644: }
2645: else {
2646: drawOutline(g2, dataArea);
2647: }
2648:
2649: }
2650:
2651:
2662: protected Map drawAxes(Graphics2D g2,
2663: Rectangle2D plotArea,
2664: Rectangle2D dataArea,
2665: PlotRenderingInfo plotState) {
2666:
2667: AxisCollection axisCollection = new AxisCollection();
2668:
2669:
2670: for (int index = 0; index < this.domainAxes.size(); index++) {
2671: CategoryAxis xAxis = (CategoryAxis) this.domainAxes.get(index);
2672: if (xAxis != null) {
2673: axisCollection.add(xAxis, getDomainAxisEdge(index));
2674: }
2675: }
2676:
2677:
2678: for (int index = 0; index < this.rangeAxes.size(); index++) {
2679: ValueAxis yAxis = (ValueAxis) this.rangeAxes.get(index);
2680: if (yAxis != null) {
2681: axisCollection.add(yAxis, getRangeAxisEdge(index));
2682: }
2683: }
2684:
2685: Map axisStateMap = new HashMap();
2686:
2687:
2688: double cursor = dataArea.getMinY() - this.axisOffset.calculateTopOutset(
2689: dataArea.getHeight());
2690: Iterator iterator = axisCollection.getAxesAtTop().iterator();
2691: while (iterator.hasNext()) {
2692: Axis axis = (Axis) iterator.next();
2693: if (axis != null) {
2694: AxisState axisState = axis.draw(g2, cursor, plotArea, dataArea,
2695: RectangleEdge.TOP, plotState);
2696: cursor = axisState.getCursor();
2697: axisStateMap.put(axis, axisState);
2698: }
2699: }
2700:
2701:
2702: cursor = dataArea.getMaxY()
2703: + this.axisOffset.calculateBottomOutset(dataArea.getHeight());
2704: iterator = axisCollection.getAxesAtBottom().iterator();
2705: while (iterator.hasNext()) {
2706: Axis axis = (Axis) iterator.next();
2707: if (axis != null) {
2708: AxisState axisState = axis.draw(g2, cursor, plotArea, dataArea,
2709: RectangleEdge.BOTTOM, plotState);
2710: cursor = axisState.getCursor();
2711: axisStateMap.put(axis, axisState);
2712: }
2713: }
2714:
2715:
2716: cursor = dataArea.getMinX()
2717: - this.axisOffset.calculateLeftOutset(dataArea.getWidth());
2718: iterator = axisCollection.getAxesAtLeft().iterator();
2719: while (iterator.hasNext()) {
2720: Axis axis = (Axis) iterator.next();
2721: if (axis != null) {
2722: AxisState axisState = axis.draw(g2, cursor, plotArea, dataArea,
2723: RectangleEdge.LEFT, plotState);
2724: cursor = axisState.getCursor();
2725: axisStateMap.put(axis, axisState);
2726: }
2727: }
2728:
2729:
2730: cursor = dataArea.getMaxX()
2731: + this.axisOffset.calculateRightOutset(dataArea.getWidth());
2732: iterator = axisCollection.getAxesAtRight().iterator();
2733: while (iterator.hasNext()) {
2734: Axis axis = (Axis) iterator.next();
2735: if (axis != null) {
2736: AxisState axisState = axis.draw(g2, cursor, plotArea, dataArea,
2737: RectangleEdge.RIGHT, plotState);
2738: cursor = axisState.getCursor();
2739: axisStateMap.put(axis, axisState);
2740: }
2741: }
2742:
2743: return axisStateMap;
2744:
2745: }
2746:
2747:
2758: public boolean render(Graphics2D g2, Rectangle2D dataArea, int index,
2759: PlotRenderingInfo info) {
2760:
2761: boolean foundData = false;
2762: CategoryDataset currentDataset = getDataset(index);
2763: CategoryItemRenderer renderer = getRenderer(index);
2764: CategoryAxis domainAxis = getDomainAxisForDataset(index);
2765: ValueAxis rangeAxis = getRangeAxisForDataset(index);
2766: boolean hasData = !DatasetUtilities.isEmptyOrNull(currentDataset);
2767: if (hasData && renderer != null) {
2768:
2769: foundData = true;
2770: CategoryItemRendererState state = renderer.initialise(g2, dataArea,
2771: this, index, info);
2772: int columnCount = currentDataset.getColumnCount();
2773: int rowCount = currentDataset.getRowCount();
2774: int passCount = renderer.getPassCount();
2775: for (int pass = 0; pass < passCount; pass++) {
2776: if (this.columnRenderingOrder == SortOrder.ASCENDING) {
2777: for (int column = 0; column < columnCount; column++) {
2778: if (this.rowRenderingOrder == SortOrder.ASCENDING) {
2779: for (int row = 0; row < rowCount; row++) {
2780: renderer.drawItem(g2, state, dataArea, this,
2781: domainAxis, rangeAxis, currentDataset,
2782: row, column, pass);
2783: }
2784: }
2785: else {
2786: for (int row = rowCount - 1; row >= 0; row--) {
2787: renderer.drawItem(g2, state, dataArea, this,
2788: domainAxis, rangeAxis, currentDataset,
2789: row, column, pass);
2790: }
2791: }
2792: }
2793: }
2794: else {
2795: for (int column = columnCount - 1; column >= 0; column--) {
2796: if (this.rowRenderingOrder == SortOrder.ASCENDING) {
2797: for (int row = 0; row < rowCount; row++) {
2798: renderer.drawItem(g2, state, dataArea, this,
2799: domainAxis, rangeAxis, currentDataset,
2800: row, column, pass);
2801: }
2802: }
2803: else {
2804: for (int row = rowCount - 1; row >= 0; row--) {
2805: renderer.drawItem(g2, state, dataArea, this,
2806: domainAxis, rangeAxis, currentDataset,
2807: row, column, pass);
2808: }
2809: }
2810: }
2811: }
2812: }
2813: }
2814: return foundData;
2815:
2816: }
2817:
2818:
2826: protected void drawDomainGridlines(Graphics2D g2, Rectangle2D dataArea) {
2827:
2828:
2829: if (isDomainGridlinesVisible()) {
2830: CategoryAnchor anchor = getDomainGridlinePosition();
2831: RectangleEdge domainAxisEdge = getDomainAxisEdge();
2832: Stroke gridStroke = getDomainGridlineStroke();
2833: Paint gridPaint = getDomainGridlinePaint();
2834: if ((gridStroke != null) && (gridPaint != null)) {
2835:
2836: CategoryDataset data = getDataset();
2837: if (data != null) {
2838: CategoryAxis axis = getDomainAxis();
2839: if (axis != null) {
2840: int columnCount = data.getColumnCount();
2841: for (int c = 0; c < columnCount; c++) {
2842: double xx = axis.getCategoryJava2DCoordinate(
2843: anchor, c, columnCount, dataArea,
2844: domainAxisEdge);
2845: CategoryItemRenderer renderer1 = getRenderer();
2846: if (renderer1 != null) {
2847: renderer1.drawDomainGridline(g2, this,
2848: dataArea, xx);
2849: }
2850: }
2851: }
2852: }
2853: }
2854: }
2855: }
2856:
2857:
2866: protected void drawRangeGridlines(Graphics2D g2, Rectangle2D dataArea,
2867: List ticks) {
2868:
2869: if (isRangeGridlinesVisible()) {
2870: Stroke gridStroke = getRangeGridlineStroke();
2871: Paint gridPaint = getRangeGridlinePaint();
2872: if ((gridStroke != null) && (gridPaint != null)) {
2873: ValueAxis axis = getRangeAxis();
2874: if (axis != null) {
2875: Iterator iterator = ticks.iterator();
2876: while (iterator.hasNext()) {
2877: ValueTick tick = (ValueTick) iterator.next();
2878: CategoryItemRenderer renderer1 = getRenderer();
2879: if (renderer1 != null) {
2880: renderer1.drawRangeGridline(g2, this,
2881: getRangeAxis(), dataArea, tick.getValue());
2882: }
2883: }
2884: }
2885: }
2886: }
2887: }
2888:
2889:
2895: protected void drawAnnotations(Graphics2D g2, Rectangle2D dataArea) {
2896:
2897: if (getAnnotations() != null) {
2898: Iterator iterator = getAnnotations().iterator();
2899: while (iterator.hasNext()) {
2900: CategoryAnnotation annotation
2901: = (CategoryAnnotation) iterator.next();
2902: annotation.draw(g2, this, dataArea, getDomainAxis(),
2903: getRangeAxis());
2904: }
2905: }
2906:
2907: }
2908:
2909:
2920: protected void drawDomainMarkers(Graphics2D g2, Rectangle2D dataArea,
2921: int index, Layer layer) {
2922:
2923: CategoryItemRenderer r = getRenderer(index);
2924: if (r == null) {
2925: return;
2926: }
2927:
2928: Collection markers = getDomainMarkers(index, layer);
2929: CategoryAxis axis = getDomainAxisForDataset(index);
2930: if (markers != null && axis != null) {
2931: Iterator iterator = markers.iterator();
2932: while (iterator.hasNext()) {
2933: CategoryMarker marker = (CategoryMarker) iterator.next();
2934: r.drawDomainMarker(g2, this, axis, marker, dataArea);
2935: }
2936: }
2937:
2938: }
2939:
2940:
2951: protected void drawRangeMarkers(Graphics2D g2, Rectangle2D dataArea,
2952: int index, Layer layer) {
2953:
2954: CategoryItemRenderer r = getRenderer(index);
2955: if (r == null) {
2956: return;
2957: }
2958:
2959: Collection markers = getRangeMarkers(index, layer);
2960: ValueAxis axis = getRangeAxisForDataset(index);
2961: if (markers != null && axis != null) {
2962: Iterator iterator = markers.iterator();
2963: while (iterator.hasNext()) {
2964: Marker marker = (Marker) iterator.next();
2965: r.drawRangeMarker(g2, this, axis, marker, dataArea);
2966: }
2967: }
2968:
2969: }
2970:
2971:
2981: protected void drawRangeLine(Graphics2D g2, Rectangle2D dataArea,
2982: double value, Stroke stroke, Paint paint) {
2983:
2984: double java2D = getRangeAxis().valueToJava2D(value, dataArea,
2985: getRangeAxisEdge());
2986: Line2D line = null;
2987: if (this.orientation == PlotOrientation.HORIZONTAL) {
2988: line = new Line2D.Double(java2D, dataArea.getMinY(), java2D,
2989: dataArea.getMaxY());
2990: }
2991: else if (this.orientation == PlotOrientation.VERTICAL) {
2992: line = new Line2D.Double(dataArea.getMinX(), java2D,
2993: dataArea.getMaxX(), java2D);
2994: }
2995: g2.setStroke(stroke);
2996: g2.setPaint(paint);
2997: g2.draw(line);
2998:
2999: }
3000:
3001:
3014: protected void drawRangeCrosshair(Graphics2D g2, Rectangle2D dataArea,
3015: PlotOrientation orientation, double value, ValueAxis axis,
3016: Stroke stroke, Paint paint) {
3017:
3018: if (!axis.getRange().contains(value)) {
3019: return;
3020: }
3021: Line2D line = null;
3022: if (orientation == PlotOrientation.HORIZONTAL) {
3023: double xx = axis.valueToJava2D(value, dataArea,
3024: RectangleEdge.BOTTOM);
3025: line = new Line2D.Double(xx, dataArea.getMinY(), xx,
3026: dataArea.getMaxY());
3027: }
3028: else {
3029: double yy = axis.valueToJava2D(value, dataArea,
3030: RectangleEdge.LEFT);
3031: line = new Line2D.Double(dataArea.getMinX(), yy,
3032: dataArea.getMaxX(), yy);
3033: }
3034: g2.setStroke(stroke);
3035: g2.setPaint(paint);
3036: g2.draw(line);
3037:
3038: }
3039:
3040:
3049: public Range getDataRange(ValueAxis axis) {
3050:
3051: Range result = null;
3052: List mappedDatasets = new ArrayList();
3053:
3054: int rangeIndex = this.rangeAxes.indexOf(axis);
3055: if (rangeIndex >= 0) {
3056: mappedDatasets.addAll(datasetsMappedToRangeAxis(rangeIndex));
3057: }
3058: else if (axis == getRangeAxis()) {
3059: mappedDatasets.addAll(datasetsMappedToRangeAxis(0));
3060: }
3061:
3062:
3063:
3064: Iterator iterator = mappedDatasets.iterator();
3065: while (iterator.hasNext()) {
3066: CategoryDataset d = (CategoryDataset) iterator.next();
3067: CategoryItemRenderer r = getRendererForDataset(d);
3068: if (r != null) {
3069: result = Range.combine(result, r.findRangeBounds(d));
3070: }
3071: }
3072: return result;
3073:
3074: }
3075:
3076:
3086: private List datasetsMappedToDomainAxis(int axisIndex) {
3087: List result = new ArrayList();
3088: for (int datasetIndex = 0; datasetIndex < this.datasets.size();
3089: datasetIndex++) {
3090: Object dataset = this.datasets.get(datasetIndex);
3091: if (dataset != null) {
3092: Integer m = (Integer) this.datasetToDomainAxisMap.get(
3093: datasetIndex);
3094: if (m == null) {
3095:
3096: if (axisIndex == 0) {
3097: result.add(dataset);
3098: }
3099: }
3100: else {
3101: if (m.intValue() == axisIndex) {
3102: result.add(dataset);
3103: }
3104: }
3105: }
3106: }
3107: return result;
3108: }
3109:
3110:
3118: private List datasetsMappedToRangeAxis(int index) {
3119: List result = new ArrayList();
3120: for (int i = 0; i < this.datasets.size(); i++) {
3121: Object dataset = this.datasets.get(i);
3122: if (dataset != null) {
3123: Integer m = (Integer) this.datasetToRangeAxisMap.get(i);
3124: if (m == null) {
3125:
3126: if (index == 0) {
3127: result.add(dataset);
3128: }
3129: }
3130: else {
3131: if (m.intValue() == index) {
3132: result.add(dataset);
3133: }
3134: }
3135: }
3136: }
3137: return result;
3138: }
3139:
3140:
3148: public int getWeight() {
3149: return this.weight;
3150: }
3151:
3152:
3159: public void setWeight(int weight) {
3160: this.weight = weight;
3161:
3162: }
3163:
3164:
3171: public AxisSpace getFixedDomainAxisSpace() {
3172: return this.fixedDomainAxisSpace;
3173: }
3174:
3175:
3182: public void setFixedDomainAxisSpace(AxisSpace space) {
3183: this.fixedDomainAxisSpace = space;
3184:
3185: }
3186:
3187:
3194: public AxisSpace getFixedRangeAxisSpace() {
3195: return this.fixedRangeAxisSpace;
3196: }
3197:
3198:
3205: public void setFixedRangeAxisSpace(AxisSpace space) {
3206: this.fixedRangeAxisSpace = space;
3207:
3208: }
3209:
3210:
3217: public List getCategories() {
3218: List result = null;
3219: if (getDataset() != null) {
3220: result = Collections.unmodifiableList(getDataset().getColumnKeys());
3221: }
3222: return result;
3223: }
3224:
3225:
3235: public List getCategoriesForAxis(CategoryAxis axis) {
3236: List result = new ArrayList();
3237: int axisIndex = this.domainAxes.indexOf(axis);
3238: List datasets = datasetsMappedToDomainAxis(axisIndex);
3239: Iterator iterator = datasets.iterator();
3240: while (iterator.hasNext()) {
3241: CategoryDataset dataset = (CategoryDataset) iterator.next();
3242:
3243: for (int i = 0; i < dataset.getColumnCount(); i++) {
3244: Comparable category = dataset.getColumnKey(i);
3245: if (!result.contains(category)) {
3246: result.add(category);
3247: }
3248: }
3249: }
3250: return result;
3251: }
3252:
3253:
3261: public boolean getDrawSharedDomainAxis() {
3262: return this.drawSharedDomainAxis;
3263: }
3264:
3265:
3273: public void setDrawSharedDomainAxis(boolean draw) {
3274: this.drawSharedDomainAxis = draw;
3275: notifyListeners(new PlotChangeEvent(this));
3276: }
3277:
3278:
3286: public boolean isDomainZoomable() {
3287: return false;
3288: }
3289:
3290:
3297: public boolean isRangeZoomable() {
3298: return true;
3299: }
3300:
3301:
3309: public void zoomDomainAxes(double factor, PlotRenderingInfo state,
3310: Point2D source) {
3311:
3312: }
3313:
3314:
3323: public void zoomDomainAxes(double lowerPercent, double upperPercent,
3324: PlotRenderingInfo state, Point2D source) {
3325:
3326: }
3327:
3328:
3335: public void zoomRangeAxes(double factor, PlotRenderingInfo state,
3336: Point2D source) {
3337: for (int i = 0; i < this.rangeAxes.size(); i++) {
3338: ValueAxis rangeAxis = (ValueAxis) this.rangeAxes.get(i);
3339: if (rangeAxis != null) {
3340: rangeAxis.resizeRange(factor);
3341: }
3342: }
3343: }
3344:
3345:
3353: public void zoomRangeAxes(double lowerPercent, double upperPercent,
3354: PlotRenderingInfo state, Point2D source) {
3355: for (int i = 0; i < this.rangeAxes.size(); i++) {
3356: ValueAxis rangeAxis = (ValueAxis) this.rangeAxes.get(i);
3357: if (rangeAxis != null) {
3358: rangeAxis.zoomRange(lowerPercent, upperPercent);
3359: }
3360: }
3361: }
3362:
3363:
3370: public double getAnchorValue() {
3371: return this.anchorValue;
3372: }
3373:
3374:
3382: public void setAnchorValue(double value) {
3383: setAnchorValue(value, true);
3384: }
3385:
3386:
3395: public void setAnchorValue(double value, boolean notify) {
3396: this.anchorValue = value;
3397: if (notify) {
3398: notifyListeners(new PlotChangeEvent(this));
3399: }
3400: }
3401:
3402:
3409: public boolean equals(Object obj) {
3410:
3411: if (obj == this) {
3412: return true;
3413: }
3414: if (!(obj instanceof CategoryPlot)) {
3415: return false;
3416: }
3417: if (!super.equals(obj)) {
3418: return false;
3419: }
3420:
3421: CategoryPlot that = (CategoryPlot) obj;
3422:
3423: if (this.orientation != that.orientation) {
3424: return false;
3425: }
3426: if (!ObjectUtilities.equal(this.axisOffset, that.axisOffset)) {
3427: return false;
3428: }
3429: if (!this.domainAxes.equals(that.domainAxes)) {
3430: return false;
3431: }
3432: if (!this.domainAxisLocations.equals(that.domainAxisLocations)) {
3433: return false;
3434: }
3435: if (this.drawSharedDomainAxis != that.drawSharedDomainAxis) {
3436: return false;
3437: }
3438: if (!this.rangeAxes.equals(that.rangeAxes)) {
3439: return false;
3440: }
3441: if (!this.rangeAxisLocations.equals(that.rangeAxisLocations)) {
3442: return false;
3443: }
3444: if (!ObjectUtilities.equal(this.datasetToDomainAxisMap,
3445: that.datasetToDomainAxisMap)) {
3446: return false;
3447: }
3448: if (!ObjectUtilities.equal(this.datasetToRangeAxisMap,
3449: that.datasetToRangeAxisMap)) {
3450: return false;
3451: }
3452: if (!ObjectUtilities.equal(this.renderers, that.renderers)) {
3453: return false;
3454: }
3455: if (this.renderingOrder != that.renderingOrder) {
3456: return false;
3457: }
3458: if (this.columnRenderingOrder != that.columnRenderingOrder) {
3459: return false;
3460: }
3461: if (this.rowRenderingOrder != that.rowRenderingOrder) {
3462: return false;
3463: }
3464: if (this.domainGridlinesVisible != that.domainGridlinesVisible) {
3465: return false;
3466: }
3467: if (this.domainGridlinePosition != that.domainGridlinePosition) {
3468: return false;
3469: }
3470: if (!ObjectUtilities.equal(this.domainGridlineStroke,
3471: that.domainGridlineStroke)) {
3472: return false;
3473: }
3474: if (!PaintUtilities.equal(this.domainGridlinePaint,
3475: that.domainGridlinePaint)) {
3476: return false;
3477: }
3478: if (this.rangeGridlinesVisible != that.rangeGridlinesVisible) {
3479: return false;
3480: }
3481: if (!ObjectUtilities.equal(this.rangeGridlineStroke,
3482: that.rangeGridlineStroke)) {
3483: return false;
3484: }
3485: if (!PaintUtilities.equal(this.rangeGridlinePaint,
3486: that.rangeGridlinePaint)) {
3487: return false;
3488: }
3489: if (this.anchorValue != that.anchorValue) {
3490: return false;
3491: }
3492: if (this.rangeCrosshairVisible != that.rangeCrosshairVisible) {
3493: return false;
3494: }
3495: if (this.rangeCrosshairValue != that.rangeCrosshairValue) {
3496: return false;
3497: }
3498: if (!ObjectUtilities.equal(this.rangeCrosshairStroke,
3499: that.rangeCrosshairStroke)) {
3500: return false;
3501: }
3502: if (!PaintUtilities.equal(this.rangeCrosshairPaint,
3503: that.rangeCrosshairPaint)) {
3504: return false;
3505: }
3506: if (this.rangeCrosshairLockedOnData
3507: != that.rangeCrosshairLockedOnData) {
3508: return false;
3509: }
3510: if (!ObjectUtilities.equal(this.foregroundRangeMarkers,
3511: that.foregroundRangeMarkers)) {
3512: return false;
3513: }
3514: if (!ObjectUtilities.equal(this.backgroundRangeMarkers,
3515: that.backgroundRangeMarkers)) {
3516: return false;
3517: }
3518: if (!ObjectUtilities.equal(this.annotations, that.annotations)) {
3519: return false;
3520: }
3521: if (this.weight != that.weight) {
3522: return false;
3523: }
3524: if (!ObjectUtilities.equal(this.fixedDomainAxisSpace,
3525: that.fixedDomainAxisSpace)) {
3526: return false;
3527: }
3528: if (!ObjectUtilities.equal(this.fixedRangeAxisSpace,
3529: that.fixedRangeAxisSpace)) {
3530: return false;
3531: }
3532:
3533: return true;
3534:
3535: }
3536:
3537:
3544: public Object clone() throws CloneNotSupportedException {
3545:
3546: CategoryPlot clone = (CategoryPlot) super.clone();
3547:
3548: clone.domainAxes = new ObjectList();
3549: for (int i = 0; i < this.domainAxes.size(); i++) {
3550: CategoryAxis xAxis = (CategoryAxis) this.domainAxes.get(i);
3551: if (xAxis != null) {
3552: CategoryAxis clonedAxis = (CategoryAxis) xAxis.clone();
3553: clone.setDomainAxis(i, clonedAxis);
3554: }
3555: }
3556: clone.domainAxisLocations
3557: = (ObjectList) this.domainAxisLocations.clone();
3558:
3559: clone.rangeAxes = new ObjectList();
3560: for (int i = 0; i < this.rangeAxes.size(); i++) {
3561: ValueAxis yAxis = (ValueAxis) this.rangeAxes.get(i);
3562: if (yAxis != null) {
3563: ValueAxis clonedAxis = (ValueAxis) yAxis.clone();
3564: clone.setRangeAxis(i, clonedAxis);
3565: }
3566: }
3567: clone.rangeAxisLocations = (ObjectList) this.rangeAxisLocations.clone();
3568:
3569: clone.datasets = (ObjectList) this.datasets.clone();
3570: for (int i = 0; i < clone.datasets.size(); i++) {
3571: CategoryDataset dataset = clone.getDataset(i);
3572: if (dataset != null) {
3573: dataset.addChangeListener(clone);
3574: }
3575: }
3576: clone.datasetToDomainAxisMap
3577: = (ObjectList) this.datasetToDomainAxisMap.clone();
3578: clone.datasetToRangeAxisMap
3579: = (ObjectList) this.datasetToRangeAxisMap.clone();
3580: clone.renderers = (ObjectList) this.renderers.clone();
3581: if (this.fixedDomainAxisSpace != null) {
3582: clone.fixedDomainAxisSpace = (AxisSpace) ObjectUtilities.clone(
3583: this.fixedDomainAxisSpace);
3584: }
3585: if (this.fixedRangeAxisSpace != null) {
3586: clone.fixedRangeAxisSpace = (AxisSpace) ObjectUtilities.clone(
3587: this.fixedRangeAxisSpace);
3588: }
3589:
3590: return clone;
3591:
3592: }
3593:
3594:
3601: private void writeObject(ObjectOutputStream stream) throws IOException {
3602: stream.defaultWriteObject();
3603: SerialUtilities.writeStroke(this.domainGridlineStroke, stream);
3604: SerialUtilities.writePaint(this.domainGridlinePaint, stream);
3605: SerialUtilities.writeStroke(this.rangeGridlineStroke, stream);
3606: SerialUtilities.writePaint(this.rangeGridlinePaint, stream);
3607: SerialUtilities.writeStroke(this.rangeCrosshairStroke, stream);
3608: SerialUtilities.writePaint(this.rangeCrosshairPaint, stream);
3609: }
3610:
3611:
3619: private void readObject(ObjectInputStream stream)
3620: throws IOException, ClassNotFoundException {
3621:
3622: stream.defaultReadObject();
3623: this.domainGridlineStroke = SerialUtilities.readStroke(stream);
3624: this.domainGridlinePaint = SerialUtilities.readPaint(stream);
3625: this.rangeGridlineStroke = SerialUtilities.readStroke(stream);
3626: this.rangeGridlinePaint = SerialUtilities.readPaint(stream);
3627: this.rangeCrosshairStroke = SerialUtilities.readStroke(stream);
3628: this.rangeCrosshairPaint = SerialUtilities.readPaint(stream);
3629:
3630: for (int i = 0; i < this.domainAxes.size(); i++) {
3631: CategoryAxis xAxis = (CategoryAxis) this.domainAxes.get(i);
3632: if (xAxis != null) {
3633: xAxis.setPlot(this);
3634: xAxis.addChangeListener(this);
3635: }
3636: }
3637: for (int i = 0; i < this.rangeAxes.size(); i++) {
3638: ValueAxis yAxis = (ValueAxis) this.rangeAxes.get(i);
3639: if (yAxis != null) {
3640: yAxis.setPlot(this);
3641: yAxis.addChangeListener(this);
3642: }
3643: }
3644: int datasetCount = this.datasets.size();
3645: for (int i = 0; i < datasetCount; i++) {
3646: Dataset dataset = (Dataset) this.datasets.get(i);
3647: if (dataset != null) {
3648: dataset.addChangeListener(this);
3649: }
3650: }
3651: int rendererCount = this.renderers.size();
3652: for (int i = 0; i < rendererCount; i++) {
3653: CategoryItemRenderer renderer
3654: = (CategoryItemRenderer) this.renderers.get(i);
3655: if (renderer != null) {
3656: renderer.addChangeListener(this);
3657: }
3658: }
3659:
3660: }
3661:
3662: }