1:
56:
57: package ;
58:
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: import ;
76: import ;
77: import ;
78: import ;
79: import ;
80: import ;
81:
82: import ;
83: import ;
84: import ;
85: import ;
86: import ;
87: import ;
88: import ;
89: import ;
90: import ;
91: import ;
92: import ;
93: import ;
94: import ;
95: import ;
96:
97:
103: public class PeriodAxis extends ValueAxis
104: implements Cloneable, PublicCloneable, Serializable {
105:
106:
107: private static final long serialVersionUID = 8353295532075872069L;
108:
109:
110: private RegularTimePeriod first;
111:
112:
113: private RegularTimePeriod last;
114:
115:
119: private TimeZone timeZone;
120:
121:
124: private Calendar calendar;
125:
126:
130: private Class autoRangeTimePeriodClass;
131:
132:
136: private Class majorTickTimePeriodClass;
137:
138:
142: private boolean minorTickMarksVisible;
143:
144:
148: private Class minorTickTimePeriodClass;
149:
150:
151: private float minorTickMarkInsideLength = 0.0f;
152:
153:
154: private float minorTickMarkOutsideLength = 2.0f;
155:
156:
157: private transient Stroke minorTickMarkStroke = new BasicStroke(0.5f);
158:
159:
160: private transient Paint minorTickMarkPaint = Color.black;
161:
162:
163: private PeriodAxisLabelInfo[] labelInfo;
164:
165:
170: public PeriodAxis(String label) {
171: this(label, new Day(), new Day());
172: }
173:
174:
183: public PeriodAxis(String label,
184: RegularTimePeriod first, RegularTimePeriod last) {
185: this(label, first, last, TimeZone.getDefault());
186: }
187:
188:
198: public PeriodAxis(String label,
199: RegularTimePeriod first, RegularTimePeriod last,
200: TimeZone timeZone) {
201:
202: super(label, null);
203: this.first = first;
204: this.last = last;
205: this.timeZone = timeZone;
206:
207: this.calendar = Calendar.getInstance(timeZone);
208: this.autoRangeTimePeriodClass = first.getClass();
209: this.majorTickTimePeriodClass = first.getClass();
210: this.minorTickMarksVisible = false;
211: this.minorTickTimePeriodClass = RegularTimePeriod.downsize(
212: this.majorTickTimePeriodClass);
213: setAutoRange(true);
214: this.labelInfo = new PeriodAxisLabelInfo[2];
215: this.labelInfo[0] = new PeriodAxisLabelInfo(Month.class,
216: new SimpleDateFormat("MMM"));
217: this.labelInfo[1] = new PeriodAxisLabelInfo(Year.class,
218: new SimpleDateFormat("yyyy"));
219:
220: }
221:
222:
227: public RegularTimePeriod getFirst() {
228: return this.first;
229: }
230:
231:
237: public void setFirst(RegularTimePeriod first) {
238: if (first == null) {
239: throw new IllegalArgumentException("Null 'first' argument.");
240: }
241: this.first = first;
242: notifyListeners(new AxisChangeEvent(this));
243: }
244:
245:
250: public RegularTimePeriod getLast() {
251: return this.last;
252: }
253:
254:
260: public void setLast(RegularTimePeriod last) {
261: if (last == null) {
262: throw new IllegalArgumentException("Null 'last' argument.");
263: }
264: this.last = last;
265: notifyListeners(new AxisChangeEvent(this));
266: }
267:
268:
274: public TimeZone getTimeZone() {
275: return this.timeZone;
276: }
277:
278:
284: public void setTimeZone(TimeZone zone) {
285: if (zone == null) {
286: throw new IllegalArgumentException("Null 'zone' argument.");
287: }
288: this.timeZone = zone;
289:
290: this.calendar = Calendar.getInstance(zone);
291: notifyListeners(new AxisChangeEvent(this));
292: }
293:
294:
300: public Class getAutoRangeTimePeriodClass() {
301: return this.autoRangeTimePeriodClass;
302: }
303:
304:
311: public void setAutoRangeTimePeriodClass(Class c) {
312: if (c == null) {
313: throw new IllegalArgumentException("Null 'c' argument.");
314: }
315: this.autoRangeTimePeriodClass = c;
316: notifyListeners(new AxisChangeEvent(this));
317: }
318:
319:
324: public Class getMajorTickTimePeriodClass() {
325: return this.majorTickTimePeriodClass;
326: }
327:
328:
335: public void setMajorTickTimePeriodClass(Class c) {
336: if (c == null) {
337: throw new IllegalArgumentException("Null 'c' argument.");
338: }
339: this.majorTickTimePeriodClass = c;
340: notifyListeners(new AxisChangeEvent(this));
341: }
342:
343:
349: public boolean isMinorTickMarksVisible() {
350: return this.minorTickMarksVisible;
351: }
352:
353:
360: public void setMinorTickMarksVisible(boolean visible) {
361: this.minorTickMarksVisible = visible;
362: notifyListeners(new AxisChangeEvent(this));
363: }
364:
365:
370: public Class getMinorTickTimePeriodClass() {
371: return this.minorTickTimePeriodClass;
372: }
373:
374:
381: public void setMinorTickTimePeriodClass(Class c) {
382: if (c == null) {
383: throw new IllegalArgumentException("Null 'c' argument.");
384: }
385: this.minorTickTimePeriodClass = c;
386: notifyListeners(new AxisChangeEvent(this));
387: }
388:
389:
395: public Stroke getMinorTickMarkStroke() {
396: return this.minorTickMarkStroke;
397: }
398:
399:
406: public void setMinorTickMarkStroke(Stroke stroke) {
407: if (stroke == null) {
408: throw new IllegalArgumentException("Null 'stroke' argument.");
409: }
410: this.minorTickMarkStroke = stroke;
411: notifyListeners(new AxisChangeEvent(this));
412: }
413:
414:
420: public Paint getMinorTickMarkPaint() {
421: return this.minorTickMarkPaint;
422: }
423:
424:
431: public void setMinorTickMarkPaint(Paint paint) {
432: if (paint == null) {
433: throw new IllegalArgumentException("Null 'paint' argument.");
434: }
435: this.minorTickMarkPaint = paint;
436: notifyListeners(new AxisChangeEvent(this));
437: }
438:
439:
444: public float getMinorTickMarkInsideLength() {
445: return this.minorTickMarkInsideLength;
446: }
447:
448:
454: public void setMinorTickMarkInsideLength(float length) {
455: this.minorTickMarkInsideLength = length;
456: notifyListeners(new AxisChangeEvent(this));
457: }
458:
459:
464: public float getMinorTickMarkOutsideLength() {
465: return this.minorTickMarkOutsideLength;
466: }
467:
468:
474: public void setMinorTickMarkOutsideLength(float length) {
475: this.minorTickMarkOutsideLength = length;
476: notifyListeners(new AxisChangeEvent(this));
477: }
478:
479:
484: public PeriodAxisLabelInfo[] getLabelInfo() {
485: return this.labelInfo;
486: }
487:
488:
493: public void setLabelInfo(PeriodAxisLabelInfo[] info) {
494: this.labelInfo = info;
495:
496: }
497:
498:
503: public Range getRange() {
504:
505: return new Range(this.first.getFirstMillisecond(this.calendar),
506: this.last.getLastMillisecond(this.calendar));
507: }
508:
509:
520: public void setRange(Range range, boolean turnOffAutoRange,
521: boolean notify) {
522: super.setRange(range, turnOffAutoRange, false);
523: long upper = Math.round(range.getUpperBound());
524: long lower = Math.round(range.getLowerBound());
525: this.first = createInstance(this.autoRangeTimePeriodClass,
526: new Date(lower), this.timeZone);
527: this.last = createInstance(this.autoRangeTimePeriodClass,
528: new Date(upper), this.timeZone);
529: if (notify) {
530: notifyListeners(new AxisChangeEvent(this));
531: }
532: }
533:
534:
538: public void configure() {
539: if (this.isAutoRange()) {
540: autoAdjustRange();
541: }
542: }
543:
544:
557: public AxisSpace reserveSpace(Graphics2D g2, Plot plot,
558: Rectangle2D plotArea, RectangleEdge edge,
559: AxisSpace space) {
560:
561: if (space == null) {
562: space = new AxisSpace();
563: }
564:
565:
566: if (!isVisible()) {
567: return space;
568: }
569:
570:
571: double dimension = getFixedDimension();
572: if (dimension > 0.0) {
573: space.ensureAtLeast(dimension, edge);
574: }
575:
576:
577: Rectangle2D labelEnclosure = getLabelEnclosure(g2, edge);
578: double labelHeight = 0.0;
579: double labelWidth = 0.0;
580: double tickLabelBandsDimension = 0.0;
581:
582: for (int i = 0; i < this.labelInfo.length; i++) {
583: PeriodAxisLabelInfo info = this.labelInfo[i];
584: FontMetrics fm = g2.getFontMetrics(info.getLabelFont());
585: tickLabelBandsDimension
586: += info.getPadding().extendHeight(fm.getHeight());
587: }
588:
589: if (RectangleEdge.isTopOrBottom(edge)) {
590: labelHeight = labelEnclosure.getHeight();
591: space.add(labelHeight + tickLabelBandsDimension, edge);
592: }
593: else if (RectangleEdge.isLeftOrRight(edge)) {
594: labelWidth = labelEnclosure.getWidth();
595: space.add(labelWidth + tickLabelBandsDimension, edge);
596: }
597:
598:
599: double tickMarkSpace = 0.0;
600: if (isTickMarksVisible()) {
601: tickMarkSpace = getTickMarkOutsideLength();
602: }
603: if (this.minorTickMarksVisible) {
604: tickMarkSpace = Math.max(tickMarkSpace,
605: this.minorTickMarkOutsideLength);
606: }
607: space.add(tickMarkSpace, edge);
608: return space;
609: }
610:
611:
625: public AxisState draw(Graphics2D g2,
626: double cursor,
627: Rectangle2D plotArea,
628: Rectangle2D dataArea,
629: RectangleEdge edge,
630: PlotRenderingInfo plotState) {
631:
632: AxisState axisState = new AxisState(cursor);
633: if (isAxisLineVisible()) {
634: drawAxisLine(g2, cursor, dataArea, edge);
635: }
636: drawTickMarks(g2, axisState, dataArea, edge);
637: for (int band = 0; band < this.labelInfo.length; band++) {
638: axisState = drawTickLabels(band, g2, axisState, dataArea, edge);
639: }
640:
641:
642:
643: axisState = drawLabel(getLabel(), g2, plotArea, dataArea, edge,
644: axisState);
645: return axisState;
646:
647: }
648:
649:
657: protected void drawTickMarks(Graphics2D g2, AxisState state,
658: Rectangle2D dataArea,
659: RectangleEdge edge) {
660: if (RectangleEdge.isTopOrBottom(edge)) {
661: drawTickMarksHorizontal(g2, state, dataArea, edge);
662: }
663: else if (RectangleEdge.isLeftOrRight(edge)) {
664: drawTickMarksVertical(g2, state, dataArea, edge);
665: }
666: }
667:
668:
677: protected void drawTickMarksHorizontal(Graphics2D g2, AxisState state,
678: Rectangle2D dataArea,
679: RectangleEdge edge) {
680: List ticks = new ArrayList();
681: double x0 = dataArea.getX();
682: double y0 = state.getCursor();
683: double insideLength = getTickMarkInsideLength();
684: double outsideLength = getTickMarkOutsideLength();
685: RegularTimePeriod t = RegularTimePeriod.createInstance(
686: this.majorTickTimePeriodClass, this.first.getStart(),
687: getTimeZone());
688: long t0 = t.getFirstMillisecond(this.calendar);
689: Line2D inside = null;
690: Line2D outside = null;
691: long firstOnAxis = getFirst().getFirstMillisecond(this.calendar);
692: long lastOnAxis = getLast().getLastMillisecond(this.calendar);
693: while (t0 <= lastOnAxis) {
694: ticks.add(new NumberTick(new Double(t0), "", TextAnchor.CENTER,
695: TextAnchor.CENTER, 0.0));
696: x0 = valueToJava2D(t0, dataArea, edge);
697: if (edge == RectangleEdge.TOP) {
698: inside = new Line2D.Double(x0, y0, x0, y0 + insideLength);
699: outside = new Line2D.Double(x0, y0, x0, y0 - outsideLength);
700: }
701: else if (edge == RectangleEdge.BOTTOM) {
702: inside = new Line2D.Double(x0, y0, x0, y0 - insideLength);
703: outside = new Line2D.Double(x0, y0, x0, y0 + outsideLength);
704: }
705: if (t0 > firstOnAxis) {
706: g2.setPaint(getTickMarkPaint());
707: g2.setStroke(getTickMarkStroke());
708: g2.draw(inside);
709: g2.draw(outside);
710: }
711:
712: if (this.minorTickMarksVisible) {
713: RegularTimePeriod tminor = RegularTimePeriod.createInstance(
714: this.minorTickTimePeriodClass, new Date(t0),
715: getTimeZone());
716: long tt0 = tminor.getFirstMillisecond(this.calendar);
717: while (tt0 < t.getLastMillisecond(this.calendar)
718: && tt0 < lastOnAxis) {
719: double xx0 = valueToJava2D(tt0, dataArea, edge);
720: if (edge == RectangleEdge.TOP) {
721: inside = new Line2D.Double(xx0, y0, xx0,
722: y0 + this.minorTickMarkInsideLength);
723: outside = new Line2D.Double(xx0, y0, xx0,
724: y0 - this.minorTickMarkOutsideLength);
725: }
726: else if (edge == RectangleEdge.BOTTOM) {
727: inside = new Line2D.Double(xx0, y0, xx0,
728: y0 - this.minorTickMarkInsideLength);
729: outside = new Line2D.Double(xx0, y0, xx0,
730: y0 + this.minorTickMarkOutsideLength);
731: }
732: if (tt0 >= firstOnAxis) {
733: g2.setPaint(this.minorTickMarkPaint);
734: g2.setStroke(this.minorTickMarkStroke);
735: g2.draw(inside);
736: g2.draw(outside);
737: }
738: tminor = tminor.next();
739: tt0 = tminor.getFirstMillisecond(this.calendar);
740: }
741: }
742: t = t.next();
743: t0 = t.getFirstMillisecond(this.calendar);
744: }
745: if (edge == RectangleEdge.TOP) {
746: state.cursorUp(Math.max(outsideLength,
747: this.minorTickMarkOutsideLength));
748: }
749: else if (edge == RectangleEdge.BOTTOM) {
750: state.cursorDown(Math.max(outsideLength,
751: this.minorTickMarkOutsideLength));
752: }
753: state.setTicks(ticks);
754: }
755:
756:
764: protected void drawTickMarksVertical(Graphics2D g2, AxisState state,
765: Rectangle2D dataArea,
766: RectangleEdge edge) {
767:
768: }
769:
770:
781: protected AxisState drawTickLabels(int band, Graphics2D g2, AxisState state,
782: Rectangle2D dataArea,
783: RectangleEdge edge) {
784:
785:
786: double delta1 = 0.0;
787: FontMetrics fm = g2.getFontMetrics(this.labelInfo[band].getLabelFont());
788: if (edge == RectangleEdge.BOTTOM) {
789: delta1 = this.labelInfo[band].getPadding().calculateTopOutset(
790: fm.getHeight());
791: }
792: else if (edge == RectangleEdge.TOP) {
793: delta1 = this.labelInfo[band].getPadding().calculateBottomOutset(
794: fm.getHeight());
795: }
796: state.moveCursor(delta1, edge);
797: long axisMin = this.first.getFirstMillisecond(this.calendar);
798: long axisMax = this.last.getLastMillisecond(this.calendar);
799: g2.setFont(this.labelInfo[band].getLabelFont());
800: g2.setPaint(this.labelInfo[band].getLabelPaint());
801:
802:
803: RegularTimePeriod p1 = this.labelInfo[band].createInstance(
804: new Date(axisMin), this.timeZone);
805: RegularTimePeriod p2 = this.labelInfo[band].createInstance(
806: new Date(axisMax), this.timeZone);
807: String label1 = this.labelInfo[band].getDateFormat().format(
808: new Date(p1.getMiddleMillisecond(this.calendar)));
809: String label2 = this.labelInfo[band].getDateFormat().format(
810: new Date(p2.getMiddleMillisecond(this.calendar)));
811: Rectangle2D b1 = TextUtilities.getTextBounds(label1, g2,
812: g2.getFontMetrics());
813: Rectangle2D b2 = TextUtilities.getTextBounds(label2, g2,
814: g2.getFontMetrics());
815: double w = Math.max(b1.getWidth(), b2.getWidth());
816: long ww = Math.round(java2DToValue(dataArea.getX() + w + 5.0,
817: dataArea, edge));
818: if (isInverted()) {
819: ww = axisMax - ww;
820: }
821: else {
822: ww = ww - axisMin;
823: }
824: long length = p1.getLastMillisecond(this.calendar)
825: - p1.getFirstMillisecond(this.calendar);
826: int periods = (int) (ww / length) + 1;
827:
828: RegularTimePeriod p = this.labelInfo[band].createInstance(
829: new Date(axisMin), this.timeZone);
830: Rectangle2D b = null;
831: long lastXX = 0L;
832: float y = (float) (state.getCursor());
833: TextAnchor anchor = TextAnchor.TOP_CENTER;
834: float yDelta = (float) b1.getHeight();
835: if (edge == RectangleEdge.TOP) {
836: anchor = TextAnchor.BOTTOM_CENTER;
837: yDelta = -yDelta;
838: }
839: while (p.getFirstMillisecond(this.calendar) <= axisMax) {
840: float x = (float) valueToJava2D(p.getMiddleMillisecond(
841: this.calendar), dataArea, edge);
842: DateFormat df = this.labelInfo[band].getDateFormat();
843: String label = df.format(new Date(p.getMiddleMillisecond(
844: this.calendar)));
845: long first = p.getFirstMillisecond(this.calendar);
846: long last = p.getLastMillisecond(this.calendar);
847: if (last > axisMax) {
848:
849:
850: Rectangle2D bb = TextUtilities.getTextBounds(label, g2,
851: g2.getFontMetrics());
852: if ((x + bb.getWidth() / 2) > dataArea.getMaxX()) {
853: float xstart = (float) valueToJava2D(Math.max(first,
854: axisMin), dataArea, edge);
855: if (bb.getWidth() < (dataArea.getMaxX() - xstart)) {
856: x = ((float) dataArea.getMaxX() + xstart) / 2.0f;
857: }
858: else {
859: label = null;
860: }
861: }
862: }
863: if (first < axisMin) {
864:
865:
866: Rectangle2D bb = TextUtilities.getTextBounds(label, g2,
867: g2.getFontMetrics());
868: if ((x - bb.getWidth() / 2) < dataArea.getX()) {
869: float xlast = (float) valueToJava2D(Math.min(last,
870: axisMax), dataArea, edge);
871: if (bb.getWidth() < (xlast - dataArea.getX())) {
872: x = (xlast + (float) dataArea.getX()) / 2.0f;
873: }
874: else {
875: label = null;
876: }
877: }
878:
879: }
880: if (label != null) {
881: g2.setPaint(this.labelInfo[band].getLabelPaint());
882: b = TextUtilities.drawAlignedString(label, g2, x, y, anchor);
883: }
884: if (lastXX > 0L) {
885: if (this.labelInfo[band].getDrawDividers()) {
886: long nextXX = p.getFirstMillisecond(this.calendar);
887: long mid = (lastXX + nextXX) / 2;
888: float mid2d = (float) valueToJava2D(mid, dataArea, edge);
889: g2.setStroke(this.labelInfo[band].getDividerStroke());
890: g2.setPaint(this.labelInfo[band].getDividerPaint());
891: g2.draw(new Line2D.Float(mid2d, y, mid2d, y + yDelta));
892: }
893: }
894: lastXX = last;
895: for (int i = 0; i < periods; i++) {
896: p = p.next();
897: }
898: }
899: double used = 0.0;
900: if (b != null) {
901: used = b.getHeight();
902:
903: if (edge == RectangleEdge.BOTTOM) {
904: used += this.labelInfo[band].getPadding().calculateBottomOutset(
905: fm.getHeight());
906: }
907: else if (edge == RectangleEdge.TOP) {
908: used += this.labelInfo[band].getPadding().calculateTopOutset(
909: fm.getHeight());
910: }
911: }
912: state.moveCursor(used, edge);
913: return state;
914: }
915:
916:
927: public List refreshTicks(Graphics2D g2,
928: AxisState state,
929: Rectangle2D dataArea,
930: RectangleEdge edge) {
931: return Collections.EMPTY_LIST;
932: }
933:
934:
946: public double valueToJava2D(double value,
947: Rectangle2D area,
948: RectangleEdge edge) {
949:
950: double result = Double.NaN;
951: double axisMin = this.first.getFirstMillisecond(this.calendar);
952: double axisMax = this.last.getLastMillisecond(this.calendar);
953: if (RectangleEdge.isTopOrBottom(edge)) {
954: double minX = area.getX();
955: double maxX = area.getMaxX();
956: if (isInverted()) {
957: result = maxX + ((value - axisMin) / (axisMax - axisMin))
958: * (minX - maxX);
959: }
960: else {
961: result = minX + ((value - axisMin) / (axisMax - axisMin))
962: * (maxX - minX);
963: }
964: }
965: else if (RectangleEdge.isLeftOrRight(edge)) {
966: double minY = area.getMinY();
967: double maxY = area.getMaxY();
968: if (isInverted()) {
969: result = minY + (((value - axisMin) / (axisMax - axisMin))
970: * (maxY - minY));
971: }
972: else {
973: result = maxY - (((value - axisMin) / (axisMax - axisMin))
974: * (maxY - minY));
975: }
976: }
977: return result;
978:
979: }
980:
981:
991: public double java2DToValue(double java2DValue,
992: Rectangle2D area,
993: RectangleEdge edge) {
994:
995: double result = Double.NaN;
996: double min = 0.0;
997: double max = 0.0;
998: double axisMin = this.first.getFirstMillisecond(this.calendar);
999: double axisMax = this.last.getLastMillisecond(this.calendar);
1000: if (RectangleEdge.isTopOrBottom(edge)) {
1001: min = area.getX();
1002: max = area.getMaxX();
1003: }
1004: else if (RectangleEdge.isLeftOrRight(edge)) {
1005: min = area.getMaxY();
1006: max = area.getY();
1007: }
1008: if (isInverted()) {
1009: result = axisMax - ((java2DValue - min) / (max - min)
1010: * (axisMax - axisMin));
1011: }
1012: else {
1013: result = axisMin + ((java2DValue - min) / (max - min)
1014: * (axisMax - axisMin));
1015: }
1016: return result;
1017: }
1018:
1019:
1022: protected void autoAdjustRange() {
1023:
1024: Plot plot = getPlot();
1025: if (plot == null) {
1026: return;
1027: }
1028:
1029: if (plot instanceof ValueAxisPlot) {
1030: ValueAxisPlot vap = (ValueAxisPlot) plot;
1031:
1032: Range r = vap.getDataRange(this);
1033: if (r == null) {
1034: r = getDefaultAutoRange();
1035: }
1036:
1037: long upper = Math.round(r.getUpperBound());
1038: long lower = Math.round(r.getLowerBound());
1039: this.first = createInstance(this.autoRangeTimePeriodClass,
1040: new Date(lower), this.timeZone);
1041: this.last = createInstance(this.autoRangeTimePeriodClass,
1042: new Date(upper), this.timeZone);
1043: setRange(r, false, false);
1044: }
1045:
1046: }
1047:
1048:
1055: public boolean equals(Object obj) {
1056: if (obj == this) {
1057: return true;
1058: }
1059: if (obj instanceof PeriodAxis && super.equals(obj)) {
1060: PeriodAxis that = (PeriodAxis) obj;
1061: if (!this.first.equals(that.first)) {
1062: return false;
1063: }
1064: if (!this.last.equals(that.last)) {
1065: return false;
1066: }
1067: if (!this.timeZone.equals(that.timeZone)) {
1068: return false;
1069: }
1070: if (!this.autoRangeTimePeriodClass.equals(
1071: that.autoRangeTimePeriodClass)) {
1072: return false;
1073: }
1074: if (!(isMinorTickMarksVisible()
1075: == that.isMinorTickMarksVisible())) {
1076: return false;
1077: }
1078: if (!this.majorTickTimePeriodClass.equals(
1079: that.majorTickTimePeriodClass)) {
1080: return false;
1081: }
1082: if (!this.minorTickTimePeriodClass.equals(
1083: that.minorTickTimePeriodClass)) {
1084: return false;
1085: }
1086: if (!this.minorTickMarkPaint.equals(that.minorTickMarkPaint)) {
1087: return false;
1088: }
1089: if (!this.minorTickMarkStroke.equals(that.minorTickMarkStroke)) {
1090: return false;
1091: }
1092: if (!Arrays.equals(this.labelInfo, that.labelInfo)) {
1093: return false;
1094: }
1095: return true;
1096: }
1097: return false;
1098: }
1099:
1100:
1105: public int hashCode() {
1106: if (getLabel() != null) {
1107: return getLabel().hashCode();
1108: }
1109: else {
1110: return 0;
1111: }
1112: }
1113:
1114:
1122: public Object clone() throws CloneNotSupportedException {
1123: PeriodAxis clone = (PeriodAxis) super.clone();
1124: clone.timeZone = (TimeZone) this.timeZone.clone();
1125: clone.labelInfo = new PeriodAxisLabelInfo[this.labelInfo.length];
1126: for (int i = 0; i < this.labelInfo.length; i++) {
1127: clone.labelInfo[i] = this.labelInfo[i];
1128:
1129: }
1130: return clone;
1131: }
1132:
1133:
1144: private RegularTimePeriod createInstance(Class periodClass,
1145: Date millisecond, TimeZone zone) {
1146: RegularTimePeriod result = null;
1147: try {
1148: Constructor c = periodClass.getDeclaredConstructor(new Class[] {
1149: Date.class, TimeZone.class});
1150: result = (RegularTimePeriod) c.newInstance(new Object[] {
1151: millisecond, zone});
1152: }
1153: catch (Exception e) {
1154:
1155: }
1156: return result;
1157: }
1158:
1159:
1166: private void writeObject(ObjectOutputStream stream) throws IOException {
1167: stream.defaultWriteObject();
1168: SerialUtilities.writeStroke(this.minorTickMarkStroke, stream);
1169: SerialUtilities.writePaint(this.minorTickMarkPaint, stream);
1170: }
1171:
1172:
1180: private void readObject(ObjectInputStream stream)
1181: throws IOException, ClassNotFoundException {
1182: stream.defaultReadObject();
1183: this.minorTickMarkStroke = SerialUtilities.readStroke(stream);
1184: this.minorTickMarkPaint = SerialUtilities.readPaint(stream);
1185: }
1186:
1187: }