1:
91:
92: package ;
93:
94: import ;
95: import ;
96: import ;
97: import ;
98: import ;
99: import ;
100: import ;
101: import ;
102: import ;
103: import ;
104: import ;
105: import ;
106: import ;
107: import ;
108: import ;
109:
110: import ;
111: import ;
112: import ;
113: import ;
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:
129:
132: public class CategoryAxis extends Axis implements Cloneable, Serializable {
133:
134:
135: private static final long serialVersionUID = 5886554608114265863L;
136:
137:
140: public static final double DEFAULT_AXIS_MARGIN = 0.05;
141:
142:
146: public static final double DEFAULT_CATEGORY_MARGIN = 0.20;
147:
148:
149: private double lowerMargin;
150:
151:
152: private double upperMargin;
153:
154:
155: private double categoryMargin;
156:
157:
158: private int maximumCategoryLabelLines;
159:
160:
164: private float maximumCategoryLabelWidthRatio;
165:
166:
167: private int categoryLabelPositionOffset;
168:
169:
173: private CategoryLabelPositions categoryLabelPositions;
174:
175:
176: private Map tickLabelFontMap;
177:
178:
179: private transient Map tickLabelPaintMap;
180:
181:
182: private Map categoryLabelToolTips;
183:
184:
187: public CategoryAxis() {
188: this(null);
189: }
190:
191:
196: public CategoryAxis(String label) {
197:
198: super(label);
199:
200: this.lowerMargin = DEFAULT_AXIS_MARGIN;
201: this.upperMargin = DEFAULT_AXIS_MARGIN;
202: this.categoryMargin = DEFAULT_CATEGORY_MARGIN;
203: this.maximumCategoryLabelLines = 1;
204: this.maximumCategoryLabelWidthRatio = 0.0f;
205:
206: setTickMarksVisible(false);
207:
208: this.categoryLabelPositionOffset = 4;
209: this.categoryLabelPositions = CategoryLabelPositions.STANDARD;
210: this.tickLabelFontMap = new HashMap();
211: this.tickLabelPaintMap = new HashMap();
212: this.categoryLabelToolTips = new HashMap();
213:
214: }
215:
216:
224: public double getLowerMargin() {
225: return this.lowerMargin;
226: }
227:
228:
237: public void setLowerMargin(double margin) {
238: this.lowerMargin = margin;
239: notifyListeners(new AxisChangeEvent(this));
240: }
241:
242:
250: public double getUpperMargin() {
251: return this.upperMargin;
252: }
253:
254:
263: public void setUpperMargin(double margin) {
264: this.upperMargin = margin;
265: notifyListeners(new AxisChangeEvent(this));
266: }
267:
268:
275: public double getCategoryMargin() {
276: return this.categoryMargin;
277: }
278:
279:
289: public void setCategoryMargin(double margin) {
290: this.categoryMargin = margin;
291: notifyListeners(new AxisChangeEvent(this));
292: }
293:
294:
301: public int getMaximumCategoryLabelLines() {
302: return this.maximumCategoryLabelLines;
303: }
304:
305:
313: public void setMaximumCategoryLabelLines(int lines) {
314: this.maximumCategoryLabelLines = lines;
315: notifyListeners(new AxisChangeEvent(this));
316: }
317:
318:
325: public float getMaximumCategoryLabelWidthRatio() {
326: return this.maximumCategoryLabelWidthRatio;
327: }
328:
329:
337: public void setMaximumCategoryLabelWidthRatio(float ratio) {
338: this.maximumCategoryLabelWidthRatio = ratio;
339: notifyListeners(new AxisChangeEvent(this));
340: }
341:
342:
350: public int getCategoryLabelPositionOffset() {
351: return this.categoryLabelPositionOffset;
352: }
353:
354:
362: public void setCategoryLabelPositionOffset(int offset) {
363: this.categoryLabelPositionOffset = offset;
364: notifyListeners(new AxisChangeEvent(this));
365: }
366:
367:
375: public CategoryLabelPositions getCategoryLabelPositions() {
376: return this.categoryLabelPositions;
377: }
378:
379:
387: public void setCategoryLabelPositions(CategoryLabelPositions positions) {
388: if (positions == null) {
389: throw new IllegalArgumentException("Null 'positions' argument.");
390: }
391: this.categoryLabelPositions = positions;
392: notifyListeners(new AxisChangeEvent(this));
393: }
394:
395:
404: public Font getTickLabelFont(Comparable category) {
405: if (category == null) {
406: throw new IllegalArgumentException("Null 'category' argument.");
407: }
408: Font result = (Font) this.tickLabelFontMap.get(category);
409:
410: if (result == null) {
411: result = getTickLabelFont();
412: }
413: return result;
414: }
415:
416:
425: public void setTickLabelFont(Comparable category, Font font) {
426: if (category == null) {
427: throw new IllegalArgumentException("Null 'category' argument.");
428: }
429: if (font == null) {
430: this.tickLabelFontMap.remove(category);
431: }
432: else {
433: this.tickLabelFontMap.put(category, font);
434: }
435: notifyListeners(new AxisChangeEvent(this));
436: }
437:
438:
447: public Paint getTickLabelPaint(Comparable category) {
448: if (category == null) {
449: throw new IllegalArgumentException("Null 'category' argument.");
450: }
451: Paint result = (Paint) this.tickLabelPaintMap.get(category);
452:
453: if (result == null) {
454: result = getTickLabelPaint();
455: }
456: return result;
457: }
458:
459:
468: public void setTickLabelPaint(Comparable category, Paint paint) {
469: if (category == null) {
470: throw new IllegalArgumentException("Null 'category' argument.");
471: }
472: if (paint == null) {
473: this.tickLabelPaintMap.remove(category);
474: }
475: else {
476: this.tickLabelPaintMap.put(category, paint);
477: }
478: notifyListeners(new AxisChangeEvent(this));
479: }
480:
481:
490: public void addCategoryLabelToolTip(Comparable category, String tooltip) {
491: if (category == null) {
492: throw new IllegalArgumentException("Null 'category' argument.");
493: }
494: this.categoryLabelToolTips.put(category, tooltip);
495: notifyListeners(new AxisChangeEvent(this));
496: }
497:
498:
509: public String getCategoryLabelToolTip(Comparable category) {
510: if (category == null) {
511: throw new IllegalArgumentException("Null 'category' argument.");
512: }
513: return (String) this.categoryLabelToolTips.get(category);
514: }
515:
516:
525: public void removeCategoryLabelToolTip(Comparable category) {
526: if (category == null) {
527: throw new IllegalArgumentException("Null 'category' argument.");
528: }
529: this.categoryLabelToolTips.remove(category);
530: notifyListeners(new AxisChangeEvent(this));
531: }
532:
533:
540: public void clearCategoryLabelToolTips() {
541: this.categoryLabelToolTips.clear();
542: notifyListeners(new AxisChangeEvent(this));
543: }
544:
545:
556: public double getCategoryJava2DCoordinate(CategoryAnchor anchor,
557: int category,
558: int categoryCount,
559: Rectangle2D area,
560: RectangleEdge edge) {
561:
562: double result = 0.0;
563: if (anchor == CategoryAnchor.START) {
564: result = getCategoryStart(category, categoryCount, area, edge);
565: }
566: else if (anchor == CategoryAnchor.MIDDLE) {
567: result = getCategoryMiddle(category, categoryCount, area, edge);
568: }
569: else if (anchor == CategoryAnchor.END) {
570: result = getCategoryEnd(category, categoryCount, area, edge);
571: }
572: return result;
573:
574: }
575:
576:
589: public double getCategoryStart(int category, int categoryCount,
590: Rectangle2D area,
591: RectangleEdge edge) {
592:
593: double result = 0.0;
594: if ((edge == RectangleEdge.TOP) || (edge == RectangleEdge.BOTTOM)) {
595: result = area.getX() + area.getWidth() * getLowerMargin();
596: }
597: else if ((edge == RectangleEdge.LEFT)
598: || (edge == RectangleEdge.RIGHT)) {
599: result = area.getMinY() + area.getHeight() * getLowerMargin();
600: }
601:
602: double categorySize = calculateCategorySize(categoryCount, area, edge);
603: double categoryGapWidth = calculateCategoryGapSize(categoryCount, area,
604: edge);
605:
606: result = result + category * (categorySize + categoryGapWidth);
607: return result;
608:
609: }
610:
611:
624: public double getCategoryMiddle(int category, int categoryCount,
625: Rectangle2D area, RectangleEdge edge) {
626:
627: return getCategoryStart(category, categoryCount, area, edge)
628: + calculateCategorySize(categoryCount, area, edge) / 2;
629:
630: }
631:
632:
645: public double getCategoryEnd(int category, int categoryCount,
646: Rectangle2D area, RectangleEdge edge) {
647:
648: return getCategoryStart(category, categoryCount, area, edge)
649: + calculateCategorySize(categoryCount, area, edge);
650:
651: }
652:
653:
668: public double getCategorySeriesMiddle(Comparable category,
669: Comparable seriesKey, CategoryDataset dataset, double itemMargin,
670: Rectangle2D area, RectangleEdge edge) {
671:
672: int categoryIndex = dataset.getColumnIndex(category);
673: int categoryCount = dataset.getColumnCount();
674: int seriesIndex = dataset.getRowIndex(seriesKey);
675: int seriesCount = dataset.getRowCount();
676: double start = getCategoryStart(categoryIndex, categoryCount, area,
677: edge);
678: double end = getCategoryEnd(categoryIndex, categoryCount, area, edge);
679: double width = end - start;
680: if (seriesCount == 1) {
681: return start + width / 2.0;
682: }
683: else {
684: double gap = (width * itemMargin) / (seriesCount - 1);
685: double ww = (width * (1 - itemMargin)) / seriesCount;
686: return start + (seriesIndex * (ww + gap)) + ww / 2.0;
687: }
688: }
689:
690:
700: protected double calculateCategorySize(int categoryCount, Rectangle2D area,
701: RectangleEdge edge) {
702:
703: double result = 0.0;
704: double available = 0.0;
705:
706: if ((edge == RectangleEdge.TOP) || (edge == RectangleEdge.BOTTOM)) {
707: available = area.getWidth();
708: }
709: else if ((edge == RectangleEdge.LEFT)
710: || (edge == RectangleEdge.RIGHT)) {
711: available = area.getHeight();
712: }
713: if (categoryCount > 1) {
714: result = available * (1 - getLowerMargin() - getUpperMargin()
715: - getCategoryMargin());
716: result = result / categoryCount;
717: }
718: else {
719: result = available * (1 - getLowerMargin() - getUpperMargin());
720: }
721: return result;
722:
723: }
724:
725:
735: protected double calculateCategoryGapSize(int categoryCount,
736: Rectangle2D area,
737: RectangleEdge edge) {
738:
739: double result = 0.0;
740: double available = 0.0;
741:
742: if ((edge == RectangleEdge.TOP) || (edge == RectangleEdge.BOTTOM)) {
743: available = area.getWidth();
744: }
745: else if ((edge == RectangleEdge.LEFT)
746: || (edge == RectangleEdge.RIGHT)) {
747: available = area.getHeight();
748: }
749:
750: if (categoryCount > 1) {
751: result = available * getCategoryMargin() / (categoryCount - 1);
752: }
753:
754: return result;
755:
756: }
757:
758:
769: public AxisSpace reserveSpace(Graphics2D g2, Plot plot,
770: Rectangle2D plotArea,
771: RectangleEdge edge, AxisSpace space) {
772:
773:
774: if (space == null) {
775: space = new AxisSpace();
776: }
777:
778:
779: if (!isVisible()) {
780: return space;
781: }
782:
783:
784: double tickLabelHeight = 0.0;
785: double tickLabelWidth = 0.0;
786: if (isTickLabelsVisible()) {
787: g2.setFont(getTickLabelFont());
788: AxisState state = new AxisState();
789:
790: refreshTicks(g2, state, plotArea, edge);
791: if (edge == RectangleEdge.TOP) {
792: tickLabelHeight = state.getMax();
793: }
794: else if (edge == RectangleEdge.BOTTOM) {
795: tickLabelHeight = state.getMax();
796: }
797: else if (edge == RectangleEdge.LEFT) {
798: tickLabelWidth = state.getMax();
799: }
800: else if (edge == RectangleEdge.RIGHT) {
801: tickLabelWidth = state.getMax();
802: }
803: }
804:
805:
806: Rectangle2D labelEnclosure = getLabelEnclosure(g2, edge);
807: double labelHeight = 0.0;
808: double labelWidth = 0.0;
809: if (RectangleEdge.isTopOrBottom(edge)) {
810: labelHeight = labelEnclosure.getHeight();
811: space.add(labelHeight + tickLabelHeight
812: + this.categoryLabelPositionOffset, edge);
813: }
814: else if (RectangleEdge.isLeftOrRight(edge)) {
815: labelWidth = labelEnclosure.getWidth();
816: space.add(labelWidth + tickLabelWidth
817: + this.categoryLabelPositionOffset, edge);
818: }
819: return space;
820:
821: }
822:
823:
826: public void configure() {
827:
828: }
829:
830:
846: public AxisState draw(Graphics2D g2,
847: double cursor,
848: Rectangle2D plotArea,
849: Rectangle2D dataArea,
850: RectangleEdge edge,
851: PlotRenderingInfo plotState) {
852:
853:
854: if (!isVisible()) {
855: return new AxisState(cursor);
856: }
857:
858: if (isAxisLineVisible()) {
859: drawAxisLine(g2, cursor, dataArea, edge);
860: }
861:
862:
863: AxisState state = new AxisState(cursor);
864: state = drawCategoryLabels(g2, plotArea, dataArea, edge, state,
865: plotState);
866: state = drawLabel(getLabel(), g2, plotArea, dataArea, edge, state);
867:
868: return state;
869:
870: }
871:
872:
888: protected AxisState drawCategoryLabels(Graphics2D g2,
889: Rectangle2D dataArea,
890: RectangleEdge edge,
891: AxisState state,
892: PlotRenderingInfo plotState) {
893:
894:
895:
896: return drawCategoryLabels(g2, dataArea, dataArea, edge, state,
897: plotState);
898: }
899:
900:
914: protected AxisState drawCategoryLabels(Graphics2D g2,
915: Rectangle2D plotArea,
916: Rectangle2D dataArea,
917: RectangleEdge edge,
918: AxisState state,
919: PlotRenderingInfo plotState) {
920:
921: if (state == null) {
922: throw new IllegalArgumentException("Null 'state' argument.");
923: }
924:
925: if (isTickLabelsVisible()) {
926: List ticks = refreshTicks(g2, state, plotArea, edge);
927: state.setTicks(ticks);
928:
929: int categoryIndex = 0;
930: Iterator iterator = ticks.iterator();
931: while (iterator.hasNext()) {
932:
933: CategoryTick tick = (CategoryTick) iterator.next();
934: g2.setFont(getTickLabelFont(tick.getCategory()));
935: g2.setPaint(getTickLabelPaint(tick.getCategory()));
936:
937: CategoryLabelPosition position
938: = this.categoryLabelPositions.getLabelPosition(edge);
939: double x0 = 0.0;
940: double x1 = 0.0;
941: double y0 = 0.0;
942: double y1 = 0.0;
943: if (edge == RectangleEdge.TOP) {
944: x0 = getCategoryStart(categoryIndex, ticks.size(),
945: dataArea, edge);
946: x1 = getCategoryEnd(categoryIndex, ticks.size(), dataArea,
947: edge);
948: y1 = state.getCursor() - this.categoryLabelPositionOffset;
949: y0 = y1 - state.getMax();
950: }
951: else if (edge == RectangleEdge.BOTTOM) {
952: x0 = getCategoryStart(categoryIndex, ticks.size(),
953: dataArea, edge);
954: x1 = getCategoryEnd(categoryIndex, ticks.size(), dataArea,
955: edge);
956: y0 = state.getCursor() + this.categoryLabelPositionOffset;
957: y1 = y0 + state.getMax();
958: }
959: else if (edge == RectangleEdge.LEFT) {
960: y0 = getCategoryStart(categoryIndex, ticks.size(),
961: dataArea, edge);
962: y1 = getCategoryEnd(categoryIndex, ticks.size(), dataArea,
963: edge);
964: x1 = state.getCursor() - this.categoryLabelPositionOffset;
965: x0 = x1 - state.getMax();
966: }
967: else if (edge == RectangleEdge.RIGHT) {
968: y0 = getCategoryStart(categoryIndex, ticks.size(),
969: dataArea, edge);
970: y1 = getCategoryEnd(categoryIndex, ticks.size(), dataArea,
971: edge);
972: x0 = state.getCursor() + this.categoryLabelPositionOffset;
973: x1 = x0 - state.getMax();
974: }
975: Rectangle2D area = new Rectangle2D.Double(x0, y0, (x1 - x0),
976: (y1 - y0));
977: Point2D anchorPoint = RectangleAnchor.coordinates(area,
978: position.getCategoryAnchor());
979: TextBlock block = tick.getLabel();
980: block.draw(g2, (float) anchorPoint.getX(),
981: (float) anchorPoint.getY(), position.getLabelAnchor(),
982: (float) anchorPoint.getX(), (float) anchorPoint.getY(),
983: position.getAngle());
984: Shape bounds = block.calculateBounds(g2,
985: (float) anchorPoint.getX(), (float) anchorPoint.getY(),
986: position.getLabelAnchor(), (float) anchorPoint.getX(),
987: (float) anchorPoint.getY(), position.getAngle());
988: if (plotState != null && plotState.getOwner() != null) {
989: EntityCollection entities
990: = plotState.getOwner().getEntityCollection();
991: if (entities != null) {
992: String tooltip = getCategoryLabelToolTip(
993: tick.getCategory());
994: entities.add(new CategoryLabelEntity(tick.getCategory(),
995: bounds, tooltip, null));
996: }
997: }
998: categoryIndex++;
999: }
1000:
1001: if (edge.equals(RectangleEdge.TOP)) {
1002: double h = state.getMax() + this.categoryLabelPositionOffset;
1003: state.cursorUp(h);
1004: }
1005: else if (edge.equals(RectangleEdge.BOTTOM)) {
1006: double h = state.getMax() + this.categoryLabelPositionOffset;
1007: state.cursorDown(h);
1008: }
1009: else if (edge == RectangleEdge.LEFT) {
1010: double w = state.getMax() + this.categoryLabelPositionOffset;
1011: state.cursorLeft(w);
1012: }
1013: else if (edge == RectangleEdge.RIGHT) {
1014: double w = state.getMax() + this.categoryLabelPositionOffset;
1015: state.cursorRight(w);
1016: }
1017: }
1018: return state;
1019: }
1020:
1021:
1031: public List refreshTicks(Graphics2D g2,
1032: AxisState state,
1033: Rectangle2D dataArea,
1034: RectangleEdge edge) {
1035:
1036: List ticks = new java.util.ArrayList();
1037:
1038:
1039: if (dataArea.getHeight() <= 0.0 || dataArea.getWidth() < 0.0) {
1040: return ticks;
1041: }
1042:
1043: CategoryPlot plot = (CategoryPlot) getPlot();
1044: List categories = plot.getCategoriesForAxis(this);
1045: double max = 0.0;
1046:
1047: if (categories != null) {
1048: CategoryLabelPosition position
1049: = this.categoryLabelPositions.getLabelPosition(edge);
1050: float r = this.maximumCategoryLabelWidthRatio;
1051: if (r <= 0.0) {
1052: r = position.getWidthRatio();
1053: }
1054:
1055: float l = 0.0f;
1056: if (position.getWidthType() == CategoryLabelWidthType.CATEGORY) {
1057: l = (float) calculateCategorySize(categories.size(), dataArea,
1058: edge);
1059: }
1060: else {
1061: if (RectangleEdge.isLeftOrRight(edge)) {
1062: l = (float) dataArea.getWidth();
1063: }
1064: else {
1065: l = (float) dataArea.getHeight();
1066: }
1067: }
1068: int categoryIndex = 0;
1069: Iterator iterator = categories.iterator();
1070: while (iterator.hasNext()) {
1071: Comparable category = (Comparable) iterator.next();
1072: TextBlock label = createLabel(category, l * r, edge, g2);
1073: if (edge == RectangleEdge.TOP || edge == RectangleEdge.BOTTOM) {
1074: max = Math.max(max, calculateTextBlockHeight(label,
1075: position, g2));
1076: }
1077: else if (edge == RectangleEdge.LEFT
1078: || edge == RectangleEdge.RIGHT) {
1079: max = Math.max(max, calculateTextBlockWidth(label,
1080: position, g2));
1081: }
1082: Tick tick = new CategoryTick(category, label,
1083: position.getLabelAnchor(),
1084: position.getRotationAnchor(), position.getAngle());
1085: ticks.add(tick);
1086: categoryIndex = categoryIndex + 1;
1087: }
1088: }
1089: state.setMax(max);
1090: return ticks;
1091:
1092: }
1093:
1094:
1104: protected TextBlock createLabel(Comparable category, float width,
1105: RectangleEdge edge, Graphics2D g2) {
1106: TextBlock label = TextUtilities.createTextBlock(category.toString(),
1107: getTickLabelFont(category), getTickLabelPaint(category), width,
1108: this.maximumCategoryLabelLines, new G2TextMeasurer(g2));
1109: return label;
1110: }
1111:
1112:
1121: protected double calculateTextBlockWidth(TextBlock block,
1122: CategoryLabelPosition position, Graphics2D g2) {
1123:
1124: RectangleInsets insets = getTickLabelInsets();
1125: Size2D size = block.calculateDimensions(g2);
1126: Rectangle2D box = new Rectangle2D.Double(0.0, 0.0, size.getWidth(),
1127: size.getHeight());
1128: Shape rotatedBox = ShapeUtilities.rotateShape(box, position.getAngle(),
1129: 0.0f, 0.0f);
1130: double w = rotatedBox.getBounds2D().getWidth() + insets.getLeft()
1131: + insets.getRight();
1132: return w;
1133:
1134: }
1135:
1136:
1145: protected double calculateTextBlockHeight(TextBlock block,
1146: CategoryLabelPosition position,
1147: Graphics2D g2) {
1148:
1149: RectangleInsets insets = getTickLabelInsets();
1150: Size2D size = block.calculateDimensions(g2);
1151: Rectangle2D box = new Rectangle2D.Double(0.0, 0.0, size.getWidth(),
1152: size.getHeight());
1153: Shape rotatedBox = ShapeUtilities.rotateShape(box, position.getAngle(),
1154: 0.0f, 0.0f);
1155: double h = rotatedBox.getBounds2D().getHeight()
1156: + insets.getTop() + insets.getBottom();
1157: return h;
1158:
1159: }
1160:
1161:
1169: public Object clone() throws CloneNotSupportedException {
1170: CategoryAxis clone = (CategoryAxis) super.clone();
1171: clone.tickLabelFontMap = new HashMap(this.tickLabelFontMap);
1172: clone.tickLabelPaintMap = new HashMap(this.tickLabelPaintMap);
1173: clone.categoryLabelToolTips = new HashMap(this.categoryLabelToolTips);
1174: return clone;
1175: }
1176:
1177:
1184: public boolean equals(Object obj) {
1185: if (obj == this) {
1186: return true;
1187: }
1188: if (!(obj instanceof CategoryAxis)) {
1189: return false;
1190: }
1191: if (!super.equals(obj)) {
1192: return false;
1193: }
1194: CategoryAxis that = (CategoryAxis) obj;
1195: if (that.lowerMargin != this.lowerMargin) {
1196: return false;
1197: }
1198: if (that.upperMargin != this.upperMargin) {
1199: return false;
1200: }
1201: if (that.categoryMargin != this.categoryMargin) {
1202: return false;
1203: }
1204: if (that.maximumCategoryLabelWidthRatio
1205: != this.maximumCategoryLabelWidthRatio) {
1206: return false;
1207: }
1208: if (that.categoryLabelPositionOffset
1209: != this.categoryLabelPositionOffset) {
1210: return false;
1211: }
1212: if (!ObjectUtilities.equal(that.categoryLabelPositions,
1213: this.categoryLabelPositions)) {
1214: return false;
1215: }
1216: if (!ObjectUtilities.equal(that.categoryLabelToolTips,
1217: this.categoryLabelToolTips)) {
1218: return false;
1219: }
1220: if (!ObjectUtilities.equal(this.tickLabelFontMap,
1221: that.tickLabelFontMap)) {
1222: return false;
1223: }
1224: if (!equalPaintMaps(this.tickLabelPaintMap, that.tickLabelPaintMap)) {
1225: return false;
1226: }
1227: return true;
1228: }
1229:
1230:
1235: public int hashCode() {
1236: if (getLabel() != null) {
1237: return getLabel().hashCode();
1238: }
1239: else {
1240: return 0;
1241: }
1242: }
1243:
1244:
1251: private void writeObject(ObjectOutputStream stream) throws IOException {
1252: stream.defaultWriteObject();
1253: writePaintMap(this.tickLabelPaintMap, stream);
1254: }
1255:
1256:
1264: private void readObject(ObjectInputStream stream)
1265: throws IOException, ClassNotFoundException {
1266: stream.defaultReadObject();
1267: this.tickLabelPaintMap = readPaintMap(stream);
1268: }
1269:
1270:
1283: private Map readPaintMap(ObjectInputStream in)
1284: throws IOException, ClassNotFoundException {
1285: boolean isNull = in.readBoolean();
1286: if (isNull) {
1287: return null;
1288: }
1289: Map result = new HashMap();
1290: int count = in.readInt();
1291: for (int i = 0; i < count; i++) {
1292: Comparable category = (Comparable) in.readObject();
1293: Paint paint = SerialUtilities.readPaint(in);
1294: result.put(category, paint);
1295: }
1296: return result;
1297: }
1298:
1299:
1310: private void writePaintMap(Map map, ObjectOutputStream out)
1311: throws IOException {
1312: if (map == null) {
1313: out.writeBoolean(true);
1314: }
1315: else {
1316: out.writeBoolean(false);
1317: Set keys = map.keySet();
1318: int count = keys.size();
1319: out.writeInt(count);
1320: Iterator iterator = keys.iterator();
1321: while (iterator.hasNext()) {
1322: Comparable key = (Comparable) iterator.next();
1323: out.writeObject(key);
1324: SerialUtilities.writePaint((Paint) map.get(key), out);
1325: }
1326: }
1327: }
1328:
1329:
1338: private boolean equalPaintMaps(Map map1, Map map2) {
1339: if (map1.size() != map2.size()) {
1340: return false;
1341: }
1342: Set entries = map1.entrySet();
1343: Iterator iterator = entries.iterator();
1344: while (iterator.hasNext()) {
1345: Map.Entry entry = (Map.Entry) iterator.next();
1346: Paint p1 = (Paint) entry.getValue();
1347: Paint p2 = (Paint) map2.get(entry.getKey());
1348: if (!PaintUtilities.equal(p1, p2)) {
1349: return false;
1350: }
1351: }
1352: return true;
1353: }
1354:
1355: }