📄 meterplot.java
字号:
// paint);
// drawArc(g2, meterArea,
// data.getMaximumValue().doubleValue(),
// maxValue.doubleValue(),
// paint);
// }
// else {
drawArc(g2, meterArea, minValue, maxValue, paint);
// }
// draw a tick at each end of the range...
drawTick(g2, meterArea, minValue, true, paint);
drawTick(g2, meterArea, maxValue, true, paint);
//}
}
/**
* Draws an arc.
*
* @param g2 the graphics device.
* @param area the plot area.
* @param minValue the minimum value.
* @param maxValue the maximum value.
* @param paint the paint.
*/
protected void drawArc(Graphics2D g2, Rectangle2D area, double minValue, double maxValue,
Paint paint) {
drawArc(g2, area, minValue, maxValue, paint, 0);
}
/**
* Draws an arc.
*
* @param g2 the graphics device.
* @param area the plot area.
* @param minValue the minimum value.
* @param maxValue the maximum value.
* @param paint the paint.
* @param outlineType the outline type.
*/
protected void drawArc(Graphics2D g2, Rectangle2D area, double minValue, double maxValue,
Paint paint, int outlineType) {
double startAngle = calculateAngle(maxValue);
double endAngle = calculateAngle(minValue);
double extent = endAngle - startAngle;
double x = area.getX();
double y = area.getY();
double w = area.getWidth();
double h = area.getHeight();
g2.setPaint(paint);
if (outlineType > 0) {
g2.setStroke(new BasicStroke(10.0f));
}
else {
g2.setStroke(new BasicStroke(DEFAULT_BORDER_SIZE));
}
int joinType = Arc2D.OPEN;
if (outlineType > 0) {
if (this.shape == DialShape.PIE) {
joinType = Arc2D.PIE;
}
else if (this.shape == DialShape.CHORD) {
if (this.meterAngle > 180) {
joinType = Arc2D.CHORD;
}
else {
joinType = Arc2D.PIE;
}
}
else if (this.shape == DialShape.CIRCLE) {
joinType = Arc2D.PIE;
extent = 360;
}
else {
throw new IllegalStateException(
"MeterPlot.drawArc(...): dialType not recognised."
);
}
}
Arc2D.Double arc = new Arc2D.Double(x, y, w, h, startAngle, extent, joinType);
if (outlineType > 0) {
g2.fill(arc);
}
else {
g2.draw(arc);
}
}
/**
* Calculate an angle ???
*
* @param value the value.
*
* @return the result.
*/
double calculateAngle(double value) {
value -= this.minMeterValue;
double ret = this.meterCalcAngle - ((value / this.meterRange) * this.meterAngle);
return ret;
}
/**
* Draws the ticks.
*
* @param g2 the graphics device.
* @param meterArea the meter area.
* @param minValue the minimum value.
* @param maxValue the maximum value.
*/
protected void drawTicks(Graphics2D g2, Rectangle2D meterArea, double minValue,
double maxValue) {
int numberOfTicks = 20;
double diff = (maxValue - minValue) / numberOfTicks;
for (double i = minValue; i <= maxValue; i += diff) {
drawTick(g2, meterArea, i);
}
}
/**
* Draws a tick.
*
* @param g2 the graphics device.
* @param meterArea the meter area.
* @param value the value.
*/
protected void drawTick(Graphics2D g2, Rectangle2D meterArea, double value) {
drawTick(g2, meterArea, value, false, null, false, null);
}
/**
* Draws a tick.
*
* @param g2 the graphics device.
* @param meterArea the meter area.
* @param value the value.
* @param label the label.
* @param color the color.
*/
protected void drawTick(Graphics2D g2, Rectangle2D meterArea, double value, boolean label,
Paint color) {
drawTick(g2, meterArea, value, label, color, false, null);
}
/**
* Draws a tick on the chart (also handles a special case [curValue=true] that draws the
* value in the middle of the dial).
*
* @param g2 the graphics device.
* @param meterArea the meter area.
* @param value the tick value.
* @param label a flag that controls whether or not a value label is drawn.
* @param labelPaint the label color.
* @param curValue a flag for the special case of the current value.
* @param units the unit-of-measure for the dial.
*/
protected void drawTick(Graphics2D g2, Rectangle2D meterArea,
double value, boolean label, Paint labelPaint, boolean curValue, String units) {
double valueAngle = calculateAngle(value);
double meterMiddleX = meterArea.getCenterX();
double meterMiddleY = meterArea.getCenterY();
if (labelPaint == null) {
labelPaint = Color.white;
}
g2.setPaint(labelPaint);
g2.setStroke(new BasicStroke(2.0f));
double valueP2X = 0;
double valueP2Y = 0;
if (!curValue) {
double radius = (meterArea.getWidth() / 2) + DEFAULT_BORDER_SIZE;
double radius1 = radius - 15;
double valueP1X = meterMiddleX + (radius * Math.cos(Math.PI * (valueAngle / 180)));
double valueP1Y = meterMiddleY - (radius * Math.sin(Math.PI * (valueAngle / 180)));
valueP2X = meterMiddleX + (radius1 * Math.cos(Math.PI * (valueAngle / 180)));
valueP2Y = meterMiddleY - (radius1 * Math.sin(Math.PI * (valueAngle / 180)));
Line2D.Double line = new Line2D.Double(valueP1X, valueP1Y, valueP2X, valueP2Y);
g2.draw(line);
}
else {
valueP2X = meterMiddleX;
valueP2Y = meterMiddleY;
valueAngle = 90;
}
if (this.tickLabelType == VALUE_LABELS && label) {
String tickLabel = this.tickLabelFormat.format(value);
if (curValue && units != null) {
tickLabel += " " + units;
}
if (curValue) {
g2.setFont(getValueFont());
}
else {
if (this.tickLabelFont != null) {
g2.setFont(this.tickLabelFont);
}
}
FontMetrics fm = g2.getFontMetrics();
Rectangle2D tickLabelBounds = TextUtilities.getTextBounds(tickLabel, g2, fm);
double x = valueP2X;
double y = valueP2Y;
if (curValue) {
y += DEFAULT_CIRCLE_SIZE;
}
if (valueAngle == 90 || valueAngle == 270) {
x = x - tickLabelBounds.getWidth() / 2;
}
else if (valueAngle < 90 || valueAngle > 270) {
x = x - tickLabelBounds.getWidth();
}
if ((valueAngle > 135 && valueAngle < 225) || valueAngle > 315 || valueAngle < 45) {
y = y - tickLabelBounds.getHeight() / 2;
}
else {
y = y + tickLabelBounds.getHeight() / 2;
}
g2.drawString(tickLabel, (float) x, (float) y);
}
}
/**
* Returns a short string describing the type of plot.
*
* @return always <i>Meter Plot</i>.
*/
public String getPlotType() {
return localizationResources.getString("Meter_Plot");
}
/**
* A zoom method that does nothing. Plots are required to support the zoom operation. In the
* case of a meter plot, 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
}
/**
* Tests the plot for equality with an arbitrary object. Note that the dataset is ignored
* for the purposes of testing equality.
*
* @param object the object (<code>null</code> permitted).
*
* @return A boolean.
*/
public boolean equals(Object object) {
if (object == this) {
return true;
}
if (object instanceof MeterPlot && super.equals(object)) {
MeterPlot p = (MeterPlot) object;
//private ValueDataset dataset <-- ignored
if (!ObjectUtils.equal(this.units, p.units)) {
return false;
}
if (!ObjectUtils.equal(this.range, p.range)) {
return false;
}
if (!ObjectUtils.equal(this.normalRange, p.normalRange)) {
return false;
}
if (!ObjectUtils.equal(this.warningRange, p.warningRange)) {
return false;
}
if (!ObjectUtils.equal(this.criticalRange, p.criticalRange)) {
return false;
}
if (!ObjectUtils.equal(this.dialOutlinePaint, p.dialOutlinePaint)) {
return false;
}
if (!ObjectUtils.equal(this.normalPaint, p.normalPaint)) {
return false;
}
if (!ObjectUtils.equal(this.warningPaint, p.warningPaint)) {
return false;
}
if (!ObjectUtils.equal(this.criticalPaint, p.criticalPaint)) {
return false;
}
if (this.shape != p.shape) {
return false;
}
if (!ObjectUtils.equal(this.dialBackgroundPaint, p.dialBackgroundPaint)) {
return false;
}
if (!ObjectUtils.equal(this.needlePaint, p.needlePaint)) {
return false;
}
if (!ObjectUtils.equal(this.valueFont, p.valueFont)) {
return false;
}
if (!ObjectUtils.equal(this.valuePaint, p.valuePaint)) {
return false;
}
if (this.tickLabelType != p.tickLabelType) {
return false;
}
if (!ObjectUtils.equal(this.tickLabelFont, p.tickLabelFont)) {
return false;
}
if (!ObjectUtils.equal(this.tickLabelFormat, p.tickLabelFormat)) {
return false;
}
if (this.drawBorder != p.drawBorder) {
return false;
}
if (this.meterAngle != p.meterAngle) {
return false;
}
return true;
}
return false;
}
/**
* 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.writePaint(this.criticalPaint, stream);
SerialUtilities.writePaint(this.dialBackgroundPaint, stream);
SerialUtilities.writePaint(this.needlePaint, stream);
SerialUtilities.writePaint(this.normalPaint, stream);
SerialUtilities.writePaint(this.valuePaint, stream);
SerialUtilities.writePaint(this.warningPaint, 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.criticalPaint = SerialUtilities.readPaint(stream);
this.dialBackgroundPaint = SerialUtilities.readPaint(stream);
this.needlePaint = SerialUtilities.readPaint(stream);
this.normalPaint = SerialUtilities.readPaint(stream);
this.valuePaint = SerialUtilities.readPaint(stream);
this.warningPaint = SerialUtilities.readPaint(stream);
if (this.dataset != null) {
this.dataset.addChangeListener(this);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
// DEPRECATED
///////////////////////////////////////////////////////////////////////////////////////////////
/** Constant for meter type 'pie'. */
public static final int DIALTYPE_PIE = 0;
/** Constant for meter type 'circle'. */
public static final int DIALTYPE_CIRCLE = 1;
/** Constant for meter type 'chord'. */
public static final int DIALTYPE_CHORD = 2;
/**
* Returns the type of dial (DIALTYPE_PIE, DIALTYPE_CIRCLE, DIALTYPE_CHORD).
*
* @return The dial type.
*
* @deprecated Use getDialShape().
*/
public int getDialType() {
if (this.shape == DialShape.CIRCLE) {
return MeterPlot.DIALTYPE_CIRCLE;
}
else if (this.shape == DialShape.CHORD) {
return MeterPlot.DIALTYPE_CHORD;
}
else if (this.shape == DialShape.PIE) {
return MeterPlot.DIALTYPE_PIE;
}
else {
throw new IllegalStateException("MeterPlot.getDialType: unrecognised dial type.");
}
}
/**
* Sets the dial type (background shape).
* <P>
* This controls the shape of the dial background. Use one of the constants:
* DIALTYPE_PIE, DIALTYPE_CIRCLE, or DIALTYPE_CHORD.
*
* @param type The dial type.
*
* @deprecated Use setDialShape(...).
*/
public void setDialType(int type) {
switch (type) {
case MeterPlot.DIALTYPE_CIRCLE:
setDialShape(DialShape.CIRCLE);
break;
case MeterPlot.DIALTYPE_CHORD:
setDialShape(DialShape.CHORD);
break;
case MeterPlot.DIALTYPE_PIE:
setDialShape(DialShape.PIE);
break;
default:
throw new IllegalArgumentException("MeterPlot.setDialType: unrecognised type.");
}
}
/**
* Correct cloning support, management of deeper copies and listeners
* @see Plot#clone()
*/
public Object clone() throws CloneNotSupportedException {
MeterPlot clone = (MeterPlot) super.clone();
if (clone.dataset != null) {
clone.dataset.addChangeListener(clone);
}
// range immutable -> OK
// DialShape immutable -> OK
// private DialShape shape = DialShape.CIRCLE;
return clone;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -