Source code: com/javathis/utilities/ui/JTVerticalFlowLayout.java
1 /**
2 * JTUtilities - The Pure Java Utilities
3 * Copyright(c) 2002 by Rodney S. Foley
4 * <pre>
5 * This library is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU Lesser General Public License as published by the Free
7 * Software Foundation; either version 2.1 of the License, or (at your option)
8 * any later version.
9 *
10 * This library is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; if not, write to:
17 *
18 * Free Software Foundation, Inc.
19 * 59 Temple Place, Suite 330
20 * Boston, MA 02111-1307, USA
21 *
22 * or download it from: http://www.fsf.org/licenses/licenses.html#LGPL
23 * </pre>
24 */
25 package com.javathis.utilities.ui;
26
27 import java.awt.*;
28 import javax.swing.*;
29
30 /**
31 * <code>JTVerticalFlowLayout</code> is similar to <code>FlowLayout</code> except
32 * it lays out components vertically. It similar int behavior of the
33 * <code>FlowLayout</code> class, except it's vertical.
34 * <p>
35 * It has the additional feature where you can specify to fill to the edge.
36 * This causes the <code>JTVerticalFlowLayout</code> manager to resize all the
37 * components to expand to the width fo the column.
38 * <p>
39 * Warning: This causes problems when the main panel has less space that it
40 * needs. It also prohibits multi-column output. Additionally the vertical
41 * fill, fills the last component to the remaining height of the container.
42 */
43 public class JTVerticalFlowLayout extends FlowLayout
44 {
45
46 public static final int TOP = 0;
47 public static final int MIDDLE = 1;
48 public static final int BOTTOM = 2;
49
50 int hgap;
51 int vgap;
52
53 boolean horizontalFill;
54 boolean verticalFill;
55
56 /**
57 * Construct a new <code>JTVerticalFlowLayout</code> with a TOP alignemnt,
58 * the horizontal fill is true, the vertical fill is false, and both gaps
59 * are set to 5.
60 * <p>
61 * Note: Delegates to the following constructor:
62 * <p>
63 * JTVerticalFlowLayout(int, int, int, boolean, boolean)
64 */
65 public JTVerticalFlowLayout()
66 {
67 this(TOP, 5, 5, true, false);
68 }
69
70 /**
71 * Construct a new <code>JTVerticalFlowLayout</code> with a TOP alignemnt,
72 * with the provided horizontal and vertical fills, and both gaps are set
73 * to 5.
74 * <p>
75 * Note: Delegates to the following constructor:
76 * <p>
77 * JTVerticalFlowLayout(int, int, int, boolean, boolean)
78 *
79 * @param horizontalFill
80 * @param verticalFill
81 */
82 public JTVerticalFlowLayout(boolean horizontalFill, boolean verticalFill)
83 {
84 this(TOP, 5, 5, horizontalFill, verticalFill);
85 }
86
87 /**
88 * Construct a new <code>JTVerticalFlowLayout</code> with the provided alignemnt,
89 * the horizontal fill is true, the vertical fill is false, and both gaps
90 * are set to 5.
91 * <p>
92 * Note: Delegates to the following constructor:
93 * <p>
94 * JTVerticalFlowLayout(int, int, int, boolean, boolean)
95 *
96 * @param align
97 */
98 public JTVerticalFlowLayout(int align)
99 {
100 this(align, 5, 5, true, false);
101 }
102
103 /**
104 * Construct a new <code>JTVerticalFlowLayout</code> with the provided alignemnt,
105 * with the provided horizontal and vertical fills, and both gaps are set
106 * to 5.
107 * <p>
108 * Note: Delegates to the following constructor:
109 * <p>
110 * JTVerticalFlowLayout(int, int, int, boolean, boolean)
111 *
112 * @param align
113 * @param horizontalFill
114 * @param verticalFill
115 */
116 public JTVerticalFlowLayout(int align, boolean horizontalFill, boolean verticalFill)
117 {
118 this(align, 5, 5, horizontalFill, verticalFill);
119 }
120
121 /**
122 * Construct a new <code>JTVerticalFlowLayout</code> with the provided arguments.
123 *
124 * @param align
125 * @param hgap
126 * @param vgap
127 * @param horizontalFill
128 * @param verticalFill
129 */
130 public JTVerticalFlowLayout(int align, int hgap, int vgap, boolean horizontalFill, boolean verticalFill)
131 {
132 setAlignment(align);
133
134 this.hgap = hgap;
135 this.vgap = vgap;
136
137 this.horizontalFill = horizontalFill;
138 this.verticalFill = verticalFill;
139 }
140
141 public int getHgap()
142 {
143 return hgap;
144 }
145
146 public void setHgap(int hgap)
147 {
148 this.hgap = hgap;
149 super.setHgap(hgap);
150 }
151
152 public int getVgap()
153 {
154 return vgap;
155 }
156
157 public void setVgap(int vgap)
158 {
159 this.vgap = vgap;
160 super.setVgap(vgap);
161 }
162
163 public Dimension preferredLayoutSize(Container target)
164 {
165 Dimension tarsiz = new Dimension(0, 0);
166
167 for (int i = 0 ; i < target.getComponentCount(); i++)
168 {
169 Component m = target.getComponent(i);
170
171 if (m.isVisible())
172 {
173 Dimension d = m.getPreferredSize();
174 tarsiz.width = Math.max(tarsiz.width, d.width);
175
176 if (i > 0)
177 tarsiz.height += vgap;
178
179 tarsiz.height += d.height;
180 }
181 }
182
183 Insets insets = target.getInsets();
184
185 tarsiz.width += insets.left + insets.right + hgap*2;
186 tarsiz.height += insets.top + insets.bottom + vgap*2;
187
188 return tarsiz;
189 }
190
191 public Dimension minimumLayoutSize(Container target)
192 {
193 Dimension tarsiz = new Dimension(0, 0);
194
195 for (int i = 0 ; i < target.getComponentCount(); i++)
196 {
197 Component m = target.getComponent(i);
198
199 if (m.isVisible())
200 {
201 Dimension d = m.getMinimumSize();
202 tarsiz.width = Math.max(tarsiz.width, d.width);
203
204 if (i > 0)
205 tarsiz.height += vgap;
206
207 tarsiz.height += d.height;
208 }
209 }
210
211 Insets insets = target.getInsets();
212
213 tarsiz.width += insets.left + insets.right + hgap*2;
214 tarsiz.height += insets.top + insets.bottom + vgap*2;
215
216 return tarsiz;
217 }
218
219 public void setVerticalFill(boolean verticalFill)
220 {
221 this.verticalFill = verticalFill;
222 }
223
224 public boolean getVerticalFill()
225 {
226 return verticalFill;
227 }
228
229 public void setHorizontalFill(boolean horizontalFill)
230 {
231 this.horizontalFill = horizontalFill;
232 }
233
234 public boolean getHorizontalFill()
235 {
236 return horizontalFill;
237 }
238
239 private void moveComponents(Container target, int x, int y, int width, int height, int first, int last)
240 {
241 int align = getAlignment();
242 Insets insets = target.getInsets();
243
244 if ( align == this.MIDDLE )
245 y += height / 2;
246
247 if ( align == this.BOTTOM )
248 y += height;
249
250 for (int i = first ; i < last ; i++)
251 {
252 Component m = target.getComponent(i);
253 Dimension md = m.getSize();
254
255 if (m.isVisible())
256 {
257 int px = x + (width-md.width)/2;
258 m.setLocation(px, y);
259 y += vgap + md.height;
260 }
261 }
262 }
263
264 public void layoutContainer(Container target)
265 {
266 Insets insets = target.getInsets();
267
268 int maxheight = target.getSize().height - (insets.top + insets.bottom + vgap*2);
269 int maxwidth = target.getSize().width - (insets.left + insets.right + hgap*2);
270 int numcomp = target.getComponentCount();
271
272 int x = insets.left + hgap;
273 int y = 0 ;
274
275 int colw = 0, start = 0;
276
277 for (int i = 0 ; i < numcomp ; i++)
278 {
279 Component m = target.getComponent(i);
280
281 if (m.isVisible())
282 {
283 Dimension d = m.getPreferredSize();
284
285 if ((this.verticalFill) && (i == (numcomp-1)))
286 d.height = Math.max((maxheight - y), m.getPreferredSize().height);
287
288 if ( this.horizontalFill )
289 {
290 m.setSize(maxwidth, d.height);
291 d.width = maxwidth;
292 }
293 else
294 m.setSize(d.width, d.height);
295
296 if ( y + d.height > maxheight )
297 {
298 moveComponents(target, x, insets.top + vgap, colw, maxheight-y, start, i);
299 y = d.height;
300 x += hgap + colw;
301 colw = d.width;
302 start = i;
303 }
304 else
305 {
306 if ( y > 0 )
307 y += vgap;
308 y += d.height;
309 colw = Math.max(colw, d.width);
310 }
311 }
312 }
313
314 moveComponents(target, x, insets.top + vgap, colw, maxheight - y, start, numcomp);
315 }
316
317 public static void main(String[] args)
318 {
319 try
320 {
321 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
322 }
323 catch(Exception e)
324 {
325 e.printStackTrace();
326 }
327
328 JFrame frame = new JFrame("ToolBar Test");
329 JPanel panel = new JPanel(new JTVerticalFlowLayout());
330
331 JButton buttonOne = new JButton("One");
332 JButton buttonTwo = new JButton("Two");
333 JButton buttonThree = new JButton("Three");
334 JButton buttonFour = new JButton("Four");
335
336 panel.add(buttonOne);
337 panel.add(buttonTwo);
338 panel.add(buttonThree);
339 panel.add(buttonFour);
340
341 frame.getContentPane().setLayout(new BorderLayout());
342 frame.getContentPane().add(panel, BorderLayout.CENTER);
343
344 frame.setSize(640, 480);
345 frame.show();
346 }
347 }