View Javadoc

1   /*
2    * Created on Nov 8, 2004 
3    * 
4    *   Magic-Project is a turn based strategy simulator
5    *   Copyright (C) 2003-2007 Fabrice Daugan
6    *
7    *   This program is free software; you can redistribute it and/or modify it 
8    * under the terms of the GNU General Public License as published by the Free 
9    * Software Foundation; either version 2 of the License, or (at your option) any
10   * later version.
11   *
12   *   This program is distributed in the hope that it will be useful, but WITHOUT 
13   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14   * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
15   * details.
16   *
17   *   You should have received a copy of the GNU General Public License along  
18   * with this program; if not, write to the Free Software Foundation, Inc., 
19   * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20   * 
21   */
22  package net.sf.magicproject.ui.layout;
23  
24  import java.awt.Component;
25  import java.awt.Container;
26  import java.awt.Dimension;
27  import java.awt.Insets;
28  import java.awt.LayoutManager;
29  
30  /***
31   * A flow layout arranges components in a directional flow, much like lines of
32   * text in a paragraph. The flow direction is determined by the container's
33   * <code>componentOrientation</code> property and may be one of two values:
34   * <ul>
35   * <li><code>ComponentOrientation.LEFT_TO_RIGHT</code>
36   * <li><code>ComponentOrientation.RIGHT_TO_LEFT</code>
37   * </ul>
38   * Flow layouts are typically used to arrange buttons in a panel. It arranges
39   * buttons horizontally until no more buttons fit on the same line.
40   * <p>
41   * A flow layout lets each component assume its natural (preferred) size.
42   * 
43   * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
44   * @since 0.80
45   */
46  public class FlowLayout2 implements LayoutManager {
47  
48  	/***
49  	 * Constructs a new <code>FlowLayout</code> with a centered alignment and a
50  	 * default 5-unit horizontal and vertical gap.
51  	 */
52  	public FlowLayout2() {
53  		this(5, 5);
54  	}
55  
56  	/***
57  	 * Creates a new flow layout manager with the indicated horizontal and
58  	 * vertical gaps.
59  	 * <p>
60  	 * 
61  	 * @param hgap
62  	 *          the horizontal gap between components and between the components
63  	 *          and the borders of the <code>Container</code>
64  	 * @param vgap
65  	 *          the vertical gap between components and between the components and
66  	 *          the borders of the <code>Container</code>
67  	 */
68  	public FlowLayout2(int hgap, int vgap) {
69  		this.hgap = hgap;
70  		this.vgap = vgap;
71  	}
72  
73  	/***
74  	 * Gets the horizontal gap between components and between the components and
75  	 * the borders of the <code>Container</code>
76  	 * 
77  	 * @return the horizontal gap between components and between the components
78  	 *         and the borders of the <code>Container</code>
79  	 * @see java.awt.FlowLayout#setHgap
80  	 * @since JDK1.1
81  	 */
82  	public int getHgap() {
83  		return hgap;
84  	}
85  
86  	/***
87  	 * Sets the horizontal gap between components and between the components and
88  	 * the borders of the <code>Container</code>.
89  	 * 
90  	 * @param hgap
91  	 *          the horizontal gap between components and between the components
92  	 *          and the borders of the <code>Container</code>
93  	 * @see java.awt.FlowLayout#getHgap
94  	 * @since JDK1.1
95  	 */
96  	public void setHgap(int hgap) {
97  		this.hgap = hgap;
98  	}
99  
100 	/***
101 	 * Gets the vertical gap between components and between the components and the
102 	 * borders of the <code>Container</code>.
103 	 * 
104 	 * @return the vertical gap between components and between the components and
105 	 *         the borders of the <code>Container</code>
106 	 * @see java.awt.FlowLayout#setVgap
107 	 * @since JDK1.1
108 	 */
109 	public int getVgap() {
110 		return vgap;
111 	}
112 
113 	/***
114 	 * Sets the vertical gap between components and between the components and the
115 	 * borders of the <code>Container</code>.
116 	 * 
117 	 * @param vgap
118 	 *          the vertical gap between components and between the components and
119 	 *          the borders of the <code>Container</code>
120 	 * @see java.awt.FlowLayout#getVgap
121 	 * @since JDK1.1
122 	 */
123 	public void setVgap(int vgap) {
124 		this.vgap = vgap;
125 	}
126 
127 	public void addLayoutComponent(String name, Component comp) {
128 		// Ignore this event
129 	}
130 
131 	public void removeLayoutComponent(Component comp) {
132 		// Ignore this event
133 	}
134 
135 	public Dimension preferredLayoutSize(Container target) {
136 		synchronized (target.getTreeLock()) {
137 			Dimension dim = new Dimension(0, 0);
138 			int nmembers = target.getComponentCount();
139 			boolean firstVisibleComponent = true;
140 
141 			for (int i = 0; i < nmembers; i++) {
142 				Component m = target.getComponent(i);
143 				if (m.isVisible()) {
144 					Dimension d = m.getPreferredSize();
145 					dim.height = Math.max(dim.height, d.height);
146 					if (firstVisibleComponent) {
147 						firstVisibleComponent = false;
148 					} else {
149 						dim.width += hgap;
150 					}
151 					dim.width += d.width;
152 				}
153 			}
154 			Insets insets = target.getInsets();
155 			dim.width += insets.left + insets.right + hgap * 2;
156 			dim.height += insets.top + insets.bottom + vgap * 2;
157 			return dim;
158 		}
159 	}
160 
161 	public Dimension minimumLayoutSize(Container target) {
162 		synchronized (target.getTreeLock()) {
163 			Dimension dim = new Dimension(0, 0);
164 			int nmembers = target.getComponentCount();
165 
166 			for (int i = 0; i < nmembers; i++) {
167 				Component m = target.getComponent(i);
168 				if (m.isVisible()) {
169 					Dimension d = m.getMinimumSize();
170 					dim.height = Math.max(dim.height, d.height);
171 					if (i > 0) {
172 						dim.width += hgap;
173 					}
174 					dim.width += d.width;
175 				}
176 			}
177 			Insets insets = target.getInsets();
178 			dim.width += insets.left + insets.right + hgap * 2;
179 			dim.height += insets.top + insets.bottom + vgap * 2;
180 			return dim;
181 		}
182 	}
183 
184 	public void layoutContainer(Container target) {
185 		synchronized (target.getTreeLock()) {
186 			Insets insets = target.getInsets();
187 			int maxwidth = target.getWidth()
188 					- (insets.left + insets.right + hgap * 2);
189 			int nmembers = target.getComponentCount();
190 			int x = maxwidth;
191 			int y = target.getHeight() - insets.bottom - vgap;
192 			int rowh = 0;
193 
194 			for (int i = 0; i < nmembers; i++) {
195 				Component m = target.getComponent(i);
196 				if (m.isVisible()) {
197 					Dimension d = m.getPreferredSize();
198 					m.setSize(d.width, d.height);
199 
200 					if (x - d.width >= 0) {
201 						if (x < maxwidth) {
202 							x -= hgap;
203 						}
204 						x -= d.width;
205 						rowh = Math.max(rowh, d.height);
206 					} else {
207 						x = maxwidth - d.width;
208 						y -= vgap + rowh;
209 						rowh = d.height;
210 					}
211 					m.setLocation(x, y - (int) d.getHeight());
212 				}
213 			}
214 		}
215 	}
216 
217 	/***
218 	 * The flow layout manager allows a seperation of components with gaps. The
219 	 * horizontal gap will specify the space between components and between the
220 	 * components and the borders of the <code>Container</code>.
221 	 * 
222 	 * @serial
223 	 * @see #getHgap()
224 	 * @see #setHgap(int)
225 	 */
226 	protected int hgap;
227 
228 	/***
229 	 * The flow layout manager allows a seperation of components with gaps. The
230 	 * vertical gap will specify the space between rows and between the the rows
231 	 * and the borders of the <code>Container</code>.
232 	 * 
233 	 * @serial
234 	 * @see #getHgap()
235 	 * @see #setHgap(int)
236 	 */
237 	protected int vgap;
238 
239 }