1:
87:
88: package ;
89:
90: import ;
91: import ;
92: import ;
93: import ;
94: import ;
95: import ;
96: import ;
97: import ;
98: import ;
99: import ;
100: import ;
101: import ;
102: import ;
103: import ;
104: import ;
105:
106: import ;
107: import ;
108: import ;
109: import ;
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:
125:
128: public class CategoryAxis extends Axis implements Cloneable, Serializable {
129:
130:
131: private static final long serialVersionUID = 5886554608114265863L;
132:
133:
136: public static final double DEFAULT_AXIS_MARGIN = 0.05;
137:
138:
142: public static final double DEFAULT_CATEGORY_MARGIN = 0.20;
143:
144:
145: private double lowerMargin;
146:
147:
148: private double upperMargin;
149:
150:
151: private double categoryMargin;
152:
153:
154: private int maximumCategoryLabelLines;
155:
156:
160: private float maximumCategoryLabelWidthRatio;
161:
162:
163: private int categoryLabelPositionOffset;
164:
165:
169: private CategoryLabelPositions categoryLabelPositions;
170:
171:
172: private Map tickLabelFontMap;
173:
174:
175: private transient Map tickLabelPaintMap;
176:
177:
178: private Map categoryLabelToolTips;
179:
180:
183: public CategoryAxis() {
184: this(null);
185: }
186:
187:
192: public CategoryAxis(String label) {
193:
194: super(label);
195:
196: this.lowerMargin = DEFAULT_AXIS_MARGIN;
197: this.upperMargin = DEFAULT_AXIS_MARGIN;
198: this.categoryMargin = DEFAULT_CATEGORY_MARGIN;
199: this.maximumCategoryLabelLines = 1;
200: this.maximumCategoryLabelWidthRatio = 0.0f;
201:
202: setTickMarksVisible(false);
203:
204: this.categoryLabelPositionOffset = 4;
205: this.categoryLabelPositions = CategoryLabelPositions.STANDARD;
206: this.tickLabelFontMap = new HashMap();
207: this.tickLabelPaintMap = new HashMap();
208: this.categoryLabelToolTips = new HashMap();
209:
210: }
211:
212:
220: public double getLowerMargin() {
221: return this.lowerMargin;
222: }
223:
224:
233: public void setLowerMargin(double margin) {
234: this.lowerMargin = margin;
235: notifyListeners(new AxisChangeEvent(this));
236: }
237:
238:
246: public double getUpperMargin() {
247: return this.upperMargin;
248: }
249:
250:
259: public void setUpperMargin(double margin) {
260: this.upperMargin = margin;
261: notifyListeners(new AxisChangeEvent(this));
262: }
263:
264:
271: public double getCategoryMargin() {
272: return this.categoryMargin;
273: }
274:
275:
285: public void setCategoryMargin(double margin) {
286: this.categoryMargin = margin;
287: notifyListeners(new AxisChangeEvent(this));
288: }
289:
290:
297: public int getMaximumCategoryLabelLines() {
298: return this.maximumCategoryLabelLines;
299: }
300:
301:
309: public void setMaximumCategoryLabelLines(int lines) {
310: this.maximumCategoryLabelLines = lines;
311: notifyListeners(new AxisChangeEvent(this));
312: }
313:
314:
321: public float getMaximumCategoryLabelWidthRatio() {
322: return this.maximumCategoryLabelWidthRatio;
323: }
324:
325:
333: public void setMaximumCategoryLabelWidthRatio(float ratio) {
334: this.maximumCategoryLabelWidthRatio = ratio;
335: notifyListeners(new AxisChangeEvent(this));
336: }
337:
338:
346: public int getCategoryLabelPositionOffset() {
347: return this.categoryLabelPositionOffset;
348: }
349:
350:
358: public void setCategoryLabelPositionOffset(int offset) {
359: this.categoryLabelPositionOffset = offset;
360: notifyListeners(new AxisChangeEvent(this));
361: }
362:
363:
371: public CategoryLabelPositions getCategoryLabelPositions() {
372: return this.categoryLabelPositions;
373: }
374:
375:
383: public void setCategoryLabelPositions(CategoryLabelPositions positions) {
384: if (positions == null) {
385: throw new IllegalArgumentException("Null 'positions' argument.");
386: }
387: this.categoryLabelPositions = positions;
388: notifyListeners(new AxisChangeEvent(this));
389: }
390:
391:
400: public Font getTickLabelFont(Comparable category) {
401: if (category == null) {
402: throw new IllegalArgumentException("Null 'category' argument.");
403: }
404: Font result = (Font) this.tickLabelFontMap.get(category);
405:
406: if (result == null) {
407: result = getTickLabelFont();
408: }
409: return result;
410: }
411:
412:
421: public void setTickLabelFont(Comparable category, Font font) {
422: if (category == null) {
423: throw new IllegalArgumentException("Null 'category' argument.");
424: }
425: if (font == null) {
426: this.tickLabelFontMap.remove(category);
427: }
428: else {
429: this.tickLabelFontMap.put(category, font);
430: }
431: notifyListeners(new AxisChangeEvent(this));
432: }
433:
434:
443: public Paint getTickLabelPaint(Comparable category) {
444: if (category == null) {
445: throw new IllegalArgumentException("Null 'category' argument.");
446: }
447: Paint result = (Paint) this.tickLabelPaintMap.get(category);
448:
449: if (result == null) {
450: result = getTickLabelPaint();
451: }
452: return result;
453: }
454:
455:
464: public void setTickLabelPaint(Comparable category, Paint paint) {
465: if (category == null) {
466: throw new IllegalArgumentException("Null 'category' argument.");
467: }
468: if (paint == null) {
469: this.tickLabelPaintMap.remove(category);
470: }
471: else {
472: this.tickLabelPaintMap.put(category, paint);
473: }
474: notifyListeners(new AxisChangeEvent(this));
475: }
476:
477:
486: public void addCategoryLabelToolTip(Comparable category, String tooltip) {
487: if (category == null) {
488: throw new IllegalArgumentException("Null 'category' argument.");
489: }
490: this.categoryLabelToolTips.put(category, tooltip);
491: notifyListeners(new AxisChangeEvent(this));
492: }
493:
494:
505: public String getCategoryLabelToolTip(Comparable category) {
506: if (category == null) {
507: throw new IllegalArgumentException("Null 'category' argument.");
508: }
509: return (String) this.categoryLabelToolTips.get(category);
510: }
511:
512:
521: public void removeCategoryLabelToolTip(Comparable category) {
522: if (category == null) {
523: throw new IllegalArgumentException("Null 'category' argument.");
524: }
525: this.categoryLabelToolTips.remove(category);
526: notifyListeners(new AxisChangeEvent(this));
527: }
528:
529:
536: public void clearCategoryLabelToolTips() {
537: this.categoryLabelToolTips.clear();
538: notifyListeners(new AxisChangeEvent(this));
539: }
540:
541:
552: public double getCategoryJava2DCoordinate(CategoryAnchor anchor,
553: int category,
554: int categoryCount,
555: Rectangle2D area,
556: RectangleEdge edge) {
557:
558: double result = 0.0;
559: if (anchor == CategoryAnchor.START) {
560: result = getCategoryStart(category, categoryCount, area, edge);
561: }
562: else if (anchor == CategoryAnchor.MIDDLE) {
563: result = getCategoryMiddle(category, categoryCount, area, edge);
564: }
565: else if (anchor == CategoryAnchor.END) {
566: result = getCategoryEnd(category, categoryCount, area, edge);
567: }
568: return result;
569:
570: }
571:
572:
585: public double getCategoryStart(int category, int categoryCount,
586: Rectangle2D area,
587: RectangleEdge edge) {
588:
589: double result = 0.0;
590: if ((edge == RectangleEdge.TOP) || (edge == RectangleEdge.BOTTOM)) {
591: result = area.getX() + area.getWidth() * getLowerMargin();
592: }
593: else if ((edge == RectangleEdge.LEFT)
594: || (edge == RectangleEdge.RIGHT)) {
595: result = area.getMinY() + area.getHeight() * getLowerMargin();
596: }
597:
598: double categorySize = calculateCategorySize(categoryCount, area, edge);
599: double categoryGapWidth = calculateCategoryGapSize(categoryCount, area,
600: edge);
601:
602: result = result + category * (categorySize + categoryGapWidth);
603: return result;
604:
605: }
606:
607:
620: public double getCategoryMiddle(int category, int categoryCount,
621: Rectangle2D area, RectangleEdge edge) {
622:
623: return getCategoryStart(category, categoryCount, area, edge)
624: + calculateCategorySize(categoryCount, area, edge) / 2;
625:
626: }
627:
628:
641: public double getCategoryEnd(int category, int categoryCount,
642: Rectangle2D area, RectangleEdge edge) {
643:
644: return getCategoryStart(category, categoryCount, area, edge)
645: + calculateCategorySize(categoryCount, area, edge);
646:
647: }
648:
649:
664: public double getCategorySeriesMiddle(Comparable category,
665: Comparable seriesKey, CategoryDataset dataset, double itemMargin,
666: Rectangle2D area, RectangleEdge edge) {
667:
668: int categoryIndex = dataset.getColumnIndex(category);
669: int categoryCount = dataset.getColumnCount();
670: int seriesIndex = dataset.getRowIndex(seriesKey);
671: int seriesCount = dataset.getRowCount();
672: double start = getCategoryStart(categoryIndex, categoryCount, area,
673: edge);
674: double end = getCategoryEnd(categoryIndex, categoryCount, area, edge);
675: double width = end - start;
676: if (seriesCount == 1) {
677: return start + width / 2.0;
678: }
679: else {
680: double gap = (width * itemMargin) / (seriesCount - 1);
681: double ww = (width * (1 - itemMargin)) / seriesCount;
682: return start + (seriesIndex * (ww + gap)) + ww / 2.0;
683: }
684: }
685:
686:
696: protected double calculateCategorySize(int categoryCount, Rectangle2D area,
697: RectangleEdge edge) {
698:
699: double result = 0.0;
700: double available = 0.0;
701:
702: if ((edge == RectangleEdge.TOP) || (edge == RectangleEdge.BOTTOM)) {
703: available = area.getWidth();
704: }
705: else if ((edge == RectangleEdge.LEFT)
706: || (edge == RectangleEdge.RIGHT)) {
707: available = area.getHeight();
708: }
709: if (categoryCount > 1) {
710: result = available * (1 - getLowerMargin() - getUpperMargin()
711: - getCategoryMargin());
712: result = result / categoryCount;
713: }
714: else {
715: result = available * (1 - getLowerMargin() - getUpperMargin());
716: }
717: return result;
718:
719: }
720:
721:
731: protected double calculateCategoryGapSize(int categoryCount,
732: Rectangle2D area,
733: RectangleEdge edge) {
734:
735: double result = 0.0;
736: double available = 0.0;
737:
738: if ((edge == RectangleEdge.TOP) || (edge == RectangleEdge.BOTTOM)) {
739: available = area.getWidth();
740: }
741: else if ((edge == RectangleEdge.LEFT)
742: || (edge == RectangleEdge.RIGHT)) {
743: available = area.getHeight();
744: }
745:
746: if (categoryCount > 1) {
747: result = available * getCategoryMargin() / (categoryCount - 1);
748: }
749:
750: return result;
751:
752: }
753:
754:
765: public AxisSpace reserveSpace(Graphics2D g2, Plot plot,
766: Rectangle2D plotArea,
767: RectangleEdge edge, AxisSpace space) {
768:
769:
770: if (space == null) {
771: space = new AxisSpace();
772: }
773:
774:
775: if (!isVisible()) {
776: return space;
777: }
778:
779:
780: double tickLabelHeight = 0.0;
781: double tickLabelWidth = 0.0;
782: if (isTickLabelsVisible()) {
783: g2.setFont(getTickLabelFont());
784: AxisState state = new AxisState();
785:
786: refreshTicks(g2, state, plotArea, edge);
787: if (edge == RectangleEdge.TOP) {
788: tickLabelHeight = state.getMax();
789: }
790: else if (edge == RectangleEdge.BOTTOM) {
791: tickLabelHeight = state.getMax();
792: }
793: else if (edge == RectangleEdge.LEFT) {
794: tickLabelWidth = state.getMax();
795: }
796: else if (edge == RectangleEdge.RIGHT) {
797: tickLabelWidth = state.getMax();
798: }
799: }
800:
801:
802: Rectangle2D labelEnclosure = getLabelEnclosure(g2, edge);
803: double labelHeight = 0.0;
804: double labelWidth = 0.0;
805: if (RectangleEdge.isTopOrBottom(edge)) {
806: labelHeight = labelEnclosure.getHeight();
807: space.add(labelHeight + tickLabelHeight
808: + this.categoryLabelPositionOffset, edge);
809: }
810: else if (RectangleEdge.isLeftOrRight(edge)) {
811: labelWidth = labelEnclosure.getWidth();
812: space.add(labelWidth + tickLabelWidth
813: + this.categoryLabelPositionOffset, edge);
814: }
815: return space;
816:
817: }
818:
819:
822: public void configure() {
823:
824: }
825:
826:
842: public AxisState draw(Graphics2D g2,
843: double cursor,
844: Rectangle2D plotArea,
845: Rectangle2D dataArea,
846: RectangleEdge edge,
847: PlotRenderingInfo plotState) {
848:
849:
850: if (!isVisible()) {
851: return new AxisState(cursor);
852: }
853:
854: if (isAxisLineVisible()) {
855: drawAxisLine(g2, cursor, dataArea, edge);
856: }
857:
858:
859: AxisState state = new AxisState(cursor);
860: state = drawCategoryLabels(g2, plotArea, dataArea, edge, state,
861: plotState);
862: state = drawLabel(getLabel(), g2, plotArea, dataArea, edge, state);
863:
864: return state;
865:
866: }
867:
868:
884: protected AxisState drawCategoryLabels(Graphics2D g2,
885: Rectangle2D dataArea,
886: RectangleEdge edge,
887: AxisState state,
888: PlotRenderingInfo plotState) {
889:
890:
891:
892: return drawCategoryLabels(g2, dataArea, dataArea, edge, state,
893: plotState);
894: }
895:
896:
910: protected AxisState drawCategoryLabels(Graphics2D g2,
911: Rectangle2D plotArea,
912: Rectangle2D dataArea,
913: RectangleEdge edge,
914: AxisState state,
915: PlotRenderingInfo plotState) {
916:
917: if (state == null) {
918: throw new IllegalArgumentException("Null 'state' argument.");
919: }
920:
921: if (isTickLabelsVisible()) {
922: List ticks = refreshTicks(g2, state, plotArea, edge);
923: state.setTicks(ticks);
924:
925: int categoryIndex = 0;
926: Iterator iterator = ticks.iterator();
927: while (iterator.hasNext()) {
928:
929: CategoryTick tick = (CategoryTick) iterator.next();
930: g2.setFont(getTickLabelFont(tick.getCategory()));
931: g2.setPaint(getTickLabelPaint(tick.getCategory()));
932:
933: CategoryLabelPosition position
934: = this.categoryLabelPositions.getLabelPosition(edge);
935: double x0 = 0.0;
936: double x1 = 0.0;
937: double y0 = 0.0;
938: double y1 = 0.0;
939: if (edge == RectangleEdge.TOP) {
940: x0 = getCategoryStart(categoryIndex, ticks.size(),
941: dataArea, edge);
942: x1 = getCategoryEnd(categoryIndex, ticks.size(), dataArea,
943: edge);
944: y1 = state.getCursor() - this.categoryLabelPositionOffset;
945: y0 = y1 - state.getMax();
946: }
947: else if (edge == RectangleEdge.BOTTOM) {
948: x0 = getCategoryStart(categoryIndex, ticks.size(),
949: dataArea, edge);
950: x1 = getCategoryEnd(categoryIndex, ticks.size(), dataArea,
951: edge);
952: y0 = state.getCursor() + this.categoryLabelPositionOffset;
953: y1 = y0 + state.getMax();
954: }
955: else if (edge == RectangleEdge.LEFT) {
956: y0 = getCategoryStart(categoryIndex, ticks.size(),
957: dataArea, edge);
958: y1 = getCategoryEnd(categoryIndex, ticks.size(), dataArea,
959: edge);
960: x1 = state.getCursor() - this.categoryLabelPositionOffset;
961: x0 = x1 - state.getMax();
962: }
963: else if (edge == RectangleEdge.RIGHT) {
964: y0 = getCategoryStart(categoryIndex, ticks.size(),
965: dataArea, edge);
966: y1 = getCategoryEnd(categoryIndex, ticks.size(), dataArea,
967: edge);
968: x0 = state.getCursor() + this.categoryLabelPositionOffset;
969: x1 = x0 - state.getMax();
970: }
971: Rectangle2D area = new Rectangle2D.Double(x0, y0, (x1 - x0),
972: (y1 - y0));
973: Point2D anchorPoint = RectangleAnchor.coordinates(area,
974: position.getCategoryAnchor());
975: TextBlock block = tick.getLabel();
976: block.draw(g2, (float) anchorPoint.getX(),
977: (float) anchorPoint.getY(), position.getLabelAnchor(),
978: (float) anchorPoint.getX(), (float) anchorPoint.getY(),
979: position.getAngle());
980: Shape bounds = block.calculateBounds(g2,
981: (float) anchorPoint.getX(), (float) anchorPoint.getY(),
982: position.getLabelAnchor(), (float) anchorPoint.getX(),
983: (float) anchorPoint.getY(), position.getAngle());
984: if (plotState != null && plotState.getOwner() != null) {
985: EntityCollection entities
986: = plotState.getOwner().getEntityCollection();
987: if (entities != null) {
988: String tooltip = getCategoryLabelToolTip(
989: tick.getCategory());
990: entities.add(new CategoryLabelEntity(tick.getCategory(),
991: bounds, tooltip, null));
992: }
993: }
994: categoryIndex++;
995: }
996:
997: if (edge.equals(RectangleEdge.TOP)) {
998: double h = state.getMax() + this.categoryLabelPositionOffset;
999: state.cursorUp(h);
1000: }
1001: else if (edge.equals(RectangleEdge.BOTTOM)) {
1002: double h = state.getMax() + this.categoryLabelPositionOffset;
1003: state.cursorDown(h);
1004: }
1005: else if (edge == RectangleEdge.LEFT) {
1006: double w = state.getMax() + this.categoryLabelPositionOffset;
1007: state.cursorLeft(w);
1008: }
1009: else if (edge == RectangleEdge.RIGHT) {
1010: double w = state.getMax() + this.categoryLabelPositionOffset;
1011: state.cursorRight(w);
1012: }
1013: }
1014: return state;
1015: }
1016:
1017:
1027: public List refreshTicks(Graphics2D g2,
1028: AxisState state,
1029: Rectangle2D dataArea,
1030: RectangleEdge edge) {
1031:
1032: List ticks = new java.util.ArrayList();
1033:
1034:
1035: if (dataArea.getHeight() <= 0.0 || dataArea.getWidth() < 0.0) {
1036: return ticks;
1037: }
1038:
1039: CategoryPlot plot = (CategoryPlot) getPlot();
1040: List categories = plot.getCategoriesForAxis(this);
1041: double max = 0.0;
1042:
1043: if (categories != null) {
1044: CategoryLabelPosition position
1045: = this.categoryLabelPositions.getLabelPosition(edge);
1046: float r = this.maximumCategoryLabelWidthRatio;
1047: if (r <= 0.0) {
1048: r = position.getWidthRatio();
1049: }
1050:
1051: float l = 0.0f;
1052: if (position.getWidthType() == CategoryLabelWidthType.CATEGORY) {
1053: l = (float) calculateCategorySize(categories.size(), dataArea,
1054: edge);
1055: }
1056: else {
1057: if (RectangleEdge.isLeftOrRight(edge)) {
1058: l = (float) dataArea.getWidth();
1059: }
1060: else {
1061: l = (float) dataArea.getHeight();
1062: }
1063: }
1064: int categoryIndex = 0;
1065: Iterator iterator = categories.iterator();
1066: while (iterator.hasNext()) {
1067: Comparable category = (Comparable) iterator.next();
1068: TextBlock label = createLabel(category, l * r, edge, g2);
1069: if (edge == RectangleEdge.TOP || edge == RectangleEdge.BOTTOM) {
1070: max = Math.max(max, calculateTextBlockHeight(label,
1071: position, g2));
1072: }
1073: else if (edge == RectangleEdge.LEFT
1074: || edge == RectangleEdge.RIGHT) {
1075: max = Math.max(max, calculateTextBlockWidth(label,
1076: position, g2));
1077: }
1078: Tick tick = new CategoryTick(category, label,
1079: position.getLabelAnchor(),
1080: position.getRotationAnchor(), position.getAngle());
1081: ticks.add(tick);
1082: categoryIndex = categoryIndex + 1;
1083: }
1084: }
1085: state.setMax(max);
1086: return ticks;
1087:
1088: }
1089:
1090:
1100: protected TextBlock createLabel(Comparable category, float width,
1101: RectangleEdge edge, Graphics2D g2) {
1102: TextBlock label = TextUtilities.createTextBlock(category.toString(),
1103: getTickLabelFont(category), getTickLabelPaint(category), width,
1104: this.maximumCategoryLabelLines, new G2TextMeasurer(g2));
1105: return label;
1106: }
1107:
1108:
1117: protected double calculateTextBlockWidth(TextBlock block,
1118: CategoryLabelPosition position,
1119: Graphics2D g2) {
1120:
1121: RectangleInsets insets = getTickLabelInsets();
1122: Size2D size = block.calculateDimensions(g2);
1123: Rectangle2D box = new Rectangle2D.Double(0.0, 0.0, size.getWidth(),
1124: size.getHeight());
1125: Shape rotatedBox = ShapeUtilities.rotateShape(box, position.getAngle(),
1126: 0.0f, 0.0f);
1127: double w = rotatedBox.getBounds2D().getWidth() + insets.getTop()
1128: + insets.getBottom();
1129: return w;
1130:
1131: }
1132:
1133:
1142: protected double calculateTextBlockHeight(TextBlock block,
1143: CategoryLabelPosition position,
1144: Graphics2D g2) {
1145:
1146: RectangleInsets insets = getTickLabelInsets();
1147: Size2D size = block.calculateDimensions(g2);
1148: Rectangle2D box = new Rectangle2D.Double(0.0, 0.0, size.getWidth(),
1149: size.getHeight());
1150: Shape rotatedBox = ShapeUtilities.rotateShape(box, position.getAngle(),
1151: 0.0f, 0.0f);
1152: double h = rotatedBox.getBounds2D().getHeight()
1153: + insets.getTop() + insets.getBottom();
1154: return h;
1155:
1156: }
1157:
1158:
1166: public Object clone() throws CloneNotSupportedException {
1167: CategoryAxis clone = (CategoryAxis) super.clone();
1168: clone.tickLabelFontMap = new HashMap(this.tickLabelFontMap);
1169: clone.tickLabelPaintMap = new HashMap(this.tickLabelPaintMap);
1170: clone.categoryLabelToolTips = new HashMap(this.categoryLabelToolTips);
1171: return clone;
1172: }
1173:
1174:
1181: public boolean equals(Object obj) {
1182: if (obj == this) {
1183: return true;
1184: }
1185: if (!(obj instanceof CategoryAxis)) {
1186: return false;
1187: }
1188: if (!super.equals(obj)) {
1189: return false;
1190: }
1191: CategoryAxis that = (CategoryAxis) obj;
1192: if (that.lowerMargin != this.lowerMargin) {
1193: return false;
1194: }
1195: if (that.upperMargin != this.upperMargin) {
1196: return false;
1197: }
1198: if (that.categoryMargin != this.categoryMargin) {
1199: return false;
1200: }
1201: if (that.maximumCategoryLabelWidthRatio
1202: != this.maximumCategoryLabelWidthRatio) {
1203: return false;
1204: }
1205: if (that.categoryLabelPositionOffset
1206: != this.categoryLabelPositionOffset) {
1207: return false;
1208: }
1209: if (!ObjectUtilities.equal(that.categoryLabelPositions,
1210: this.categoryLabelPositions)) {
1211: return false;
1212: }
1213: if (!ObjectUtilities.equal(that.categoryLabelToolTips,
1214: this.categoryLabelToolTips)) {
1215: return false;
1216: }
1217: if (!ObjectUtilities.equal(this.tickLabelFontMap,
1218: that.tickLabelFontMap)) {
1219: return false;
1220: }
1221: if (!equalPaintMaps(this.tickLabelPaintMap, that.tickLabelPaintMap)) {
1222: return false;
1223: }
1224: return true;
1225: }
1226:
1227:
1232: public int hashCode() {
1233: if (getLabel() != null) {
1234: return getLabel().hashCode();
1235: }
1236: else {
1237: return 0;
1238: }
1239: }
1240:
1241:
1248: private void writeObject(ObjectOutputStream stream) throws IOException {
1249: stream.defaultWriteObject();
1250: writePaintMap(this.tickLabelPaintMap, stream);
1251: }
1252:
1253:
1261: private void readObject(ObjectInputStream stream)
1262: throws IOException, ClassNotFoundException {
1263: stream.defaultReadObject();
1264: this.tickLabelPaintMap = readPaintMap(stream);
1265: }
1266:
1267:
1280: private Map readPaintMap(ObjectInputStream in)
1281: throws IOException, ClassNotFoundException {
1282: boolean isNull = in.readBoolean();
1283: if (isNull) {
1284: return null;
1285: }
1286: Map result = new HashMap();
1287: int count = in.readInt();
1288: for (int i = 0; i < count; i++) {
1289: Comparable category = (Comparable) in.readObject();
1290: Paint paint = SerialUtilities.readPaint(in);
1291: result.put(category, paint);
1292: }
1293: return result;
1294: }
1295:
1296:
1307: private void writePaintMap(Map map, ObjectOutputStream out)
1308: throws IOException {
1309: if (map == null) {
1310: out.writeBoolean(true);
1311: }
1312: else {
1313: out.writeBoolean(false);
1314: Set keys = map.keySet();
1315: int count = keys.size();
1316: out.writeInt(count);
1317: Iterator iterator = keys.iterator();
1318: while (iterator.hasNext()) {
1319: Comparable key = (Comparable) iterator.next();
1320: out.writeObject(key);
1321: SerialUtilities.writePaint((Paint) map.get(key), out);
1322: }
1323: }
1324: }
1325:
1326:
1335: private boolean equalPaintMaps(Map map1, Map map2) {
1336: if (map1.size() != map2.size()) {
1337: return false;
1338: }
1339: Set keys = map1.keySet();
1340: Iterator iterator = keys.iterator();
1341: while (iterator.hasNext()) {
1342: Comparable key = (Comparable) iterator.next();
1343: Paint p1 = (Paint) map1.get(key);
1344: Paint p2 = (Paint) map2.get(key);
1345: if (!PaintUtilities.equal(p1, p2)) {
1346: return false;
1347: }
1348: }
1349: return true;
1350: }
1351:
1352: }