1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package net.sf.magicproject.ui.layout;
24
25 import java.awt.Component;
26 import java.awt.Container;
27 import java.awt.Dimension;
28 import java.awt.Insets;
29 import java.awt.LayoutManager;
30
31 /***
32 * A flow layout arranges components in a directional flow, much like lines of
33 * text in a paragraph. The flow direction is determined by the container's
34 * <code>componentOrientation</code> property and may be one of two values:
35 * <ul>
36 * <li><code>ComponentOrientation.LEFT_TO_RIGHT</code>
37 * <li><code>ComponentOrientation.RIGHT_TO_LEFT</code>
38 * </ul>
39 * Flow layouts are typically used to arrange buttons in a panel. It arranges
40 * buttons horizontally until no more buttons fit on the same line.
41 * <p>
42 * A flow layout lets each component assume its natural (preferred) size.
43 *
44 * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
45 * @since 0.80
46 */
47 public class FlowLayout2Center implements LayoutManager {
48
49 /***
50 * Constructs a new <code>FlowLayout2Center</code> with a centered alignment
51 * and a default 5-unit horizontal and vertical gap.
52 */
53 public FlowLayout2Center() {
54 this(5, 5);
55 }
56
57 /***
58 * Creates a new flow layout manager with the indicated horizontal and
59 * vertical gaps.
60 * <p>
61 *
62 * @param hgap
63 * the horizontal gap between components and between the components
64 * and the borders of the <code>Container</code>
65 * @param vgap
66 * the vertical gap between components and between the components and
67 * the borders of the <code>Container</code>
68 */
69 public FlowLayout2Center(int hgap, int vgap) {
70 this.hgap = hgap;
71 this.vgap = vgap;
72 }
73
74 /***
75 * Gets the horizontal gap between components and between the components and
76 * the borders of the <code>Container</code>
77 *
78 * @return the horizontal gap between components and between the components
79 * and the borders of the <code>Container</code>
80 * @see java.awt.FlowLayout#setHgap
81 * @since JDK1.1
82 */
83 public int getHgap() {
84 return hgap;
85 }
86
87 /***
88 * Sets the horizontal gap between components and between the components and
89 * the borders of the <code>Container</code>.
90 *
91 * @param hgap
92 * the horizontal gap between components and between the components
93 * and the borders of the <code>Container</code>
94 * @see java.awt.FlowLayout#getHgap
95 * @since JDK1.1
96 */
97 public void setHgap(int hgap) {
98 this.hgap = hgap;
99 }
100
101 /***
102 * Gets the vertical gap between components and between the components and the
103 * borders of the <code>Container</code>.
104 *
105 * @return the vertical gap between components and between the components and
106 * the borders of the <code>Container</code>
107 * @see java.awt.FlowLayout#setVgap
108 * @since JDK1.1
109 */
110 public int getVgap() {
111 return vgap;
112 }
113
114 /***
115 * Sets the vertical gap between components and between the components and the
116 * borders of the <code>Container</code>.
117 *
118 * @param vgap
119 * the vertical gap between components and between the components and
120 * the borders of the <code>Container</code>
121 * @see java.awt.FlowLayout#getVgap
122 * @since JDK1.1
123 */
124 public void setVgap(int vgap) {
125 this.vgap = vgap;
126 }
127
128 public void addLayoutComponent(String name, Component comp) {
129
130 }
131
132 public void removeLayoutComponent(Component comp) {
133
134 }
135
136 public Dimension preferredLayoutSize(Container target) {
137 synchronized (target.getTreeLock()) {
138 Dimension dim = new Dimension(0, 0);
139 int nmembers = target.getComponentCount();
140 boolean firstVisibleComponent = true;
141
142 for (int i = 0; i < nmembers; i++) {
143 Component m = target.getComponent(i);
144 if (m.isVisible()) {
145 Dimension d = m.getPreferredSize();
146 dim.height = Math.max(dim.height, d.height);
147 if (firstVisibleComponent) {
148 firstVisibleComponent = false;
149 } else {
150 dim.width += hgap;
151 }
152 dim.width += d.width;
153 }
154 }
155 Insets insets = target.getInsets();
156 dim.width += insets.left + insets.right + hgap * 2;
157 dim.height += insets.top + insets.bottom + vgap * 2;
158 return dim;
159 }
160 }
161
162 public Dimension minimumLayoutSize(Container target) {
163 synchronized (target.getTreeLock()) {
164 Dimension dim = new Dimension(0, 0);
165 int nmembers = target.getComponentCount();
166
167 for (int i = 0; i < nmembers; i++) {
168 Component m = target.getComponent(i);
169 if (m.isVisible()) {
170 Dimension d = m.getMinimumSize();
171 dim.height = Math.max(dim.height, d.height);
172 if (i > 0) {
173 dim.width += hgap;
174 }
175 dim.width += d.width;
176 }
177 }
178 Insets insets = target.getInsets();
179 dim.width += insets.left + insets.right + hgap * 2;
180 dim.height += insets.top + insets.bottom + vgap * 2;
181 return dim;
182 }
183 }
184
185 public void layoutContainer(Container target) {
186 synchronized (target.getTreeLock()) {
187 Insets insets = target.getInsets();
188 int maxwidth = target.getWidth()
189 - (insets.left + insets.right + hgap * 2);
190 int nmembers = target.getComponentCount();
191 int x = 0;
192 int y = target.getHeight() - insets.bottom - vgap;
193 int rowh = 0;
194 int start = 0;
195
196 for (int i = 0; i < nmembers; i++) {
197 Component m = target.getComponent(i);
198 if (m.isVisible()) {
199 Dimension d = m.getPreferredSize();
200 m.setSize(d.width, d.height);
201
202 if (x == 0 || x + d.width <= maxwidth) {
203 if (x > 0) {
204 x += hgap;
205 }
206 x += d.width;
207 rowh = Math.max(rowh, d.height);
208 } else {
209 moveComponents(target, insets.left + hgap, y, maxwidth - x, rowh,
210 start, i);
211 x = d.width;
212 y -= vgap + rowh;
213 rowh = d.height;
214 start = i;
215 }
216 }
217 }
218 moveComponents(target, insets.left + hgap, y, maxwidth - x, rowh, start,
219 nmembers);
220 }
221 }
222
223 /***
224 * Centers the elements in the specified row, if there is any slack.
225 *
226 * @param target
227 * the component which needs to be moved
228 * @param x
229 * the x coordinate
230 * @param y
231 * the y coordinate
232 * @param width
233 * the width dimensions
234 * @param height
235 * the height dimensions
236 * @param rowStart
237 * the beginning of the row
238 * @param rowEnd
239 * the the ending of the row
240 */
241 private void moveComponents(Container target, int x, int y, int width,
242 int height, int rowStart, int rowEnd) {
243 int xRec = x;
244 synchronized (target.getTreeLock()) {
245 xRec += width / 2;
246 for (int i = rowStart; i < rowEnd; i++) {
247 Component m = target.getComponent(i);
248 if (m.isVisible()) {
249 m.setLocation(target.getWidth() - xRec - m.getWidth(), y - height
250 + (height - m.getHeight()) / 2);
251 xRec += m.getWidth() + hgap;
252 }
253 }
254 }
255 }
256
257 /***
258 * The flow layout manager allows a seperation of components with gaps. The
259 * horizontal gap will specify the space between components and between the
260 * components and the borders of the <code>Container</code>.
261 *
262 * @serial
263 * @see #getHgap()
264 * @see #setHgap(int)
265 */
266 protected int hgap;
267
268 /***
269 * The flow layout manager allows a seperation of components with gaps. The
270 * vertical gap will specify the space between rows and between the the rows
271 * and the borders of the <code>Container</code>.
272 *
273 * @serial
274 * @see #getHgap()
275 * @see #setHgap(int)
276 */
277 protected int vgap;
278
279 }