📄 meterplot.java
字号:
/* ===========================================================
* JFreeChart : a free chart library for the Java(tm) platform
* ===========================================================
*
* (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
*
* Project Info: http://www.jfree.org/jfreechart/index.html
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* --------------
* MeterPlot.java
* --------------
* (C) Copyright 2000-2007, by Hari and Contributors.
*
* Original Author: Hari (ourhari@hotmail.com);
* Contributor(s): David Gilbert (for Object Refinery Limited);
* Bob Orchard;
* Arnaud Lelievre;
* Nicolas Brodu;
* David Bastend;
*
* $Id: MeterPlot.java,v 1.13.2.10 2007/05/18 10:28:21 mungady Exp $
*
* Changes
* -------
* 01-Apr-2002 : Version 1, contributed by Hari (DG);
* 23-Apr-2002 : Moved dataset from JFreeChart to Plot (DG);
* 22-Aug-2002 : Added changes suggest by Bob Orchard, changed Color to Paint
* for consistency, plus added Javadoc comments (DG);
* 01-Oct-2002 : Fixed errors reported by Checkstyle (DG);
* 23-Jan-2003 : Removed one constructor (DG);
* 26-Mar-2003 : Implemented Serializable (DG);
* 20-Aug-2003 : Changed dataset from MeterDataset --> ValueDataset, added
* equals() method,
* 08-Sep-2003 : Added internationalization via use of properties
* resourceBundle (RFE 690236) (AL);
* implemented Cloneable, and various other changes (DG);
* 08-Sep-2003 : Added serialization methods (NB);
* 11-Sep-2003 : Added cloning support (NB);
* 16-Sep-2003 : Changed ChartRenderingInfo --> PlotRenderingInfo (DG);
* 25-Sep-2003 : Fix useless cloning. Correct dataset listener registration in
* constructor. (NB)
* 29-Oct-2003 : Added workaround for font alignment in PDF output (DG);
* 17-Jan-2004 : Changed to allow dialBackgroundPaint to be set to null - see
* bug 823628 (DG);
* 07-Apr-2004 : Changed string bounds calculation (DG);
* 12-May-2004 : Added tickLabelFormat attribute - see RFE 949566. Also
* updated the equals() method (DG);
* 02-Nov-2004 : Added sanity checks for range, and only draw the needle if the
* value is contained within the overall range - see bug report
* 1056047 (DG);
* 11-Jan-2005 : Removed deprecated code in preparation for the 1.0.0
* release (DG);
* 02-Feb-2005 : Added optional background paint for each region (DG);
* 22-Mar-2005 : Removed 'normal', 'warning' and 'critical' regions and put in
* facility to define an arbitrary number of MeterIntervals,
* based on a contribution by David Bastend (DG);
* 20-Apr-2005 : Small update for change to LegendItem constructors (DG);
* 05-May-2005 : Updated draw() method parameters (DG);
* 08-Jun-2005 : Fixed equals() method to handle GradientPaint (DG);
* 10-Nov-2005 : Added tickPaint, tickSize and valuePaint attributes, and
* put value label drawing code into a separate method (DG);
* ------------- JFREECHART 1.0.x ---------------------------------------------
* 05-Mar-2007 : Restore clip region correctly (see bug 1667750) (DG);
* 18-May-2007 : Set dataset for LegendItem (DG);
*
*/
package org.jfree.chart.plot;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.Arc2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.text.NumberFormat;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.ResourceBundle;
import org.jfree.chart.LegendItem;
import org.jfree.chart.LegendItemCollection;
import org.jfree.chart.event.PlotChangeEvent;
import org.jfree.data.Range;
import org.jfree.data.general.DatasetChangeEvent;
import org.jfree.data.general.ValueDataset;
import org.jfree.io.SerialUtilities;
import org.jfree.text.TextUtilities;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.TextAnchor;
import org.jfree.util.ObjectUtilities;
import org.jfree.util.PaintUtilities;
/**
* A plot that displays a single value in the form of a needle on a dial.
* Defined ranges (for example, 'normal', 'warning' and 'critical') can be
* highlighted on the dial.
*/
public class MeterPlot extends Plot implements Serializable, Cloneable {
/** For serialization. */
private static final long serialVersionUID = 2987472457734470962L;
/** The default background paint. */
static final Paint DEFAULT_DIAL_BACKGROUND_PAINT = Color.black;
/** The default needle paint. */
static final Paint DEFAULT_NEEDLE_PAINT = Color.green;
/** The default value font. */
static final Font DEFAULT_VALUE_FONT = new Font("SansSerif", Font.BOLD, 12);
/** The default value paint. */
static final Paint DEFAULT_VALUE_PAINT = Color.yellow;
/** The default meter angle. */
public static final int DEFAULT_METER_ANGLE = 270;
/** The default border size. */
public static final float DEFAULT_BORDER_SIZE = 3f;
/** The default circle size. */
public static final float DEFAULT_CIRCLE_SIZE = 10f;
/** The default label font. */
public static final Font DEFAULT_LABEL_FONT = new Font("SansSerif",
Font.BOLD, 10);
/** The dataset (contains a single value). */
private ValueDataset dataset;
/** The dial shape (background shape). */
private DialShape shape;
/** The dial extent (measured in degrees). */
private int meterAngle;
/** The overall range of data values on the dial. */
private Range range;
/** The tick size. */
private double tickSize;
/** The paint used to draw the ticks. */
private transient Paint tickPaint;
/** The units displayed on the dial. */
private String units;
/** The font for the value displayed in the center of the dial. */
private Font valueFont;
/** The paint for the value displayed in the center of the dial. */
private transient Paint valuePaint;
/** A flag that controls whether or not the border is drawn. */
private boolean drawBorder;
/** The outline paint. */
private transient Paint dialOutlinePaint;
/** The paint for the dial background. */
private transient Paint dialBackgroundPaint;
/** The paint for the needle. */
private transient Paint needlePaint;
/** A flag that controls whether or not the tick labels are visible. */
private boolean tickLabelsVisible;
/** The tick label font. */
private Font tickLabelFont;
/** The tick label paint. */
private transient Paint tickLabelPaint;
/** The tick label format. */
private NumberFormat tickLabelFormat;
/** The resourceBundle for the localization. */
protected static ResourceBundle localizationResources =
ResourceBundle.getBundle("org.jfree.chart.plot.LocalizationBundle");
/**
* A (possibly empty) list of the {@link MeterInterval}s to be highlighted
* on the dial.
*/
private List intervals;
/**
* Creates a new plot with a default range of <code>0</code> to
* <code>100</code> and no value to display.
*/
public MeterPlot() {
this(null);
}
/**
* Creates a new plot that displays the value from the supplied dataset.
*
* @param dataset the dataset (<code>null</code> permitted).
*/
public MeterPlot(ValueDataset dataset) {
super();
this.shape = DialShape.CIRCLE;
this.meterAngle = DEFAULT_METER_ANGLE;
this.range = new Range(0.0, 100.0);
this.tickSize = 10.0;
this.tickPaint = Color.white;
this.units = "Units";
this.needlePaint = MeterPlot.DEFAULT_NEEDLE_PAINT;
this.tickLabelsVisible = true;
this.tickLabelFont = MeterPlot.DEFAULT_LABEL_FONT;
this.tickLabelPaint = Color.black;
this.tickLabelFormat = NumberFormat.getInstance();
this.valueFont = MeterPlot.DEFAULT_VALUE_FONT;
this.valuePaint = MeterPlot.DEFAULT_VALUE_PAINT;
this.dialBackgroundPaint = MeterPlot.DEFAULT_DIAL_BACKGROUND_PAINT;
this.intervals = new java.util.ArrayList();
setDataset(dataset);
}
/**
* Returns the dial shape. The default is {@link DialShape#CIRCLE}).
*
* @return The dial shape (never <code>null</code>).
*
* @see #setDialShape(DialShape)
*/
public DialShape getDialShape() {
return this.shape;
}
/**
* Sets the dial shape and sends a {@link PlotChangeEvent} to all
* registered listeners.
*
* @param shape the shape (<code>null</code> not permitted).
*
* @see #getDialShape()
*/
public void setDialShape(DialShape shape) {
if (shape == null) {
throw new IllegalArgumentException("Null 'shape' argument.");
}
this.shape = shape;
notifyListeners(new PlotChangeEvent(this));
}
/**
* Returns the meter angle in degrees. This defines, in part, the shape
* of the dial. The default is 270 degrees.
*
* @return The meter angle (in degrees).
*
* @see #setMeterAngle(int)
*/
public int getMeterAngle() {
return this.meterAngle;
}
/**
* Sets the angle (in degrees) for the whole range of the dial and sends
* a {@link PlotChangeEvent} to all registered listeners.
*
* @param angle the angle (in degrees, in the range 1-360).
*
* @see #getMeterAngle()
*/
public void setMeterAngle(int angle) {
if (angle < 1 || angle > 360) {
throw new IllegalArgumentException("Invalid 'angle' (" + angle
+ ")");
}
this.meterAngle = angle;
notifyListeners(new PlotChangeEvent(this));
}
/**
* Returns the overall range for the dial.
*
* @return The overall range (never <code>null</code>).
*
* @see #setRange(Range)
*/
public Range getRange() {
return this.range;
}
/**
* Sets the range for the dial and sends a {@link PlotChangeEvent} to all
* registered listeners.
*
* @param range the range (<code>null</code> not permitted and zero-length
* ranges not permitted).
*
* @see #getRange()
*/
public void setRange(Range range) {
if (range == null) {
throw new IllegalArgumentException("Null 'range' argument.");
}
if (!(range.getLength() > 0.0)) {
throw new IllegalArgumentException(
"Range length must be positive.");
}
this.range = range;
notifyListeners(new PlotChangeEvent(this));
}
/**
* Returns the tick size (the interval between ticks on the dial).
*
* @return The tick size.
*
* @see #setTickSize(double)
*/
public double getTickSize() {
return this.tickSize;
}
/**
* Sets the tick size and sends a {@link PlotChangeEvent} to all
* registered listeners.
*
* @param size the tick size (must be > 0).
*
* @see #getTickSize()
*/
public void setTickSize(double size) {
if (size <= 0) {
throw new IllegalArgumentException("Requires 'size' > 0.");
}
this.tickSize = size;
notifyListeners(new PlotChangeEvent(this));
}
/**
* Returns the paint used to draw the ticks around the dial.
*
* @return The paint used to draw the ticks around the dial (never
* <code>null</code>).
*
* @see #setTickPaint(Paint)
*/
public Paint getTickPaint() {
return this.tickPaint;
}
/**
* Sets the paint used to draw the tick labels around the dial and sends
* a {@link PlotChangeEvent} to all registered listeners.
*
* @param paint the paint (<code>null</code> not permitted).
*
* @see #getTickPaint()
*/
public void setTickPaint(Paint paint) {
if (paint == null) {
throw new IllegalArgumentException("Null 'paint' argument.");
}
this.tickPaint = paint;
notifyListeners(new PlotChangeEvent(this));
}
/**
* Returns a string describing the units for the dial.
*
* @return The units (possibly <code>null</code>).
*
* @see #setUnits(String)
*/
public String getUnits() {
return this.units;
}
/**
* Sets the units for the dial and sends a {@link PlotChangeEvent} to all
* registered listeners.
*
* @param units the units (<code>null</code> permitted).
*
* @see #getUnits()
*/
public void setUnits(String units) {
this.units = units;
notifyListeners(new PlotChangeEvent(this));
}
/**
* Returns the paint for the needle.
*
* @return The paint (never <code>null</code>).
*
* @see #setNeedlePaint(Paint)
*/
public Paint getNeedlePaint() {
return this.needlePaint;
}
/**
* Sets the paint used to display the needle and sends a
* {@link PlotChangeEvent} to all registered listeners.
*
* @param paint the paint (<code>null</code> not permitted).
*
* @see #getNeedlePaint()
*/
public void setNeedlePaint(Paint paint) {
if (paint == null) {
throw new IllegalArgumentException("Null 'paint' argument.");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -