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