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 + -
显示快捷键?