KickJava   Java API By Example, From Geeks To Geeks.

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


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  * ColumnArrangement.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: ColumnArrangement.java,v 1.12.2.2 2006/08/04 11:48:41 mungady Exp $
36  *
37  * Changes:
38  * --------
39  * 22-Oct-2004 : Version 1 (DG);
40  * 04-Feb-2005 : Added equals() and implemented Serializable (DG);
41  *
42  */

43
44 package org.jfree.chart.block;
45
46 import java.awt.Graphics2D JavaDoc;
47 import java.awt.geom.Rectangle2D JavaDoc;
48 import java.io.Serializable JavaDoc;
49 import java.util.ArrayList JavaDoc;
50 import java.util.List JavaDoc;
51
52 import org.jfree.ui.HorizontalAlignment;
53 import org.jfree.ui.Size2D;
54 import org.jfree.ui.VerticalAlignment;
55
56 /**
57  * Arranges blocks in a column layout. This class is immutable.
58  */

59 public class ColumnArrangement implements Arrangement, Serializable JavaDoc {
60
61     /** For serialization. */
62     private static final long serialVersionUID = -5315388482898581555L;
63     
64     /** The horizontal alignment of blocks. */
65     private HorizontalAlignment horizontalAlignment;
66     
67     /** The vertical alignment of blocks within each row. */
68     private VerticalAlignment verticalAlignment;
69     
70     /** The horizontal gap between columns. */
71     private double horizontalGap;
72     
73     /** The vertical gap between items in a column. */
74     private double verticalGap;
75     
76     /**
77      * Creates a new instance.
78      */

79     public ColumnArrangement() {
80     }
81     
82     /**
83      * Creates a new instance.
84      *
85      * @param hAlign the horizontal alignment (currently ignored).
86      * @param vAlign the vertical alignment (currently ignored).
87      * @param hGap the horizontal gap.
88      * @param vGap the vertical gap.
89      */

90     public ColumnArrangement(HorizontalAlignment hAlign,
91                              VerticalAlignment vAlign,
92                              double hGap, double vGap) {
93         this.horizontalAlignment = hAlign;
94         this.verticalAlignment = vAlign;
95         this.horizontalGap = hGap;
96         this.verticalGap = vGap;
97     }
98     
99     /**
100      * Adds a block to be managed by this instance. This method is usually
101      * called by the {@link BlockContainer}, you shouldn't need to call it
102      * directly.
103      *
104      * @param block the block.
105      * @param key a key that controls the position of the block.
106      */

107     public void add(Block block, Object JavaDoc key) {
108         // since the flow layout is relatively straightforward, no information
109
// needs to be recorded here
110
}
111     
112     /**
113      * Calculates and sets the bounds of all the items in the specified
114      * container, subject to the given constraint. The <code>Graphics2D</code>
115      * can be used by some items (particularly items containing text) to
116      * calculate sizing parameters.
117      *
118      * @param container the container whose items are being arranged.
119      * @param g2 the graphics device.
120      * @param constraint the size constraint.
121      *
122      * @return The size of the container after arrangement of the contents.
123      */

124     public Size2D arrange(BlockContainer container, Graphics2D JavaDoc g2,
125                           RectangleConstraint constraint) {
126         
127         LengthConstraintType w = constraint.getWidthConstraintType();
128         LengthConstraintType h = constraint.getHeightConstraintType();
129         if (w == LengthConstraintType.NONE) {
130             if (h == LengthConstraintType.NONE) {
131                 return arrangeNN(container, g2);
132             }
133             else if (h == LengthConstraintType.FIXED) {
134                 throw new RuntimeException JavaDoc("Not implemented.");
135             }
136             else if (h == LengthConstraintType.RANGE) {
137                 throw new RuntimeException JavaDoc("Not implemented.");
138             }
139         }
140         else if (w == LengthConstraintType.FIXED) {
141             if (h == LengthConstraintType.NONE) {
142                 throw new RuntimeException JavaDoc("Not implemented.");
143             }
144             else if (h == LengthConstraintType.FIXED) {
145                 return arrangeFF(container, g2, constraint);
146             }
147             else if (h == LengthConstraintType.RANGE) {
148                 throw new RuntimeException JavaDoc("Not implemented.");
149             }
150         }
151         else if (w == LengthConstraintType.RANGE) {
152             if (h == LengthConstraintType.NONE) {
153                 throw new RuntimeException JavaDoc("Not implemented.");
154             }
155             else if (h == LengthConstraintType.FIXED) {
156                 return arrangeRF(container, g2, constraint);
157             }
158             else if (h == LengthConstraintType.RANGE) {
159                 return arrangeRR(container, g2, constraint);
160             }
161         }
162         return new Size2D(); // TODO: complete this
163

164     }
165
166     /**
167      * Calculates and sets the bounds of all the items in the specified
168      * container, subject to the given constraint. The <code>Graphics2D</code>
169      * can be used by some items (particularly items containing text) to
170      * calculate sizing parameters.
171      *
172      * @param container the container whose items are being arranged.
173      * @param g2 the graphics device.
174      * @param constraint the size constraint.
175      *
176      * @return The container size after the arrangement.
177      */

178     protected Size2D arrangeFF(BlockContainer container, Graphics2D JavaDoc g2,
179                                RectangleConstraint constraint) {
180         // TODO: implement properly
181
return arrangeNF(container, g2, constraint);
182     }
183     
184     /**
185      * Calculates and sets the bounds of all the items in the specified
186      * container, subject to the given constraint. The <code>Graphics2D</code>
187      * can be used by some items (particularly items containing text) to
188      * calculate sizing parameters.
189      *
190      * @param container the container whose items are being arranged.
191      * @param constraint the size constraint.
192      * @param g2 the graphics device.
193      *
194      * @return The container size after the arrangement.
195      */

196     protected Size2D arrangeNF(BlockContainer container, Graphics2D JavaDoc g2,
197                                RectangleConstraint constraint) {
198     
199         List JavaDoc blocks = container.getBlocks();
200         
201         double height = constraint.getHeight();
202         if (height <= 0.0) {
203             height = Double.POSITIVE_INFINITY;
204         }
205         
206         double x = 0.0;
207         double y = 0.0;
208         double maxWidth = 0.0;
209         List JavaDoc itemsInColumn = new ArrayList JavaDoc();
210         for (int i = 0; i < blocks.size(); i++) {
211             Block block = (Block) blocks.get(i);
212             Size2D size = block.arrange(g2, RectangleConstraint.NONE);
213             if (y + size.height <= height) {
214                 itemsInColumn.add(block);
215                 block.setBounds(
216                     new Rectangle2D.Double JavaDoc(x, y, size.width, size.height)
217                 );
218                 y = y + size.height + this.verticalGap;
219                 maxWidth = Math.max(maxWidth, size.width);
220             }
221             else {
222                 if (itemsInColumn.isEmpty()) {
223                     // place in this column (truncated) anyway
224
block.setBounds(
225                         new Rectangle2D.Double JavaDoc(
226                             x, y, size.width, Math.min(size.height, height - y)
227                         )
228                     );
229                     y = 0.0;
230                     x = x + size.width + this.horizontalGap;
231                 }
232                 else {
233                     // start new column
234
itemsInColumn.clear();
235                     x = x + maxWidth + this.horizontalGap;
236                     y = 0.0;
237                     maxWidth = size.width;
238                     block.setBounds(
239                         new Rectangle2D.Double JavaDoc(
240                             x, y, size.width, Math.min(size.height, height)
241                         )
242                     );
243                     y = size.height + this.verticalGap;
244                     itemsInColumn.add(block);
245                 }
246             }
247         }
248         return new Size2D(x + maxWidth, constraint.getHeight());
249     }
250
251     protected Size2D arrangeRR(BlockContainer container, Graphics2D JavaDoc g2,
252                                RectangleConstraint constraint) {
253
254         // first arrange without constraints, and see if this fits within
255
// the required ranges...
256
Size2D s1 = arrangeNN(container, g2);
257         if (constraint.getHeightRange().contains(s1.height)) {
258             return s1; // TODO: we didn't check the width yet
259
}
260         else {
261             RectangleConstraint c = constraint.toFixedHeight(
262                 constraint.getHeightRange().getUpperBound()
263             );
264             return arrangeRF(container, g2, c);
265         }
266     }
267     
268     /**
269      * Arranges the blocks in the container using a fixed height and a
270      * range for the width.
271      *
272      * @param container the container.
273      * @param g2 the graphics device.
274      * @param constraint the constraint.
275      *
276      * @return The size of the container after arrangement.
277      */

278     protected Size2D arrangeRF(BlockContainer container, Graphics2D JavaDoc g2,
279                                RectangleConstraint constraint) {
280
281         Size2D s = arrangeNF(container, g2, constraint);
282         if (constraint.getWidthRange().contains(s.width)) {
283             return s;
284         }
285         else {
286             RectangleConstraint c = constraint.toFixedWidth(
287                 constraint.getWidthRange().constrain(s.getWidth())
288             );
289             return arrangeFF(container, g2, c);
290         }
291     }
292
293     /**
294      * Arranges the blocks without any constraints. This puts all blocks
295      * into a single column.
296      *
297      * @param container the container.
298      * @param g2 the graphics device.
299      *
300      * @return The size after the arrangement.
301      */

302     protected Size2D arrangeNN(BlockContainer container, Graphics2D JavaDoc g2) {
303         double y = 0.0;
304         double height = 0.0;
305         double maxWidth = 0.0;
306         List JavaDoc blocks = container.getBlocks();
307         int blockCount = blocks.size();
308         if (blockCount > 0) {
309             Size2D[] sizes = new Size2D[blocks.size()];
310             for (int i = 0; i < blocks.size(); i++) {
311                 Block block = (Block) blocks.get(i);
312                 sizes[i] = block.arrange(g2, RectangleConstraint.NONE);
313                 height = height + sizes[i].getHeight();
314                 maxWidth = Math.max(sizes[i].width, maxWidth);
315                 block.setBounds(
316                     new Rectangle2D.Double JavaDoc(
317                         0.0, y, sizes[i].width, sizes[i].height
318                     )
319                 );
320                 y = y + sizes[i].height + this.verticalGap;
321             }
322             if (blockCount > 1) {
323                 height = height + this.verticalGap * (blockCount - 1);
324             }
325             if (this.horizontalAlignment != HorizontalAlignment.LEFT) {
326                 for (int i = 0; i < blocks.size(); i++) {
327                     //Block b = (Block) blocks.get(i);
328
if (this.horizontalAlignment
329                             == HorizontalAlignment.CENTER) {
330                         //TODO: shift block right by half
331
}
332                     else if (this.horizontalAlignment
333                             == HorizontalAlignment.RIGHT) {
334                         //TODO: shift block over to right
335
}
336                 }
337             }
338         }
339         return new Size2D(maxWidth, height);
340     }
341
342     /**
343      * Clears any cached information.
344      */

345     public void clear() {
346         // no action required.
347
}
348     
349     /**
350      * Tests this instance for equality with an arbitrary object.
351      *
352      * @param obj the object (<code>null</code> permitted).
353      *
354      * @return A boolean.
355      */

356     public boolean equals(Object JavaDoc obj) {
357         if (obj == this) {
358             return true;
359         }
360         if (!(obj instanceof ColumnArrangement)) {
361             return false;
362         }
363         ColumnArrangement that = (ColumnArrangement) obj;
364         if (this.horizontalAlignment != that.horizontalAlignment) {
365             return false;
366         }
367         if (this.verticalAlignment != that.verticalAlignment) {
368             return false;
369         }
370         if (this.horizontalGap != that.horizontalGap) {
371             return false;
372         }
373         if (this.verticalGap != that.verticalGap) {
374             return false;
375         }
376         return true;
377     }
378     
379
380 }
381
Popular Tags