meterplot.java
来自「JfreeChart 常用图表例子」· Java 代码 · 共 1,194 行 · 第 1/3 页
JAVA
1,194 行
Paint backgroundPaint = interval.getBackgroundPaint(); if (backgroundPaint != null) { fillArc(g2, meterArea, minValue, maxValue, backgroundPaint, false); } if (outlinePaint != null) { if (outlineStroke != null) { drawArc( g2, meterArea, minValue, maxValue, outlinePaint, outlineStroke ); } drawTick(g2, meterArea, minValue, true, outlinePaint); drawTick(g2, meterArea, maxValue, true, outlinePaint); } } /** * 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 stroke the stroke. */ protected void drawArc(Graphics2D g2, Rectangle2D area, double minValue, double maxValue, Paint paint, Stroke stroke) { double startAngle = valueToAngle(maxValue); double endAngle = valueToAngle(minValue); double extent = endAngle - startAngle; double x = area.getX(); double y = area.getY(); double w = area.getWidth(); double h = area.getHeight(); g2.setPaint(paint); g2.setStroke(stroke); if (paint != null && stroke != null) { Arc2D.Double arc = new Arc2D.Double( x, y, w, h, startAngle, extent, Arc2D.OPEN ); g2.setPaint(paint); g2.setStroke(stroke); g2.draw(arc); } } /** * Fills an arc on the dial between the given values. * * @param g2 the graphics device. * @param area the plot area. * @param minValue the minimum data value. * @param maxValue the maximum data value. * @param paint the background paint (<code>null</code> not permitted). */ private void fillArc(Graphics2D g2, Rectangle2D area, double minValue, double maxValue, Paint paint, boolean dial) { if (paint == null) { throw new IllegalArgumentException("Null 'paint' argument"); } double startAngle = valueToAngle(maxValue); double endAngle = valueToAngle(minValue); double extent = endAngle - startAngle; double x = area.getX(); double y = area.getY(); double w = area.getWidth(); double h = area.getHeight(); int joinType = Arc2D.OPEN; if (this.shape == DialShape.PIE) { joinType = Arc2D.PIE; } else if (this.shape == DialShape.CHORD) { if (dial && this.meterAngle > 180) { joinType = Arc2D.CHORD; } else { joinType = Arc2D.PIE; } } else if (this.shape == DialShape.CIRCLE) { joinType = Arc2D.PIE; if (dial) { extent = 360; } } else { throw new IllegalStateException("DialShape not recognised."); } g2.setPaint(paint); Arc2D.Double arc = new Arc2D.Double( x, y, w, h, startAngle, extent, joinType ); g2.fill(arc); } /** * Translates a data value to an angle on the dial. * * @param value the value. * * @return The angle on the dial. */ public double valueToAngle(double value) { value = value - this.range.getLowerBound(); double baseAngle = 180 + ((this.meterAngle - 180) / 2); return baseAngle - ((value / this.range.getLength()) * this.meterAngle); } /** * Draws the 20 ticks that subdivide the overall range. * * @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 v = minValue; v <= maxValue; v += diff) { drawTick(g2, meterArea, v); } } /** * 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 display a label? * @param paint the paint. */ protected void drawTick(Graphics2D g2, Rectangle2D meterArea, double value, boolean label, Paint paint) { drawTick(g2, meterArea, value, label, paint, 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 = valueToAngle(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.tickLabelsVisible && 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 A string describing the type of plot. */ 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 that = (MeterPlot) object; if (!ObjectUtilities.equal(this.units, that.units)) { return false; } if (!ObjectUtilities.equal(this.range, that.range)) { return false; } if (!ObjectUtilities.equal(this.intervals, that.intervals)) { return false; } if (!ObjectUtilities.equal(this.dialOutlinePaint, that.dialOutlinePaint)) { return false; } if (this.shape != that.shape) { return false; } if (!ObjectUtilities.equal(this.dialBackgroundPaint, that.dialBackgroundPaint)) { return false; } if (!ObjectUtilities.equal(this.needlePaint, that.needlePaint)) { return false; } if (!ObjectUtilities.equal(this.valueFont, that.valueFont)) { return false; } if (!ObjectUtilities.equal(this.valuePaint, that.valuePaint)) { return false; } if (this.tickLabelsVisible != that.tickLabelsVisible) { return false; } if (!ObjectUtilities.equal(this.tickLabelFont, that.tickLabelFont)) { return false; } if (!ObjectUtilities.equal(this.tickLabelFormat, that.tickLabelFormat)) { return false; } if (this.drawBorder != that.drawBorder) { return false; } if (this.meterAngle != that.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.dialBackgroundPaint, stream); SerialUtilities.writePaint(this.needlePaint, stream); SerialUtilities.writePaint(this.valuePaint, 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.dialBackgroundPaint = SerialUtilities.readPaint(stream); this.needlePaint = SerialUtilities.readPaint(stream); this.valuePaint = SerialUtilities.readPaint(stream); if (this.dataset != null) { this.dataset.addChangeListener(this); } } /** * Returns an independent copy (clone) of the plot. The dataset is NOT * cloned - both the original and the clone will have a reference to the * same dataset. * * @return A clone. * * @throws CloneNotSupportedException if some component of the plot cannot * be cloned. */ public Object clone() throws CloneNotSupportedException { MeterPlot clone = (MeterPlot) super.clone(); clone.tickLabelFormat = (NumberFormat) this.tickLabelFormat.clone(); // the following relies on the fact that the intervals are immutable clone.intervals = new java.util.ArrayList(this.intervals); if (clone.dataset != null) { clone.dataset.addChangeListener(clone); } return clone; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?