001/* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-present, by David Gilbert and Contributors. 006 * 007 * Project Info: http://www.jfree.org/jfreechart/index.html 008 * 009 * This library is free software; you can redistribute it and/or modify it 010 * under the terms of the GNU Lesser General Public License as published by 011 * the Free Software Foundation; either version 2.1 of the License, or 012 * (at your option) any later version. 013 * 014 * This library is distributed in the hope that it will be useful, but 015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 017 * License for more details. 018 * 019 * You should have received a copy of the GNU Lesser General Public 020 * License along with this library; if not, write to the Free Software 021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 022 * USA. 023 * 024 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 025 * Other names may be trademarks of their respective owners.] 026 * 027 * ------------------- 028 * DialBackground.java 029 * ------------------- 030 * (C) Copyright 2006-present, by David Gilbert. 031 * 032 * Original Author: David Gilbert; 033 * Contributor(s): -; 034 * 035 */ 036 037package org.jfree.chart.plot.dial; 038 039import java.awt.Color; 040import java.awt.GradientPaint; 041import java.awt.Graphics2D; 042import java.awt.Paint; 043import java.awt.geom.Rectangle2D; 044import java.io.IOException; 045import java.io.ObjectInputStream; 046import java.io.ObjectOutputStream; 047import java.io.Serializable; 048 049import org.jfree.chart.HashUtils; 050import org.jfree.chart.ui.GradientPaintTransformer; 051import org.jfree.chart.ui.StandardGradientPaintTransformer; 052import org.jfree.chart.util.PaintUtils; 053import org.jfree.chart.util.Args; 054import org.jfree.chart.util.PublicCloneable; 055import org.jfree.chart.util.SerialUtils; 056 057/** 058 * A regular dial layer that can be used to draw the background for a dial. 059 */ 060public class DialBackground extends AbstractDialLayer implements DialLayer, 061 Cloneable, PublicCloneable, Serializable { 062 063 /** For serialization. */ 064 static final long serialVersionUID = -9019069533317612375L; 065 066 /** 067 * The background paint. This field is transient because serialization 068 * requires special handling. 069 */ 070 private transient Paint paint; 071 072 /** 073 * The transformer used when the background paint is an instance of 074 * {@code GradientPaint}. 075 */ 076 private GradientPaintTransformer gradientPaintTransformer; 077 078 /** 079 * Creates a new instance of {@code DialBackground}. The 080 * default background paint is {@code Color.WHITE}. 081 */ 082 public DialBackground() { 083 this(Color.WHITE); 084 } 085 086 /** 087 * Creates a new instance of {@code DialBackground}. 088 * 089 * @param paint the paint ({@code null} not permitted). 090 * 091 * @throws IllegalArgumentException if {@code Paint} is 092 * {@code null}. 093 */ 094 public DialBackground(Paint paint) { 095 Args.nullNotPermitted(paint, "paint"); 096 this.paint = paint; 097 this.gradientPaintTransformer = new StandardGradientPaintTransformer(); 098 } 099 100 /** 101 * Returns the paint used to fill the background. 102 * 103 * @return The paint (never {@code null}). 104 * 105 * @see #setPaint(Paint) 106 */ 107 public Paint getPaint() { 108 return this.paint; 109 } 110 111 /** 112 * Sets the paint for the dial background and sends a 113 * {@link DialLayerChangeEvent} to all registered listeners. 114 * 115 * @param paint the paint ({@code null} not permitted). 116 * 117 * @see #getPaint() 118 */ 119 public void setPaint(Paint paint) { 120 Args.nullNotPermitted(paint, "paint"); 121 this.paint = paint; 122 notifyListeners(new DialLayerChangeEvent(this)); 123 } 124 125 /** 126 * Returns the transformer used to adjust the coordinates of any 127 * {@code GradientPaint} instance used for the background paint. 128 * 129 * @return The transformer (never {@code null}). 130 * 131 * @see #setGradientPaintTransformer(GradientPaintTransformer) 132 */ 133 public GradientPaintTransformer getGradientPaintTransformer() { 134 return this.gradientPaintTransformer; 135 } 136 137 /** 138 * Sets the transformer used to adjust the coordinates of any 139 * {@code GradientPaint} instance used for the background paint, and 140 * sends a {@link DialLayerChangeEvent} to all registered listeners. 141 * 142 * @param t the transformer ({@code null} not permitted). 143 * 144 * @see #getGradientPaintTransformer() 145 */ 146 public void setGradientPaintTransformer(GradientPaintTransformer t) { 147 Args.nullNotPermitted(t, "t"); 148 this.gradientPaintTransformer = t; 149 notifyListeners(new DialLayerChangeEvent(this)); 150 } 151 152 /** 153 * Returns {@code true} to indicate that this layer should be 154 * clipped within the dial window. 155 * 156 * @return {@code true}. 157 */ 158 @Override 159 public boolean isClippedToWindow() { 160 return true; 161 } 162 163 /** 164 * Draws the background to the specified graphics device. If the dial 165 * frame specifies a window, the clipping region will already have been 166 * set to this window before this method is called. 167 * 168 * @param g2 the graphics device ({@code null} not permitted). 169 * @param plot the plot (ignored here). 170 * @param frame the dial frame (ignored here). 171 * @param view the view rectangle ({@code null} not permitted). 172 */ 173 @Override 174 public void draw(Graphics2D g2, DialPlot plot, Rectangle2D frame, 175 Rectangle2D view) { 176 177 Paint p = this.paint; 178 if (p instanceof GradientPaint) { 179 p = this.gradientPaintTransformer.transform((GradientPaint) p, 180 view); 181 } 182 g2.setPaint(p); 183 g2.fill(view); 184 } 185 186 /** 187 * Tests this instance for equality with an arbitrary object. 188 * 189 * @param obj the object ({@code null} permitted). 190 * 191 * @return A boolean. 192 */ 193 @Override 194 public boolean equals(Object obj) { 195 if (obj == this) { 196 return true; 197 } 198 if (!(obj instanceof DialBackground)) { 199 return false; 200 } 201 DialBackground that = (DialBackground) obj; 202 if (!PaintUtils.equal(this.paint, that.paint)) { 203 return false; 204 } 205 if (!this.gradientPaintTransformer.equals( 206 that.gradientPaintTransformer)) { 207 return false; 208 } 209 return super.equals(obj); 210 } 211 212 /** 213 * Returns a hash code for this instance. 214 * 215 * @return The hash code. 216 */ 217 @Override 218 public int hashCode() { 219 int result = 193; 220 result = 37 * result + HashUtils.hashCodeForPaint(this.paint); 221 result = 37 * result + this.gradientPaintTransformer.hashCode(); 222 return result; 223 } 224 225 /** 226 * Returns a clone of this instance. 227 * 228 * @return The clone. 229 * 230 * @throws CloneNotSupportedException if some attribute of this instance 231 * cannot be cloned. 232 */ 233 @Override 234 public Object clone() throws CloneNotSupportedException { 235 return super.clone(); 236 } 237 238 /** 239 * Provides serialization support. 240 * 241 * @param stream the output stream. 242 * 243 * @throws IOException if there is an I/O error. 244 */ 245 private void writeObject(ObjectOutputStream stream) throws IOException { 246 stream.defaultWriteObject(); 247 SerialUtils.writePaint(this.paint, stream); 248 } 249 250 /** 251 * Provides serialization support. 252 * 253 * @param stream the input stream. 254 * 255 * @throws IOException if there is an I/O error. 256 * @throws ClassNotFoundException if there is a classpath problem. 257 */ 258 private void readObject(ObjectInputStream stream) 259 throws IOException, ClassNotFoundException { 260 stream.defaultReadObject(); 261 this.paint = SerialUtils.readPaint(stream); 262 } 263 264}