KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > chart > block > AbstractBlock


1 /* ===========================================================
2  * JFreeChart : a free chart library for the Java(tm) platform
3  * ===========================================================
4  *
5  * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
6  *
7  * Project Info: http://www.jfree.org/jfreechart/index.html
8  *
9  * This library is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22  * USA.
23  *
24  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
25  * in the United States and other countries.]
26  *
27  * ------------------
28  * AbstractBlock.java
29  * ------------------
30  * (C) Copyright 2004, 2005, by Object Refinery Limited.
31  *
32  * Original Author: David Gilbert (for Object Refinery Limited);
33  * Contributor(s): -;
34  *
35  * $Id: AbstractBlock.java,v 1.12.2.2 2006/08/04 11:37:50 mungady Exp $
36  *
37  * Changes:
38  * --------
39  * 22-Oct-2004 : Version 1 (DG);
40  * 02-Feb-2005 : Added accessor methods for margin (DG);
41  * 04-Feb-2005 : Added equals() method and implemented Serializable (DG);
42  * 03-May-2005 : Added null argument checks (DG);
43  * 06-May-2005 : Added convenience methods for setting margin, border and
44  * padding (DG);
45  *
46  */

47
48 package org.jfree.chart.block;
49
50 import java.awt.Graphics2D JavaDoc;
51 import java.awt.geom.Rectangle2D JavaDoc;
52 import java.io.IOException JavaDoc;
53 import java.io.ObjectInputStream JavaDoc;
54 import java.io.ObjectOutputStream JavaDoc;
55 import java.io.Serializable JavaDoc;
56
57 import org.jfree.data.Range;
58 import org.jfree.io.SerialUtilities;
59 import org.jfree.ui.RectangleInsets;
60 import org.jfree.ui.Size2D;
61
62 /**
63  * A convenience class for creating new classes that implement
64  * the {@link Block} interface.
65  */

66 public class AbstractBlock implements Serializable JavaDoc {
67
68     /** For serialization. */
69     private static final long serialVersionUID = 7689852412141274563L;
70     
71     /** The id for the block. */
72     private String JavaDoc id;
73     
74     /** The margin around the outside of the block. */
75     private RectangleInsets margin;
76     
77     /** The border for the block. */
78     private BlockBorder border;
79
80     /** The padding between the block content and the border. */
81     private RectangleInsets padding;
82     
83     /**
84      * The natural width of the block (may be overridden if there are
85      * constraints in sizing).
86      */

87     private double width;
88     
89     /**
90      * The natural height of the block (may be overridden if there are
91      * constraints in sizing).
92      */

93     private double height;
94     
95     /**
96      * The current bounds for the block (position of the block in Java2D space).
97      */

98     private transient Rectangle2D JavaDoc bounds;
99     
100     /**
101      * Creates a new block.
102      */

103     protected AbstractBlock() {
104         this.id = null;
105         this.width = 0.0;
106         this.height = 0.0;
107         this.bounds = new Rectangle2D.Float JavaDoc();
108         this.margin = RectangleInsets.ZERO_INSETS;
109         this.border = BlockBorder.NONE;
110         this.padding = RectangleInsets.ZERO_INSETS;
111     }
112     
113     /**
114      * Returns the id.
115      *
116      * @return The id (possibly <code>null</code>).
117      */

118     public String JavaDoc getID() {
119         return this.id;
120     }
121     
122     /**
123      * Sets the id for the block.
124      *
125      * @param id the id (<code>null</code> permitted).
126      */

127     public void setID(String JavaDoc id) {
128         this.id = id;
129     }
130     
131     /**
132      * Returns the natural width of the block, if this is known in advance.
133      * The actual width of the block may be overridden if layout constraints
134      * make this necessary.
135      *
136      * @return The width.
137      */

138     public double getWidth() {
139         return this.width;
140     }
141     
142     /**
143      * Sets the natural width of the block, if this is known in advance.
144      *
145      * @param width the width (in Java2D units)
146      */

147     public void setWidth(double width) {
148         this.width = width;
149     }
150     
151     /**
152      * Returns the natural height of the block, if this is known in advance.
153      * The actual height of the block may be overridden if layout constraints
154      * make this necessary.
155      *
156      * @return The height.
157      */

158     public double getHeight() {
159         return this.height;
160     }
161     
162     /**
163      * Sets the natural width of the block, if this is known in advance.
164      *
165      * @param height the width (in Java2D units)
166      */

167     public void setHeight(double height) {
168         this.height = height;
169     }
170     
171     /**
172      * Returns the margin.
173      *
174      * @return The margin (never <code>null</code>).
175      */

176     public RectangleInsets getMargin() {
177         return this.margin;
178     }
179         
180     /**
181      * Sets the margin (use {@link RectangleInsets#ZERO_INSETS} for no
182      * padding).
183      *
184      * @param margin the margin (<code>null</code> not permitted).
185      */

186     public void setMargin(RectangleInsets margin) {
187         if (margin == null) {
188             throw new IllegalArgumentException JavaDoc("Null 'margin' argument.");
189         }
190         this.margin = margin;
191     }
192
193     /**
194      * Sets the margin.
195      *
196      * @param top the top margin.
197      * @param left the left margin.
198      * @param bottom the bottom margin.
199      * @param right the right margin.
200      */

201     public void setMargin(double top, double left, double bottom,
202                           double right) {
203         setMargin(new RectangleInsets(top, left, bottom, right));
204     }
205
206     /**
207      * Returns the border.
208      *
209      * @return The border (never <code>null</code>).
210      */

211     public BlockBorder getBorder() {
212         return this.border;
213     }
214     
215     /**
216      * Sets the border for the block (use {@link BlockBorder#NONE} for
217      * no border).
218      *
219      * @param border the border (<code>null</code> not permitted).
220      */

221     public void setBorder(BlockBorder border) {
222         if (border == null) {
223             throw new IllegalArgumentException JavaDoc("Null 'border' argument.");
224         }
225         this.border = border;
226     }
227     
228     /**
229      * Sets a black border with the specified line widths.
230      *
231      * @param top the top border line width.
232      * @param left the left border line width.
233      * @param bottom the bottom border line width.
234      * @param right the right border line width.
235      */

236     public void setBorder(double top, double left, double bottom,
237                           double right) {
238         setBorder(new BlockBorder(top, left, bottom, right));
239     }
240     
241     /**
242      * Returns the padding.
243      *
244      * @return The padding (never <code>null</code>).
245      */

246     public RectangleInsets getPadding() {
247         return this.padding;
248     }
249     
250     /**
251      * Sets the padding (use {@link RectangleInsets#ZERO_INSETS} for no
252      * padding).
253      *
254      * @param padding the padding (<code>null</code> not permitted).
255      */

256     public void setPadding(RectangleInsets padding) {
257         if (padding == null) {
258             throw new IllegalArgumentException JavaDoc("Null 'padding' argument.");
259         }
260         this.padding = padding;
261     }
262
263     /**
264      * Returns the x-offset for the content within the block.
265      *
266      * @return The x-offset.
267      */

268     public double getContentXOffset() {
269         return this.margin.getLeft() + this.border.getInsets().getLeft()
270             + this.padding.getLeft();
271     }
272     
273     /**
274      * Returns the y-offset for the content within the block.
275      *
276      * @return The y-offset.
277      */

278     public double getContentYOffset() {
279         return this.margin.getTop() + this.border.getInsets().getTop()
280             + this.padding.getTop();
281     }
282     
283     /**
284      * Sets the padding.
285      *
286      * @param top the top padding.
287      * @param left the left padding.
288      * @param bottom the bottom padding.
289      * @param right the right padding.
290      */

291     public void setPadding(double top, double left, double bottom,
292                            double right) {
293         setPadding(new RectangleInsets(top, left, bottom, right));
294     }
295     
296     /**
297      * Arranges the contents of the block, with no constraints, and returns
298      * the block size.
299      *
300      * @param g2 the graphics device.
301      *
302      * @return The block size (in Java2D units, never <code>null</code>).
303      */

304     public Size2D arrange(Graphics2D JavaDoc g2) {
305         return arrange(g2, RectangleConstraint.NONE);
306     }
307
308     /**
309      * Arranges the contents of the block, within the given constraints, and
310      * returns the block size.
311      *
312      * @param g2 the graphics device.
313      * @param constraint the constraint (<code>null</code> not permitted).
314      *
315      * @return The block size (in Java2D units, never <code>null</code>).
316      */

317     public Size2D arrange(Graphics2D JavaDoc g2, RectangleConstraint constraint) {
318         Size2D base = new Size2D(getWidth(), getHeight());
319         return constraint.calculateConstrainedSize(base);
320     }
321
322     /**
323      * Returns the current bounds of the block.
324      *
325      * @return The bounds.
326      */

327     public Rectangle2D JavaDoc getBounds() {
328         return this.bounds;
329     }
330     
331     /**
332      * Sets the bounds of the block.
333      *
334      * @param bounds the bounds (<code>null</code> not permitted).
335      */

336     public void setBounds(Rectangle2D JavaDoc bounds) {
337         if (bounds == null) {
338             throw new IllegalArgumentException JavaDoc("Null 'bounds' argument.");
339         }
340         this.bounds = bounds;
341     }
342     
343     /**
344      * Calculate the width available for content after subtracting
345      * the margin, border and padding space from the specified fixed
346      * width.
347      *
348      * @param fixedWidth the fixed width.
349      *
350      * @return The available space.
351      */

352     protected double trimToContentWidth(double fixedWidth) {
353         double result = this.margin.trimWidth(fixedWidth);
354         result = this.border.getInsets().trimWidth(result);
355         result = this.padding.trimWidth(result);
356         return Math.max(result, 0.0);
357     }
358
359     /**
360      * Calculate the height available for content after subtracting
361      * the margin, border and padding space from the specified fixed
362      * height.
363      *
364      * @param fixedHeight the fixed height.
365      *
366      * @return The available space.
367      */

368     protected double trimToContentHeight(double fixedHeight) {
369         double result = this.margin.trimHeight(fixedHeight);
370         result = this.border.getInsets().trimHeight(result);
371         result = this.padding.trimHeight(result);
372         return Math.max(result, 0.0);
373     }
374     
375     /**
376      * Returns a constraint for the content of this block that will result in
377      * the bounds of the block matching the specified constraint.
378      *
379      * @param c the outer constraint (<code>null</code> not permitted).
380      *
381      * @return The content constraint.
382      */

383     protected RectangleConstraint toContentConstraint(RectangleConstraint c) {
384         if (c == null) {
385             throw new IllegalArgumentException JavaDoc("Null 'c' argument.");
386         }
387         if (c.equals(RectangleConstraint.NONE)) {
388             return c;
389         }
390         double w = c.getWidth();
391         Range wr = c.getWidthRange();
392         double h = c.getHeight();
393         Range hr = c.getHeightRange();
394         double ww = trimToContentWidth(w);
395         double hh = trimToContentHeight(h);
396         Range wwr = trimToContentWidth(wr);
397         Range hhr = trimToContentHeight(hr);
398         return new RectangleConstraint(
399             ww, wwr, c.getWidthConstraintType(),
400             hh, hhr, c.getHeightConstraintType()
401         );
402     }
403
404     private Range trimToContentWidth(Range r) {
405         if (r == null) {
406             return null;
407         }
408         double lowerBound = 0.0;
409         double upperBound = Double.POSITIVE_INFINITY;
410         if (r.getLowerBound() > 0.0) {
411             lowerBound = trimToContentWidth(r.getLowerBound());
412         }
413         if (r.getUpperBound() < Double.POSITIVE_INFINITY) {
414             upperBound = trimToContentWidth(r.getUpperBound());
415         }
416         return new Range(lowerBound, upperBound);
417     }
418     
419     private Range trimToContentHeight(Range r) {
420         if (r == null) {
421             return null;
422         }
423         double lowerBound = 0.0;
424         double upperBound = Double.POSITIVE_INFINITY;
425         if (r.getLowerBound() > 0.0) {
426             lowerBound = trimToContentHeight(r.getLowerBound());
427         }
428         if (r.getUpperBound() < Double.POSITIVE_INFINITY) {
429             upperBound = trimToContentHeight(r.getUpperBound());
430         }
431         return new Range(lowerBound, upperBound);
432     }
433     
434     /**
435      * Adds the margin, border and padding to the specified content width.
436      *
437      * @param contentWidth the content width.
438      *
439      * @return The adjusted width.
440      */

441     protected double calculateTotalWidth(double contentWidth) {
442         double result = contentWidth;
443         result = this.padding.extendWidth(result);
444         result = this.border.getInsets().extendWidth(result);
445         result = this.margin.extendWidth(result);
446         return result;
447     }
448
449     /**
450      * Adds the margin, border and padding to the specified content height.
451      *
452      * @param contentHeight the content height.
453      *
454      * @return The adjusted height.
455      */

456     protected double calculateTotalHeight(double contentHeight) {
457         double result = contentHeight;
458         result = this.padding.extendHeight(result);
459         result = this.border.getInsets().extendHeight(result);
460         result = this.margin.extendHeight(result);
461         return result;
462     }
463
464     /**
465      * Reduces the specified area by the amount of space consumed
466      * by the margin.
467      *
468      * @param area the area (<code>null</code> not permitted).
469      *
470      * @return The trimmed area.
471      */

472     protected Rectangle2D JavaDoc trimMargin(Rectangle2D JavaDoc area) {
473         // defer argument checking...
474
this.margin.trim(area);
475         return area;
476     }
477     
478     /**
479      * Reduces the specified area by the amount of space consumed
480      * by the border.
481      *
482      * @param area the area (<code>null</code> not permitted).
483      *
484      * @return The trimmed area.
485      */

486     protected Rectangle2D JavaDoc trimBorder(Rectangle2D JavaDoc area) {
487         // defer argument checking...
488
this.border.getInsets().trim(area);
489         return area;
490     }
491
492     /**
493      * Reduces the specified area by the amount of space consumed
494      * by the padding.
495      *
496      * @param area the area (<code>null</code> not permitted).
497      *
498      * @return The trimmed area.
499      */

500     protected Rectangle2D JavaDoc trimPadding(Rectangle2D JavaDoc area) {
501         // defer argument checking...
502
this.padding.trim(area);
503         return area;
504     }
505
506     /**
507      * Draws the border around the perimeter of the specified area.
508      *
509      * @param g2 the graphics device.
510      * @param area the area.
511      */

512     protected void drawBorder(Graphics2D JavaDoc g2, Rectangle2D JavaDoc area) {
513         this.border.draw(g2, area);
514     }
515     
516     /**
517      * Tests this block for equality with an arbitrary object.
518      *
519      * @param obj the object (<code>null</code> permitted).
520      *
521      * @return A boolean.
522      */

523     public boolean equals(Object JavaDoc obj) {
524         if (obj == this) {
525             return true;
526         }
527         if (!(obj instanceof AbstractBlock)) {
528             return false;
529         }
530         AbstractBlock that = (AbstractBlock) obj;
531         if (!this.border.equals(that.border)) {
532             return false;
533         }
534         if (!this.bounds.equals(that.bounds)) {
535             return false;
536         }
537         if (!this.margin.equals(that.margin)) {
538             return false;
539         }
540         if (!this.padding.equals(that.padding)) {
541             return false;
542         }
543         if (this.height != that.height) {
544             return false;
545         }
546         if (this.width != that.width) {
547             return false;
548         }
549         return true;
550     }
551     
552     /**
553      * Provides serialization support.
554      *
555      * @param stream the output stream.
556      *
557      * @throws IOException if there is an I/O error.
558      */

559     private void writeObject(ObjectOutputStream JavaDoc stream) throws IOException JavaDoc {
560         stream.defaultWriteObject();
561         SerialUtilities.writeShape(this.bounds, stream);
562     }
563
564     /**
565      * Provides serialization support.
566      *
567      * @param stream the input stream.
568      *
569      * @throws IOException if there is an I/O error.
570      * @throws ClassNotFoundException if there is a classpath problem.
571      */

572     private void readObject(ObjectInputStream JavaDoc stream)
573         throws IOException JavaDoc, ClassNotFoundException JavaDoc {
574         stream.defaultReadObject();
575         this.bounds = (Rectangle2D JavaDoc) SerialUtilities.readShape(stream);
576     }
577
578 }
579
Popular Tags