1:
54:
55: package ;
56:
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: import ;
76: import ;
77: import ;
78: import ;
79:
80: import ;
81: import ;
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:
95:
101: public class PeriodAxis extends ValueAxis
102: implements Cloneable, PublicCloneable, Serializable {
103:
104:
105: private static final long serialVersionUID = 8353295532075872069L;
106:
107:
108: private RegularTimePeriod first;
109:
110:
111: private RegularTimePeriod last;
112:
113:
117: private TimeZone timeZone;
118:
119:
122: private Calendar calendar;
123:
124:
128: private Class autoRangeTimePeriodClass;
129:
130:
134: private Class majorTickTimePeriodClass;
135:
136:
140: private boolean minorTickMarksVisible;
141:
142:
146: private Class minorTickTimePeriodClass;
147:
148:
149: private float minorTickMarkInsideLength = 0.0f;
150:
151:
152: private float minorTickMarkOutsideLength = 2.0f;
153:
154:
155: private transient Stroke minorTickMarkStroke = new BasicStroke(0.5f);
156:
157:
158: private transient Paint minorTickMarkPaint = Color.black;
159:
160:
161: private PeriodAxisLabelInfo[] labelInfo;
162:
163:
168: public PeriodAxis(String label) {
169: this(label, new Day(), new Day());
170: }
171:
172:
181: public PeriodAxis(String label,
182: RegularTimePeriod first, RegularTimePeriod last) {
183: this(label, first, last, TimeZone.getDefault());
184: }
185:
186:
196: public PeriodAxis(String label,
197: RegularTimePeriod first, RegularTimePeriod last,
198: TimeZone timeZone) {
199:
200: super(label, null);
201: this.first = first;
202: this.last = last;
203: this.timeZone = timeZone;
204: this.calendar = Calendar.getInstance(timeZone);
205: this.autoRangeTimePeriodClass = first.getClass();
206: this.majorTickTimePeriodClass = first.getClass();
207: this.minorTickMarksVisible = false;
208: this.minorTickTimePeriodClass = RegularTimePeriod.downsize(
209: this.majorTickTimePeriodClass);
210: setAutoRange(true);
211: this.labelInfo = new PeriodAxisLabelInfo[2];
212: this.labelInfo[0] = new PeriodAxisLabelInfo(Month.class,
213: new SimpleDateFormat("MMM"));
214: this.labelInfo[1] = new PeriodAxisLabelInfo(Year.class,
215: new SimpleDateFormat("yyyy"));
216:
217: }
218:
219:
224: public RegularTimePeriod getFirst() {
225: return this.first;
226: }
227:
228:
234: public void setFirst(RegularTimePeriod first) {
235: if (first == null) {
236: throw new IllegalArgumentException("Null 'first' argument.");
237: }
238: this.first = first;
239: notifyListeners(new AxisChangeEvent(this));
240: }
241:
242:
247: public RegularTimePeriod getLast() {
248: return this.last;
249: }
250:
251:
257: public void setLast(RegularTimePeriod last) {
258: if (last == null) {
259: throw new IllegalArgumentException("Null 'last' argument.");
260: }
261: this.last = last;
262: notifyListeners(new AxisChangeEvent(this));
263: }
264:
265:
271: public TimeZone getTimeZone() {
272: return this.timeZone;
273: }
274:
275:
281: public void setTimeZone(TimeZone zone) {
282: if (zone == null) {
283: throw new IllegalArgumentException("Null 'zone' argument.");
284: }
285: this.timeZone = zone;
286: this.calendar = Calendar.getInstance(zone);
287: notifyListeners(new AxisChangeEvent(this));
288: }
289:
290:
296: public Class getAutoRangeTimePeriodClass() {
297: return this.autoRangeTimePeriodClass;
298: }
299:
300:
307: public void setAutoRangeTimePeriodClass(Class c) {
308: if (c == null) {
309: throw new IllegalArgumentException("Null 'c' argument.");
310: }
311: this.autoRangeTimePeriodClass = c;
312: notifyListeners(new AxisChangeEvent(this));
313: }
314:
315:
320: public Class getMajorTickTimePeriodClass() {
321: return this.majorTickTimePeriodClass;
322: }
323:
324:
331: public void setMajorTickTimePeriodClass(Class c) {
332: if (c == null) {
333: throw new IllegalArgumentException("Null 'c' argument.");
334: }
335: this.majorTickTimePeriodClass = c;
336: notifyListeners(new AxisChangeEvent(this));
337: }
338:
339:
345: public boolean isMinorTickMarksVisible() {
346: return this.minorTickMarksVisible;
347: }
348:
349:
356: public void setMinorTickMarksVisible(boolean visible) {
357: this.minorTickMarksVisible = visible;
358: notifyListeners(new AxisChangeEvent(this));
359: }
360:
361:
366: public Class getMinorTickTimePeriodClass() {
367: return this.minorTickTimePeriodClass;
368: }
369:
370:
377: public void setMinorTickTimePeriodClass(Class c) {
378: if (c == null) {
379: throw new IllegalArgumentException("Null 'c' argument.");
380: }
381: this.minorTickTimePeriodClass = c;
382: notifyListeners(new AxisChangeEvent(this));
383: }
384:
385:
391: public Stroke getMinorTickMarkStroke() {
392: return this.minorTickMarkStroke;
393: }
394:
395:
402: public void setMinorTickMarkStroke(Stroke stroke) {
403: if (stroke == null) {
404: throw new IllegalArgumentException("Null 'stroke' argument.");
405: }
406: this.minorTickMarkStroke = stroke;
407: notifyListeners(new AxisChangeEvent(this));
408: }
409:
410:
416: public Paint getMinorTickMarkPaint() {
417: return this.minorTickMarkPaint;
418: }
419:
420:
427: public void setMinorTickMarkPaint(Paint paint) {
428: if (paint == null) {
429: throw new IllegalArgumentException("Null 'paint' argument.");
430: }
431: this.minorTickMarkPaint = paint;
432: notifyListeners(new AxisChangeEvent(this));
433: }
434:
435:
440: public float getMinorTickMarkInsideLength() {
441: return this.minorTickMarkInsideLength;
442: }
443:
444:
450: public void setMinorTickMarkInsideLength(float length) {
451: this.minorTickMarkInsideLength = length;
452: notifyListeners(new AxisChangeEvent(this));
453: }
454:
455:
460: public float getMinorTickMarkOutsideLength() {
461: return this.minorTickMarkOutsideLength;
462: }
463:
464:
470: public void setMinorTickMarkOutsideLength(float length) {
471: this.minorTickMarkOutsideLength = length;
472: notifyListeners(new AxisChangeEvent(this));
473: }
474:
475:
480: public PeriodAxisLabelInfo[] getLabelInfo() {
481: return this.labelInfo;
482: }
483:
484:
489: public void setLabelInfo(PeriodAxisLabelInfo[] info) {
490: this.labelInfo = info;
491:
492: }
493:
494:
499: public Range getRange() {
500:
501: return new Range(this.first.getFirstMillisecond(this.calendar),
502: this.last.getLastMillisecond(this.calendar));
503: }
504:
505:
516: public void setRange(Range range, boolean turnOffAutoRange,
517: boolean notify) {
518: super.setRange(range, turnOffAutoRange, false);
519: long upper = Math.round(range.getUpperBound());
520: long lower = Math.round(range.getLowerBound());
521: this.first = createInstance(this.autoRangeTimePeriodClass,
522: new Date(lower), this.timeZone);
523: this.last = createInstance(this.autoRangeTimePeriodClass,
524: new Date(upper), this.timeZone);
525: }
526:
527:
531: public void configure() {
532: if (this.isAutoRange()) {
533: autoAdjustRange();
534: }
535: }
536:
537:
550: public AxisSpace reserveSpace(Graphics2D g2, Plot plot,
551: Rectangle2D plotArea, RectangleEdge edge,
552: AxisSpace space) {
553:
554: if (space == null) {
555: space = new AxisSpace();
556: }
557:
558:
559: if (!isVisible()) {
560: return space;
561: }
562:
563:
564: double dimension = getFixedDimension();
565: if (dimension > 0.0) {
566: space.ensureAtLeast(dimension, edge);
567: }
568:
569:
570: Rectangle2D labelEnclosure = getLabelEnclosure(g2, edge);
571: double labelHeight = 0.0;
572: double labelWidth = 0.0;
573: double tickLabelBandsDimension = 0.0;
574:
575: for (int i = 0; i < this.labelInfo.length; i++) {
576: PeriodAxisLabelInfo info = this.labelInfo[i];
577: FontMetrics fm = g2.getFontMetrics(info.getLabelFont());
578: tickLabelBandsDimension
579: += info.getPadding().extendHeight(fm.getHeight());
580: }
581:
582: if (RectangleEdge.isTopOrBottom(edge)) {
583: labelHeight = labelEnclosure.getHeight();
584: space.add(labelHeight + tickLabelBandsDimension, edge);
585: }
586: else if (RectangleEdge.isLeftOrRight(edge)) {
587: labelWidth = labelEnclosure.getWidth();
588: space.add(labelWidth + tickLabelBandsDimension, edge);
589: }
590:
591:
592: double tickMarkSpace = 0.0;
593: if (isTickMarksVisible()) {
594: tickMarkSpace = getTickMarkOutsideLength();
595: }
596: if (this.minorTickMarksVisible) {
597: tickMarkSpace = Math.max(tickMarkSpace,
598: this.minorTickMarkOutsideLength);
599: }
600: space.add(tickMarkSpace, edge);
601: return space;
602: }
603:
604:
618: public AxisState draw(Graphics2D g2,
619: double cursor,
620: Rectangle2D plotArea,
621: Rectangle2D dataArea,
622: RectangleEdge edge,
623: PlotRenderingInfo plotState) {
624:
625: AxisState axisState = new AxisState(cursor);
626: if (isAxisLineVisible()) {
627: drawAxisLine(g2, cursor, dataArea, edge);
628: }
629: drawTickMarks(g2, axisState, dataArea, edge);
630: for (int band = 0; band < this.labelInfo.length; band++) {
631: axisState = drawTickLabels(band, g2, axisState, dataArea, edge);
632: }
633:
634:
635:
636: axisState = drawLabel(getLabel(), g2, plotArea, dataArea, edge,
637: axisState);
638: return axisState;
639:
640: }
641:
642:
650: protected void drawTickMarks(Graphics2D g2, AxisState state,
651: Rectangle2D dataArea,
652: RectangleEdge edge) {
653: if (RectangleEdge.isTopOrBottom(edge)) {
654: drawTickMarksHorizontal(g2, state, dataArea, edge);
655: }
656: else if (RectangleEdge.isLeftOrRight(edge)) {
657: drawTickMarksVertical(g2, state, dataArea, edge);
658: }
659: }
660:
661:
670: protected void drawTickMarksHorizontal(Graphics2D g2, AxisState state,
671: Rectangle2D dataArea,
672: RectangleEdge edge) {
673: List ticks = new ArrayList();
674: double x0 = dataArea.getX();
675: double y0 = state.getCursor();
676: double insideLength = getTickMarkInsideLength();
677: double outsideLength = getTickMarkOutsideLength();
678: RegularTimePeriod t = RegularTimePeriod.createInstance(
679: this.majorTickTimePeriodClass, this.first.getStart(),
680: getTimeZone());
681: long t0 = t.getFirstMillisecond(this.calendar);
682: Line2D inside = null;
683: Line2D outside = null;
684: long firstOnAxis = getFirst().getFirstMillisecond(this.calendar);
685: long lastOnAxis = getLast().getLastMillisecond(this.calendar);
686: while (t0 <= lastOnAxis) {
687: ticks.add(new NumberTick(new Double(t0), "", TextAnchor.CENTER,
688: TextAnchor.CENTER, 0.0));
689: x0 = valueToJava2D(t0, dataArea, edge);
690: if (edge == RectangleEdge.TOP) {
691: inside = new Line2D.Double(x0, y0, x0, y0 + insideLength);
692: outside = new Line2D.Double(x0, y0, x0, y0 - outsideLength);
693: }
694: else if (edge == RectangleEdge.BOTTOM) {
695: inside = new Line2D.Double(x0, y0, x0, y0 - insideLength);
696: outside = new Line2D.Double(x0, y0, x0, y0 + outsideLength);
697: }
698: if (t0 > firstOnAxis) {
699: g2.setPaint(getTickMarkPaint());
700: g2.setStroke(getTickMarkStroke());
701: g2.draw(inside);
702: g2.draw(outside);
703: }
704:
705: if (this.minorTickMarksVisible) {
706: RegularTimePeriod tminor = RegularTimePeriod.createInstance(
707: this.minorTickTimePeriodClass, new Date(t0),
708: getTimeZone());
709: long tt0 = tminor.getFirstMillisecond(this.calendar);
710: while (tt0 < t.getLastMillisecond(this.calendar)
711: && tt0 < lastOnAxis) {
712: double xx0 = valueToJava2D(tt0, dataArea, edge);
713: if (edge == RectangleEdge.TOP) {
714: inside = new Line2D.Double(xx0, y0, xx0,
715: y0 + this.minorTickMarkInsideLength);
716: outside = new Line2D.Double(xx0, y0, xx0,
717: y0 - this.minorTickMarkOutsideLength);
718: }
719: else if (edge == RectangleEdge.BOTTOM) {
720: inside = new Line2D.Double(xx0, y0, xx0,
721: y0 - this.minorTickMarkInsideLength);
722: outside = new Line2D.Double(xx0, y0, xx0,
723: y0 + this.minorTickMarkOutsideLength);
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(this.calendar);
733: }
734: }
735: t = t.next();
736: t0 = t.getFirstMillisecond(this.calendar);
737: }
738: if (edge == RectangleEdge.TOP) {
739: state.cursorUp(Math.max(outsideLength,
740: this.minorTickMarkOutsideLength));
741: }
742: else if (edge == RectangleEdge.BOTTOM) {
743: state.cursorDown(Math.max(outsideLength,
744: this.minorTickMarkOutsideLength));
745: }
746: state.setTicks(ticks);
747: }
748:
749:
757: protected void drawTickMarksVertical(Graphics2D g2, AxisState state,
758: Rectangle2D dataArea,
759: RectangleEdge edge) {
760:
761: }
762:
763:
774: protected AxisState drawTickLabels(int band, Graphics2D g2, AxisState state,
775: Rectangle2D dataArea,
776: RectangleEdge edge) {
777:
778:
779: double delta1 = 0.0;
780: FontMetrics fm = g2.getFontMetrics(this.labelInfo[band].getLabelFont());
781: if (edge == RectangleEdge.BOTTOM) {
782: delta1 = this.labelInfo[band].getPadding().calculateTopOutset(
783: fm.getHeight());
784: }
785: else if (edge == RectangleEdge.TOP) {
786: delta1 = this.labelInfo[band].getPadding().calculateBottomOutset(
787: fm.getHeight());
788: }
789: state.moveCursor(delta1, edge);
790: long axisMin = this.first.getFirstMillisecond(this.calendar);
791: long axisMax = this.last.getLastMillisecond(this.calendar);
792: g2.setFont(this.labelInfo[band].getLabelFont());
793: g2.setPaint(this.labelInfo[band].getLabelPaint());
794:
795:
796: RegularTimePeriod p1 = this.labelInfo[band].createInstance(
797: new Date(axisMin), this.timeZone);
798: RegularTimePeriod p2 = this.labelInfo[band].createInstance(
799: new Date(axisMax), this.timeZone);
800: String label1 = this.labelInfo[band].getDateFormat().format(
801: new Date(p1.getMiddleMillisecond(this.calendar)));
802: String label2 = this.labelInfo[band].getDateFormat().format(
803: new Date(p2.getMiddleMillisecond(this.calendar)));
804: Rectangle2D b1 = TextUtilities.getTextBounds(label1, g2,
805: g2.getFontMetrics());
806: Rectangle2D b2 = TextUtilities.getTextBounds(label2, g2,
807: g2.getFontMetrics());
808: double w = Math.max(b1.getWidth(), b2.getWidth());
809: long ww = Math.round(java2DToValue(dataArea.getX() + w + 5.0,
810: dataArea, edge));
811: if (isInverted()) {
812: ww = axisMax - ww;
813: }
814: else {
815: ww = ww - axisMin;
816: }
817: long length = p1.getLastMillisecond(this.calendar)
818: - p1.getFirstMillisecond(this.calendar);
819: int periods = (int) (ww / length) + 1;
820:
821: RegularTimePeriod p = this.labelInfo[band].createInstance(
822: new Date(axisMin), this.timeZone);
823: Rectangle2D b = null;
824: long lastXX = 0L;
825: float y = (float) (state.getCursor());
826: TextAnchor anchor = TextAnchor.TOP_CENTER;
827: float yDelta = (float) b1.getHeight();
828: if (edge == RectangleEdge.TOP) {
829: anchor = TextAnchor.BOTTOM_CENTER;
830: yDelta = -yDelta;
831: }
832: while (p.getFirstMillisecond(this.calendar) <= axisMax) {
833: float x = (float) valueToJava2D(p.getMiddleMillisecond(
834: this.calendar), dataArea, edge);
835: DateFormat df = this.labelInfo[band].getDateFormat();
836: String label = df.format(new Date(p.getMiddleMillisecond(
837: this.calendar)));
838: long first = p.getFirstMillisecond(this.calendar);
839: long last = p.getLastMillisecond(this.calendar);
840: if (last > axisMax) {
841:
842:
843: Rectangle2D bb = TextUtilities.getTextBounds(label, g2,
844: g2.getFontMetrics());
845: if ((x + bb.getWidth() / 2) > dataArea.getMaxX()) {
846: float xstart = (float) valueToJava2D(Math.max(first,
847: axisMin), dataArea, edge);
848: if (bb.getWidth() < (dataArea.getMaxX() - xstart)) {
849: x = ((float) dataArea.getMaxX() + xstart) / 2.0f;
850: }
851: else {
852: label = null;
853: }
854: }
855: }
856: if (first < axisMin) {
857:
858:
859: Rectangle2D bb = TextUtilities.getTextBounds(label, g2,
860: g2.getFontMetrics());
861: if ((x - bb.getWidth() / 2) < dataArea.getX()) {
862: float xlast = (float) valueToJava2D(Math.min(last,
863: axisMax), dataArea, edge);
864: if (bb.getWidth() < (xlast - dataArea.getX())) {
865: x = (xlast + (float) dataArea.getX()) / 2.0f;
866: }
867: else {
868: label = null;
869: }
870: }
871:
872: }
873: if (label != null) {
874: g2.setPaint(this.labelInfo[band].getLabelPaint());
875: b = TextUtilities.drawAlignedString(label, g2, x, y, anchor);
876: }
877: if (lastXX > 0L) {
878: if (this.labelInfo[band].getDrawDividers()) {
879: long nextXX = p.getFirstMillisecond(this.calendar);
880: long mid = (lastXX + nextXX) / 2;
881: float mid2d = (float) valueToJava2D(mid, dataArea, edge);
882: g2.setStroke(this.labelInfo[band].getDividerStroke());
883: g2.setPaint(this.labelInfo[band].getDividerPaint());
884: g2.draw(new Line2D.Float(mid2d, y, mid2d, y + yDelta));
885: }
886: }
887: lastXX = last;
888: for (int i = 0; i < periods; i++) {
889: p = p.next();
890: }
891: }
892: double used = 0.0;
893: if (b != null) {
894: used = b.getHeight();
895:
896: if (edge == RectangleEdge.BOTTOM) {
897: used += this.labelInfo[band].getPadding().calculateBottomOutset(
898: fm.getHeight());
899: }
900: else if (edge == RectangleEdge.TOP) {
901: used += this.labelInfo[band].getPadding().calculateTopOutset(
902: fm.getHeight());
903: }
904: }
905: state.moveCursor(used, edge);
906: return state;
907: }
908:
909:
920: public List refreshTicks(Graphics2D g2,
921: AxisState state,
922: Rectangle2D dataArea,
923: RectangleEdge edge) {
924: return Collections.EMPTY_LIST;
925: }
926:
927:
939: public double valueToJava2D(double value,
940: Rectangle2D area,
941: RectangleEdge edge) {
942:
943: double result = Double.NaN;
944: double axisMin = this.first.getFirstMillisecond(this.calendar);
945: double axisMax = this.last.getLastMillisecond(this.calendar);
946: if (RectangleEdge.isTopOrBottom(edge)) {
947: double minX = area.getX();
948: double maxX = area.getMaxX();
949: if (isInverted()) {
950: result = maxX + ((value - axisMin) / (axisMax - axisMin))
951: * (minX - maxX);
952: }
953: else {
954: result = minX + ((value - axisMin) / (axisMax - axisMin))
955: * (maxX - minX);
956: }
957: }
958: else if (RectangleEdge.isLeftOrRight(edge)) {
959: double minY = area.getMinY();
960: double maxY = area.getMaxY();
961: if (isInverted()) {
962: result = minY + (((value - axisMin) / (axisMax - axisMin))
963: * (maxY - minY));
964: }
965: else {
966: result = maxY - (((value - axisMin) / (axisMax - axisMin))
967: * (maxY - minY));
968: }
969: }
970: return result;
971:
972: }
973:
974:
984: public double java2DToValue(double java2DValue,
985: Rectangle2D area,
986: RectangleEdge edge) {
987:
988: double result = Double.NaN;
989: double min = 0.0;
990: double max = 0.0;
991: double axisMin = this.first.getFirstMillisecond(this.calendar);
992: double axisMax = this.last.getLastMillisecond(this.calendar);
993: if (RectangleEdge.isTopOrBottom(edge)) {
994: min = area.getX();
995: max = area.getMaxX();
996: }
997: else if (RectangleEdge.isLeftOrRight(edge)) {
998: min = area.getMaxY();
999: max = area.getY();
1000: }
1001: if (isInverted()) {
1002: result = axisMax - ((java2DValue - min) / (max - min)
1003: * (axisMax - axisMin));
1004: }
1005: else {
1006: result = axisMin + ((java2DValue - min) / (max - min)
1007: * (axisMax - axisMin));
1008: }
1009: return result;
1010: }
1011:
1012:
1015: protected void autoAdjustRange() {
1016:
1017: Plot plot = getPlot();
1018: if (plot == null) {
1019: return;
1020: }
1021:
1022: if (plot instanceof ValueAxisPlot) {
1023: ValueAxisPlot vap = (ValueAxisPlot) plot;
1024:
1025: Range r = vap.getDataRange(this);
1026: if (r == null) {
1027: r = getDefaultAutoRange();
1028: }
1029:
1030: long upper = Math.round(r.getUpperBound());
1031: long lower = Math.round(r.getLowerBound());
1032: this.first = createInstance(this.autoRangeTimePeriodClass,
1033: new Date(lower), this.timeZone);
1034: this.last = createInstance(this.autoRangeTimePeriodClass,
1035: new Date(upper), this.timeZone);
1036: setRange(r, false, false);
1037: }
1038:
1039: }
1040:
1041:
1048: public boolean equals(Object obj) {
1049: if (obj == this) {
1050: return true;
1051: }
1052: if (obj instanceof PeriodAxis && super.equals(obj)) {
1053: PeriodAxis that = (PeriodAxis) obj;
1054: if (!this.first.equals(that.first)) {
1055: return false;
1056: }
1057: if (!this.last.equals(that.last)) {
1058: return false;
1059: }
1060: if (!this.timeZone.equals(that.timeZone)) {
1061: return false;
1062: }
1063: if (!this.autoRangeTimePeriodClass.equals(
1064: that.autoRangeTimePeriodClass)) {
1065: return false;
1066: }
1067: if (!(isMinorTickMarksVisible()
1068: == that.isMinorTickMarksVisible())) {
1069: return false;
1070: }
1071: if (!this.majorTickTimePeriodClass.equals(
1072: that.majorTickTimePeriodClass)) {
1073: return false;
1074: }
1075: if (!this.minorTickTimePeriodClass.equals(
1076: that.minorTickTimePeriodClass)) {
1077: return false;
1078: }
1079: if (!this.minorTickMarkPaint.equals(that.minorTickMarkPaint)) {
1080: return false;
1081: }
1082: if (!this.minorTickMarkStroke.equals(that.minorTickMarkStroke)) {
1083: return false;
1084: }
1085: if (!Arrays.equals(this.labelInfo, that.labelInfo)) {
1086: return false;
1087: }
1088: return true;
1089: }
1090: return false;
1091: }
1092:
1093:
1098: public int hashCode() {
1099: if (getLabel() != null) {
1100: return getLabel().hashCode();
1101: }
1102: else {
1103: return 0;
1104: }
1105: }
1106:
1107:
1115: public Object clone() throws CloneNotSupportedException {
1116: PeriodAxis clone = (PeriodAxis) super.clone();
1117: clone.timeZone = (TimeZone) this.timeZone.clone();
1118: clone.labelInfo = new PeriodAxisLabelInfo[this.labelInfo.length];
1119: for (int i = 0; i < this.labelInfo.length; i++) {
1120: clone.labelInfo[i] = this.labelInfo[i];
1121:
1122: }
1123: return clone;
1124: }
1125:
1126:
1137: private RegularTimePeriod createInstance(Class periodClass,
1138: Date millisecond, TimeZone zone) {
1139: RegularTimePeriod result = null;
1140: try {
1141: Constructor c = periodClass.getDeclaredConstructor(new Class[] {
1142: Date.class, TimeZone.class});
1143: result = (RegularTimePeriod) c.newInstance(new Object[] {
1144: millisecond, zone});
1145: }
1146: catch (Exception e) {
1147:
1148: }
1149: return result;
1150: }
1151:
1152:
1159: private void writeObject(ObjectOutputStream stream) throws IOException {
1160: stream.defaultWriteObject();
1161: SerialUtilities.writeStroke(this.minorTickMarkStroke, stream);
1162: SerialUtilities.writePaint(this.minorTickMarkPaint, stream);
1163: }
1164:
1165:
1173: private void readObject(ObjectInputStream stream)
1174: throws IOException, ClassNotFoundException {
1175: stream.defaultReadObject();
1176: this.minorTickMarkStroke = SerialUtilities.readStroke(stream);
1177: this.minorTickMarkPaint = SerialUtilities.readPaint(stream);
1178: }
1179:
1180: }