001: /* ========================================================================
002: * JCommon : a free general purpose class library for the Java(tm) platform
003: * ========================================================================
004: *
005: * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
006: *
007: * Project Info: http://www.jfree.org/jcommon/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: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
025: * in the United States and other countries.]
026: *
027: * ------------
028: * TextBox.java
029: * ------------
030: * (C) Copyright 2004, by Object Refinery Limited and Contributors.
031: *
032: * Original Author: David Gilbert (for Object Refinery Limited);
033: * Contributor(s): -;
034: *
035: * $Id: TextBox.java,v 1.12 2005/11/16 15:58:41 taqua Exp $
036: *
037: * Changes
038: * -------
039: * 09-Mar-2004 : Version 1 (DG);
040: * 22-Mar-2004 : Added equals() method and implemented Serializable (DG);
041: * 09-Nov-2004 : Renamed getAdjustedHeight() --> calculateExtendedHeight() in
042: * Spacer class (DG);
043: * 22-Feb-2005 : Replaced Spacer with RectangleInsets (DG);
044: *
045: */
046:
047: package org.jfree.text;
048:
049: import java.awt.BasicStroke;
050: import java.awt.Color;
051: import java.awt.Font;
052: import java.awt.Graphics2D;
053: import java.awt.Paint;
054: import java.awt.Stroke;
055: import java.awt.geom.Rectangle2D;
056: import java.io.IOException;
057: import java.io.ObjectInputStream;
058: import java.io.ObjectOutputStream;
059: import java.io.Serializable;
060:
061: import org.jfree.io.SerialUtilities;
062: import org.jfree.ui.RectangleAnchor;
063: import org.jfree.ui.RectangleInsets;
064: import org.jfree.ui.Size2D;
065: import org.jfree.util.ObjectUtilities;
066:
067: /**
068: * A box containing a text block.
069: *
070: * @author David Gilbert
071: */
072: public class TextBox implements Serializable {
073:
074: /** For serialization. */
075: private static final long serialVersionUID = 3360220213180203706L;
076:
077: /** The outline paint. */
078: private transient Paint outlinePaint;
079:
080: /** The outline stroke. */
081: private transient Stroke outlineStroke;
082:
083: /** The interior space. */
084: private RectangleInsets interiorGap;
085:
086: /** The background paint. */
087: private transient Paint backgroundPaint;
088:
089: /** The shadow paint. */
090: private transient Paint shadowPaint;
091:
092: /** The shadow x-offset. */
093: private double shadowXOffset = 2.0;
094:
095: /** The shadow y-offset. */
096: private double shadowYOffset = 2.0;
097:
098: /** The text block. */
099: private TextBlock textBlock;
100:
101: /**
102: * Creates an empty text box.
103: */
104: public TextBox() {
105: this ((TextBlock) null);
106: }
107:
108: /**
109: * Creates a text box.
110: *
111: * @param text the text.
112: */
113: public TextBox(final String text) {
114: this ((TextBlock) null);
115: if (text != null) {
116: this .textBlock = new TextBlock();
117: this .textBlock.addLine(text, new Font("SansSerif",
118: Font.PLAIN, 10), Color.black);
119: }
120: }
121:
122: /**
123: * Creates a new text box.
124: *
125: * @param block the text block.
126: */
127: public TextBox(final TextBlock block) {
128: this .outlinePaint = Color.black;
129: this .outlineStroke = new BasicStroke(1.0f);
130: this .interiorGap = new RectangleInsets(1.0, 3.0, 1.0, 3.0);
131: this .backgroundPaint = new Color(255, 255, 192);
132: this .shadowPaint = Color.gray;
133: this .shadowXOffset = 2.0;
134: this .shadowYOffset = 2.0;
135: this .textBlock = block;
136: }
137:
138: /**
139: * Returns the outline paint.
140: *
141: * @return The outline paint.
142: */
143: public Paint getOutlinePaint() {
144: return this .outlinePaint;
145: }
146:
147: /**
148: * Sets the outline paint.
149: *
150: * @param paint the paint.
151: */
152: public void setOutlinePaint(final Paint paint) {
153: this .outlinePaint = paint;
154: }
155:
156: /**
157: * Returns the outline stroke.
158: *
159: * @return The outline stroke.
160: */
161: public Stroke getOutlineStroke() {
162: return this .outlineStroke;
163: }
164:
165: /**
166: * Sets the outline stroke.
167: *
168: * @param stroke the stroke.
169: */
170: public void setOutlineStroke(final Stroke stroke) {
171: this .outlineStroke = stroke;
172: }
173:
174: /**
175: * Returns the interior gap.
176: *
177: * @return The interior gap.
178: */
179: public RectangleInsets getInteriorGap() {
180: return this .interiorGap;
181: }
182:
183: /**
184: * Sets the interior gap.
185: *
186: * @param gap the gap.
187: */
188: public void setInteriorGap(final RectangleInsets gap) {
189: this .interiorGap = gap;
190: }
191:
192: /**
193: * Returns the background paint.
194: *
195: * @return The background paint.
196: */
197: public Paint getBackgroundPaint() {
198: return this .backgroundPaint;
199: }
200:
201: /**
202: * Sets the background paint.
203: *
204: * @param paint the paint.
205: */
206: public void setBackgroundPaint(final Paint paint) {
207: this .backgroundPaint = paint;
208: }
209:
210: /**
211: * Returns the shadow paint.
212: *
213: * @return The shadow paint.
214: */
215: public Paint getShadowPaint() {
216: return this .shadowPaint;
217: }
218:
219: /**
220: * Sets the shadow paint.
221: *
222: * @param paint the paint.
223: */
224: public void setShadowPaint(final Paint paint) {
225: this .shadowPaint = paint;
226: }
227:
228: /**
229: * Returns the x-offset for the shadow effect.
230: *
231: * @return The offset.
232: */
233: public double getShadowXOffset() {
234: return this .shadowXOffset;
235: }
236:
237: /**
238: * Sets the x-offset for the shadow effect.
239: *
240: * @param offset the offset (in Java2D units).
241: */
242: public void setShadowXOffset(final double offset) {
243: this .shadowXOffset = offset;
244: }
245:
246: /**
247: * Returns the y-offset for the shadow effect.
248: *
249: * @return The offset.
250: */
251: public double getShadowYOffset() {
252: return this .shadowYOffset;
253: }
254:
255: /**
256: * Sets the y-offset for the shadow effect.
257: *
258: * @param offset the offset (in Java2D units).
259: */
260: public void setShadowYOffset(final double offset) {
261: this .shadowYOffset = offset;
262: }
263:
264: /**
265: * Returns the text block.
266: *
267: * @return The text block.
268: */
269: public TextBlock getTextBlock() {
270: return this .textBlock;
271: }
272:
273: /**
274: * Sets the text block.
275: *
276: * @param block the block.
277: */
278: public void setTextBlock(final TextBlock block) {
279: this .textBlock = block;
280: }
281:
282: /**
283: * Draws the text box.
284: *
285: * @param g2 the graphics device.
286: * @param x the x-coordinate.
287: * @param y the y-coordinate.
288: * @param anchor the anchor point.
289: */
290: public void draw(final Graphics2D g2, final float x, final float y,
291: final RectangleAnchor anchor) {
292: final Size2D d1 = this .textBlock.calculateDimensions(g2);
293: final double w = this .interiorGap.extendWidth(d1.getWidth());
294: final double h = this .interiorGap.extendHeight(d1.getHeight());
295: final Size2D d2 = new Size2D(w, h);
296: final Rectangle2D bounds = RectangleAnchor.createRectangle(d2,
297: x, y, anchor);
298:
299: if (this .shadowPaint != null) {
300: final Rectangle2D shadow = new Rectangle2D.Double(bounds
301: .getX()
302: + this .shadowXOffset, bounds.getY()
303: + this .shadowYOffset, bounds.getWidth(), bounds
304: .getHeight());
305: g2.setPaint(this .shadowPaint);
306: g2.fill(shadow);
307: }
308: if (this .backgroundPaint != null) {
309: g2.setPaint(this .backgroundPaint);
310: g2.fill(bounds);
311: }
312:
313: if (this .outlinePaint != null && this .outlineStroke != null) {
314: g2.setPaint(this .outlinePaint);
315: g2.setStroke(this .outlineStroke);
316: g2.draw(bounds);
317: }
318:
319: this .textBlock.draw(g2, (float) bounds.getCenterX(),
320: (float) bounds.getCenterY(), TextBlockAnchor.CENTER);
321:
322: }
323:
324: /**
325: * Returns the height of the text box.
326: *
327: * @param g2 the graphics device.
328: *
329: * @return The height (in Java2D units).
330: */
331: public double getHeight(final Graphics2D g2) {
332: final Size2D d = this .textBlock.calculateDimensions(g2);
333: return this .interiorGap.extendHeight(d.getHeight());
334: }
335:
336: /**
337: * Tests this object for equality with an arbitrary object.
338: *
339: * @param obj the object to test against (<code>null</code> permitted).
340: *
341: * @return A boolean.
342: */
343: public boolean equals(final Object obj) {
344: if (obj == this ) {
345: return true;
346: }
347: if (!(obj instanceof TextBox)) {
348: return false;
349: }
350: final TextBox that = (TextBox) obj;
351: if (!ObjectUtilities
352: .equal(this .outlinePaint, that.outlinePaint)) {
353: return false;
354: }
355: if (!ObjectUtilities.equal(this .outlineStroke,
356: that.outlineStroke)) {
357: return false;
358: }
359: if (!ObjectUtilities.equal(this .interiorGap, that.interiorGap)) {
360: return false;
361: }
362: if (!ObjectUtilities.equal(this .backgroundPaint,
363: that.backgroundPaint)) {
364: return false;
365: }
366: if (!ObjectUtilities.equal(this .shadowPaint, that.shadowPaint)) {
367: return false;
368: }
369: if (this .shadowXOffset != that.shadowXOffset) {
370: return false;
371: }
372: if (this .shadowYOffset != that.shadowYOffset) {
373: return false;
374: }
375: if (!ObjectUtilities.equal(this .textBlock, that.textBlock)) {
376: return false;
377: }
378:
379: return true;
380: }
381:
382: /**
383: * Returns a hash code for this object.
384: *
385: * @return A hash code.
386: */
387: public int hashCode() {
388: int result;
389: long temp;
390: result = (this .outlinePaint != null ? this .outlinePaint
391: .hashCode() : 0);
392: result = 29
393: * result
394: + (this .outlineStroke != null ? this .outlineStroke
395: .hashCode() : 0);
396: result = 29
397: * result
398: + (this .interiorGap != null ? this .interiorGap
399: .hashCode() : 0);
400: result = 29
401: * result
402: + (this .backgroundPaint != null ? this .backgroundPaint
403: .hashCode() : 0);
404: result = 29
405: * result
406: + (this .shadowPaint != null ? this .shadowPaint
407: .hashCode() : 0);
408: temp = this .shadowXOffset != +0.0d ? Double
409: .doubleToLongBits(this .shadowXOffset) : 0L;
410: result = 29 * result + (int) (temp ^ (temp >>> 32));
411: temp = this .shadowYOffset != +0.0d ? Double
412: .doubleToLongBits(this .shadowYOffset) : 0L;
413: result = 29 * result + (int) (temp ^ (temp >>> 32));
414: result = 29
415: * result
416: + (this .textBlock != null ? this .textBlock.hashCode()
417: : 0);
418: return result;
419: }
420:
421: /**
422: * Provides serialization support.
423: *
424: * @param stream the output stream.
425: *
426: * @throws IOException if there is an I/O error.
427: */
428: private void writeObject(final ObjectOutputStream stream)
429: throws IOException {
430: stream.defaultWriteObject();
431: SerialUtilities.writePaint(this .outlinePaint, stream);
432: SerialUtilities.writeStroke(this .outlineStroke, stream);
433: SerialUtilities.writePaint(this .backgroundPaint, stream);
434: SerialUtilities.writePaint(this .shadowPaint, stream);
435: }
436:
437: /**
438: * Provides serialization support.
439: *
440: * @param stream the input stream.
441: *
442: * @throws IOException if there is an I/O error.
443: * @throws ClassNotFoundException if there is a classpath problem.
444: */
445: private void readObject(final ObjectInputStream stream)
446: throws IOException, ClassNotFoundException {
447: stream.defaultReadObject();
448: this.outlinePaint = SerialUtilities.readPaint(stream);
449: this.outlineStroke = SerialUtilities.readStroke(stream);
450: this.backgroundPaint = SerialUtilities.readPaint(stream);
451: this.shadowPaint = SerialUtilities.readPaint(stream);
452: }
453:
454: }
|