1:
51:
52: package ;
53:
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72: import ;
73: import ;
74: import ;
75:
76: import ;
77: import ;
78: import ;
79: import ;
80: import ;
81: import ;
82: import ;
83: import ;
84: import ;
85: import ;
86: import ;
87: import ;
88: import ;
89: import ;
90:
91:
97: public class PeriodAxis extends ValueAxis
98: implements Cloneable, PublicCloneable, Serializable {
99:
100:
101: private static final long serialVersionUID = 8353295532075872069L;
102:
103:
104: private RegularTimePeriod first;
105:
106:
107: private RegularTimePeriod last;
108:
109:
113: private TimeZone timeZone;
114:
115:
119: private Class autoRangeTimePeriodClass;
120:
121:
125: private Class majorTickTimePeriodClass;
126:
127:
131: private boolean minorTickMarksVisible;
132:
133:
137: private Class minorTickTimePeriodClass;
138:
139:
140: private float minorTickMarkInsideLength = 0.0f;
141:
142:
143: private float minorTickMarkOutsideLength = 2.0f;
144:
145:
146: private transient Stroke minorTickMarkStroke = new BasicStroke(0.5f);
147:
148:
149: private transient Paint minorTickMarkPaint = Color.black;
150:
151:
152: private PeriodAxisLabelInfo[] labelInfo;
153:
154:
159: public PeriodAxis(String label) {
160: this(label, new Day(), new Day());
161: }
162:
163:
172: public PeriodAxis(String label,
173: RegularTimePeriod first, RegularTimePeriod last) {
174: this(label, first, last, TimeZone.getDefault());
175: }
176:
177:
187: public PeriodAxis(String label,
188: RegularTimePeriod first, RegularTimePeriod last,
189: TimeZone timeZone) {
190:
191: super(label, null);
192: this.first = first;
193: this.last = last;
194: this.timeZone = timeZone;
195: this.autoRangeTimePeriodClass = first.getClass();
196: this.majorTickTimePeriodClass = first.getClass();
197: this.minorTickMarksVisible = false;
198: this.minorTickTimePeriodClass = RegularTimePeriod.downsize(
199: this.majorTickTimePeriodClass
200: );
201: setAutoRange(true);
202: this.labelInfo = new PeriodAxisLabelInfo[2];
203: this.labelInfo[0] = new PeriodAxisLabelInfo(
204: Month.class, new SimpleDateFormat("MMM")
205: );
206: this.labelInfo[1] = new PeriodAxisLabelInfo(
207: Year.class, new SimpleDateFormat("yyyy")
208: );
209:
210: }
211:
212:
217: public RegularTimePeriod getFirst() {
218: return this.first;
219: }
220:
221:
227: public void setFirst(RegularTimePeriod first) {
228: if (first == null) {
229: throw new IllegalArgumentException("Null 'first' argument.");
230: }
231: this.first = first;
232: notifyListeners(new AxisChangeEvent(this));
233: }
234:
235:
240: public RegularTimePeriod getLast() {
241: return this.last;
242: }
243:
244:
250: public void setLast(RegularTimePeriod last) {
251: if (last == null) {
252: throw new IllegalArgumentException("Null 'last' argument.");
253: }
254: this.last = last;
255: notifyListeners(new AxisChangeEvent(this));
256: }
257:
258:
264: public TimeZone getTimeZone() {
265: return this.timeZone;
266: }
267:
268:
274: public void setTimeZone(TimeZone zone) {
275: if (zone == null) {
276: throw new IllegalArgumentException("Null 'zone' argument.");
277: }
278: this.timeZone = zone;
279: notifyListeners(new AxisChangeEvent(this));
280: }
281:
282:
288: public Class getAutoRangeTimePeriodClass() {
289: return this.autoRangeTimePeriodClass;
290: }
291:
292:
299: public void setAutoRangeTimePeriodClass(Class c) {
300: if (c == null) {
301: throw new IllegalArgumentException("Null 'c' argument.");
302: }
303: this.autoRangeTimePeriodClass = c;
304: notifyListeners(new AxisChangeEvent(this));
305: }
306:
307:
312: public Class getMajorTickTimePeriodClass() {
313: return this.majorTickTimePeriodClass;
314: }
315:
316:
323: public void setMajorTickTimePeriodClass(Class c) {
324: if (c == null) {
325: throw new IllegalArgumentException("Null 'c' argument.");
326: }
327: this.majorTickTimePeriodClass = c;
328: notifyListeners(new AxisChangeEvent(this));
329: }
330:
331:
337: public boolean isMinorTickMarksVisible() {
338: return this.minorTickMarksVisible;
339: }
340:
341:
348: public void setMinorTickMarksVisible(boolean visible) {
349: this.minorTickMarksVisible = visible;
350: notifyListeners(new AxisChangeEvent(this));
351: }
352:
353:
358: public Class getMinorTickTimePeriodClass() {
359: return this.minorTickTimePeriodClass;
360: }
361:
362:
369: public void setMinorTickTimePeriodClass(Class c) {
370: if (c == null) {
371: throw new IllegalArgumentException("Null 'c' argument.");
372: }
373: this.minorTickTimePeriodClass = c;
374: notifyListeners(new AxisChangeEvent(this));
375: }
376:
377:
383: public Stroke getMinorTickMarkStroke() {
384: return this.minorTickMarkStroke;
385: }
386:
387:
394: public void setMinorTickMarkStroke(Stroke stroke) {
395: if (stroke == null) {
396: throw new IllegalArgumentException("Null 'stroke' argument.");
397: }
398: this.minorTickMarkStroke = stroke;
399: notifyListeners(new AxisChangeEvent(this));
400: }
401:
402:
408: public Paint getMinorTickMarkPaint() {
409: return this.minorTickMarkPaint;
410: }
411:
412:
419: public void setMinorTickMarkPaint(Paint paint) {
420: if (paint == null) {
421: throw new IllegalArgumentException("Null 'paint' argument.");
422: }
423: this.minorTickMarkPaint = paint;
424: notifyListeners(new AxisChangeEvent(this));
425: }
426:
427:
432: public float getMinorTickMarkInsideLength() {
433: return this.minorTickMarkInsideLength;
434: }
435:
436:
442: public void setMinorTickMarkInsideLength(float length) {
443: this.minorTickMarkInsideLength = length;
444: notifyListeners(new AxisChangeEvent(this));
445: }
446:
447:
452: public float getMinorTickMarkOutsideLength() {
453: return this.minorTickMarkOutsideLength;
454: }
455:
456:
462: public void setMinorTickMarkOutsideLength(float length) {
463: this.minorTickMarkOutsideLength = length;
464: notifyListeners(new AxisChangeEvent(this));
465: }
466:
467:
472: public PeriodAxisLabelInfo[] getLabelInfo() {
473: return this.labelInfo;
474: }
475:
476:
481: public void setLabelInfo(PeriodAxisLabelInfo[] info) {
482: this.labelInfo = info;
483: }
484:
485:
490: public Range getRange() {
491:
492: return new Range(
493: this.first.getFirstMillisecond(this.timeZone),
494: this.last.getLastMillisecond(this.timeZone)
495: );
496: }
497:
498:
509: public void setRange(Range range, boolean turnOffAutoRange,
510: boolean notify) {
511: super.setRange(range, turnOffAutoRange, false);
512: long upper = Math.round(range.getUpperBound());
513: long lower = Math.round(range.getLowerBound());
514: this.first = createInstance(
515: this.autoRangeTimePeriodClass, new Date(lower), this.timeZone
516: );
517: this.last = createInstance(
518: this.autoRangeTimePeriodClass, new Date(upper), this.timeZone
519: );
520: }
521:
522:
526: public void configure() {
527: if (this.isAutoRange()) {
528: autoAdjustRange();
529: }
530: }
531:
532:
545: public AxisSpace reserveSpace(Graphics2D g2, Plot plot,
546: Rectangle2D plotArea, RectangleEdge edge,
547: AxisSpace space) {
548:
549: if (space == null) {
550: space = new AxisSpace();
551: }
552:
553:
554: if (!isVisible()) {
555: return space;
556: }
557:
558:
559: double dimension = getFixedDimension();
560: if (dimension > 0.0) {
561: space.ensureAtLeast(dimension, edge);
562: }
563:
564:
565: Rectangle2D labelEnclosure = getLabelEnclosure(g2, edge);
566: double labelHeight = 0.0;
567: double labelWidth = 0.0;
568: double tickLabelBandsDimension = 0.0;
569:
570: for (int i = 0; i < this.labelInfo.length; i++) {
571: PeriodAxisLabelInfo info = this.labelInfo[i];
572: FontMetrics fm = g2.getFontMetrics(info.getLabelFont());
573: tickLabelBandsDimension
574: += info.getPadding().extendHeight(fm.getHeight());
575: }
576:
577: if (RectangleEdge.isTopOrBottom(edge)) {
578: labelHeight = labelEnclosure.getHeight();
579: space.add(labelHeight + tickLabelBandsDimension, edge);
580: }
581: else if (RectangleEdge.isLeftOrRight(edge)) {
582: labelWidth = labelEnclosure.getWidth();
583: space.add(labelWidth + tickLabelBandsDimension, edge);
584: }
585:
586:
587: double tickMarkSpace = 0.0;
588: if (isTickMarksVisible()) {
589: tickMarkSpace = getTickMarkOutsideLength();
590: }
591: if (this.minorTickMarksVisible) {
592: tickMarkSpace = Math.max(
593: tickMarkSpace, this.minorTickMarkOutsideLength
594: );
595: }
596: space.add(tickMarkSpace, edge);
597: return space;
598: }
599:
600:
614: public AxisState draw(Graphics2D g2,
615: double cursor,
616: Rectangle2D plotArea,
617: Rectangle2D dataArea,
618: RectangleEdge edge,
619: PlotRenderingInfo plotState) {
620:
621: AxisState axisState = new AxisState(cursor);
622: if (isAxisLineVisible()) {
623: drawAxisLine(g2, cursor, dataArea, edge);
624: }
625: drawTickMarks(g2, axisState, dataArea, edge);
626: for (int band = 0; band < this.labelInfo.length; band++) {
627: axisState = drawTickLabels(band, g2, axisState, dataArea, edge);
628: }
629:
630:
631:
632: axisState = drawLabel(
633: getLabel(), g2, plotArea, dataArea, edge, axisState
634: );
635: return axisState;
636:
637: }
638:
639:
647: protected void drawTickMarks(Graphics2D g2, AxisState state,
648: Rectangle2D dataArea,
649: RectangleEdge edge) {
650: if (RectangleEdge.isTopOrBottom(edge)) {
651: drawTickMarksHorizontal(g2, state, dataArea, edge);
652: }
653: else if (RectangleEdge.isLeftOrRight(edge)) {
654: drawTickMarksVertical(g2, state, dataArea, edge);
655: }
656: }
657:
658:
667: protected void drawTickMarksHorizontal(Graphics2D g2, AxisState state,
668: Rectangle2D dataArea,
669: RectangleEdge edge) {
670: List ticks = new ArrayList();
671: double x0 = dataArea.getX();
672: double y0 = state.getCursor();
673: double insideLength = getTickMarkInsideLength();
674: double outsideLength = getTickMarkOutsideLength();
675: RegularTimePeriod t = RegularTimePeriod.createInstance(
676: this.majorTickTimePeriodClass, this.first.getStart(), getTimeZone()
677: );
678: long t0 = t.getFirstMillisecond(getTimeZone());
679: Line2D inside = null;
680: Line2D outside = null;
681: long firstOnAxis = getFirst().getFirstMillisecond(getTimeZone());
682: long lastOnAxis = getLast().getLastMillisecond(getTimeZone());
683: while (t0 <= lastOnAxis) {
684: ticks.add(new NumberTick(new Double(t0), "", TextAnchor.CENTER, TextAnchor.CENTER, 0.0));
685: x0 = valueToJava2D(t0, dataArea, edge);
686: if (edge == RectangleEdge.TOP) {
687: inside = new Line2D.Double(x0, y0, x0, y0 + insideLength);
688: outside = new Line2D.Double(x0, y0, x0, y0 - outsideLength);
689: }
690: else if (edge == RectangleEdge.BOTTOM) {
691: inside = new Line2D.Double(x0, y0, x0, y0 - insideLength);
692: outside = new Line2D.Double(x0, y0, x0, y0 + outsideLength);
693: }
694: if (t0 > firstOnAxis) {
695: g2.setPaint(getTickMarkPaint());
696: g2.setStroke(getTickMarkStroke());
697: g2.draw(inside);
698: g2.draw(outside);
699: }
700:
701: if (this.minorTickMarksVisible) {
702: RegularTimePeriod tminor = RegularTimePeriod.createInstance(
703: this.minorTickTimePeriodClass, new Date(t0), getTimeZone()
704: );
705: long tt0 = tminor.getFirstMillisecond(getTimeZone());
706: while (tt0 < t.getLastMillisecond(getTimeZone())
707: && tt0 < lastOnAxis) {
708: double xx0 = valueToJava2D(tt0, dataArea, edge);
709: if (edge == RectangleEdge.TOP) {
710: inside = new Line2D.Double(
711: xx0, y0, xx0, y0 + this.minorTickMarkInsideLength
712: );
713: outside = new Line2D.Double(
714: xx0, y0, xx0, y0 - this.minorTickMarkOutsideLength
715: );
716: }
717: else if (edge == RectangleEdge.BOTTOM) {
718: inside = new Line2D.Double(
719: xx0, y0, xx0, y0 - this.minorTickMarkInsideLength
720: );
721: outside = new Line2D.Double(
722: xx0, y0, xx0, y0 + this.minorTickMarkOutsideLength
723: );
724: }
725: if (tt0 >= firstOnAxis) {
726: g2.setPaint(this.minorTickMarkPaint);
727: g2.setStroke(this.minorTickMarkStroke);
728: g2.draw(inside);
729: g2.draw(outside);
730: }
731: tminor = tminor.next();
732: tt0 = tminor.getFirstMillisecond(getTimeZone());
733: }
734: }
735: t = t.next();
736: t0 = t.getFirstMillisecond(getTimeZone());
737: }
738: if (edge == RectangleEdge.TOP) {
739: state.cursorUp(
740: Math.max(outsideLength, this.minorTickMarkOutsideLength)
741: );
742: }
743: else if (edge == RectangleEdge.BOTTOM) {
744: state.cursorDown(
745: Math.max(outsideLength, this.minorTickMarkOutsideLength)
746: );
747: }
748: state.setTicks(ticks);
749: }
750:
751:
759: protected void drawTickMarksVertical(Graphics2D g2, AxisState state,
760: Rectangle2D dataArea,
761: RectangleEdge edge) {
762:
763: }
764:
765:
776: protected AxisState drawTickLabels(int band, Graphics2D g2, AxisState state,
777: Rectangle2D dataArea,
778: RectangleEdge edge) {
779:
780:
781: double delta1 = 0.0;
782: FontMetrics fm = g2.getFontMetrics(this.labelInfo[band].getLabelFont());
783: if (edge == RectangleEdge.BOTTOM) {
784: delta1 = this.labelInfo[band].getPadding().calculateTopOutset(
785: fm.getHeight()
786: );
787: }
788: else if (edge == RectangleEdge.TOP) {
789: delta1 = this.labelInfo[band].getPadding().calculateBottomOutset(
790: fm.getHeight()
791: );
792: }
793: state.moveCursor(delta1, edge);
794: long axisMin = this.first.getFirstMillisecond(this.timeZone);
795: long axisMax = this.last.getLastMillisecond(this.timeZone);
796: g2.setFont(this.labelInfo[band].getLabelFont());
797: g2.setPaint(this.labelInfo[band].getLabelPaint());
798:
799:
800: RegularTimePeriod p1 = this.labelInfo[band].createInstance(
801: new Date(axisMin), this.timeZone
802: );
803: RegularTimePeriod p2 = this.labelInfo[band].createInstance(
804: new Date(axisMax), this.timeZone
805: );
806: String label1 = this.labelInfo[band].getDateFormat().format(
807: new Date(p1.getMiddleMillisecond(this.timeZone))
808: );
809: String label2 = this.labelInfo[band].getDateFormat().format(
810: new Date(p2.getMiddleMillisecond(this.timeZone))
811: );
812: Rectangle2D b1 = TextUtilities.getTextBounds(
813: label1, g2, g2.getFontMetrics()
814: );
815: Rectangle2D b2 = TextUtilities.getTextBounds(
816: label2, g2, g2.getFontMetrics()
817: );
818: double w = Math.max(b1.getWidth(), b2.getWidth());
819: long ww = Math.round(
820: java2DToValue(dataArea.getX() + w + 5.0, dataArea, edge)
821: ) - axisMin;
822: long length = p1.getLastMillisecond(this.timeZone)
823: - p1.getFirstMillisecond(this.timeZone);
824: int periods = (int) (ww / length) + 1;
825:
826: RegularTimePeriod p = this.labelInfo[band].createInstance(
827: new Date(axisMin), this.timeZone
828: );
829: Rectangle2D b = null;
830: long lastXX = 0L;
831: float y = (float) (state.getCursor());
832: TextAnchor anchor = TextAnchor.TOP_CENTER;
833: float yDelta = (float) b1.getHeight();
834: if (edge == RectangleEdge.TOP) {
835: anchor = TextAnchor.BOTTOM_CENTER;
836: yDelta = -yDelta;
837: }
838: while (p.getFirstMillisecond(this.timeZone) <= axisMax) {
839: float x = (float) valueToJava2D(
840: p.getMiddleMillisecond(this.timeZone), dataArea, edge
841: );
842: DateFormat df = this.labelInfo[band].getDateFormat();
843: String label = df.format(
844: new Date(p.getMiddleMillisecond(this.timeZone))
845: );
846: long first = p.getFirstMillisecond(this.timeZone);
847: long last = p.getLastMillisecond(this.timeZone);
848: if (last > axisMax) {
849:
850:
851: Rectangle2D bb = TextUtilities.getTextBounds(
852: label, g2, g2.getFontMetrics()
853: );
854: if ((x + bb.getWidth() / 2) > dataArea.getMaxX()) {
855: float xstart = (float) valueToJava2D(
856: Math.max(first, axisMin), dataArea, edge
857: );
858: if (bb.getWidth() < (dataArea.getMaxX() - xstart)) {
859: x = ((float) dataArea.getMaxX() + xstart) / 2.0f;
860: }
861: else {
862: label = null;
863: }
864: }
865: }
866: if (first < axisMin) {
867:
868:
869: Rectangle2D bb = TextUtilities.getTextBounds(
870: label, g2, g2.getFontMetrics()
871: );
872: if ((x - bb.getWidth() / 2) < dataArea.getX()) {
873: float xlast = (float) valueToJava2D(
874: Math.min(last, axisMax), dataArea, edge
875: );
876: if (bb.getWidth() < (xlast - dataArea.getX())) {
877: x = (xlast + (float) dataArea.getX()) / 2.0f;
878: }
879: else {
880: label = null;
881: }
882: }
883:
884: }
885: if (label != null) {
886: g2.setPaint(this.labelInfo[band].getLabelPaint());
887: b = TextUtilities.drawAlignedString(label, g2, x, y, anchor);
888: }
889: if (lastXX > 0L) {
890: if (this.labelInfo[band].getDrawDividers()) {
891: long nextXX = p.getFirstMillisecond(this.timeZone);
892: long mid = (lastXX + nextXX) / 2;
893: float mid2d = (float) valueToJava2D(mid, dataArea, edge);
894: g2.setStroke(this.labelInfo[band].getDividerStroke());
895: g2.setPaint(this.labelInfo[band].getDividerPaint());
896: g2.draw(
897: new Line2D.Float(mid2d, y, mid2d, y + yDelta)
898: );
899: }
900: }
901: lastXX = last;
902: for (int i = 0; i < periods; i++) {
903: p = p.next();
904: }
905: }
906: double used = 0.0;
907: if (b != null) {
908: used = b.getHeight();
909:
910: if (edge == RectangleEdge.BOTTOM) {
911: used += this.labelInfo[band].getPadding().calculateBottomOutset(
912: fm.getHeight()
913: );
914: }
915: else if (edge == RectangleEdge.TOP) {
916: used += this.labelInfo[band].getPadding().calculateTopOutset(
917: fm.getHeight()
918: );
919: }
920: }
921: state.moveCursor(used, edge);
922: return state;
923: }
924:
925:
936: public List refreshTicks(Graphics2D g2,
937: AxisState state,
938: Rectangle2D dataArea,
939: RectangleEdge edge) {
940: return Collections.EMPTY_LIST;
941: }
942:
943:
955: public double valueToJava2D(double value,
956: Rectangle2D area,
957: RectangleEdge edge) {
958:
959: double result = Double.NaN;
960: double axisMin = this.first.getFirstMillisecond(this.timeZone);
961: double axisMax = this.last.getLastMillisecond(this.timeZone);
962: if (RectangleEdge.isTopOrBottom(edge)) {
963: double minX = area.getX();
964: double maxX = area.getMaxX();
965: if (isInverted()) {
966: result = maxX + ((value - axisMin) / (axisMax - axisMin))
967: * (minX - maxX);
968: }
969: else {
970: result = minX + ((value - axisMin) / (axisMax - axisMin))
971: * (maxX - minX);
972: }
973: }
974: else if (RectangleEdge.isLeftOrRight(edge)) {
975: double minY = area.getMinY();
976: double maxY = area.getMaxY();
977: if (isInverted()) {
978: result = minY + (((value - axisMin) / (axisMax - axisMin))
979: * (maxY - minY));
980: }
981: else {
982: result = maxY - (((value - axisMin) / (axisMax - axisMin))
983: * (maxY - minY));
984: }
985: }
986: return result;
987:
988: }
989:
990:
1000: public double java2DToValue(double java2DValue,
1001: Rectangle2D area,
1002: RectangleEdge edge) {
1003:
1004: double result = Double.NaN;
1005: double min = 0.0;
1006: double max = 0.0;
1007: double axisMin = this.first.getFirstMillisecond(this.timeZone);
1008: double axisMax = this.last.getLastMillisecond(this.timeZone);
1009: if (RectangleEdge.isTopOrBottom(edge)) {
1010: min = area.getX();
1011: max = area.getMaxX();
1012: }
1013: else if (RectangleEdge.isLeftOrRight(edge)) {
1014: min = area.getMaxY();
1015: max = area.getY();
1016: }
1017: if (isInverted()) {
1018: result = axisMax - ((java2DValue - min) / (max - min)
1019: * (axisMax - axisMin));
1020: }
1021: else {
1022: result = axisMin + ((java2DValue - min) / (max - min)
1023: * (axisMax - axisMin));
1024: }
1025: return result;
1026: }
1027:
1028:
1031: protected void autoAdjustRange() {
1032:
1033: Plot plot = getPlot();
1034: if (plot == null) {
1035: return;
1036: }
1037:
1038: if (plot instanceof ValueAxisPlot) {
1039: ValueAxisPlot vap = (ValueAxisPlot) plot;
1040:
1041: Range r = vap.getDataRange(this);
1042: if (r == null) {
1043: r = new Range(DEFAULT_LOWER_BOUND, DEFAULT_UPPER_BOUND);
1044: }
1045:
1046: long upper = Math.round(r.getUpperBound());
1047: long lower = Math.round(r.getLowerBound());
1048: this.first = createInstance(
1049: this.autoRangeTimePeriodClass, new Date(lower), this.timeZone
1050: );
1051: this.last = createInstance(
1052: this.autoRangeTimePeriodClass, new Date(upper), this.timeZone
1053: );
1054: setRange(r, false, false);
1055: }
1056:
1057: }
1058:
1059:
1066: public boolean equals(Object obj) {
1067: if (obj == this) {
1068: return true;
1069: }
1070: if (obj instanceof PeriodAxis && super.equals(obj)) {
1071: PeriodAxis that = (PeriodAxis) obj;
1072: if (!this.first.equals(that.first)) {
1073: return false;
1074: }
1075: if (!this.last.equals(that.last)) {
1076: return false;
1077: }
1078: if (!this.timeZone.equals(that.timeZone)) {
1079: return false;
1080: }
1081: if (!this.autoRangeTimePeriodClass.equals(
1082: that.autoRangeTimePeriodClass
1083: )) {
1084: return false;
1085: }
1086: if (!(isMinorTickMarksVisible()
1087: == that.isMinorTickMarksVisible())) {
1088: return false;
1089: }
1090: if (!this.majorTickTimePeriodClass.equals(
1091: that.majorTickTimePeriodClass)) {
1092: return false;
1093: }
1094: if (!this.minorTickTimePeriodClass.equals(
1095: that.minorTickTimePeriodClass)) {
1096: return false;
1097: }
1098: if (!this.minorTickMarkPaint.equals(that.minorTickMarkPaint)) {
1099: return false;
1100: }
1101: if (!this.minorTickMarkStroke.equals(that.minorTickMarkStroke)) {
1102: return false;
1103: }
1104: if (!Arrays.equals(this.labelInfo, that.labelInfo)) {
1105: return false;
1106: }
1107: return true;
1108: }
1109: return false;
1110: }
1111:
1112:
1117: public int hashCode() {
1118: if (getLabel() != null) {
1119: return getLabel().hashCode();
1120: }
1121: else {
1122: return 0;
1123: }
1124: }
1125:
1126:
1134: public Object clone() throws CloneNotSupportedException {
1135: PeriodAxis clone = (PeriodAxis) super.clone();
1136: clone.timeZone = (TimeZone) this.timeZone.clone();
1137: clone.labelInfo = new PeriodAxisLabelInfo[this.labelInfo.length];
1138: for (int i = 0; i < this.labelInfo.length; i++) {
1139: clone.labelInfo[i] = this.labelInfo[i];
1140:
1141: }
1142: return clone;
1143: }
1144:
1145:
1156: private RegularTimePeriod createInstance(Class periodClass,
1157: Date millisecond, TimeZone zone) {
1158: RegularTimePeriod result = null;
1159: try {
1160: Constructor c = periodClass.getDeclaredConstructor(
1161: new Class[] {Date.class, TimeZone.class}
1162: );
1163: result = (RegularTimePeriod) c.newInstance(
1164: new Object[] {millisecond, zone}
1165: );
1166: }
1167: catch (Exception e) {
1168:
1169: }
1170: return result;
1171: }
1172:
1173:
1180: private void writeObject(ObjectOutputStream stream) throws IOException {
1181: stream.defaultWriteObject();
1182: SerialUtilities.writeStroke(this.minorTickMarkStroke, stream);
1183: SerialUtilities.writePaint(this.minorTickMarkPaint, stream);
1184: }
1185:
1186:
1194: private void readObject(ObjectInputStream stream)
1195: throws IOException, ClassNotFoundException {
1196: stream.defaultReadObject();
1197: this.minorTickMarkStroke = SerialUtilities.readStroke(stream);
1198: this.minorTickMarkPaint = SerialUtilities.readPaint(stream);
1199: }
1200:
1201: }