1 74 75 package org.jfree.chart.plot; 76 77 import java.awt.BasicStroke ; 78 import java.awt.Color ; 79 import java.awt.Font ; 80 import java.awt.FontMetrics ; 81 import java.awt.Graphics2D ; 82 import java.awt.Paint ; 83 import java.awt.Stroke ; 84 import java.awt.geom.Area ; 85 import java.awt.geom.Ellipse2D ; 86 import java.awt.geom.Line2D ; 87 import java.awt.geom.Point2D ; 88 import java.awt.geom.Rectangle2D ; 89 import java.awt.geom.RoundRectangle2D ; 90 import java.io.IOException ; 91 import java.io.ObjectInputStream ; 92 import java.io.ObjectOutputStream ; 93 import java.io.Serializable ; 94 import java.text.DecimalFormat ; 95 import java.text.NumberFormat ; 96 import java.util.ResourceBundle ; 97 98 import org.jfree.chart.LegendItemCollection; 99 import org.jfree.chart.axis.NumberAxis; 100 import org.jfree.chart.axis.ValueAxis; 101 import org.jfree.chart.event.PlotChangeEvent; 102 import org.jfree.data.Range; 103 import org.jfree.data.general.DatasetChangeEvent; 104 import org.jfree.data.general.DefaultValueDataset; 105 import org.jfree.data.general.ValueDataset; 106 import org.jfree.io.SerialUtilities; 107 import org.jfree.ui.RectangleEdge; 108 import org.jfree.ui.RectangleInsets; 109 import org.jfree.util.ObjectUtilities; 110 import org.jfree.util.UnitType; 111 112 132 public class ThermometerPlot extends Plot implements ValueAxisPlot, 133 Zoomable, 134 Cloneable , 135 Serializable { 136 137 138 private static final long serialVersionUID = 4087093313147984390L; 139 140 141 public static final int UNITS_NONE = 0; 142 143 144 public static final int UNITS_FAHRENHEIT = 1; 145 146 147 public static final int UNITS_CELCIUS = 2; 148 149 150 public static final int UNITS_KELVIN = 3; 151 152 153 public static final int NONE = 0; 154 155 156 public static final int RIGHT = 1; 157 158 159 public static final int LEFT = 2; 160 161 162 public static final int BULB = 3; 163 164 165 public static final int NORMAL = 0; 166 167 168 public static final int WARNING = 1; 169 170 171 public static final int CRITICAL = 2; 172 173 174 protected static final int BULB_RADIUS = 40; 175 176 177 protected static final int BULB_DIAMETER = BULB_RADIUS * 2; 178 179 180 protected static final int COLUMN_RADIUS = 20; 181 182 183 protected static final int COLUMN_DIAMETER = COLUMN_RADIUS * 2; 184 185 186 protected static final int GAP_RADIUS = 5; 187 188 189 protected static final int GAP_DIAMETER = GAP_RADIUS * 2; 190 191 192 protected static final int AXIS_GAP = 10; 193 194 195 protected static final String [] UNITS 196 = {"", "\u00B0F", "\u00B0C", "\u00B0K"}; 197 198 199 protected static final int RANGE_LOW = 0; 200 201 202 protected static final int RANGE_HIGH = 1; 203 204 205 protected static final int DISPLAY_LOW = 2; 206 207 208 protected static final int DISPLAY_HIGH = 3; 209 210 211 protected static final double DEFAULT_LOWER_BOUND = 0.0; 212 213 214 protected static final double DEFAULT_UPPER_BOUND = 100.0; 215 216 217 private ValueDataset dataset; 218 219 220 private ValueAxis rangeAxis; 221 222 223 private double lowerBound = DEFAULT_LOWER_BOUND; 224 225 226 private double upperBound = DEFAULT_UPPER_BOUND; 227 228 231 private RectangleInsets padding; 232 233 234 private transient Stroke thermometerStroke = new BasicStroke (1.0f); 235 236 237 private transient Paint thermometerPaint = Color.black; 238 239 240 private int units = UNITS_CELCIUS; 241 242 243 private int valueLocation = BULB; 244 245 246 private int axisLocation = LEFT; 247 248 249 private Font valueFont = new Font ("SansSerif", Font.BOLD, 16); 250 251 252 private transient Paint valuePaint = Color.white; 253 254 255 private NumberFormat valueFormat = new DecimalFormat (); 256 257 258 private transient Paint mercuryPaint = Color.lightGray; 259 260 261 private boolean showValueLines = false; 262 263 264 private int subrange = -1; 265 266 267 private double[][] subrangeInfo = { 268 {0.0, 50.0, 0.0, 50.0}, 269 {50.0, 75.0, 50.0, 75.0}, 270 {75.0, 100.0, 75.0, 100.0} 271 }; 272 273 277 private boolean followDataInSubranges = false; 278 279 283 private boolean useSubrangePaint = true; 284 285 286 private Paint [] subrangePaint = { 287 Color.green, 288 Color.orange, 289 Color.red 290 }; 291 292 293 private boolean subrangeIndicatorsVisible = true; 294 295 296 private transient Stroke subrangeIndicatorStroke = new BasicStroke (2.0f); 297 298 299 private transient Stroke rangeIndicatorStroke = new BasicStroke (3.0f); 300 301 302 protected static ResourceBundle localizationResources = 303 ResourceBundle.getBundle("org.jfree.chart.plot.LocalizationBundle"); 304 305 308 public ThermometerPlot() { 309 this(new DefaultValueDataset()); 310 } 311 312 317 public ThermometerPlot(ValueDataset dataset) { 318 319 super(); 320 321 this.padding = new RectangleInsets( 322 UnitType.RELATIVE, 0.05, 0.05, 0.05, 0.05 323 ); 324 this.dataset = dataset; 325 if (dataset != null) { 326 dataset.addChangeListener(this); 327 } 328 NumberAxis axis = new NumberAxis(null); 329 axis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); 330 axis.setAxisLineVisible(false); 331 332 setRangeAxis(axis); 333 setAxisRange(); 334 } 335 336 341 public ValueDataset getDataset() { 342 return this.dataset; 343 } 344 345 351 public void setDataset(ValueDataset dataset) { 352 353 ValueDataset existing = this.dataset; 356 if (existing != null) { 357 existing.removeChangeListener(this); 358 } 359 360 this.dataset = dataset; 362 if (dataset != null) { 363 setDatasetGroup(dataset.getGroup()); 364 dataset.addChangeListener(this); 365 } 366 367 DatasetChangeEvent event = new DatasetChangeEvent(this, dataset); 369 datasetChanged(event); 370 371 } 372 373 378 public ValueAxis getRangeAxis() { 379 return this.rangeAxis; 380 } 381 382 387 public void setRangeAxis(ValueAxis axis) { 388 389 if (axis != null) { 390 axis.setPlot(this); 391 axis.addChangeListener(this); 392 } 393 394 if (this.rangeAxis != null) { 396 this.rangeAxis.removeChangeListener(this); 397 } 398 399 this.rangeAxis = axis; 400 401 } 402 403 410 public double getLowerBound() { 411 return this.lowerBound; 412 } 413 414 419 public void setLowerBound(double lower) { 420 this.lowerBound = lower; 421 setAxisRange(); 422 } 423 424 430 public double getUpperBound() { 431 return this.upperBound; 432 } 433 434 439 public void setUpperBound(double upper) { 440 this.upperBound = upper; 441 setAxisRange(); 442 } 443 444 450 public void setRange(double lower, double upper) { 451 this.lowerBound = lower; 452 this.upperBound = upper; 453 setAxisRange(); 454 } 455 456 462 public RectangleInsets getPadding() { 463 return this.padding; 464 } 465 466 471 public void setPadding(RectangleInsets padding) { 472 this.padding = padding; 473 notifyListeners(new PlotChangeEvent(this)); 474 } 475 476 481 public Stroke getThermometerStroke() { 482 return this.thermometerStroke; 483 } 484 485 490 public void setThermometerStroke(Stroke s) { 491 if (s != null) { 492 this.thermometerStroke = s; 493 notifyListeners(new PlotChangeEvent(this)); 494 } 495 } 496 497 502 public Paint getThermometerPaint() { 503 return this.thermometerPaint; 504 } 505 506 511 public void setThermometerPaint(Paint paint) { 512 if (paint != null) { 513 this.thermometerPaint = paint; 514 notifyListeners(new PlotChangeEvent(this)); 515 } 516 } 517 518 523 public int getUnits() { 524 return this.units; 525 } 526 527 541 public void setUnits(int u) { 542 if ((u >= 0) && (u < UNITS.length)) { 543 if (this.units != u) { 544 this.units = u; 545 notifyListeners(new PlotChangeEvent(this)); 546 } 547 } 548 } 549 550 555 public void setUnits(String u) { 556 if (u == null) { 557 return; 558 } 559 560 u = u.toUpperCase().trim(); 561 for (int i = 0; i < UNITS.length; ++i) { 562 if (u.equals(UNITS[i].toUpperCase().trim())) { 563 setUnits(i); 564 i = UNITS.length; 565 } 566 } 567 } 568 569 574 public int getValueLocation() { 575 return this.valueLocation; 576 } 577 578 589 public void setValueLocation(int location) { 590 if ((location >= 0) && (location < 4)) { 591 this.valueLocation = location; 592 notifyListeners(new PlotChangeEvent(this)); 593 } 594 else { 595 throw new IllegalArgumentException ("Location not recognised."); 596 } 597 } 598 599 610 public void setAxisLocation(int location) { 611 if ((location >= 0) && (location < 3)) { 612 this.axisLocation = location; 613 notifyListeners(new PlotChangeEvent(this)); 614 } 615 else { 616 throw new IllegalArgumentException ("Location not recognised."); 617 } 618 } 619 620 625 public int getAxisLocation() { 626 return this.axisLocation; 627 } 628 629 634 public Font getValueFont() { 635 return this.valueFont; 636 } 637 638 643 public void setValueFont(Font f) { 644 if ((f != null) && (!this.valueFont.equals(f))) { 645 this.valueFont = f; 646 notifyListeners(new PlotChangeEvent(this)); 647 } 648 } 649 650 655 public Paint getValuePaint() { 656 return this.valuePaint; 657 } 658 659 664 public void setValuePaint(Paint p) { 665 if ((p != null) && (!this.valuePaint.equals(p))) { 666 this.valuePaint = p; 667 notifyListeners(new PlotChangeEvent(this)); 668 } 669 } 670 671 676 public void setValueFormat(NumberFormat formatter) { 677 if (formatter != null) { 678 this.valueFormat = formatter; 679 notifyListeners(new PlotChangeEvent(this)); 680 } 681 } 682 683 688 public Paint getMercuryPaint() { 689 return this.mercuryPaint; 690 } 691 692 697 public void setMercuryPaint(Paint paint) { 698 this.mercuryPaint = paint; 699 notifyListeners(new PlotChangeEvent(this)); 700 } 701 702 707 public boolean getShowValueLines() { 708 return this.showValueLines; 709 } 710 711 716 public void setShowValueLines(boolean b) { 717 this.showValueLines = b; 718 notifyListeners(new PlotChangeEvent(this)); 719 } 720 721 728 public void setSubrangeInfo(int range, double low, double hi) { 729 setSubrangeInfo(range, low, hi, low, hi); 730 } 731 732 741 public void setSubrangeInfo(int range, 742 double rangeLow, double rangeHigh, 743 double displayLow, double displayHigh) { 744 745 if ((range >= 0) && (range < 3)) { 746 setSubrange(range, rangeLow, rangeHigh); 747 setDisplayRange(range, displayLow, displayHigh); 748 setAxisRange(); 749 notifyListeners(new PlotChangeEvent(this)); 750 } 751 752 } 753 754 761 public void setSubrange(int range, double low, double high) { 762 if ((range >= 0) && (range < 3)) { 763 this.subrangeInfo[range][RANGE_HIGH] = high; 764 this.subrangeInfo[range][RANGE_LOW] = low; 765 } 766 } 767 768 775 public void setDisplayRange(int range, double low, double high) { 776 777 if ((range >= 0) && (range < this.subrangeInfo.length) 778 && isValidNumber(high) && isValidNumber(low)) { 779 780 if (high > low) { 781 this.subrangeInfo[range][DISPLAY_HIGH] = high; 782 this.subrangeInfo[range][DISPLAY_LOW] = low; 783 } 784 else { 785 this.subrangeInfo[range][DISPLAY_HIGH] = high; 786 this.subrangeInfo[range][DISPLAY_LOW] = low; 787 } 788 789 } 790 791 } 792 793 800 public Paint getSubrangePaint(int range) { 801 if ((range >= 0) && (range < this.subrangePaint.length)) { 802 return this.subrangePaint[range]; 803 } 804 else { 805 return this.mercuryPaint; 806 } 807 } 808 809 815 public void setSubrangePaint(int range, Paint paint) { 816 if ((range >= 0) 817 && (range < this.subrangePaint.length) && (paint != null)) { 818 this.subrangePaint[range] = paint; 819 notifyListeners(new PlotChangeEvent(this)); 820 } 821 } 822 823 829 public boolean getFollowDataInSubranges() { 830 return this.followDataInSubranges; 831 } 832 833 839 public void setFollowDataInSubranges(boolean flag) { 840 this.followDataInSubranges = flag; 841 notifyListeners(new PlotChangeEvent(this)); 842 } 843 844 850 public boolean getUseSubrangePaint() { 851 return this.useSubrangePaint; 852 } 853 854 859 public void setUseSubrangePaint(boolean flag) { 860 this.useSubrangePaint = flag; 861 notifyListeners(new PlotChangeEvent(this)); 862 } 863 864 874 public void draw(Graphics2D g2, Rectangle2D area, Point2D anchor, 875 PlotState parentState, 876 PlotRenderingInfo info) { 877 878 RoundRectangle2D outerStem = new RoundRectangle2D.Double (); 879 RoundRectangle2D innerStem = new RoundRectangle2D.Double (); 880 RoundRectangle2D mercuryStem = new RoundRectangle2D.Double (); 881 Ellipse2D outerBulb = new Ellipse2D.Double (); 882 Ellipse2D innerBulb = new Ellipse2D.Double (); 883 String temp = null; 884 FontMetrics metrics = null; 885 if (info != null) { 886 info.setPlotArea(area); 887 } 888 889 RectangleInsets insets = getInsets(); 891 insets.trim(area); 892 drawBackground(g2, area); 893 894 int midX = (int) (area.getX() + (area.getWidth() / 2)); 897 int midY = (int) (area.getY() + (area.getHeight() / 2)); 898 int stemTop = (int) (area.getMinY() + BULB_RADIUS); 899 int stemBottom = (int) (area.getMaxY() - BULB_DIAMETER); 900 Rectangle2D dataArea = new Rectangle2D.Double ( 901 midX - COLUMN_RADIUS, stemTop, COLUMN_RADIUS, stemBottom - stemTop 902 ); 903 904 outerBulb.setFrame( 905 midX - BULB_RADIUS, stemBottom, BULB_DIAMETER, BULB_DIAMETER 906 ); 907 908 outerStem.setRoundRect( 909 midX - COLUMN_RADIUS, area.getMinY(), COLUMN_DIAMETER, 910 stemBottom + BULB_DIAMETER - stemTop, 911 COLUMN_DIAMETER, COLUMN_DIAMETER 912 ); 913 914 Area outerThermometer = new Area (outerBulb); 915 Area tempArea = new Area (outerStem); 916 outerThermometer.add(tempArea); 917 918 innerBulb.setFrame( 919 midX - BULB_RADIUS + GAP_RADIUS, stemBottom + GAP_RADIUS, 920 BULB_DIAMETER - GAP_DIAMETER, BULB_DIAMETER - GAP_DIAMETER 921 ); 922 923 innerStem.setRoundRect( 924 midX - COLUMN_RADIUS + GAP_RADIUS, area.getMinY() + GAP_RADIUS, 925 COLUMN_DIAMETER - GAP_DIAMETER, 926 stemBottom + BULB_DIAMETER - GAP_DIAMETER - stemTop, 927 COLUMN_DIAMETER - GAP_DIAMETER, COLUMN_DIAMETER - GAP_DIAMETER 928 ); 929 930 Area innerThermometer = new Area (innerBulb); 931 tempArea = new Area (innerStem); 932 innerThermometer.add(tempArea); 933 934 if ((this.dataset != null) && (this.dataset.getValue() != null)) { 935 double current = this.dataset.getValue().doubleValue(); 936 double ds = this.rangeAxis.valueToJava2D( 937 current, dataArea, RectangleEdge.LEFT 938 ); 939 940 int i = COLUMN_DIAMETER - GAP_DIAMETER; int j = COLUMN_RADIUS - GAP_RADIUS; int l = (i / 2); 943 int k = (int) Math.round(ds); 944 if (k < (GAP_RADIUS + area.getMinY())) { 945 k = (int) (GAP_RADIUS + area.getMinY()); 946 l = BULB_RADIUS; 947 } 948 949 Area mercury = new Area (innerBulb); 950 951 if (k < (stemBottom + BULB_RADIUS)) { 952 mercuryStem.setRoundRect( 953 midX - j, k, i, (stemBottom + BULB_RADIUS) - k, l, l 954 ); 955 tempArea = new Area (mercuryStem); 956 mercury.add(tempArea); 957 } 958 959 g2.setPaint(getCurrentPaint()); 960 g2.fill(mercury); 961 962 if (this.subrangeIndicatorsVisible) { 964 g2.setStroke(this.subrangeIndicatorStroke); 965 Range range = this.rangeAxis.getRange(); 966 967 double value = this.subrangeInfo[NORMAL][RANGE_LOW]; 969 if (range.contains(value)) { 970 double x = midX + COLUMN_RADIUS + 2; 971 double y = this.rangeAxis.valueToJava2D( 972 value, dataArea, RectangleEdge.LEFT 973 ); 974 Line2D line = new Line2D.Double (x, y, x + 10, y); 975 g2.setPaint(this.subrangePaint[NORMAL]); 976 g2.draw(line); 977 } 978 979 value = this.subrangeInfo[WARNING][RANGE_LOW]; 981 if (range.contains(value)) { 982 double x = midX + COLUMN_RADIUS + 2; 983 double y = this.rangeAxis.valueToJava2D( 984 value, dataArea, RectangleEdge.LEFT 985 ); 986 Line2D line = new Line2D.Double (x, y, x + 10, y); 987 g2.setPaint(this.subrangePaint[WARNING]); 988 g2.draw(line); 989 } 990 991 value = this.subrangeInfo[CRITICAL][RANGE_LOW]; 993 if (range.contains(value)) { 994 double x = midX + COLUMN_RADIUS + 2; 995 double y = this.rangeAxis.valueToJava2D( 996 value, dataArea, RectangleEdge.LEFT 997 ); 998 Line2D line = new Line2D.Double (x, y, x + 10, y); 999 g2.setPaint(this.subrangePaint[CRITICAL]); 1000 g2.draw(line); 1001 } 1002 } 1003 1004 if ((this.rangeAxis != null) && (this.axisLocation != NONE)) { 1006 int drawWidth = AXIS_GAP; 1007 if (this.showValueLines) { 1008 drawWidth += COLUMN_DIAMETER; 1009 } 1010 Rectangle2D drawArea; 1011 double cursor = 0; 1012 1013 switch (this.axisLocation) { 1014 case RIGHT: 1015 cursor = midX + COLUMN_RADIUS; 1016 drawArea = new Rectangle2D.Double ( 1017 cursor, 1018 stemTop, 1019 drawWidth, 1020 (stemBottom - stemTop + 1) 1021 ); 1022 this.rangeAxis.draw( 1023 g2, cursor, area, drawArea, 1024 RectangleEdge.RIGHT, null 1025 ); 1026 break; 1027 1028 case LEFT: 1029 default: 1030 cursor = midX - COLUMN_RADIUS; 1032 drawArea = new Rectangle2D.Double ( 1033 cursor, 1034 stemTop, 1035 drawWidth, 1036 (stemBottom - stemTop + 1) 1037 ); 1038 this.rangeAxis.draw( 1039 g2, cursor, area, drawArea, 1040 RectangleEdge.LEFT, null 1041 ); 1042 break; 1043 } 1044 1045 } 1046 1047 g2.setFont(this.valueFont); 1049 g2.setPaint(this.valuePaint); 1050 metrics = g2.getFontMetrics(); 1051 switch (this.valueLocation) { 1052 case RIGHT: 1053 g2.drawString( 1054 this.valueFormat.format(current), 1055 midX + COLUMN_RADIUS + GAP_RADIUS, midY 1056 ); 1057 break; 1058 case LEFT: 1059 String valueString = this.valueFormat.format(current); 1060 int stringWidth = metrics.stringWidth(valueString); 1061 g2.drawString( 1062 valueString, 1063 midX - COLUMN_RADIUS - GAP_RADIUS - stringWidth, midY 1064 ); 1065 break; 1066 case BULB: 1067 temp = this.valueFormat.format(current); 1068 i = metrics.stringWidth(temp) / 2; 1069 g2.drawString( 1070 temp, midX - i, 1071 stemBottom + BULB_RADIUS + GAP_RADIUS 1072 ); 1073 break; 1074 default: 1075 } 1076 1077 } 1078 1079 g2.setPaint(this.thermometerPaint); 1080 g2.setFont(this.valueFont); 1081 1082 metrics = g2.getFontMetrics(); 1084 int tickX1 = midX - COLUMN_RADIUS - GAP_DIAMETER 1085 - metrics.stringWidth(UNITS[this.units]); 1086 if (tickX1 > area.getMinX()) { 1087 g2.drawString( 1088 UNITS[this.units], tickX1, (int) (area.getMinY() + 20) 1089 ); 1090 } 1091 1092 g2.setStroke(this.thermometerStroke); 1094 g2.draw(outerThermometer); 1095 g2.draw(innerThermometer); 1096 1097 drawOutline(g2, area); 1098 } 1099 1100 1107 public void zoom(double percent) { 1108 } 1110 1111 1116 public String getPlotType() { 1117 return localizationResources.getString("Thermometer_Plot"); 1118 } 1119 1120 1125 public void datasetChanged(DatasetChangeEvent event) { 1126 Number vn = this.dataset.getValue(); 1127 if (vn != null) { 1128 double value = vn.doubleValue(); 1129 if (inSubrange(NORMAL, value)) { 1130 this.subrange = NORMAL; 1131 } 1132 else if (inSubrange(WARNING, value)) { 1133 this.subrange = WARNING; 1134 } 1135 else if (inSubrange(CRITICAL, value)) { 1136 this.subrange = CRITICAL; 1137 } 1138 else { 1139 this.subrange = -1; 1140 } 1141 setAxisRange(); 1142 } 1143 super.datasetChanged(event); 1144 } 1145 1146 1153 public Number getMinimumVerticalDataValue() { 1154 return new Double (this.lowerBound); 1155 } 1156 1157 1164 public Number getMaximumVerticalDataValue() { 1165 return new Double (this.upperBound); 1166 } 1167 1168 1175 public Range getDataRange(ValueAxis axis) { 1176 return new Range(this.lowerBound, this.upperBound); 1177 } 1178 1179 1182 protected void setAxisRange() { 1183 if ((this.subrange >= 0) && (this.followDataInSubranges)) { 1184 this.rangeAxis.setRange( 1185 new Range(this.subrangeInfo[this.subrange][DISPLAY_LOW], 1186 this.subrangeInfo[this.subrange][DISPLAY_HIGH]) 1187 ); 1188 } 1189 else { 1190 this.rangeAxis.setRange(this.lowerBound, this.upperBound); 1191 } 1192 } 1193 1194 1199 public LegendItemCollection getLegendItems() { 1200 return null; 1201 } 1202 1203 1208 public PlotOrientation getOrientation() { 1209 return PlotOrientation.VERTICAL; 1210 } 1211 1212 1220 protected static boolean isValidNumber(double d) { 1221 return (!(Double.isNaN(d) || Double.isInfinite(d))); 1222 } 1223 1224 1232 private boolean inSubrange(int subrange, double value) { 1233 return (value > this.subrangeInfo[subrange][RANGE_LOW] 1234 && value <= this.subrangeInfo[subrange][RANGE_HIGH]); 1235 } 1236 1237 1242 private Paint getCurrentPaint() { 1243 1244 Paint result = this.mercuryPaint; 1245 if (this.useSubrangePaint) { 1246 double value = this.dataset.getValue().doubleValue(); 1247 if (inSubrange(NORMAL, value)) { 1248 result = this.subrangePaint[NORMAL]; 1249 } 1250 else if (inSubrange(WARNING, value)) { 1251 result = this.subrangePaint[WARNING]; 1252 } 1253 else if (inSubrange(CRITICAL, value)) { 1254 result = this.subrangePaint[CRITICAL]; 1255 } 1256 } 1257 return result; 1258 } 1259 1260 1267 public boolean equals(Object obj) { 1268 1269 if (obj == this) { 1270 return true; 1271 } 1272 1273 if (!(obj instanceof ThermometerPlot)) { 1274 return false; 1275 } 1276 ThermometerPlot that = (ThermometerPlot) obj; 1277 if (!super.equals(obj)) { 1278 return false; 1279 } 1280 if (!ObjectUtilities.equal(this.dataset, that.dataset)) { 1281 return false; 1282 } 1283 if (!ObjectUtilities.equal(this.rangeAxis, that.rangeAxis)) { 1284 return false; 1285 } 1286 if (this.lowerBound != that.lowerBound) { 1287 return false; 1288 } 1289 if (this.upperBound != that.upperBound) { 1290 return false; 1291 } 1292 if (!ObjectUtilities.equal(this.padding, that.padding)) { 1293 return false; 1294 } 1295 if (!ObjectUtilities.equal( 1296 this.thermometerStroke, that.thermometerStroke 1297 )) { 1298 return false; 1299 } 1300 if (!ObjectUtilities.equal( 1301 this.thermometerPaint, that.thermometerPaint 1302 )) { 1303 return false; 1304 } 1305 if (this.units != that.units) { 1306 return false; 1307 } 1308 if (this.valueLocation != that.valueLocation) { 1309 return false; 1310 } 1311 if (!ObjectUtilities.equal(this.valueFont, that.valueFont)) { 1312 return false; 1313 } 1314 if (!ObjectUtilities.equal(this.valuePaint, that.valuePaint)) { 1315 return false; 1316 } 1317 if (!ObjectUtilities.equal(this.valueFormat, that.valueFormat)) { 1318 return false; 1319 } 1320 if (!ObjectUtilities.equal(this.mercuryPaint, that.mercuryPaint)) { 1321 return false; 1322 } 1323 if (this.showValueLines != that.showValueLines) { 1324 return false; 1325 } 1326 if (this.subrange != that.subrange) { 1327 return false; 1328 } 1329 1330 if (this.followDataInSubranges != that.followDataInSubranges) { 1331 return false; 1332 } 1333 if (this.useSubrangePaint != that.useSubrangePaint) { 1334 return false; 1335 } 1336 return true; 1337 1338 } 1339 1340 1347 public Object clone() throws CloneNotSupportedException { 1348 1349 ThermometerPlot clone = (ThermometerPlot) super.clone(); 1350 1351 if (clone.dataset != null) { 1352 clone.dataset.addChangeListener(clone); 1353 } 1354 clone.rangeAxis = (ValueAxis) ObjectUtilities.clone(this.rangeAxis); 1355 if (clone.rangeAxis != null) { 1356 clone.rangeAxis.setPlot(clone); 1357 clone.rangeAxis.addChangeListener(clone); 1358 } 1359 clone.valueFormat = (NumberFormat ) this.valueFormat.clone(); 1360 clone.subrangePaint = (Paint []) this.subrangePaint.clone(); 1361 1362 return clone; 1363 1364 } 1365 1366 1373 private void writeObject(ObjectOutputStream stream) throws IOException { 1374 stream.defaultWriteObject(); 1375 SerialUtilities.writeStroke(this.thermometerStroke, stream); 1376 SerialUtilities.writePaint(this.thermometerPaint, stream); 1377 SerialUtilities.writePaint(this.valuePaint, stream); 1378 SerialUtilities.writePaint(this.mercuryPaint, stream); 1379 SerialUtilities.writeStroke(this.subrangeIndicatorStroke, stream); 1380 SerialUtilities.writeStroke(this.rangeIndicatorStroke, stream); 1381 } 1382 1383 1391 private void readObject(ObjectInputStream stream) throws IOException , 1392 ClassNotFoundException { 1393 stream.defaultReadObject(); 1394 this.thermometerStroke = SerialUtilities.readStroke(stream); 1395 this.thermometerPaint = SerialUtilities.readPaint(stream); 1396 this.valuePaint = SerialUtilities.readPaint(stream); 1397 this.mercuryPaint = SerialUtilities.readPaint(stream); 1398 this.subrangeIndicatorStroke = SerialUtilities.readStroke(stream); 1399 this.rangeIndicatorStroke = SerialUtilities.readStroke(stream); 1400 1401 if (this.rangeAxis != null) { 1402 this.rangeAxis.addChangeListener(this); 1403 } 1404 } 1405 1406 1413 public void zoomDomainAxes(double factor, PlotRenderingInfo state, 1414 Point2D source) { 1415 } 1417 1418 1425 public void zoomRangeAxes(double factor, PlotRenderingInfo state, 1426 Point2D source) { 1427 this.rangeAxis.resizeRange(factor); 1428 } 1429 1430 1438 public void zoomDomainAxes(double lowerPercent, double upperPercent, 1439 PlotRenderingInfo state, Point2D source) { 1440 } 1442 1443 1451 public void zoomRangeAxes(double lowerPercent, double upperPercent, 1452 PlotRenderingInfo state, Point2D source) { 1453 this.rangeAxis.zoomRange(lowerPercent, upperPercent); 1454 } 1455 1456 1461 public boolean isDomainZoomable() { 1462 return false; 1463 } 1464 1465 1470 public boolean isRangeZoomable() { 1471 return true; 1472 } 1473 1474} 1475 | Popular Tags |