📄 thermometerplot.java
字号:
Area mercury = new Area(innerBulb);
if (k < (stemBottom + BULB_RADIUS)) {
mercuryStem.setRoundRect(midX - j, k, i, (stemBottom + BULB_RADIUS) - k,
l, l);
tempArea = new Area(mercuryStem);
mercury.add(tempArea);
}
g2.setPaint(getCurrentPaint());
g2.fill(mercury);
// draw range indicators...
if (this.subrangeIndicatorsVisible) {
g2.setStroke(this.subrangeIndicatorStroke);
Range range = this.rangeAxis.getRange();
// draw start of normal range
double value = this.subrangeInfo[NORMAL][RANGE_LOW];
if (range.contains(value)) {
double x = midX + COLUMN_RADIUS + 2;
double y = this.rangeAxis.valueToJava2D(value, dataArea, RectangleEdge.LEFT);
Line2D line = new Line2D.Double(x, y, x + 10, y);
g2.setPaint(this.subrangePaint[NORMAL]);
g2.draw(line);
}
// draw start of warning range
value = this.subrangeInfo[WARNING][RANGE_LOW];
if (range.contains(value)) {
double x = midX + COLUMN_RADIUS + 2;
double y = this.rangeAxis.valueToJava2D(value, dataArea, RectangleEdge.LEFT);
Line2D line = new Line2D.Double(x, y, x + 10, y);
g2.setPaint(this.subrangePaint[WARNING]);
g2.draw(line);
}
// draw start of critical range
value = this.subrangeInfo[CRITICAL][RANGE_LOW];
if (range.contains(value)) {
double x = midX + COLUMN_RADIUS + 2;
double y = this.rangeAxis.valueToJava2D(value, dataArea, RectangleEdge.LEFT);
Line2D line = new Line2D.Double(x, y, x + 10, y);
g2.setPaint(this.subrangePaint[CRITICAL]);
g2.draw(line);
}
}
// draw the axis...
if ((this.rangeAxis != null) && (this.axisLocation != NONE)) {
int drawWidth = AXIS_GAP;
if (this.showValueLines) {
drawWidth += COLUMN_DIAMETER;
}
Rectangle2D drawArea;
double cursor = 0;
switch (this.axisLocation) {
case RIGHT:
cursor = midX + COLUMN_RADIUS;
drawArea = new Rectangle2D.Double(
cursor,
stemTop,
drawWidth,
(stemBottom - stemTop + 1)
);
this.rangeAxis.draw(g2, cursor, plotArea, drawArea, RectangleEdge.RIGHT, null);
break;
case LEFT:
default:
//cursor = midX - COLUMN_RADIUS - AXIS_GAP;
cursor = midX - COLUMN_RADIUS;
drawArea = new Rectangle2D.Double(
cursor,
stemTop,
drawWidth,
(stemBottom - stemTop + 1)
);
this.rangeAxis.draw(g2, cursor, plotArea, drawArea, RectangleEdge.LEFT, null);
break;
}
//cursor = state.getCursor();
}
// draw text value on screen
g2.setFont(this.valueFont);
g2.setPaint(this.valuePaint);
metrics = g2.getFontMetrics();
switch (this.valueLocation) {
case RIGHT:
g2.drawString(this.valueFormat.format(current),
midX + COLUMN_RADIUS + GAP_RADIUS, midY);
break;
case LEFT:
String valueString = this.valueFormat.format(current);
int stringWidth = metrics.stringWidth(valueString);
g2.drawString(valueString,
midX - COLUMN_RADIUS - GAP_RADIUS - stringWidth,
midY);
break;
case BULB:
temp = this.valueFormat.format(current);
i = metrics.stringWidth(temp) / 2;
g2.drawString(temp, midX - i, stemBottom + BULB_RADIUS + GAP_RADIUS);
break;
default:
}
/***/
}
g2.setPaint(this.thermometerPaint);
g2.setFont(this.valueFont);
// draw units indicator
metrics = g2.getFontMetrics();
int tickX1 = midX - COLUMN_RADIUS - GAP_DIAMETER - metrics.stringWidth(UNITS[this.units]);
if (tickX1 > plotArea.getMinX()) {
g2.drawString(UNITS[this.units], tickX1, (int) (plotArea.getMinY() + 20));
}
// draw thermometer outline
g2.setStroke(this.thermometerStroke);
g2.draw(outerThermometer);
g2.draw(innerThermometer);
drawOutline(g2, plotArea);
}
/**
* A zoom method that does nothing. Plots are required to support the zoom operation. In the
* case of a thermometer chart, it doesn't make sense to zoom in or out, so the
* method is empty.
*
* @param percent the zoom percentage.
*/
public void zoom(double percent) {
// intentionally blank
}
/**
* Returns a short string describing the type of plot.
*
* @return a short string describing the type of plot.
*/
public String getPlotType() {
return localizationResources.getString("Thermometer_Plot");
}
/**
* Checks to see if a new value means the axis range needs adjusting.
*
* @param event the dataset change event.
*/
public void datasetChanged(DatasetChangeEvent event) {
Number vn = this.dataset.getValue();
if (vn != null) {
double value = vn.doubleValue();
if (inSubrange(NORMAL, value)) {
this.subrange = NORMAL;
}
else if (inSubrange(WARNING, value)) {
this.subrange = WARNING;
}
else if (inSubrange(CRITICAL, value)) {
this.subrange = CRITICAL;
}
else {
this.subrange = -1;
}
setAxisRange();
}
super.datasetChanged(event);
}
/**
* Returns the minimum value in either the domain or the range, whichever
* is displayed against the vertical axis for the particular type of plot
* implementing this interface.
*
* @return the minimum value in either the domain or the range.
*/
public Number getMinimumVerticalDataValue() {
return new Double(this.lowerBound);
}
/**
* Returns the maximum value in either the domain or the range, whichever
* is displayed against the vertical axis for the particular type of plot
* implementing this interface.
*
* @return the maximum value in either the domain or the range
*/
public Number getMaximumVerticalDataValue() {
return new Double(this.upperBound);
}
/**
* Returns the data range.
*
* @param axis the axis.
*
* @return The range of data displayed.
*/
public Range getDataRange(ValueAxis axis) {
return new Range(this.lowerBound, this.upperBound);
}
/**
* Sets the axis range to the current values in the rangeInfo array.
*/
protected void setAxisRange() {
if ((this.subrange >= 0) && (this.followDataInSubranges)) {
this.rangeAxis.setRange(new Range(this.subrangeInfo[this.subrange][DISPLAY_LOW],
this.subrangeInfo[this.subrange][DISPLAY_HIGH]));
}
else {
this.rangeAxis.setRange(this.lowerBound, this.upperBound);
}
}
/**
* Returns null, since the thermometer plot won't require a legend.
*
* @return null.
*
* @deprecated use getLegendItems().
*/
public List getLegendItemLabels() {
return null;
}
/**
* Returns the legend items for the plot.
*
* @return null.
*/
public LegendItemCollection getLegendItems() {
return null;
}
/**
* Returns the vertical value axis.
* <p>
* This is required by the VerticalValuePlot interface, but not used in this class.
*
* @return the vertical value axis.
*/
public ValueAxis getVerticalValueAxis() {
return this.rangeAxis;
}
/**
* Determine whether a number is valid and finite.
*
* @param d the number to be tested.
*
* @return true if the number is valid and finite, and false otherwise.
*/
protected static boolean isValidNumber(double d) {
return (!(Double.isNaN(d) || Double.isInfinite(d)));
}
/**
* Returns true if the value is in the specified range, and false otherwise.
*
* @param subrange the subrange.
* @param value the value to check.
*
* @return true or false.
*/
private boolean inSubrange(int subrange, double value) {
return (value > this.subrangeInfo[subrange][RANGE_LOW]
&& value <= this.subrangeInfo[subrange][RANGE_HIGH]);
}
/**
* Returns the mercury paint corresponding to the current data value.
*
* @return the paint.
*/
private Paint getCurrentPaint() {
Paint result = this.mercuryPaint;
if (this.useSubrangePaint) {
double value = this.dataset.getValue().doubleValue();
if (inSubrange(NORMAL, value)) {
result = this.subrangePaint[NORMAL];
}
else if (inSubrange(WARNING, value)) {
result = this.subrangePaint[WARNING];
}
else if (inSubrange(CRITICAL, value)) {
result = this.subrangePaint[CRITICAL];
}
}
return result;
}
/**
* Tests this plot for equality with another object.
*
* @param obj the object.
*
* @return <code>true</code> or <code>false</code>.
*/
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (obj instanceof ThermometerPlot) {
ThermometerPlot p = (ThermometerPlot) obj;
if (super.equals(obj)) {
boolean b0 = ObjectUtils.equal(this.dataset, p.dataset);
boolean b1 = ObjectUtils.equal(this.rangeAxis, p.rangeAxis);
boolean b2 = (this.lowerBound == p.lowerBound);
boolean b3 = (this.upperBound == p.upperBound);
boolean b4 = ObjectUtils.equal(this.padding, p.padding);
boolean b5 = ObjectUtils.equal(this.thermometerStroke,
p.thermometerStroke);
boolean b6 = ObjectUtils.equal(this.thermometerPaint,
p.thermometerPaint);
boolean b7 = (this.units == p.units);
boolean b8 = (this.valueLocation == p.valueLocation);
boolean b9 = ObjectUtils.equal(this.valueFont, p.valueFont);
boolean b10 = ObjectUtils.equal(this.valuePaint, p.valuePaint);
boolean b11 = ObjectUtils.equal(this.valueFormat, p.valueFormat);
boolean b12 = ObjectUtils.equal(this.mercuryPaint, p.mercuryPaint);
boolean b13 = (this.showValueLines == p.showValueLines);
boolean b14 = (this.subrange == p.subrange);
boolean b15 = true; //Arrays.equals(this.subRangeInfo, p.subRangeInfo);
boolean b16 = (this.followDataInSubranges == p.followDataInSubranges);
boolean b17 = (this.useSubrangePaint == p.useSubrangePaint);
return b0 && b1 && b2 && b3 && b4 && b5 && b6 && b7 && b8 && b9
&& b10 && b11 && b12 && b13 && b14 && b15 && b16 && b17;
}
}
return false;
}
/**
* Returns a clone of the plot.
*
* @return A clone.
*
* @throws CloneNotSupportedException if the plot cannot be cloned.
*/
public Object clone() throws CloneNotSupportedException {
ThermometerPlot clone = (ThermometerPlot) super.clone();
//private ValueDataset dataset <-- don't clone the dataset
if (clone.dataset != null) {
clone.dataset.addChangeListener(clone);
}
clone.rangeAxis = (ValueAxis) ObjectUtils.clone(this.rangeAxis);
if (clone.rangeAxis != null) {
clone.rangeAxis.setPlot(clone);
clone.rangeAxis.addChangeListener(clone);
}
//private double lowerBound <-- primitive
//private double upperBound <-- primitive
//private Spacer padding <-- immutable
//private transient Stroke thermometerStroke <-- immutable
//private transient Paint thermometerPaint <-- immutable
//private int units <-- primitive
//private int valueLocation <-- primitive
//private Font valueFont <-- immutable
//private transient Paint valuePaint<-- immutable
clone.valueFormat = (NumberFormat) this.valueFormat.clone();
//private transient Paint mercuryPaint <-- immutable
//private boolean showValueLines <-- primitive
//private int subrange <-- primitive
//private double[][] subrangeInfo ????????????????
//private boolean followDataInSubranges <-- primitive
//private boolean useSubrangePaint <-- primitive
clone.subrangePaint = (Paint[]) this.subrangePaint.clone();
//private boolean subrangeIndicatorsVisible <-- primitive
//private transient Stroke subrangeIndicatorStroke <-- immutable
//private transient Stroke rangeIndicatorStroke <-- immutable
return clone;
}
/**
* Provides serialization support.
*
* @param stream the output stream.
*
* @throws IOException if there is an I/O error.
*/
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writeStroke(this.thermometerStroke, stream);
SerialUtilities.writePaint(this.thermometerPaint, stream);
SerialUtilities.writePaint(this.valuePaint, stream);
SerialUtilities.writePaint(this.mercuryPaint, stream);
SerialUtilities.writeStroke(this.subrangeIndicatorStroke, stream);
SerialUtilities.writeStroke(this.rangeIndicatorStroke, stream);
}
/**
* Provides serialization support.
*
* @param stream the input stream.
*
* @throws IOException if there is an I/O error.
* @throws ClassNotFoundException if there is a classpath problem.
*/
private void readObject(ObjectInputStream stream) throws IOException,
ClassNotFoundException {
stream.defaultReadObject();
this.thermometerStroke = SerialUtilities.readStroke(stream);
this.thermometerPaint = SerialUtilities.readPaint(stream);
this.valuePaint = SerialUtilities.readPaint(stream);
this.mercuryPaint = SerialUtilities.readPaint(stream);
this.subrangeIndicatorStroke = SerialUtilities.readStroke(stream);
this.rangeIndicatorStroke = SerialUtilities.readStroke(stream);
if (this.rangeAxis != null) {
this.rangeAxis.addChangeListener(this);
}
}
/**
* Multiplies the range on the horizontal axis/axes by the specified factor.
*
* @param factor the zoom factor.
*/
public void zoomHorizontalAxes(double factor) {
// do nothing
}
/**
* Multiplies the range on the vertical axis/axes by the specified factor.
*
* @param factor the zoom factor.
*/
public void zoomVerticalAxes(double factor) {
// zoom the range axis
}
/**
* Zooms the horizontal axes.
*
* @param lowerPercent the lower percent.
* @param upperPercent the upper percent.
*/
public void zoomHorizontalAxes(double lowerPercent, double upperPercent) {
// zoom the domain axis
}
/**
* Zooms the vertical axes.
*
* @param lowerPercent the lower percent.
* @param upperPercent the upper percent.
*/
public void zoomVerticalAxes(double lowerPercent, double upperPercent) {
// zoom the domain axis
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -