001: /**
002: * Chart2D, a java library for drawing two dimensional charts.
003: * Copyright (C) 2001 Jason J. Simas
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: * The author of this library may be contacted at:
019: * E-mail: jjsimas@users.sourceforge.net
020: * Street Address: J J Simas, 887 Tico Road, Ojai, CA 93023-3555 USA
021: */package net.sourceforge.chart2d;
022:
023: import java.awt.*;
024: import java.awt.geom.*;
025: import java.util.*;
026:
027: /**
028: * A rectangle capable of automatic gradient paint, rounded corners on any single side,
029: * and warning region coloring.
030: */
031: final class FancyBar extends FancyShape {
032:
033: private Rectangle2D.Float bounds, clipBounds;
034: private float arcw, arch;
035: private RoundRectangle2D.Float bar;
036: private FancyBar[] warningBars;
037: private int dataSign, baseValue;
038: private boolean needsUpdate;
039:
040: /**
041: * Values for x, y, width, height, and roundSide needs to be set before use.
042: * Default rounding is squuare.
043: */
044: FancyBar() {
045: needsUpdate = true;
046: }
047:
048: /**
049: * Sets the value at which the bar should not begin for that end should not be rounded.
050: * @param value The base value.
051: */
052: final void setBaseValue(int value) {
053: baseValue = value;
054: needsUpdate = true;
055: }
056:
057: /**
058: * Gets the value at which the bar should not begin for that end should not be rounded.
059: * @return The base value.
060: */
061: final int getBaseValue() {
062: return baseValue;
063: }
064:
065: /**
066: * Sets which kinds of the data is graphed.
067: * Uses fields of GraphArea.
068: * Use POS for non-negative data.
069: * Use NEG for non-positive data.
070: * Use MIX for both positive and negative data.
071: * @param sign The sign of the data.
072: */
073: final void setDataSign(int sign) {
074:
075: dataSign = sign;
076: needsUpdate = true;
077: }
078:
079: /**
080: * Gets which kinds of the data is graphed.
081: * Uses fields of GraphArea.
082: * Use POS for non-negative data.
083: * Use NEG for non-positive data.
084: * Use MIX for both positive and negative data.
085: * @return The sign of the data.
086: */
087: final int getDataSign() {
088: return dataSign;
089: }
090:
091: /**
092: * Sets the bounds for this bar (specifying the size and location of the bar).
093: * @param b The bounds.
094: */
095: final void setBounds(Rectangle2D.Float b) {
096: bounds = b;
097: needsUpdate = true;
098: }
099:
100: /**
101: * Sets the clip bounds for this bar (specifying what will show).
102: * @param b The bounds.
103: */
104: final void setClipBounds(Rectangle2D.Float b) {
105: clipBounds = b;
106: needsUpdate = true;
107: }
108:
109: /**
110: * Sets the radius of the (width) arc for the bar rounding.
111: * @param w The width arc radius.
112: */
113: final void setArcw(float w) {
114: arcw = w;
115: needsUpdate = true;
116: }
117:
118: /*
119: * Sets the radius of the (height) arc for the bar rounding.
120: * @param h The height arc radius.
121: */
122: final void setArch(float h) {
123: arch = h;
124: needsUpdate = true;
125: }
126:
127: /**
128: * Gets the bounds for this bar (specifying the size and location of the bar).
129: * @return The bounds.
130: */
131: final Rectangle2D.Float getBounds() {
132: return bounds;
133: }
134:
135: /**
136: * Gets the clip bounds for this bar (specifying what will show).
137: * @return The bounds.
138: */
139: final Rectangle2D.Float getClipBounds() {
140: return clipBounds;
141: }
142:
143: /**
144: * Gets the radius of the (width) arc for the bar rounding.
145: * @return The width arc radius.
146: */
147: final float getArcw() {
148: return arcw;
149: }
150:
151: /*
152: * Gets the radius of the (height) arc for the bar rounding.
153: * @return The height arc radius.
154: */
155: final float getArch() {
156: return arch;
157: }
158:
159: /**
160: * Paints the bar on the Graphics2D object after calling update.
161: * @param g2D The Graphics2D object.
162: */
163: final void paint(Graphics2D g2D) {
164:
165: update();
166:
167: Paint oldPaint = g2D.getPaint();
168: g2D.setPaint(getPaint());
169:
170: Shape oldClip = g2D.getClip();
171: java.awt.geom.Area clipArea = new java.awt.geom.Area(clipBounds);
172: clipArea.intersect(new java.awt.geom.Area(oldClip));
173: g2D.setClip(clipArea);
174:
175: g2D.fill(bar);
176:
177: if (getOutlineExistence() && bounds.width > 2f
178: && bounds.height > 2f) {
179:
180: g2D.setPaint(getOutlinePaint());
181: g2D.draw(bar);
182: }
183:
184: g2D.setPaint(oldPaint);
185: g2D.setClip(oldClip);
186:
187: if (getWarningRegions() != null) {
188: for (int i = 0; i < warningBars.length; ++i)
189: warningBars[i].paint(g2D);
190: }
191: }
192:
193: /**
194: * Updates the FancyBar.
195: */
196: final void update() {
197:
198: super .update();
199:
200: if (needsUpdate) {
201:
202: if (getType() == LABELSLEFT) {
203:
204: if (dataSign == GraphArea.POS) {
205: bar = new RoundRectangle2D.Float(bounds.x
206: - (arcw / 2f), bounds.y, bounds.width
207: + (arcw / 2f), bounds.height, arcw, arch);
208: } else if (dataSign == GraphArea.NEG) {
209: bar = new RoundRectangle2D.Float(bounds.x,
210: bounds.y, bounds.width + (arcw / 2f),
211: bounds.height, arcw, arch);
212: } else {
213:
214: if (bounds.x >= baseValue) {
215: bar = new RoundRectangle2D.Float(bounds.x
216: - (arcw / 2f), bounds.y, bounds.width
217: + (arcw / 2f), bounds.height, arcw,
218: arch);
219: } else {
220: bar = new RoundRectangle2D.Float(bounds.x,
221: bounds.y, bounds.width + (arcw / 2f),
222: bounds.height, arcw, arch);
223: }
224: }
225: } else { //LABELSBOTTOM
226:
227: if (dataSign == GraphArea.POS) {
228: bar = new RoundRectangle2D.Float(bounds.x,
229: bounds.y, bounds.width, bounds.height
230: + (arch / 2f), arcw, arch);
231: } else if (dataSign == GraphArea.NEG) {
232: bar = new RoundRectangle2D.Float(bounds.x, bounds.y
233: - (arch / 2f), bounds.width, bounds.height
234: + (arch / 2f), arcw, arch);
235: } else {
236:
237: if (baseValue <= bounds.y) {
238: bar = new RoundRectangle2D.Float(bounds.x,
239: bounds.y - (arch / 2f), bounds.width,
240: bounds.height + (arch / 2f), arcw, arch);
241: } else {
242: bar = new RoundRectangle2D.Float(bounds.x,
243: bounds.y, bounds.width, bounds.height
244: + (arch / 2f), arcw, arch);
245: }
246: }
247: }
248:
249: if (getWarningRegions() != null) {
250:
251: warningBars = new FancyBar[getWarningRegions().size()];
252: for (int i = 0; i < warningBars.length; ++i) {
253:
254: FancyBar warningBar = new FancyBar();
255: warningBar.setBounds(bounds);
256: warningBar.setArcw(arcw);
257: warningBar.setArch(arch);
258: warningBar.setDataSign(dataSign);
259: warningBar.setBaseValue(baseValue);
260: warningBar.setWarningRegions(null);
261: warningBar.setLightBounds(getLightBounds());
262: warningBar.setLightSource(getLightSource());
263: warningBar
264: .setOutlineExistence(getOutlineExistence());
265: warningBar.setOutlineColor(getOutlineColor());
266: warningBar.setType(getType());
267: warningBar.setGraphBounds(getGraphBounds());
268: WarningRegion warningRegion = (WarningRegion) getWarningRegions()
269: .get(i);
270: Rectangle2D tempRect2D = bounds
271: .createIntersection(warningRegion
272: .getBackgroundBounds());
273: Rectangle2D.Float clipBoundsWR = new Rectangle2D.Float();
274: clipBoundsWR.setRect(tempRect2D);
275: warningBar.setClipBounds(clipBoundsWR);
276: warningBar.setColor(warningRegion
277: .getComponentColor());
278: warningBars[i] = warningBar;
279: }
280: }
281: needsUpdate = false;
282: }
283: }
284: }
|