1 54 55 package org.jfree.chart.axis; 56 57 import java.awt.BasicStroke ; 58 import java.awt.Color ; 59 import java.awt.FontMetrics ; 60 import java.awt.Graphics2D ; 61 import java.awt.Paint ; 62 import java.awt.Stroke ; 63 import java.awt.geom.Line2D ; 64 import java.awt.geom.Rectangle2D ; 65 import java.io.IOException ; 66 import java.io.ObjectInputStream ; 67 import java.io.ObjectOutputStream ; 68 import java.io.Serializable ; 69 import java.lang.reflect.Constructor ; 70 import java.text.DateFormat ; 71 import java.text.SimpleDateFormat ; 72 import java.util.ArrayList ; 73 import java.util.Arrays ; 74 import java.util.Calendar ; 75 import java.util.Collections ; 76 import java.util.Date ; 77 import java.util.List ; 78 import java.util.TimeZone ; 79 80 import org.jfree.chart.event.AxisChangeEvent; 81 import org.jfree.chart.plot.Plot; 82 import org.jfree.chart.plot.PlotRenderingInfo; 83 import org.jfree.chart.plot.ValueAxisPlot; 84 import org.jfree.data.Range; 85 import org.jfree.data.time.Day; 86 import org.jfree.data.time.Month; 87 import org.jfree.data.time.RegularTimePeriod; 88 import org.jfree.data.time.Year; 89 import org.jfree.io.SerialUtilities; 90 import org.jfree.text.TextUtilities; 91 import org.jfree.ui.RectangleEdge; 92 import org.jfree.ui.TextAnchor; 93 import org.jfree.util.PublicCloneable; 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 498 public Range getRange() { 499 return new Range(this.first.getFirstMillisecond(this.calendar), 501 this.last.getLastMillisecond(this.calendar)); 502 } 503 504 515 public void setRange(Range range, boolean turnOffAutoRange, 516 boolean notify) { 517 super.setRange(range, turnOffAutoRange, false); 518 long upper = Math.round(range.getUpperBound()); 519 long lower = Math.round(range.getLowerBound()); 520 this.first = createInstance(this.autoRangeTimePeriodClass, 521 new Date (lower), this.timeZone); 522 this.last = createInstance(this.autoRangeTimePeriodClass, 523 new Date (upper), this.timeZone); 524 } 525 526 530 public void configure() { 531 if (this.isAutoRange()) { 532 autoAdjustRange(); 533 } 534 } 535 536 549 public AxisSpace reserveSpace(Graphics2D g2, Plot plot, 550 Rectangle2D plotArea, RectangleEdge edge, 551 AxisSpace space) { 552 if (space == null) { 554 space = new AxisSpace(); 555 } 556 557 if (!isVisible()) { 559 return space; 560 } 561 562 double dimension = getFixedDimension(); 564 if (dimension > 0.0) { 565 space.ensureAtLeast(dimension, edge); 566 } 567 568 Rectangle2D labelEnclosure = getLabelEnclosure(g2, edge); 570 double labelHeight = 0.0; 571 double labelWidth = 0.0; 572 double tickLabelBandsDimension = 0.0; 573 574 for (int i = 0; i < this.labelInfo.length; i++) { 575 PeriodAxisLabelInfo info = this.labelInfo[i]; 576 FontMetrics fm = g2.getFontMetrics(info.getLabelFont()); 577 tickLabelBandsDimension 578 += info.getPadding().extendHeight(fm.getHeight()); 579 } 580 581 if (RectangleEdge.isTopOrBottom(edge)) { 582 labelHeight = labelEnclosure.getHeight(); 583 space.add(labelHeight + tickLabelBandsDimension, edge); 584 } 585 else if (RectangleEdge.isLeftOrRight(edge)) { 586 labelWidth = labelEnclosure.getWidth(); 587 space.add(labelWidth + tickLabelBandsDimension, edge); 588 } 589 590 double tickMarkSpace = 0.0; 592 if (isTickMarksVisible()) { 593 tickMarkSpace = getTickMarkOutsideLength(); 594 } 595 if (this.minorTickMarksVisible) { 596 tickMarkSpace = Math.max(tickMarkSpace, 597 this.minorTickMarkOutsideLength); 598 } 599 space.add(tickMarkSpace, edge); 600 return space; 601 } 602 603 617 public AxisState draw(Graphics2D g2, 618 double cursor, 619 Rectangle2D plotArea, 620 Rectangle2D dataArea, 621 RectangleEdge edge, 622 PlotRenderingInfo plotState) { 623 624 AxisState axisState = new AxisState(cursor); 625 if (isAxisLineVisible()) { 626 drawAxisLine(g2, cursor, dataArea, edge); 627 } 628 drawTickMarks(g2, axisState, dataArea, edge); 629 for (int band = 0; band < this.labelInfo.length; band++) { 630 axisState = drawTickLabels(band, g2, axisState, dataArea, edge); 631 } 632 633 axisState = drawLabel(getLabel(), g2, plotArea, dataArea, edge, 636 axisState); 637 return axisState; 638 639 } 640 641 649 protected void drawTickMarks(Graphics2D g2, AxisState state, 650 Rectangle2D dataArea, 651 RectangleEdge edge) { 652 if (RectangleEdge.isTopOrBottom(edge)) { 653 drawTickMarksHorizontal(g2, state, dataArea, edge); 654 } 655 else if (RectangleEdge.isLeftOrRight(edge)) { 656 drawTickMarksVertical(g2, state, dataArea, edge); 657 } 658 } 659 660 669 protected void drawTickMarksHorizontal(Graphics2D g2, AxisState state, 670 Rectangle2D dataArea, 671 RectangleEdge edge) { 672 List ticks = new ArrayList (); 673 double x0 = dataArea.getX(); 674 double y0 = state.getCursor(); 675 double insideLength = getTickMarkInsideLength(); 676 double outsideLength = getTickMarkOutsideLength(); 677 RegularTimePeriod t = RegularTimePeriod.createInstance( 678 this.majorTickTimePeriodClass, this.first.getStart(), 679 getTimeZone()); 680 long t0 = t.getFirstMillisecond(this.calendar); 681 Line2D inside = null; 682 Line2D outside = null; 683 long firstOnAxis = getFirst().getFirstMillisecond(this.calendar); 684 long lastOnAxis = getLast().getLastMillisecond(this.calendar); 685 while (t0 <= lastOnAxis) { 686 ticks.add(new NumberTick(new Double (t0), "", TextAnchor.CENTER, 687 TextAnchor.CENTER, 0.0)); 688 x0 = valueToJava2D(t0, dataArea, edge); 689 if (edge == RectangleEdge.TOP) { 690 inside = new Line2D.Double (x0, y0, x0, y0 + insideLength); 691 outside = new Line2D.Double (x0, y0, x0, y0 - outsideLength); 692 } 693 else if (edge == RectangleEdge.BOTTOM) { 694 inside = new Line2D.Double (x0, y0, x0, y0 - insideLength); 695 outside = new Line2D.Double (x0, y0, x0, y0 + outsideLength); 696 } 697 if (t0 > firstOnAxis) { 698 g2.setPaint(getTickMarkPaint()); 699 g2.setStroke(getTickMarkStroke()); 700 g2.draw(inside); 701 g2.draw(outside); 702 } 703 if (this.minorTickMarksVisible) { 705 RegularTimePeriod tminor = RegularTimePeriod.createInstance( 706 this.minorTickTimePeriodClass, new Date (t0), 707 getTimeZone()); 708 long tt0 = tminor.getFirstMillisecond(this.calendar); 709 while (tt0 < t.getLastMillisecond(this.calendar) 710 && tt0 < lastOnAxis) { 711 double xx0 = valueToJava2D(tt0, dataArea, edge); 712 if (edge == RectangleEdge.TOP) { 713 inside = new Line2D.Double (xx0, y0, xx0, 714 y0 + this.minorTickMarkInsideLength); 715 outside = new Line2D.Double (xx0, y0, xx0, 716 y0 - this.minorTickMarkOutsideLength); 717 } 718 else if (edge == RectangleEdge.BOTTOM) { 719 inside = new Line2D.Double (xx0, y0, xx0, 720 y0 - this.minorTickMarkInsideLength); 721 outside = new Line2D.Double (xx0, y0, xx0, 722 y0 + this.minorTickMarkOutsideLength); 723 } 724 if (tt0 >= firstOnAxis) { 725 g2.setPaint(this.minorTickMarkPaint); 726 g2.setStroke(this.minorTickMarkStroke); 727 g2.draw(inside); 728 g2.draw(outside); 729 } 730 tminor = tminor.next(); 731 tt0 = tminor.getFirstMillisecond(this.calendar); 732 } 733 } 734 t = t.next(); 735 t0 = t.getFirstMillisecond(this.calendar); 736 } 737 if (edge == RectangleEdge.TOP) { 738 state.cursorUp(Math.max(outsideLength, 739 this.minorTickMarkOutsideLength)); 740 } 741 else if (edge == RectangleEdge.BOTTOM) { 742 state.cursorDown(Math.max(outsideLength, 743 this.minorTickMarkOutsideLength)); 744 } 745 state.setTicks(ticks); 746 } 747 748 756 protected void drawTickMarksVertical(Graphics2D g2, AxisState state, 757 Rectangle2D dataArea, 758 RectangleEdge edge) { 759 760 } 761 762 773 protected AxisState drawTickLabels(int band, Graphics2D g2, AxisState state, 774 Rectangle2D dataArea, 775 RectangleEdge edge) { 776 777 double delta1 = 0.0; 779 FontMetrics fm = g2.getFontMetrics(this.labelInfo[band].getLabelFont()); 780 if (edge == RectangleEdge.BOTTOM) { 781 delta1 = this.labelInfo[band].getPadding().calculateTopOutset( 782 fm.getHeight()); 783 } 784 else if (edge == RectangleEdge.TOP) { 785 delta1 = this.labelInfo[band].getPadding().calculateBottomOutset( 786 fm.getHeight()); 787 } 788 state.moveCursor(delta1, edge); 789 long axisMin = this.first.getFirstMillisecond(this.calendar); 790 long axisMax = this.last.getLastMillisecond(this.calendar); 791 g2.setFont(this.labelInfo[band].getLabelFont()); 792 g2.setPaint(this.labelInfo[band].getLabelPaint()); 793 794 RegularTimePeriod p1 = this.labelInfo[band].createInstance( 796 new Date (axisMin), this.timeZone); 797 RegularTimePeriod p2 = this.labelInfo[band].createInstance( 798 new Date (axisMax), this.timeZone); 799 String label1 = this.labelInfo[band].getDateFormat().format( 800 new Date (p1.getMiddleMillisecond(this.calendar))); 801 String label2 = this.labelInfo[band].getDateFormat().format( 802 new Date (p2.getMiddleMillisecond(this.calendar))); 803 Rectangle2D b1 = TextUtilities.getTextBounds(label1, g2, 804 g2.getFontMetrics()); 805 Rectangle2D b2 = TextUtilities.getTextBounds(label2, g2, 806 g2.getFontMetrics()); 807 double w = Math.max(b1.getWidth(), b2.getWidth()); 808 long ww = Math.round(java2DToValue(dataArea.getX() + w + 5.0, 809 dataArea, edge)) - axisMin; 810 long length = p1.getLastMillisecond(this.calendar) 811 - p1.getFirstMillisecond(this.calendar); 812 int periods = (int) (ww / length) + 1; 813 814 RegularTimePeriod p = this.labelInfo[band].createInstance( 815 new Date (axisMin), this.timeZone); 816 Rectangle2D b = null; 817 long lastXX = 0L; 818 float y = (float) (state.getCursor()); 819 TextAnchor anchor = TextAnchor.TOP_CENTER; 820 float yDelta = (float) b1.getHeight(); 821 if (edge == RectangleEdge.TOP) { 822 anchor = TextAnchor.BOTTOM_CENTER; 823 yDelta = -yDelta; 824 } 825 while (p.getFirstMillisecond(this.calendar) <= axisMax) { 826 float x = (float) valueToJava2D(p.getMiddleMillisecond( 827 this.calendar), dataArea, edge); 828 DateFormat df = this.labelInfo[band].getDateFormat(); 829 String label = df.format(new Date (p.getMiddleMillisecond( 830 this.calendar))); 831 long first = p.getFirstMillisecond(this.calendar); 832 long last = p.getLastMillisecond(this.calendar); 833 if (last > axisMax) { 834 Rectangle2D bb = TextUtilities.getTextBounds(label, g2, 837 g2.getFontMetrics()); 838 if ((x + bb.getWidth() / 2) > dataArea.getMaxX()) { 839 float xstart = (float) valueToJava2D(Math.max(first, 840 axisMin), dataArea, edge); 841 if (bb.getWidth() < (dataArea.getMaxX() - xstart)) { 842 x = ((float) dataArea.getMaxX() + xstart) / 2.0f; 843 } 844 else { 845 label = null; 846 } 847 } 848 } 849 if (first < axisMin) { 850 Rectangle2D bb = TextUtilities.getTextBounds(label, g2, 853 g2.getFontMetrics()); 854 if ((x - bb.getWidth() / 2) < dataArea.getX()) { 855 float xlast = (float) valueToJava2D(Math.min(last, 856 axisMax), dataArea, edge); 857 if (bb.getWidth() < (xlast - dataArea.getX())) { 858 x = (xlast + (float) dataArea.getX()) / 2.0f; 859 } 860 else { 861 label = null; 862 } 863 } 864 865 } 866 if (label != null) { 867 g2.setPaint(this.labelInfo[band].getLabelPaint()); 868 b = TextUtilities.drawAlignedString(label, g2, x, y, anchor); 869 } 870 if (lastXX > 0L) { 871 if (this.labelInfo[band].getDrawDividers()) { 872 long nextXX = p.getFirstMillisecond(this.calendar); 873 long mid = (lastXX + nextXX) / 2; 874 float mid2d = (float) valueToJava2D(mid, dataArea, edge); 875 g2.setStroke(this.labelInfo[band].getDividerStroke()); 876 g2.setPaint(this.labelInfo[band].getDividerPaint()); 877 g2.draw(new Line2D.Float (mid2d, y, mid2d, y + yDelta)); 878 } 879 } 880 lastXX = last; 881 for (int i = 0; i < periods; i++) { 882 p = p.next(); 883 } 884 } 885 double used = 0.0; 886 if (b != null) { 887 used = b.getHeight(); 888 if (edge == RectangleEdge.BOTTOM) { 890 used += this.labelInfo[band].getPadding().calculateBottomOutset( 891 fm.getHeight()); 892 } 893 else if (edge == RectangleEdge.TOP) { 894 used += this.labelInfo[band].getPadding().calculateTopOutset( 895 fm.getHeight()); 896 } 897 } 898 state.moveCursor(used, edge); 899 return state; 900 } 901 902 913 public List refreshTicks(Graphics2D g2, 914 AxisState state, 915 Rectangle2D dataArea, 916 RectangleEdge edge) { 917 return Collections.EMPTY_LIST; 918 } 919 920 932 public double valueToJava2D(double value, 933 Rectangle2D area, 934 RectangleEdge edge) { 935 936 double result = Double.NaN; 937 double axisMin = this.first.getFirstMillisecond(this.calendar); 938 double axisMax = this.last.getLastMillisecond(this.calendar); 939 if (RectangleEdge.isTopOrBottom(edge)) { 940 double minX = area.getX(); 941 double maxX = area.getMaxX(); 942 if (isInverted()) { 943 result = maxX + ((value - axisMin) / (axisMax - axisMin)) 944 * (minX - maxX); 945 } 946 else { 947 result = minX + ((value - axisMin) / (axisMax - axisMin)) 948 * (maxX - minX); 949 } 950 } 951 else if (RectangleEdge.isLeftOrRight(edge)) { 952 double minY = area.getMinY(); 953 double maxY = area.getMaxY(); 954 if (isInverted()) { 955 result = minY + (((value - axisMin) / (axisMax - axisMin)) 956 * (maxY - minY)); 957 } 958 else { 959 result = maxY - (((value - axisMin) / (axisMax - axisMin)) 960 * (maxY - minY)); 961 } 962 } 963 return result; 964 965 } 966 967 977 public double java2DToValue(double java2DValue, 978 Rectangle2D area, 979 RectangleEdge edge) { 980 981 double result = Double.NaN; 982 double min = 0.0; 983 double max = 0.0; 984 double axisMin = this.first.getFirstMillisecond(this.calendar); 985 double axisMax = this.last.getLastMillisecond(this.calendar); 986 if (RectangleEdge.isTopOrBottom(edge)) { 987 min = area.getX(); 988 max = area.getMaxX(); 989 } 990 else if (RectangleEdge.isLeftOrRight(edge)) { 991 min = area.getMaxY(); 992 max = area.getY(); 993 } 994 if (isInverted()) { 995 result = axisMax - ((java2DValue - min) / (max - min) 996 * (axisMax - axisMin)); 997 } 998 else { 999 result = axisMin + ((java2DValue - min) / (max - min) 1000 * (axisMax - axisMin)); 1001 } 1002 return result; 1003 } 1004 1005 1008 protected void autoAdjustRange() { 1009 1010 Plot plot = getPlot(); 1011 if (plot == null) { 1012 return; } 1014 1015 if (plot instanceof ValueAxisPlot) { 1016 ValueAxisPlot vap = (ValueAxisPlot) plot; 1017 1018 Range r = vap.getDataRange(this); 1019 if (r == null) { 1020 r = new Range(DEFAULT_LOWER_BOUND, DEFAULT_UPPER_BOUND); 1021 } 1022 1023 long upper = Math.round(r.getUpperBound()); 1024 long lower = Math.round(r.getLowerBound()); 1025 this.first = createInstance(this.autoRangeTimePeriodClass, 1026 new Date (lower), this.timeZone); 1027 this.last = createInstance(this.autoRangeTimePeriodClass, 1028 new Date (upper), this.timeZone); 1029 setRange(r, false, false); 1030 } 1031 1032 } 1033 1034 1041 public boolean equals(Object obj) { 1042 if (obj == this) { 1043 return true; 1044 } 1045 if (obj instanceof PeriodAxis && super.equals(obj)) { 1046 PeriodAxis that = (PeriodAxis) obj; 1047 if (!this.first.equals(that.first)) { 1048 return false; 1049 } 1050 if (!this.last.equals(that.last)) { 1051 return false; 1052 } 1053 if (!this.timeZone.equals(that.timeZone)) { 1054 return false; 1055 } 1056 if (!this.autoRangeTimePeriodClass.equals( 1057 that.autoRangeTimePeriodClass)) { 1058 return false; 1059 } 1060 if (!(isMinorTickMarksVisible() 1061 == that.isMinorTickMarksVisible())) { 1062 return false; 1063 } 1064 if (!this.majorTickTimePeriodClass.equals( 1065 that.majorTickTimePeriodClass)) { 1066 return false; 1067 } 1068 if (!this.minorTickTimePeriodClass.equals( 1069 that.minorTickTimePeriodClass)) { 1070 return false; 1071 } 1072 if (!this.minorTickMarkPaint.equals(that.minorTickMarkPaint)) { 1073 return false; 1074 } 1075 if (!this.minorTickMarkStroke.equals(that.minorTickMarkStroke)) { 1076 return false; 1077 } 1078 if (!Arrays.equals(this.labelInfo, that.labelInfo)) { 1079 return false; 1080 } 1081 return true; 1082 } 1083 return false; 1084 } 1085 1086 1091 public int hashCode() { 1092 if (getLabel() != null) { 1093 return getLabel().hashCode(); 1094 } 1095 else { 1096 return 0; 1097 } 1098 } 1099 1100 1108 public Object clone() throws CloneNotSupportedException { 1109 PeriodAxis clone = (PeriodAxis) super.clone(); 1110 clone.timeZone = (TimeZone ) this.timeZone.clone(); 1111 clone.labelInfo = new PeriodAxisLabelInfo[this.labelInfo.length]; 1112 for (int i = 0; i < this.labelInfo.length; i++) { 1113 clone.labelInfo[i] = this.labelInfo[i]; } 1116 return clone; 1117 } 1118 1119 1130 private RegularTimePeriod createInstance(Class periodClass, 1131 Date millisecond, TimeZone zone) { 1132 RegularTimePeriod result = null; 1133 try { 1134 Constructor c = periodClass.getDeclaredConstructor(new Class [] { 1135 Date .class, TimeZone .class}); 1136 result = (RegularTimePeriod) c.newInstance(new Object [] { 1137 millisecond, zone}); 1138 } 1139 catch (Exception e) { 1140 } 1142 return result; 1143 } 1144 1145 1152 private void writeObject(ObjectOutputStream stream) throws IOException { 1153 stream.defaultWriteObject(); 1154 SerialUtilities.writeStroke(this.minorTickMarkStroke, stream); 1155 SerialUtilities.writePaint(this.minorTickMarkPaint, stream); 1156 } 1157 1158 1166 private void readObject(ObjectInputStream stream) 1167 throws IOException , ClassNotFoundException { 1168 stream.defaultReadObject(); 1169 this.minorTickMarkStroke = SerialUtilities.readStroke(stream); 1170 this.minorTickMarkPaint = SerialUtilities.readPaint(stream); 1171 } 1172 1173} 1174 | Popular Tags |