org.jfree.chart.plot.dial.StandardDialFrame Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jfreechart Show documentation
Show all versions of jfreechart Show documentation
JFreeChart is a class library, written in Java, for generating charts.
Utilising the Java2D API, it supports a wide range of chart types including
bar charts, pie charts, line charts, XY-plots, time series plots, Sankey charts
and more.
/* ===========================================================
* JFreeChart : a free chart library for the Java(tm) platform
* ===========================================================
*
* (C) Copyright 2000-present, by David Gilbert 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.
*
* [Oracle and Java are registered trademarks of Oracle and/or its affiliates.
* Other names may be trademarks of their respective owners.]
*
* ----------------------
* StandardDialFrame.java
* ----------------------
* (C) Copyright 2006-present, by David Gilbert.
*
* Original Author: David Gilbert;
* Contributor(s): -;
*
*/
package org.jfree.chart.plot.dial;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.jfree.chart.HashUtils;
import org.jfree.chart.util.PaintUtils;
import org.jfree.chart.util.Args;
import org.jfree.chart.util.PublicCloneable;
import org.jfree.chart.util.SerialUtils;
/**
* A simple circular frame for the {@link DialPlot} class.
*/
public class StandardDialFrame extends AbstractDialLayer implements DialFrame,
Cloneable, PublicCloneable, Serializable {
/** For serialization. */
static final long serialVersionUID = 1016585407507121596L;
/** The outer radius, relative to the framing rectangle. */
private double radius;
/**
* The color used for the front of the panel. This field is transient
* because it requires special handling for serialization.
*/
private transient Paint backgroundPaint;
/**
* The color used for the border around the window. This field is transient
* because it requires special handling for serialization.
*/
private transient Paint foregroundPaint;
/**
* The stroke for drawing the frame outline. This field is transient
* because it requires special handling for serialization.
*/
private transient Stroke stroke;
/**
* Creates a new instance of {@code StandardDialFrame}.
*/
public StandardDialFrame() {
this.backgroundPaint = Color.GRAY;
this.foregroundPaint = Color.BLACK;
this.stroke = new BasicStroke(2.0f);
this.radius = 0.95;
}
/**
* Returns the radius, relative to the framing rectangle.
*
* @return The radius.
*
* @see #setRadius(double)
*/
public double getRadius() {
return this.radius;
}
/**
* Sets the radius and sends a {@link DialLayerChangeEvent} to all
* registered listeners.
*
* @param radius the radius (must be positive).
*
* @see #getRadius()
*/
public void setRadius(double radius) {
if (radius <= 0) {
throw new IllegalArgumentException(
"The 'radius' must be positive.");
}
this.radius = radius;
notifyListeners(new DialLayerChangeEvent(this));
}
/**
* Returns the background paint.
*
* @return The background paint (never {@code null}).
*
* @see #setBackgroundPaint(Paint)
*/
public Paint getBackgroundPaint() {
return this.backgroundPaint;
}
/**
* Sets the background paint and sends a {@link DialLayerChangeEvent} to
* all registered listeners.
*
* @param paint the paint ({@code null} not permitted).
*
* @see #getBackgroundPaint()
*/
public void setBackgroundPaint(Paint paint) {
Args.nullNotPermitted(paint, "paint");
this.backgroundPaint = paint;
notifyListeners(new DialLayerChangeEvent(this));
}
/**
* Returns the foreground paint.
*
* @return The foreground paint (never {@code null}).
*
* @see #setForegroundPaint(Paint)
*/
public Paint getForegroundPaint() {
return this.foregroundPaint;
}
/**
* Sets the foreground paint and sends a {@link DialLayerChangeEvent} to
* all registered listeners.
*
* @param paint the paint ({@code null} not permitted).
*
* @see #getForegroundPaint()
*/
public void setForegroundPaint(Paint paint) {
Args.nullNotPermitted(paint, "paint");
this.foregroundPaint = paint;
notifyListeners(new DialLayerChangeEvent(this));
}
/**
* Returns the stroke for the frame.
*
* @return The stroke (never {@code null}).
*
* @see #setStroke(Stroke)
*/
public Stroke getStroke() {
return this.stroke;
}
/**
* Sets the stroke and sends a {@link DialLayerChangeEvent} to all
* registered listeners.
*
* @param stroke the stroke ({@code null} not permitted).
*
* @see #getStroke()
*/
public void setStroke(Stroke stroke) {
Args.nullNotPermitted(stroke, "stroke");
this.stroke = stroke;
notifyListeners(new DialLayerChangeEvent(this));
}
/**
* Returns the shape for the window for this dial. Some dial layers will
* request that their drawing be clipped within this window.
*
* @param frame the reference frame ({@code null} not permitted).
*
* @return The shape of the dial's window.
*/
@Override
public Shape getWindow(Rectangle2D frame) {
Rectangle2D f = DialPlot.rectangleByRadius(frame, this.radius,
this.radius);
return new Ellipse2D.Double(f.getX(), f.getY(), f.getWidth(),
f.getHeight());
}
/**
* Returns {@code false} to indicate that this dial layer is not
* clipped to the dial window.
*
* @return A boolean.
*/
@Override
public boolean isClippedToWindow() {
return false;
}
/**
* Draws the frame. This method is called by the {@link DialPlot} class,
* you shouldn't need to call it directly.
*
* @param g2 the graphics target ({@code null} not permitted).
* @param plot the plot ({@code null} not permitted).
* @param frame the frame ({@code null} not permitted).
* @param view the view ({@code null} not permitted).
*/
@Override
public void draw(Graphics2D g2, DialPlot plot, Rectangle2D frame,
Rectangle2D view) {
Shape window = getWindow(frame);
Rectangle2D f = DialPlot.rectangleByRadius(frame, this.radius + 0.02,
this.radius + 0.02);
Ellipse2D e = new Ellipse2D.Double(f.getX(), f.getY(), f.getWidth(),
f.getHeight());
Area area = new Area(e);
Area area2 = new Area(window);
area.subtract(area2);
g2.setPaint(this.backgroundPaint);
g2.fill(area);
g2.setStroke(this.stroke);
g2.setPaint(this.foregroundPaint);
g2.draw(window);
g2.draw(e);
}
/**
* Tests this instance for equality with an arbitrary object.
*
* @param obj the object ({@code null} permitted).
*
* @return A boolean.
*/
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof StandardDialFrame)) {
return false;
}
StandardDialFrame that = (StandardDialFrame) obj;
if (!PaintUtils.equal(this.backgroundPaint, that.backgroundPaint)) {
return false;
}
if (!PaintUtils.equal(this.foregroundPaint, that.foregroundPaint)) {
return false;
}
if (this.radius != that.radius) {
return false;
}
if (!this.stroke.equals(that.stroke)) {
return false;
}
return super.equals(obj);
}
/**
* Returns a hash code for this instance.
*
* @return The hash code.
*/
@Override
public int hashCode() {
int result = 193;
long temp = Double.doubleToLongBits(this.radius);
result = 37 * result + (int) (temp ^ (temp >>> 32));
result = 37 * result + HashUtils.hashCodeForPaint(
this.backgroundPaint);
result = 37 * result + HashUtils.hashCodeForPaint(
this.foregroundPaint);
result = 37 * result + this.stroke.hashCode();
return result;
}
/**
* Returns a clone of this instance.
*
* @return A clone.
*
* @throws CloneNotSupportedException if any of the frame's attributes
* cannot be cloned.
*/
@Override
public Object clone() throws CloneNotSupportedException {
return super.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();
SerialUtils.writePaint(this.backgroundPaint, stream);
SerialUtils.writePaint(this.foregroundPaint, stream);
SerialUtils.writeStroke(this.stroke, 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.backgroundPaint = SerialUtils.readPaint(stream);
this.foregroundPaint = SerialUtils.readPaint(stream);
this.stroke = SerialUtils.readStroke(stream);
}
}