KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > genimen > djeneric > ui > DjFormLayoutManager


1 /*
2  * Copyright (c) 2001-2005 by Genimen BV (www.genimen.com) All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, is permitted provided that the following conditions are met: -
6  * Redistributions of source code must retain the above copyright notice, this
7  * list of conditions and the following disclaimer. - Redistributions in binary
8  * form must reproduce the above copyright notice, this list of conditions and
9  * the following disclaimer in the documentation and/or other materials
10  * provided with the distribution. - All advertising materials mentioning
11  * features or use of this software must display the following acknowledgment:
12  * "This product includes Djeneric." - Products derived from this software may
13  * not be called "Djeneric" nor may "Djeneric" appear in their names without
14  * prior written permission of Genimen BV. - Redistributions of any form
15  * whatsoever must retain the following acknowledgment: "This product includes
16  * Djeneric."
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL GENIMEN BV, DJENERIC.ORG, OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */

30 package com.genimen.djeneric.ui;
31
32 import java.awt.Component JavaDoc;
33 import java.awt.Container JavaDoc;
34 import java.awt.Dimension JavaDoc;
35 import java.awt.Insets JavaDoc;
36 import java.awt.LayoutManager JavaDoc;
37 import java.util.ArrayList JavaDoc;
38
39 import javax.swing.JComponent JavaDoc;
40
41 public class DjFormLayoutManager implements LayoutManager JavaDoc
42 {
43   public static int HORIZONTAL_FLOW = 0;
44   public static int VERTICAL_FLOW = 1;
45
46   ArrayList JavaDoc _labels = new ArrayList JavaDoc();
47   ArrayList JavaDoc _fields = new ArrayList JavaDoc();
48   public final static String JavaDoc LABEL = "label";
49   public final static String JavaDoc FIELD = "field";
50
51   int _flowStyle = HORIZONTAL_FLOW;
52
53   int _yGap = 4;
54   int _xGap = 4;
55
56   int _minimumColumnSize = 50;
57
58   public DjFormLayoutManager()
59   {
60   }
61
62   public void addLayoutComponent(String JavaDoc s, Component JavaDoc c)
63   {
64     if (s.equals(LABEL))
65     {
66       _labels.add(c);
67     }
68     else
69     {
70       _fields.add(c);
71     }
72   }
73
74   private int getColumnWidth()
75   {
76     int actualMax = 0;
77
78     int lb = 0;
79     int fl = 0;
80     int fieldCount = Math.min(_fields.size(), _labels.size());
81     for (int i = 0; i < fieldCount; i++)
82     {
83       JComponent JavaDoc lbl = (JComponent JavaDoc) _labels.get(i);
84       JComponent JavaDoc fld = (JComponent JavaDoc) _fields.get(i);
85       lb = Math.max(lb, lbl.getPreferredSize().width);
86       fl = Math.max(fl, fld.getPreferredSize().width);
87
88       // Two gaps: between the label and the field, and between columns
89
actualMax = Math.max(actualMax, lb + fl + _xGap * 2);
90     }
91
92     return actualMax;
93   }
94
95   private int determineNumberOfColumns(Container JavaDoc c)
96   {
97     Insets JavaDoc insets = c.getInsets();
98     int numberOfColumns = 0;
99
100     int minimumColumnSize = _minimumColumnSize;
101     int columnWidth = getColumnWidth();
102
103     if (columnWidth < minimumColumnSize) columnWidth = minimumColumnSize;
104
105     numberOfColumns = (c.getWidth() - insets.left - insets.right) / columnWidth;
106
107     if (numberOfColumns == 0) numberOfColumns = 1;
108
109     return numberOfColumns;
110   }
111
112   public void layoutContainer(Container JavaDoc c)
113   {
114     doLayoutContainer(c, determineNumberOfColumns(c), false);
115   }
116
117   public Dimension JavaDoc preferredLayoutSize(Container JavaDoc c)
118   {
119     return doLayoutContainer(c, determineNumberOfColumns(c), true);
120   }
121
122   public Dimension JavaDoc doLayoutContainer(Container JavaDoc c, int numberOfColumns, boolean determinePreferredSize)
123   {
124     Insets JavaDoc insets = c.getInsets();
125
126     int fieldCount = Math.min(_fields.size(), _labels.size());
127
128     int columnWidth;
129     if (determinePreferredSize) columnWidth = getColumnWidth();
130     else columnWidth = (((int) c.getPreferredSize().getWidth() - insets.left - insets.right) / numberOfColumns);
131
132     int offset = _xGap;
133
134     int fieldsPerColumn = fieldCount / numberOfColumns;
135     int delta = fieldCount - fieldsPerColumn * numberOfColumns;
136
137     ArrayList JavaDoc fields;
138     ArrayList JavaDoc labels;
139
140     if (_flowStyle == HORIZONTAL_FLOW)
141     {
142       fields = new ArrayList JavaDoc();
143       labels = new ArrayList JavaDoc();
144       getFieldsSorted(numberOfColumns, fieldCount, fields, labels);
145     }
146     else
147     {
148       fields = _fields;
149       labels = _labels;
150     }
151
152     int currentFieldIndex = 0;
153     int h = 0;
154
155     for (int currentColumn = 0; currentColumn < numberOfColumns; currentColumn++)
156     {
157       offset = currentColumn * columnWidth;
158
159       int labelsWidth = 0;
160       int deltaThisColumn = 0;
161       if (delta-- > 0) deltaThisColumn = 1;
162
163       for (int i = currentFieldIndex; i < currentFieldIndex + fieldsPerColumn + deltaThisColumn; i++)
164       {
165         if (i >= fieldCount) break;
166         // no field left in this column
167
JComponent JavaDoc comp = (JComponent JavaDoc) labels.get(i);
168         labelsWidth = Math.max(labelsWidth, comp.getPreferredSize().width);
169       }
170
171       int yPos = insets.top + _yGap;
172
173       for (int i = currentFieldIndex; i < currentFieldIndex + fieldsPerColumn + deltaThisColumn; i++)
174       {
175         if (i >= fieldCount) break;
176         // no field left in this column
177
JComponent JavaDoc label = (JComponent JavaDoc) labels.get(i);
178         JComponent JavaDoc field = (JComponent JavaDoc) fields.get(i);
179
180         int height = Math.max(label.getPreferredSize().height, field.getPreferredSize().height);
181         int width = field.getPreferredSize().width;
182         if (labelsWidth + _xGap * 2 + width > columnWidth)
183         {
184           width = columnWidth - (labelsWidth + _xGap * 2);
185         }
186
187         if (!determinePreferredSize)
188         {
189           label.setBounds(offset + _xGap, yPos, labelsWidth, height);
190           field.setBounds(offset + _xGap * 2 + labelsWidth, yPos, width, height);
191         }
192         yPos += (height + _yGap);
193
194         h = Math.max(h, yPos);
195       }
196       currentFieldIndex += fieldsPerColumn + deltaThisColumn;
197     }
198     return new Dimension JavaDoc(columnWidth * numberOfColumns, h);
199   }
200
201   protected void getFieldsSorted(int numberOfColumns, int fieldCount, ArrayList JavaDoc fields, ArrayList JavaDoc labels)
202   {
203     ArrayList JavaDoc[] cols = new ArrayList JavaDoc[numberOfColumns];
204     ArrayList JavaDoc[] labs = new ArrayList JavaDoc[numberOfColumns];
205
206     for (int i = 0; i < numberOfColumns; i++)
207     {
208       cols[i] = new ArrayList JavaDoc();
209       labs[i] = new ArrayList JavaDoc();
210     }
211
212     for (int i = 0; i < fieldCount; i++)
213     {
214       cols[i % numberOfColumns].add(_fields.get(i));
215       labs[i % numberOfColumns].add(_labels.get(i));
216     }
217
218     for (int i = 0; i < numberOfColumns; i++)
219     {
220       fields.addAll(cols[i]);
221       labels.addAll(labs[i]);
222     }
223   }
224
225   public Dimension JavaDoc minimumLayoutSize(Container JavaDoc c)
226   {
227     int numberOfColumns = determineNumberOfColumns(c);
228     Insets JavaDoc insets = c.getInsets();
229     int maxWidth = 0;
230     int maxHeight = 0;
231     int labelsWidth = 0;
232
233     int fieldCount = Math.min(_fields.size(), _labels.size());
234
235     for (int i = 0; i < fieldCount; i++)
236     {
237       JComponent JavaDoc comp = (JComponent JavaDoc) _labels.get(i);
238       labelsWidth = Math.max(labelsWidth, comp.getPreferredSize().width);
239     }
240
241     maxWidth = numberOfColumns * (labelsWidth + 50);
242
243     int fieldsPerColumn = fieldCount / numberOfColumns;
244     int delta = fieldCount - fieldsPerColumn * numberOfColumns;
245
246     ArrayList JavaDoc fields;
247     ArrayList JavaDoc labels;
248
249     if (_flowStyle == HORIZONTAL_FLOW)
250     {
251       fields = new ArrayList JavaDoc();
252       labels = new ArrayList JavaDoc();
253       getFieldsSorted(numberOfColumns, fieldCount, fields, labels);
254     }
255     else
256     {
257       fields = _fields;
258       labels = _labels;
259     }
260
261     int currentFieldIndex = 0;
262
263     for (int currentColumn = 0; currentColumn < numberOfColumns; currentColumn++)
264     {
265       labelsWidth = 0;
266       int deltaThisColumn = 0;
267       if (delta-- > 0) deltaThisColumn = 1;
268
269       for (int i = currentFieldIndex; i < currentFieldIndex + fieldsPerColumn + deltaThisColumn; i++)
270       {
271         if (i >= fieldCount) break;
272         // no field left in this column
273
JComponent JavaDoc comp = (JComponent JavaDoc) _labels.get(i);
274         labelsWidth = Math.max(labelsWidth, comp.getPreferredSize().width);
275       }
276
277       int yPos = insets.top + _yGap;
278
279       for (int i = currentFieldIndex; i < currentFieldIndex + fieldsPerColumn + deltaThisColumn; i++)
280       {
281         if (i >= fieldCount) break;
282         // no field left in this column
283
JComponent JavaDoc label = (JComponent JavaDoc) labels.get(i);
284         JComponent JavaDoc field = (JComponent JavaDoc) fields.get(i);
285
286         int height = Math.max(label.getPreferredSize().height, field.getPreferredSize().height);
287         yPos += (height + _yGap);
288         maxHeight = Math.max(maxHeight, yPos);
289       }
290       currentFieldIndex += fieldsPerColumn + deltaThisColumn;
291     }
292
293     return new Dimension JavaDoc(maxWidth, maxHeight);
294   }
295
296   public void removeLayoutComponent(Component JavaDoc c)
297   {
298     _labels.remove(c);
299     _fields.remove(c);
300   }
301
302   public int getFlowStyle()
303   {
304     return _flowStyle;
305   }
306
307   public void setFlowStyle(int flowStyle)
308   {
309     _flowStyle = flowStyle;
310   }
311
312 }
Popular Tags