author | cl |
Wed, 09 Oct 2013 14:32:15 -0700 | |
changeset 21244 | 7c2ac5ca05a2 |
parent 20451 | 4cedf4e1560a |
child 21278 | ef8a3a2a72f2 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
5506 | 2 |
* Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved. |
2 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 10 |
* |
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2 | 24 |
*/ |
25 |
package java.awt; |
|
26 |
||
27 |
import java.util.Hashtable; |
|
28 |
import java.util.Arrays; |
|
29 |
||
30 |
/** |
|
31 |
* The <code>GridBagLayout</code> class is a flexible layout |
|
32 |
* manager that aligns components vertically, horizontally or along their |
|
33 |
* baseline without requiring that the components be of the same size. |
|
34 |
* Each <code>GridBagLayout</code> object maintains a dynamic, |
|
35 |
* rectangular grid of cells, with each component occupying |
|
36 |
* one or more cells, called its <em>display area</em>. |
|
37 |
* <p> |
|
38 |
* Each component managed by a <code>GridBagLayout</code> is associated with |
|
39 |
* an instance of {@link GridBagConstraints}. The constraints object |
|
40 |
* specifies where a component's display area should be located on the grid |
|
41 |
* and how the component should be positioned within its display area. In |
|
42 |
* addition to its constraints object, the <code>GridBagLayout</code> also |
|
43 |
* considers each component's minimum and preferred sizes in order to |
|
44 |
* determine a component's size. |
|
45 |
* <p> |
|
46 |
* The overall orientation of the grid depends on the container's |
|
47 |
* {@link ComponentOrientation} property. For horizontal left-to-right |
|
48 |
* orientations, grid coordinate (0,0) is in the upper left corner of the |
|
49 |
* container with x increasing to the right and y increasing downward. For |
|
50 |
* horizontal right-to-left orientations, grid coordinate (0,0) is in the upper |
|
51 |
* right corner of the container with x increasing to the left and y |
|
52 |
* increasing downward. |
|
53 |
* <p> |
|
54 |
* To use a grid bag layout effectively, you must customize one or more |
|
55 |
* of the <code>GridBagConstraints</code> objects that are associated |
|
56 |
* with its components. You customize a <code>GridBagConstraints</code> |
|
57 |
* object by setting one or more of its instance variables: |
|
58 |
* <p> |
|
59 |
* <dl> |
|
60 |
* <dt>{@link GridBagConstraints#gridx}, |
|
61 |
* {@link GridBagConstraints#gridy} |
|
62 |
* <dd>Specifies the cell containing the leading corner of the component's |
|
63 |
* display area, where the cell at the origin of the grid has address |
|
64 |
* <code>gridx = 0</code>, |
|
65 |
* <code>gridy = 0</code>. For horizontal left-to-right layout, |
|
66 |
* a component's leading corner is its upper left. For horizontal |
|
67 |
* right-to-left layout, a component's leading corner is its upper right. |
|
68 |
* Use <code>GridBagConstraints.RELATIVE</code> (the default value) |
|
69 |
* to specify that the component be placed immediately following |
|
70 |
* (along the x axis for <code>gridx</code> or the y axis for |
|
71 |
* <code>gridy</code>) the component that was added to the container |
|
72 |
* just before this component was added. |
|
73 |
* <dt>{@link GridBagConstraints#gridwidth}, |
|
74 |
* {@link GridBagConstraints#gridheight} |
|
75 |
* <dd>Specifies the number of cells in a row (for <code>gridwidth</code>) |
|
76 |
* or column (for <code>gridheight</code>) |
|
77 |
* in the component's display area. |
|
78 |
* The default value is 1. |
|
79 |
* Use <code>GridBagConstraints.REMAINDER</code> to specify |
|
80 |
* that the component's display area will be from <code>gridx</code> |
|
81 |
* to the last cell in the row (for <code>gridwidth</code>) |
|
82 |
* or from <code>gridy</code> to the last cell in the column |
|
83 |
* (for <code>gridheight</code>). |
|
84 |
* |
|
85 |
* Use <code>GridBagConstraints.RELATIVE</code> to specify |
|
86 |
* that the component's display area will be from <code>gridx</code> |
|
87 |
* to the next to the last cell in its row (for <code>gridwidth</code> |
|
88 |
* or from <code>gridy</code> to the next to the last cell in its |
|
89 |
* column (for <code>gridheight</code>). |
|
90 |
* |
|
91 |
* <dt>{@link GridBagConstraints#fill} |
|
92 |
* <dd>Used when the component's display area |
|
93 |
* is larger than the component's requested size |
|
94 |
* to determine whether (and how) to resize the component. |
|
95 |
* Possible values are |
|
96 |
* <code>GridBagConstraints.NONE</code> (the default), |
|
97 |
* <code>GridBagConstraints.HORIZONTAL</code> |
|
98 |
* (make the component wide enough to fill its display area |
|
99 |
* horizontally, but don't change its height), |
|
100 |
* <code>GridBagConstraints.VERTICAL</code> |
|
101 |
* (make the component tall enough to fill its display area |
|
102 |
* vertically, but don't change its width), and |
|
103 |
* <code>GridBagConstraints.BOTH</code> |
|
104 |
* (make the component fill its display area entirely). |
|
105 |
* <dt>{@link GridBagConstraints#ipadx}, |
|
106 |
* {@link GridBagConstraints#ipady} |
|
107 |
* <dd>Specifies the component's internal padding within the layout, |
|
108 |
* how much to add to the minimum size of the component. |
|
109 |
* The width of the component will be at least its minimum width |
|
110 |
* plus <code>ipadx</code> pixels. Similarly, the height of |
|
111 |
* the component will be at least the minimum height plus |
|
112 |
* <code>ipady</code> pixels. |
|
113 |
* <dt>{@link GridBagConstraints#insets} |
|
114 |
* <dd>Specifies the component's external padding, the minimum |
|
115 |
* amount of space between the component and the edges of its display area. |
|
116 |
* <dt>{@link GridBagConstraints#anchor} |
|
117 |
* <dd>Specifies where the component should be positioned in its display area. |
|
118 |
* There are three kinds of possible values: absolute, orientation-relative, |
|
119 |
* and baseline-relative |
|
120 |
* Orientation relative values are interpreted relative to the container's |
|
121 |
* <code>ComponentOrientation</code> property while absolute values |
|
122 |
* are not. Baseline relative values are calculated relative to the |
|
20172 | 123 |
* baseline. Valid values are: |
2 | 124 |
* <p> |
20172 | 125 |
* <center><table BORDER=0 WIDTH=800 |
2 | 126 |
* SUMMARY="absolute, relative and baseline values as described above"> |
127 |
* <tr> |
|
21244
7c2ac5ca05a2
8026021: more fix of javadoc errors and warnings reported by doclint, see the description
cl
parents:
20451
diff
changeset
|
128 |
* <th><P style="text-align:left">Absolute Values</th> |
7c2ac5ca05a2
8026021: more fix of javadoc errors and warnings reported by doclint, see the description
cl
parents:
20451
diff
changeset
|
129 |
* <th><P style="text-align:left">Orientation Relative Values</th> |
7c2ac5ca05a2
8026021: more fix of javadoc errors and warnings reported by doclint, see the description
cl
parents:
20451
diff
changeset
|
130 |
* <th><P style="text-align:left">Baseline Relative Values</th> |
2 | 131 |
* </tr> |
132 |
* <tr> |
|
133 |
* <td> |
|
20172 | 134 |
* <ul style="list-style-type:none"> |
2 | 135 |
* <li><code>GridBagConstraints.NORTH</code></li> |
136 |
* <li><code>GridBagConstraints.SOUTH</code></li> |
|
137 |
* <li><code>GridBagConstraints.WEST</code></li> |
|
138 |
* <li><code>GridBagConstraints.EAST</code></li> |
|
139 |
* <li><code>GridBagConstraints.NORTHWEST</code></li> |
|
140 |
* <li><code>GridBagConstraints.NORTHEAST</code></li> |
|
141 |
* <li><code>GridBagConstraints.SOUTHWEST</code></li> |
|
142 |
* <li><code>GridBagConstraints.SOUTHEAST</code></li> |
|
143 |
* <li><code>GridBagConstraints.CENTER</code> (the default)</li> |
|
20172 | 144 |
* </ul> |
2 | 145 |
* </td> |
146 |
* <td> |
|
20172 | 147 |
* <ul style="list-style-type:none"> |
2 | 148 |
* <li><code>GridBagConstraints.PAGE_START</code></li> |
149 |
* <li><code>GridBagConstraints.PAGE_END</code></li> |
|
150 |
* <li><code>GridBagConstraints.LINE_START</code></li> |
|
151 |
* <li><code>GridBagConstraints.LINE_END</code></li> |
|
152 |
* <li><code>GridBagConstraints.FIRST_LINE_START</code></li> |
|
153 |
* <li><code>GridBagConstraints.FIRST_LINE_END</code></li> |
|
154 |
* <li><code>GridBagConstraints.LAST_LINE_START</code></li> |
|
155 |
* <li><code>GridBagConstraints.LAST_LINE_END</code></li> |
|
20172 | 156 |
* </ul> |
2 | 157 |
* </td> |
158 |
* <td> |
|
20172 | 159 |
* <ul style="list-style-type:none"> |
2 | 160 |
* <li><code>GridBagConstraints.BASELINE</code></li> |
161 |
* <li><code>GridBagConstraints.BASELINE_LEADING</code></li> |
|
162 |
* <li><code>GridBagConstraints.BASELINE_TRAILING</code></li> |
|
163 |
* <li><code>GridBagConstraints.ABOVE_BASELINE</code></li> |
|
164 |
* <li><code>GridBagConstraints.ABOVE_BASELINE_LEADING</code></li> |
|
165 |
* <li><code>GridBagConstraints.ABOVE_BASELINE_TRAILING</code></li> |
|
166 |
* <li><code>GridBagConstraints.BELOW_BASELINE</code></li> |
|
167 |
* <li><code>GridBagConstraints.BELOW_BASELINE_LEADING</code></li> |
|
168 |
* <li><code>GridBagConstraints.BELOW_BASELINE_TRAILING</code></li> |
|
20172 | 169 |
* </ul> |
2 | 170 |
* </td> |
171 |
* </tr> |
|
20172 | 172 |
* </table></center> |
2 | 173 |
* <dt>{@link GridBagConstraints#weightx}, |
174 |
* {@link GridBagConstraints#weighty} |
|
175 |
* <dd>Used to determine how to distribute space, which is |
|
176 |
* important for specifying resizing behavior. |
|
177 |
* Unless you specify a weight for at least one component |
|
178 |
* in a row (<code>weightx</code>) and column (<code>weighty</code>), |
|
179 |
* all the components clump together in the center of their container. |
|
180 |
* This is because when the weight is zero (the default), |
|
181 |
* the <code>GridBagLayout</code> object puts any extra space |
|
182 |
* between its grid of cells and the edges of the container. |
|
183 |
* </dl> |
|
184 |
* <p> |
|
185 |
* Each row may have a baseline; the baseline is determined by the |
|
186 |
* components in that row that have a valid baseline and are aligned |
|
187 |
* along the baseline (the component's anchor value is one of {@code |
|
188 |
* BASELINE}, {@code BASELINE_LEADING} or {@code BASELINE_TRAILING}). |
|
189 |
* If none of the components in the row has a valid baseline, the row |
|
190 |
* does not have a baseline. |
|
191 |
* <p> |
|
192 |
* If a component spans rows it is aligned either to the baseline of |
|
193 |
* the start row (if the baseline-resize behavior is {@code |
|
194 |
* CONSTANT_ASCENT}) or the end row (if the baseline-resize behavior |
|
195 |
* is {@code CONSTANT_DESCENT}). The row that the component is |
|
196 |
* aligned to is called the <em>prevailing row</em>. |
|
197 |
* <p> |
|
198 |
* The following figure shows a baseline layout and includes a |
|
199 |
* component that spans rows: |
|
200 |
* <center><table summary="Baseline Layout"> |
|
201 |
* <tr ALIGN=CENTER> |
|
202 |
* <td> |
|
203 |
* <img src="doc-files/GridBagLayout-baseline.png" |
|
20451
4cedf4e1560a
8025409: Fix javadoc comments errors and warning reported by doclint report
cl
parents:
20172
diff
changeset
|
204 |
* alt="The following text describes this graphic (Figure 1)." style="float:center"> |
2 | 205 |
* </td> |
206 |
* </table></center> |
|
207 |
* This layout consists of three components: |
|
208 |
* <ul><li>A panel that starts in row 0 and ends in row 1. The panel |
|
209 |
* has a baseline-resize behavior of <code>CONSTANT_DESCENT</code> and has |
|
210 |
* an anchor of <code>BASELINE</code>. As the baseline-resize behavior |
|
211 |
* is <code>CONSTANT_DESCENT</code> the prevailing row for the panel is |
|
212 |
* row 1. |
|
213 |
* <li>Two buttons, each with a baseline-resize behavior of |
|
214 |
* <code>CENTER_OFFSET</code> and an anchor of <code>BASELINE</code>. |
|
215 |
* </ul> |
|
216 |
* Because the second button and the panel share the same prevailing row, |
|
217 |
* they are both aligned along their baseline. |
|
218 |
* <p> |
|
219 |
* Components positioned using one of the baseline-relative values resize |
|
220 |
* differently than when positioned using an absolute or orientation-relative |
|
221 |
* value. How components change is dictated by how the baseline of the |
|
222 |
* prevailing row changes. The baseline is anchored to the |
|
223 |
* bottom of the display area if any components with the same prevailing row |
|
224 |
* have a baseline-resize behavior of <code>CONSTANT_DESCENT</code>, |
|
225 |
* otherwise the baseline is anchored to the top of the display area. |
|
226 |
* The following rules dictate the resize behavior: |
|
227 |
* <ul> |
|
228 |
* <li>Resizable components positioned above the baseline can only |
|
229 |
* grow as tall as the baseline. For example, if the baseline is at 100 |
|
230 |
* and anchored at the top, a resizable component positioned above the |
|
231 |
* baseline can never grow more than 100 units. |
|
232 |
* <li>Similarly, resizable components positioned below the baseline can |
|
233 |
* only grow as high as the difference between the display height and the |
|
234 |
* baseline. |
|
235 |
* <li>Resizable components positioned on the baseline with a |
|
236 |
* baseline-resize behavior of <code>OTHER</code> are only resized if |
|
237 |
* the baseline at the resized size fits within the display area. If |
|
238 |
* the baseline is such that it does not fit within the display area |
|
239 |
* the component is not resized. |
|
240 |
* <li>Components positioned on the baseline that do not have a |
|
241 |
* baseline-resize behavior of <code>OTHER</code> |
|
242 |
* can only grow as tall as {@code display height - baseline + baseline of component}. |
|
243 |
* </ul> |
|
244 |
* If you position a component along the baseline, but the |
|
245 |
* component does not have a valid baseline, it will be vertically centered |
|
246 |
* in its space. Similarly if you have positioned a component relative |
|
247 |
* to the baseline and none of the components in the row have a valid |
|
248 |
* baseline the component is vertically centered. |
|
249 |
* <p> |
|
250 |
* The following figures show ten components (all buttons) |
|
251 |
* managed by a grid bag layout. Figure 2 shows the layout for a horizontal, |
|
252 |
* left-to-right container and Figure 3 shows the layout for a horizontal, |
|
253 |
* right-to-left container. |
|
254 |
* <p> |
|
20172 | 255 |
* <center><table WIDTH=600 summary="layout"> |
2 | 256 |
* <tr ALIGN=CENTER> |
257 |
* <td> |
|
20451
4cedf4e1560a
8025409: Fix javadoc comments errors and warning reported by doclint report
cl
parents:
20172
diff
changeset
|
258 |
* <img src="doc-files/GridBagLayout-1.gif" alt="The preceeding text describes this graphic (Figure 1)." style="float:center; margin: 7px 10px;"> |
2 | 259 |
* </td> |
260 |
* <td> |
|
20451
4cedf4e1560a
8025409: Fix javadoc comments errors and warning reported by doclint report
cl
parents:
20172
diff
changeset
|
261 |
* <img src="doc-files/GridBagLayout-2.gif" alt="The preceeding text describes this graphic (Figure 2)." style="float:center; margin: 7px 10px;"> |
2 | 262 |
* </td> |
263 |
* <tr ALIGN=CENTER> |
|
264 |
* <td>Figure 2: Horizontal, Left-to-Right</td> |
|
265 |
* <td>Figure 3: Horizontal, Right-to-Left</td> |
|
266 |
* </tr> |
|
267 |
* </table></center> |
|
268 |
* <p> |
|
269 |
* Each of the ten components has the <code>fill</code> field |
|
270 |
* of its associated <code>GridBagConstraints</code> object |
|
271 |
* set to <code>GridBagConstraints.BOTH</code>. |
|
272 |
* In addition, the components have the following non-default constraints: |
|
273 |
* <p> |
|
274 |
* <ul> |
|
275 |
* <li>Button1, Button2, Button3: <code>weightx = 1.0</code> |
|
276 |
* <li>Button4: <code>weightx = 1.0</code>, |
|
277 |
* <code>gridwidth = GridBagConstraints.REMAINDER</code> |
|
278 |
* <li>Button5: <code>gridwidth = GridBagConstraints.REMAINDER</code> |
|
279 |
* <li>Button6: <code>gridwidth = GridBagConstraints.RELATIVE</code> |
|
280 |
* <li>Button7: <code>gridwidth = GridBagConstraints.REMAINDER</code> |
|
281 |
* <li>Button8: <code>gridheight = 2</code>, |
|
282 |
* <code>weighty = 1.0</code> |
|
283 |
* <li>Button9, Button 10: |
|
284 |
* <code>gridwidth = GridBagConstraints.REMAINDER</code> |
|
285 |
* </ul> |
|
286 |
* <p> |
|
287 |
* Here is the code that implements the example shown above: |
|
288 |
* <p> |
|
289 |
* <hr><blockquote><pre> |
|
290 |
* import java.awt.*; |
|
291 |
* import java.util.*; |
|
292 |
* import java.applet.Applet; |
|
293 |
* |
|
294 |
* public class GridBagEx1 extends Applet { |
|
295 |
* |
|
296 |
* protected void makebutton(String name, |
|
297 |
* GridBagLayout gridbag, |
|
298 |
* GridBagConstraints c) { |
|
299 |
* Button button = new Button(name); |
|
300 |
* gridbag.setConstraints(button, c); |
|
301 |
* add(button); |
|
302 |
* } |
|
303 |
* |
|
304 |
* public void init() { |
|
305 |
* GridBagLayout gridbag = new GridBagLayout(); |
|
306 |
* GridBagConstraints c = new GridBagConstraints(); |
|
307 |
* |
|
308 |
* setFont(new Font("SansSerif", Font.PLAIN, 14)); |
|
309 |
* setLayout(gridbag); |
|
310 |
* |
|
311 |
* c.fill = GridBagConstraints.BOTH; |
|
312 |
* c.weightx = 1.0; |
|
313 |
* makebutton("Button1", gridbag, c); |
|
314 |
* makebutton("Button2", gridbag, c); |
|
315 |
* makebutton("Button3", gridbag, c); |
|
316 |
* |
|
317 |
* c.gridwidth = GridBagConstraints.REMAINDER; //end row |
|
318 |
* makebutton("Button4", gridbag, c); |
|
319 |
* |
|
320 |
* c.weightx = 0.0; //reset to the default |
|
321 |
* makebutton("Button5", gridbag, c); //another row |
|
322 |
* |
|
323 |
* c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last in row |
|
324 |
* makebutton("Button6", gridbag, c); |
|
325 |
* |
|
326 |
* c.gridwidth = GridBagConstraints.REMAINDER; //end row |
|
327 |
* makebutton("Button7", gridbag, c); |
|
328 |
* |
|
329 |
* c.gridwidth = 1; //reset to the default |
|
330 |
* c.gridheight = 2; |
|
331 |
* c.weighty = 1.0; |
|
332 |
* makebutton("Button8", gridbag, c); |
|
333 |
* |
|
334 |
* c.weighty = 0.0; //reset to the default |
|
335 |
* c.gridwidth = GridBagConstraints.REMAINDER; //end row |
|
336 |
* c.gridheight = 1; //reset to the default |
|
337 |
* makebutton("Button9", gridbag, c); |
|
338 |
* makebutton("Button10", gridbag, c); |
|
339 |
* |
|
340 |
* setSize(300, 100); |
|
341 |
* } |
|
342 |
* |
|
343 |
* public static void main(String args[]) { |
|
344 |
* Frame f = new Frame("GridBag Layout Example"); |
|
345 |
* GridBagEx1 ex1 = new GridBagEx1(); |
|
346 |
* |
|
347 |
* ex1.init(); |
|
348 |
* |
|
349 |
* f.add("Center", ex1); |
|
350 |
* f.pack(); |
|
351 |
* f.setSize(f.getPreferredSize()); |
|
352 |
* f.show(); |
|
353 |
* } |
|
354 |
* } |
|
355 |
* </pre></blockquote><hr> |
|
356 |
* <p> |
|
357 |
* @author Doug Stein |
|
20172 | 358 |
* @author Bill Spitzak (orignial NeWS & OLIT implementation) |
2 | 359 |
* @see java.awt.GridBagConstraints |
360 |
* @see java.awt.GridBagLayoutInfo |
|
361 |
* @see java.awt.ComponentOrientation |
|
362 |
* @since JDK1.0 |
|
363 |
*/ |
|
364 |
public class GridBagLayout implements LayoutManager2, |
|
365 |
java.io.Serializable { |
|
366 |
||
367 |
static final int EMPIRICMULTIPLIER = 2; |
|
368 |
/** |
|
369 |
* This field is no longer used to reserve arrays and keeped for backward |
|
370 |
* compatibility. Previously, this was |
|
371 |
* the maximum number of grid positions (both horizontal and |
|
372 |
* vertical) that could be laid out by the grid bag layout. |
|
373 |
* Current implementation doesn't impose any limits |
|
374 |
* on the size of a grid. |
|
375 |
*/ |
|
376 |
protected static final int MAXGRIDSIZE = 512; |
|
377 |
||
378 |
/** |
|
379 |
* The smallest grid that can be laid out by the grid bag layout. |
|
380 |
*/ |
|
381 |
protected static final int MINSIZE = 1; |
|
382 |
/** |
|
383 |
* The preferred grid size that can be laid out by the grid bag layout. |
|
384 |
*/ |
|
385 |
protected static final int PREFERREDSIZE = 2; |
|
386 |
||
387 |
/** |
|
388 |
* This hashtable maintains the association between |
|
389 |
* a component and its gridbag constraints. |
|
390 |
* The Keys in <code>comptable</code> are the components and the |
|
391 |
* values are the instances of <code>GridBagConstraints</code>. |
|
392 |
* |
|
393 |
* @serial |
|
394 |
* @see java.awt.GridBagConstraints |
|
395 |
*/ |
|
396 |
protected Hashtable<Component,GridBagConstraints> comptable; |
|
397 |
||
398 |
/** |
|
399 |
* This field holds a gridbag constraints instance |
|
400 |
* containing the default values, so if a component |
|
401 |
* does not have gridbag constraints associated with |
|
402 |
* it, then the component will be assigned a |
|
403 |
* copy of the <code>defaultConstraints</code>. |
|
404 |
* |
|
405 |
* @serial |
|
406 |
* @see #getConstraints(Component) |
|
407 |
* @see #setConstraints(Component, GridBagConstraints) |
|
408 |
* @see #lookupConstraints(Component) |
|
409 |
*/ |
|
410 |
protected GridBagConstraints defaultConstraints; |
|
411 |
||
412 |
/** |
|
413 |
* This field holds the layout information |
|
414 |
* for the gridbag. The information in this field |
|
415 |
* is based on the most recent validation of the |
|
416 |
* gridbag. |
|
417 |
* If <code>layoutInfo</code> is <code>null</code> |
|
418 |
* this indicates that there are no components in |
|
419 |
* the gridbag or if there are components, they have |
|
420 |
* not yet been validated. |
|
421 |
* |
|
422 |
* @serial |
|
423 |
* @see #getLayoutInfo(Container, int) |
|
424 |
*/ |
|
425 |
protected GridBagLayoutInfo layoutInfo; |
|
426 |
||
427 |
/** |
|
428 |
* This field holds the overrides to the column minimum |
|
429 |
* width. If this field is non-<code>null</code> the values are |
|
430 |
* applied to the gridbag after all of the minimum columns |
|
431 |
* widths have been calculated. |
|
432 |
* If columnWidths has more elements than the number of |
|
433 |
* columns, columns are added to the gridbag to match |
|
434 |
* the number of elements in columnWidth. |
|
435 |
* |
|
436 |
* @serial |
|
437 |
* @see #getLayoutDimensions() |
|
438 |
*/ |
|
439 |
public int columnWidths[]; |
|
440 |
||
441 |
/** |
|
442 |
* This field holds the overrides to the row minimum |
|
443 |
* heights. If this field is non-<code>null</code> the values are |
|
444 |
* applied to the gridbag after all of the minimum row |
|
445 |
* heights have been calculated. |
|
446 |
* If <code>rowHeights</code> has more elements than the number of |
|
447 |
* rows, rowa are added to the gridbag to match |
|
448 |
* the number of elements in <code>rowHeights</code>. |
|
449 |
* |
|
450 |
* @serial |
|
451 |
* @see #getLayoutDimensions() |
|
452 |
*/ |
|
453 |
public int rowHeights[]; |
|
454 |
||
455 |
/** |
|
456 |
* This field holds the overrides to the column weights. |
|
457 |
* If this field is non-<code>null</code> the values are |
|
458 |
* applied to the gridbag after all of the columns |
|
459 |
* weights have been calculated. |
|
460 |
* If <code>columnWeights[i]</code> > weight for column i, then |
|
461 |
* column i is assigned the weight in <code>columnWeights[i]</code>. |
|
462 |
* If <code>columnWeights</code> has more elements than the number |
|
463 |
* of columns, the excess elements are ignored - they do |
|
464 |
* not cause more columns to be created. |
|
465 |
* |
|
466 |
* @serial |
|
467 |
*/ |
|
468 |
public double columnWeights[]; |
|
469 |
||
470 |
/** |
|
471 |
* This field holds the overrides to the row weights. |
|
472 |
* If this field is non-<code>null</code> the values are |
|
473 |
* applied to the gridbag after all of the rows |
|
474 |
* weights have been calculated. |
|
475 |
* If <code>rowWeights[i]</code> > weight for row i, then |
|
476 |
* row i is assigned the weight in <code>rowWeights[i]</code>. |
|
477 |
* If <code>rowWeights</code> has more elements than the number |
|
478 |
* of rows, the excess elements are ignored - they do |
|
479 |
* not cause more rows to be created. |
|
480 |
* |
|
481 |
* @serial |
|
482 |
*/ |
|
483 |
public double rowWeights[]; |
|
484 |
||
485 |
/** |
|
486 |
* The component being positioned. This is set before calling into |
|
487 |
* <code>adjustForGravity</code>. |
|
488 |
*/ |
|
489 |
private Component componentAdjusting; |
|
490 |
||
491 |
/** |
|
492 |
* Creates a grid bag layout manager. |
|
493 |
*/ |
|
494 |
public GridBagLayout () { |
|
495 |
comptable = new Hashtable<Component,GridBagConstraints>(); |
|
496 |
defaultConstraints = new GridBagConstraints(); |
|
497 |
} |
|
498 |
||
499 |
/** |
|
500 |
* Sets the constraints for the specified component in this layout. |
|
501 |
* @param comp the component to be modified |
|
502 |
* @param constraints the constraints to be applied |
|
503 |
*/ |
|
504 |
public void setConstraints(Component comp, GridBagConstraints constraints) { |
|
505 |
comptable.put(comp, (GridBagConstraints)constraints.clone()); |
|
506 |
} |
|
507 |
||
508 |
/** |
|
509 |
* Gets the constraints for the specified component. A copy of |
|
510 |
* the actual <code>GridBagConstraints</code> object is returned. |
|
511 |
* @param comp the component to be queried |
|
512 |
* @return the constraint for the specified component in this |
|
513 |
* grid bag layout; a copy of the actual constraint |
|
514 |
* object is returned |
|
515 |
*/ |
|
516 |
public GridBagConstraints getConstraints(Component comp) { |
|
517 |
GridBagConstraints constraints = comptable.get(comp); |
|
518 |
if (constraints == null) { |
|
519 |
setConstraints(comp, defaultConstraints); |
|
520 |
constraints = comptable.get(comp); |
|
521 |
} |
|
522 |
return (GridBagConstraints)constraints.clone(); |
|
523 |
} |
|
524 |
||
525 |
/** |
|
526 |
* Retrieves the constraints for the specified component. |
|
527 |
* The return value is not a copy, but is the actual |
|
528 |
* <code>GridBagConstraints</code> object used by the layout mechanism. |
|
529 |
* <p> |
|
530 |
* If <code>comp</code> is not in the <code>GridBagLayout</code>, |
|
531 |
* a set of default <code>GridBagConstraints</code> are returned. |
|
532 |
* A <code>comp</code> value of <code>null</code> is invalid |
|
533 |
* and returns <code>null</code>. |
|
534 |
* |
|
535 |
* @param comp the component to be queried |
|
536 |
* @return the contraints for the specified component |
|
537 |
*/ |
|
538 |
protected GridBagConstraints lookupConstraints(Component comp) { |
|
539 |
GridBagConstraints constraints = comptable.get(comp); |
|
540 |
if (constraints == null) { |
|
541 |
setConstraints(comp, defaultConstraints); |
|
542 |
constraints = comptable.get(comp); |
|
543 |
} |
|
544 |
return constraints; |
|
545 |
} |
|
546 |
||
547 |
/** |
|
548 |
* Removes the constraints for the specified component in this layout |
|
549 |
* @param comp the component to be modified |
|
550 |
*/ |
|
551 |
private void removeConstraints(Component comp) { |
|
552 |
comptable.remove(comp); |
|
553 |
} |
|
554 |
||
555 |
/** |
|
556 |
* Determines the origin of the layout area, in the graphics coordinate |
|
557 |
* space of the target container. This value represents the pixel |
|
558 |
* coordinates of the top-left corner of the layout area regardless of |
|
559 |
* the <code>ComponentOrientation</code> value of the container. This |
|
560 |
* is distinct from the grid origin given by the cell coordinates (0,0). |
|
561 |
* Most applications do not call this method directly. |
|
562 |
* @return the graphics origin of the cell in the top-left |
|
563 |
* corner of the layout grid |
|
564 |
* @see java.awt.ComponentOrientation |
|
565 |
* @since JDK1.1 |
|
566 |
*/ |
|
567 |
public Point getLayoutOrigin () { |
|
568 |
Point origin = new Point(0,0); |
|
569 |
if (layoutInfo != null) { |
|
570 |
origin.x = layoutInfo.startx; |
|
571 |
origin.y = layoutInfo.starty; |
|
572 |
} |
|
573 |
return origin; |
|
574 |
} |
|
575 |
||
576 |
/** |
|
577 |
* Determines column widths and row heights for the layout grid. |
|
578 |
* <p> |
|
579 |
* Most applications do not call this method directly. |
|
580 |
* @return an array of two arrays, containing the widths |
|
581 |
* of the layout columns and |
|
582 |
* the heights of the layout rows |
|
583 |
* @since JDK1.1 |
|
584 |
*/ |
|
585 |
public int [][] getLayoutDimensions () { |
|
586 |
if (layoutInfo == null) |
|
587 |
return new int[2][0]; |
|
588 |
||
589 |
int dim[][] = new int [2][]; |
|
590 |
dim[0] = new int[layoutInfo.width]; |
|
591 |
dim[1] = new int[layoutInfo.height]; |
|
592 |
||
593 |
System.arraycopy(layoutInfo.minWidth, 0, dim[0], 0, layoutInfo.width); |
|
594 |
System.arraycopy(layoutInfo.minHeight, 0, dim[1], 0, layoutInfo.height); |
|
595 |
||
596 |
return dim; |
|
597 |
} |
|
598 |
||
599 |
/** |
|
600 |
* Determines the weights of the layout grid's columns and rows. |
|
601 |
* Weights are used to calculate how much a given column or row |
|
602 |
* stretches beyond its preferred size, if the layout has extra |
|
603 |
* room to fill. |
|
604 |
* <p> |
|
605 |
* Most applications do not call this method directly. |
|
606 |
* @return an array of two arrays, representing the |
|
607 |
* horizontal weights of the layout columns |
|
608 |
* and the vertical weights of the layout rows |
|
609 |
* @since JDK1.1 |
|
610 |
*/ |
|
611 |
public double [][] getLayoutWeights () { |
|
612 |
if (layoutInfo == null) |
|
613 |
return new double[2][0]; |
|
614 |
||
615 |
double weights[][] = new double [2][]; |
|
616 |
weights[0] = new double[layoutInfo.width]; |
|
617 |
weights[1] = new double[layoutInfo.height]; |
|
618 |
||
619 |
System.arraycopy(layoutInfo.weightX, 0, weights[0], 0, layoutInfo.width); |
|
620 |
System.arraycopy(layoutInfo.weightY, 0, weights[1], 0, layoutInfo.height); |
|
621 |
||
622 |
return weights; |
|
623 |
} |
|
624 |
||
625 |
/** |
|
626 |
* Determines which cell in the layout grid contains the point |
|
627 |
* specified by <code>(x, y)</code>. Each cell is identified |
|
628 |
* by its column index (ranging from 0 to the number of columns |
|
629 |
* minus 1) and its row index (ranging from 0 to the number of |
|
630 |
* rows minus 1). |
|
631 |
* <p> |
|
632 |
* If the <code>(x, y)</code> point lies |
|
633 |
* outside the grid, the following rules are used. |
|
634 |
* The column index is returned as zero if <code>x</code> lies to the |
|
635 |
* left of the layout for a left-to-right container or to the right of |
|
636 |
* the layout for a right-to-left container. The column index is returned |
|
637 |
* as the number of columns if <code>x</code> lies |
|
638 |
* to the right of the layout in a left-to-right container or to the left |
|
639 |
* in a right-to-left container. |
|
640 |
* The row index is returned as zero if <code>y</code> lies above the |
|
641 |
* layout, and as the number of rows if <code>y</code> lies |
|
642 |
* below the layout. The orientation of a container is determined by its |
|
643 |
* <code>ComponentOrientation</code> property. |
|
644 |
* @param x the <i>x</i> coordinate of a point |
|
645 |
* @param y the <i>y</i> coordinate of a point |
|
646 |
* @return an ordered pair of indexes that indicate which cell |
|
647 |
* in the layout grid contains the point |
|
648 |
* (<i>x</i>, <i>y</i>). |
|
649 |
* @see java.awt.ComponentOrientation |
|
650 |
* @since JDK1.1 |
|
651 |
*/ |
|
652 |
public Point location(int x, int y) { |
|
653 |
Point loc = new Point(0,0); |
|
654 |
int i, d; |
|
655 |
||
656 |
if (layoutInfo == null) |
|
657 |
return loc; |
|
658 |
||
659 |
d = layoutInfo.startx; |
|
660 |
if (!rightToLeft) { |
|
661 |
for (i=0; i<layoutInfo.width; i++) { |
|
662 |
d += layoutInfo.minWidth[i]; |
|
663 |
if (d > x) |
|
664 |
break; |
|
665 |
} |
|
666 |
} else { |
|
667 |
for (i=layoutInfo.width-1; i>=0; i--) { |
|
668 |
if (d > x) |
|
669 |
break; |
|
670 |
d += layoutInfo.minWidth[i]; |
|
671 |
} |
|
672 |
i++; |
|
673 |
} |
|
674 |
loc.x = i; |
|
675 |
||
676 |
d = layoutInfo.starty; |
|
677 |
for (i=0; i<layoutInfo.height; i++) { |
|
678 |
d += layoutInfo.minHeight[i]; |
|
679 |
if (d > y) |
|
680 |
break; |
|
681 |
} |
|
682 |
loc.y = i; |
|
683 |
||
684 |
return loc; |
|
685 |
} |
|
686 |
||
687 |
/** |
|
688 |
* Has no effect, since this layout manager does not use a per-component string. |
|
689 |
*/ |
|
690 |
public void addLayoutComponent(String name, Component comp) { |
|
691 |
} |
|
692 |
||
693 |
/** |
|
694 |
* Adds the specified component to the layout, using the specified |
|
695 |
* <code>constraints</code> object. Note that constraints |
|
696 |
* are mutable and are, therefore, cloned when cached. |
|
697 |
* |
|
698 |
* @param comp the component to be added |
|
699 |
* @param constraints an object that determines how |
|
700 |
* the component is added to the layout |
|
701 |
* @exception IllegalArgumentException if <code>constraints</code> |
|
702 |
* is not a <code>GridBagConstraint</code> |
|
703 |
*/ |
|
704 |
public void addLayoutComponent(Component comp, Object constraints) { |
|
705 |
if (constraints instanceof GridBagConstraints) { |
|
706 |
setConstraints(comp, (GridBagConstraints)constraints); |
|
707 |
} else if (constraints != null) { |
|
708 |
throw new IllegalArgumentException("cannot add to layout: constraints must be a GridBagConstraint"); |
|
709 |
} |
|
710 |
} |
|
711 |
||
712 |
/** |
|
713 |
* Removes the specified component from this layout. |
|
714 |
* <p> |
|
715 |
* Most applications do not call this method directly. |
|
716 |
* @param comp the component to be removed. |
|
717 |
* @see java.awt.Container#remove(java.awt.Component) |
|
718 |
* @see java.awt.Container#removeAll() |
|
719 |
*/ |
|
720 |
public void removeLayoutComponent(Component comp) { |
|
721 |
removeConstraints(comp); |
|
722 |
} |
|
723 |
||
724 |
/** |
|
725 |
* Determines the preferred size of the <code>parent</code> |
|
726 |
* container using this grid bag layout. |
|
727 |
* <p> |
|
728 |
* Most applications do not call this method directly. |
|
729 |
* |
|
730 |
* @param parent the container in which to do the layout |
|
731 |
* @see java.awt.Container#getPreferredSize |
|
732 |
* @return the preferred size of the <code>parent</code> |
|
733 |
* container |
|
734 |
*/ |
|
735 |
public Dimension preferredLayoutSize(Container parent) { |
|
736 |
GridBagLayoutInfo info = getLayoutInfo(parent, PREFERREDSIZE); |
|
737 |
return getMinSize(parent, info); |
|
738 |
} |
|
739 |
||
740 |
/** |
|
741 |
* Determines the minimum size of the <code>parent</code> container |
|
742 |
* using this grid bag layout. |
|
743 |
* <p> |
|
744 |
* Most applications do not call this method directly. |
|
745 |
* @param parent the container in which to do the layout |
|
746 |
* @see java.awt.Container#doLayout |
|
747 |
* @return the minimum size of the <code>parent</code> container |
|
748 |
*/ |
|
749 |
public Dimension minimumLayoutSize(Container parent) { |
|
750 |
GridBagLayoutInfo info = getLayoutInfo(parent, MINSIZE); |
|
751 |
return getMinSize(parent, info); |
|
752 |
} |
|
753 |
||
754 |
/** |
|
755 |
* Returns the maximum dimensions for this layout given the components |
|
756 |
* in the specified target container. |
|
757 |
* @param target the container which needs to be laid out |
|
758 |
* @see Container |
|
759 |
* @see #minimumLayoutSize(Container) |
|
760 |
* @see #preferredLayoutSize(Container) |
|
761 |
* @return the maximum dimensions for this layout |
|
762 |
*/ |
|
763 |
public Dimension maximumLayoutSize(Container target) { |
|
764 |
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); |
|
765 |
} |
|
766 |
||
767 |
/** |
|
768 |
* Returns the alignment along the x axis. This specifies how |
|
769 |
* the component would like to be aligned relative to other |
|
770 |
* components. The value should be a number between 0 and 1 |
|
771 |
* where 0 represents alignment along the origin, 1 is aligned |
|
772 |
* the furthest away from the origin, 0.5 is centered, etc. |
|
773 |
* <p> |
|
774 |
* @return the value <code>0.5f</code> to indicate centered |
|
775 |
*/ |
|
776 |
public float getLayoutAlignmentX(Container parent) { |
|
777 |
return 0.5f; |
|
778 |
} |
|
779 |
||
780 |
/** |
|
781 |
* Returns the alignment along the y axis. This specifies how |
|
782 |
* the component would like to be aligned relative to other |
|
783 |
* components. The value should be a number between 0 and 1 |
|
784 |
* where 0 represents alignment along the origin, 1 is aligned |
|
785 |
* the furthest away from the origin, 0.5 is centered, etc. |
|
786 |
* <p> |
|
787 |
* @return the value <code>0.5f</code> to indicate centered |
|
788 |
*/ |
|
789 |
public float getLayoutAlignmentY(Container parent) { |
|
790 |
return 0.5f; |
|
791 |
} |
|
792 |
||
793 |
/** |
|
794 |
* Invalidates the layout, indicating that if the layout manager |
|
795 |
* has cached information it should be discarded. |
|
796 |
*/ |
|
797 |
public void invalidateLayout(Container target) { |
|
798 |
} |
|
799 |
||
800 |
/** |
|
801 |
* Lays out the specified container using this grid bag layout. |
|
802 |
* This method reshapes components in the specified container in |
|
803 |
* order to satisfy the contraints of this <code>GridBagLayout</code> |
|
804 |
* object. |
|
805 |
* <p> |
|
806 |
* Most applications do not call this method directly. |
|
807 |
* @param parent the container in which to do the layout |
|
808 |
* @see java.awt.Container |
|
809 |
* @see java.awt.Container#doLayout |
|
810 |
*/ |
|
811 |
public void layoutContainer(Container parent) { |
|
812 |
arrangeGrid(parent); |
|
813 |
} |
|
814 |
||
815 |
/** |
|
816 |
* Returns a string representation of this grid bag layout's values. |
|
817 |
* @return a string representation of this grid bag layout. |
|
818 |
*/ |
|
819 |
public String toString() { |
|
820 |
return getClass().getName(); |
|
821 |
} |
|
822 |
||
823 |
/** |
|
824 |
* Print the layout information. Useful for debugging. |
|
825 |
*/ |
|
826 |
||
827 |
/* DEBUG |
|
828 |
* |
|
829 |
* protected void dumpLayoutInfo(GridBagLayoutInfo s) { |
|
830 |
* int x; |
|
831 |
* |
|
832 |
* System.out.println("Col\tWidth\tWeight"); |
|
833 |
* for (x=0; x<s.width; x++) { |
|
834 |
* System.out.println(x + "\t" + |
|
835 |
* s.minWidth[x] + "\t" + |
|
836 |
* s.weightX[x]); |
|
837 |
* } |
|
838 |
* System.out.println("Row\tHeight\tWeight"); |
|
839 |
* for (x=0; x<s.height; x++) { |
|
840 |
* System.out.println(x + "\t" + |
|
841 |
* s.minHeight[x] + "\t" + |
|
842 |
* s.weightY[x]); |
|
843 |
* } |
|
844 |
* } |
|
845 |
*/ |
|
846 |
||
847 |
/** |
|
848 |
* Print the layout constraints. Useful for debugging. |
|
849 |
*/ |
|
850 |
||
851 |
/* DEBUG |
|
852 |
* |
|
853 |
* protected void dumpConstraints(GridBagConstraints constraints) { |
|
854 |
* System.out.println( |
|
855 |
* "wt " + |
|
856 |
* constraints.weightx + |
|
857 |
* " " + |
|
858 |
* constraints.weighty + |
|
859 |
* ", " + |
|
860 |
* |
|
861 |
* "box " + |
|
862 |
* constraints.gridx + |
|
863 |
* " " + |
|
864 |
* constraints.gridy + |
|
865 |
* " " + |
|
866 |
* constraints.gridwidth + |
|
867 |
* " " + |
|
868 |
* constraints.gridheight + |
|
869 |
* ", " + |
|
870 |
* |
|
871 |
* "min " + |
|
872 |
* constraints.minWidth + |
|
873 |
* " " + |
|
874 |
* constraints.minHeight + |
|
875 |
* ", " + |
|
876 |
* |
|
877 |
* "pad " + |
|
878 |
* constraints.insets.bottom + |
|
879 |
* " " + |
|
880 |
* constraints.insets.left + |
|
881 |
* " " + |
|
882 |
* constraints.insets.right + |
|
883 |
* " " + |
|
884 |
* constraints.insets.top + |
|
885 |
* " " + |
|
886 |
* constraints.ipadx + |
|
887 |
* " " + |
|
888 |
* constraints.ipady); |
|
889 |
* } |
|
890 |
*/ |
|
891 |
||
892 |
/** |
|
893 |
* Fills in an instance of <code>GridBagLayoutInfo</code> for the |
|
894 |
* current set of managed children. This requires three passes through the |
|
895 |
* set of children: |
|
896 |
* |
|
897 |
* <ol> |
|
898 |
* <li>Figure out the dimensions of the layout grid. |
|
899 |
* <li>Determine which cells the components occupy. |
|
900 |
* <li>Distribute the weights and min sizes amoung the rows/columns. |
|
901 |
* </ol> |
|
902 |
* |
|
903 |
* This also caches the minsizes for all the children when they are |
|
904 |
* first encountered (so subsequent loops don't need to ask again). |
|
905 |
* <p> |
|
906 |
* This method should only be used internally by |
|
907 |
* <code>GridBagLayout</code>. |
|
908 |
* |
|
909 |
* @param parent the layout container |
|
910 |
* @param sizeflag either <code>PREFERREDSIZE</code> or |
|
911 |
* <code>MINSIZE</code> |
|
912 |
* @return the <code>GridBagLayoutInfo</code> for the set of children |
|
913 |
* @since 1.4 |
|
914 |
*/ |
|
915 |
protected GridBagLayoutInfo getLayoutInfo(Container parent, int sizeflag) { |
|
916 |
return GetLayoutInfo(parent, sizeflag); |
|
917 |
} |
|
918 |
||
919 |
/* |
|
920 |
* Calculate maximum array sizes to allocate arrays without ensureCapacity |
|
921 |
* we may use preCalculated sizes in whole class because of upper estimation of |
|
922 |
* maximumArrayXIndex and maximumArrayYIndex. |
|
923 |
*/ |
|
924 |
||
925 |
private long[] preInitMaximumArraySizes(Container parent){ |
|
926 |
Component components[] = parent.getComponents(); |
|
927 |
Component comp; |
|
928 |
GridBagConstraints constraints; |
|
929 |
int curX, curY; |
|
930 |
int curWidth, curHeight; |
|
931 |
int preMaximumArrayXIndex = 0; |
|
932 |
int preMaximumArrayYIndex = 0; |
|
933 |
long [] returnArray = new long[2]; |
|
934 |
||
935 |
for (int compId = 0 ; compId < components.length ; compId++) { |
|
936 |
comp = components[compId]; |
|
937 |
if (!comp.isVisible()) { |
|
938 |
continue; |
|
939 |
} |
|
940 |
||
941 |
constraints = lookupConstraints(comp); |
|
942 |
curX = constraints.gridx; |
|
943 |
curY = constraints.gridy; |
|
944 |
curWidth = constraints.gridwidth; |
|
945 |
curHeight = constraints.gridheight; |
|
946 |
||
947 |
// -1==RELATIVE, means that column|row equals to previously added component, |
|
948 |
// since each next Component with gridx|gridy == RELATIVE starts from |
|
949 |
// previous position, so we should start from previous component which |
|
950 |
// already used in maximumArray[X|Y]Index calculation. We could just increase |
|
951 |
// maximum by 1 to handle situation when component with gridx=-1 was added. |
|
952 |
if (curX < 0){ |
|
953 |
curX = ++preMaximumArrayYIndex; |
|
954 |
} |
|
955 |
if (curY < 0){ |
|
956 |
curY = ++preMaximumArrayXIndex; |
|
957 |
} |
|
958 |
// gridwidth|gridheight may be equal to RELATIVE (-1) or REMAINDER (0) |
|
959 |
// in any case using 1 instead of 0 or -1 should be sufficient to for |
|
960 |
// correct maximumArraySizes calculation |
|
961 |
if (curWidth <= 0){ |
|
962 |
curWidth = 1; |
|
963 |
} |
|
964 |
if (curHeight <= 0){ |
|
965 |
curHeight = 1; |
|
966 |
} |
|
967 |
||
968 |
preMaximumArrayXIndex = Math.max(curY + curHeight, preMaximumArrayXIndex); |
|
969 |
preMaximumArrayYIndex = Math.max(curX + curWidth, preMaximumArrayYIndex); |
|
970 |
} //for (components) loop |
|
971 |
// Must specify index++ to allocate well-working arrays. |
|
972 |
/* fix for 4623196. |
|
973 |
* now return long array instead of Point |
|
974 |
*/ |
|
975 |
returnArray[0] = preMaximumArrayXIndex; |
|
976 |
returnArray[1] = preMaximumArrayYIndex; |
|
977 |
return returnArray; |
|
978 |
} //PreInitMaximumSizes |
|
979 |
||
980 |
/** |
|
981 |
* This method is obsolete and supplied for backwards |
|
982 |
* compatability only; new code should call {@link |
|
983 |
* #getLayoutInfo(java.awt.Container, int) getLayoutInfo} instead. |
|
984 |
* This method is the same as <code>getLayoutInfo</code>; |
|
985 |
* refer to <code>getLayoutInfo</code> for details on parameters |
|
986 |
* and return value. |
|
987 |
*/ |
|
988 |
protected GridBagLayoutInfo GetLayoutInfo(Container parent, int sizeflag) { |
|
989 |
synchronized (parent.getTreeLock()) { |
|
990 |
GridBagLayoutInfo r; |
|
991 |
Component comp; |
|
992 |
GridBagConstraints constraints; |
|
993 |
Dimension d; |
|
994 |
Component components[] = parent.getComponents(); |
|
995 |
// Code below will address index curX+curWidth in the case of yMaxArray, weightY |
|
996 |
// ( respectively curY+curHeight for xMaxArray, weightX ) where |
|
997 |
// curX in 0 to preInitMaximumArraySizes.y |
|
998 |
// Thus, the maximum index that could |
|
999 |
// be calculated in the following code is curX+curX. |
|
1000 |
// EmpericMultier equals 2 because of this. |
|
1001 |
||
1002 |
int layoutWidth, layoutHeight; |
|
1003 |
int []xMaxArray; |
|
1004 |
int []yMaxArray; |
|
1005 |
int compindex, i, k, px, py, pixels_diff, nextSize; |
|
1006 |
int curX = 0; // constraints.gridx |
|
1007 |
int curY = 0; // constraints.gridy |
|
1008 |
int curWidth = 1; // constraints.gridwidth |
|
1009 |
int curHeight = 1; // constraints.gridheight |
|
1010 |
int curRow, curCol; |
|
1011 |
double weight_diff, weight; |
|
1012 |
int maximumArrayXIndex = 0; |
|
1013 |
int maximumArrayYIndex = 0; |
|
1014 |
int anchor; |
|
1015 |
||
1016 |
/* |
|
1017 |
* Pass #1 |
|
1018 |
* |
|
1019 |
* Figure out the dimensions of the layout grid (use a value of 1 for |
|
1020 |
* zero or negative widths and heights). |
|
1021 |
*/ |
|
1022 |
||
1023 |
layoutWidth = layoutHeight = 0; |
|
1024 |
curRow = curCol = -1; |
|
1025 |
long [] arraySizes = preInitMaximumArraySizes(parent); |
|
1026 |
||
1027 |
/* fix for 4623196. |
|
1028 |
* If user try to create a very big grid we can |
|
1029 |
* get NegativeArraySizeException because of integer value |
|
1030 |
* overflow (EMPIRICMULTIPLIER*gridSize might be more then Integer.MAX_VALUE). |
|
1031 |
* We need to detect this situation and try to create a |
|
1032 |
* grid with Integer.MAX_VALUE size instead. |
|
1033 |
*/ |
|
1034 |
maximumArrayXIndex = (EMPIRICMULTIPLIER * arraySizes[0] > Integer.MAX_VALUE )? Integer.MAX_VALUE : EMPIRICMULTIPLIER*(int)arraySizes[0]; |
|
1035 |
maximumArrayYIndex = (EMPIRICMULTIPLIER * arraySizes[1] > Integer.MAX_VALUE )? Integer.MAX_VALUE : EMPIRICMULTIPLIER*(int)arraySizes[1]; |
|
1036 |
||
1037 |
if (rowHeights != null){ |
|
1038 |
maximumArrayXIndex = Math.max(maximumArrayXIndex, rowHeights.length); |
|
1039 |
} |
|
1040 |
if (columnWidths != null){ |
|
1041 |
maximumArrayYIndex = Math.max(maximumArrayYIndex, columnWidths.length); |
|
1042 |
} |
|
1043 |
||
1044 |
xMaxArray = new int[maximumArrayXIndex]; |
|
1045 |
yMaxArray = new int[maximumArrayYIndex]; |
|
1046 |
||
1047 |
boolean hasBaseline = false; |
|
1048 |
for (compindex = 0 ; compindex < components.length ; compindex++) { |
|
1049 |
comp = components[compindex]; |
|
1050 |
if (!comp.isVisible()) |
|
1051 |
continue; |
|
1052 |
constraints = lookupConstraints(comp); |
|
1053 |
||
1054 |
curX = constraints.gridx; |
|
1055 |
curY = constraints.gridy; |
|
1056 |
curWidth = constraints.gridwidth; |
|
1057 |
if (curWidth <= 0) |
|
1058 |
curWidth = 1; |
|
1059 |
curHeight = constraints.gridheight; |
|
1060 |
if (curHeight <= 0) |
|
1061 |
curHeight = 1; |
|
1062 |
||
1063 |
/* If x or y is negative, then use relative positioning: */ |
|
1064 |
if (curX < 0 && curY < 0) { |
|
1065 |
if (curRow >= 0) |
|
1066 |
curY = curRow; |
|
1067 |
else if (curCol >= 0) |
|
1068 |
curX = curCol; |
|
1069 |
else |
|
1070 |
curY = 0; |
|
1071 |
} |
|
1072 |
if (curX < 0) { |
|
1073 |
px = 0; |
|
1074 |
for (i = curY; i < (curY + curHeight); i++) { |
|
1075 |
px = Math.max(px, xMaxArray[i]); |
|
1076 |
} |
|
1077 |
||
1078 |
curX = px - curX - 1; |
|
1079 |
if(curX < 0) |
|
1080 |
curX = 0; |
|
1081 |
} |
|
1082 |
else if (curY < 0) { |
|
1083 |
py = 0; |
|
1084 |
for (i = curX; i < (curX + curWidth); i++) { |
|
1085 |
py = Math.max(py, yMaxArray[i]); |
|
1086 |
} |
|
1087 |
curY = py - curY - 1; |
|
1088 |
if(curY < 0) |
|
1089 |
curY = 0; |
|
1090 |
} |
|
1091 |
||
1092 |
/* Adjust the grid width and height |
|
1093 |
* fix for 5005945: unneccessary loops removed |
|
1094 |
*/ |
|
1095 |
px = curX + curWidth; |
|
1096 |
if (layoutWidth < px) { |
|
1097 |
layoutWidth = px; |
|
1098 |
} |
|
1099 |
py = curY + curHeight; |
|
1100 |
if (layoutHeight < py) { |
|
1101 |
layoutHeight = py; |
|
1102 |
} |
|
1103 |
||
1104 |
/* Adjust xMaxArray and yMaxArray */ |
|
1105 |
for (i = curX; i < (curX + curWidth); i++) { |
|
1106 |
yMaxArray[i] =py; |
|
1107 |
} |
|
1108 |
for (i = curY; i < (curY + curHeight); i++) { |
|
1109 |
xMaxArray[i] = px; |
|
1110 |
} |
|
1111 |
||
1112 |
||
1113 |
/* Cache the current slave's size. */ |
|
1114 |
if (sizeflag == PREFERREDSIZE) |
|
1115 |
d = comp.getPreferredSize(); |
|
1116 |
else |
|
1117 |
d = comp.getMinimumSize(); |
|
1118 |
constraints.minWidth = d.width; |
|
1119 |
constraints.minHeight = d.height; |
|
1120 |
if (calculateBaseline(comp, constraints, d)) { |
|
1121 |
hasBaseline = true; |
|
1122 |
} |
|
1123 |
||
1124 |
/* Zero width and height must mean that this is the last item (or |
|
1125 |
* else something is wrong). */ |
|
1126 |
if (constraints.gridheight == 0 && constraints.gridwidth == 0) |
|
1127 |
curRow = curCol = -1; |
|
1128 |
||
1129 |
/* Zero width starts a new row */ |
|
1130 |
if (constraints.gridheight == 0 && curRow < 0) |
|
1131 |
curCol = curX + curWidth; |
|
1132 |
||
1133 |
/* Zero height starts a new column */ |
|
1134 |
else if (constraints.gridwidth == 0 && curCol < 0) |
|
1135 |
curRow = curY + curHeight; |
|
1136 |
} //for (components) loop |
|
1137 |
||
1138 |
||
1139 |
/* |
|
1140 |
* Apply minimum row/column dimensions |
|
1141 |
*/ |
|
1142 |
if (columnWidths != null && layoutWidth < columnWidths.length) |
|
1143 |
layoutWidth = columnWidths.length; |
|
1144 |
if (rowHeights != null && layoutHeight < rowHeights.length) |
|
1145 |
layoutHeight = rowHeights.length; |
|
1146 |
||
1147 |
r = new GridBagLayoutInfo(layoutWidth, layoutHeight); |
|
1148 |
||
1149 |
/* |
|
1150 |
* Pass #2 |
|
1151 |
* |
|
1152 |
* Negative values for gridX are filled in with the current x value. |
|
1153 |
* Negative values for gridY are filled in with the current y value. |
|
1154 |
* Negative or zero values for gridWidth and gridHeight end the current |
|
1155 |
* row or column, respectively. |
|
1156 |
*/ |
|
1157 |
||
1158 |
curRow = curCol = -1; |
|
1159 |
||
1160 |
Arrays.fill(xMaxArray, 0); |
|
1161 |
Arrays.fill(yMaxArray, 0); |
|
1162 |
||
1163 |
int[] maxAscent = null; |
|
1164 |
int[] maxDescent = null; |
|
1165 |
short[] baselineType = null; |
|
1166 |
||
1167 |
if (hasBaseline) { |
|
1168 |
r.maxAscent = maxAscent = new int[layoutHeight]; |
|
1169 |
r.maxDescent = maxDescent = new int[layoutHeight]; |
|
1170 |
r.baselineType = baselineType = new short[layoutHeight]; |
|
1171 |
r.hasBaseline = true; |
|
1172 |
} |
|
1173 |
||
1174 |
||
1175 |
for (compindex = 0 ; compindex < components.length ; compindex++) { |
|
1176 |
comp = components[compindex]; |
|
1177 |
if (!comp.isVisible()) |
|
1178 |
continue; |
|
1179 |
constraints = lookupConstraints(comp); |
|
1180 |
||
1181 |
curX = constraints.gridx; |
|
1182 |
curY = constraints.gridy; |
|
1183 |
curWidth = constraints.gridwidth; |
|
1184 |
curHeight = constraints.gridheight; |
|
1185 |
||
1186 |
/* If x or y is negative, then use relative positioning: */ |
|
1187 |
if (curX < 0 && curY < 0) { |
|
1188 |
if(curRow >= 0) |
|
1189 |
curY = curRow; |
|
1190 |
else if(curCol >= 0) |
|
1191 |
curX = curCol; |
|
1192 |
else |
|
1193 |
curY = 0; |
|
1194 |
} |
|
1195 |
||
1196 |
if (curX < 0) { |
|
1197 |
if (curHeight <= 0) { |
|
1198 |
curHeight += r.height - curY; |
|
1199 |
if (curHeight < 1) |
|
1200 |
curHeight = 1; |
|
1201 |
} |
|
1202 |
||
1203 |
px = 0; |
|
1204 |
for (i = curY; i < (curY + curHeight); i++) |
|
1205 |
px = Math.max(px, xMaxArray[i]); |
|
1206 |
||
1207 |
curX = px - curX - 1; |
|
1208 |
if(curX < 0) |
|
1209 |
curX = 0; |
|
1210 |
} |
|
1211 |
else if (curY < 0) { |
|
1212 |
if (curWidth <= 0) { |
|
1213 |
curWidth += r.width - curX; |
|
1214 |
if (curWidth < 1) |
|
1215 |
curWidth = 1; |
|
1216 |
} |
|
1217 |
||
1218 |
py = 0; |
|
1219 |
for (i = curX; i < (curX + curWidth); i++){ |
|
1220 |
py = Math.max(py, yMaxArray[i]); |
|
1221 |
} |
|
1222 |
||
1223 |
curY = py - curY - 1; |
|
1224 |
if(curY < 0) |
|
1225 |
curY = 0; |
|
1226 |
} |
|
1227 |
||
1228 |
if (curWidth <= 0) { |
|
1229 |
curWidth += r.width - curX; |
|
1230 |
if (curWidth < 1) |
|
1231 |
curWidth = 1; |
|
1232 |
} |
|
1233 |
||
1234 |
if (curHeight <= 0) { |
|
1235 |
curHeight += r.height - curY; |
|
1236 |
if (curHeight < 1) |
|
1237 |
curHeight = 1; |
|
1238 |
} |
|
1239 |
||
1240 |
px = curX + curWidth; |
|
1241 |
py = curY + curHeight; |
|
1242 |
||
1243 |
for (i = curX; i < (curX + curWidth); i++) { yMaxArray[i] = py; } |
|
1244 |
for (i = curY; i < (curY + curHeight); i++) { xMaxArray[i] = px; } |
|
1245 |
||
1246 |
/* Make negative sizes start a new row/column */ |
|
1247 |
if (constraints.gridheight == 0 && constraints.gridwidth == 0) |
|
1248 |
curRow = curCol = -1; |
|
1249 |
if (constraints.gridheight == 0 && curRow < 0) |
|
1250 |
curCol = curX + curWidth; |
|
1251 |
else if (constraints.gridwidth == 0 && curCol < 0) |
|
1252 |
curRow = curY + curHeight; |
|
1253 |
||
1254 |
/* Assign the new values to the gridbag slave */ |
|
1255 |
constraints.tempX = curX; |
|
1256 |
constraints.tempY = curY; |
|
1257 |
constraints.tempWidth = curWidth; |
|
1258 |
constraints.tempHeight = curHeight; |
|
1259 |
||
1260 |
anchor = constraints.anchor; |
|
1261 |
if (hasBaseline) { |
|
1262 |
switch(anchor) { |
|
1263 |
case GridBagConstraints.BASELINE: |
|
1264 |
case GridBagConstraints.BASELINE_LEADING: |
|
1265 |
case GridBagConstraints.BASELINE_TRAILING: |
|
1266 |
if (constraints.ascent >= 0) { |
|
1267 |
if (curHeight == 1) { |
|
1268 |
maxAscent[curY] = |
|
1269 |
Math.max(maxAscent[curY], |
|
1270 |
constraints.ascent); |
|
1271 |
maxDescent[curY] = |
|
1272 |
Math.max(maxDescent[curY], |
|
1273 |
constraints.descent); |
|
1274 |
} |
|
1275 |
else { |
|
1276 |
if (constraints.baselineResizeBehavior == |
|
1277 |
Component.BaselineResizeBehavior. |
|
1278 |
CONSTANT_DESCENT) { |
|
1279 |
maxDescent[curY + curHeight - 1] = |
|
1280 |
Math.max(maxDescent[curY + curHeight |
|
1281 |
- 1], |
|
1282 |
constraints.descent); |
|
1283 |
} |
|
1284 |
else { |
|
1285 |
maxAscent[curY] = Math.max(maxAscent[curY], |
|
1286 |
constraints.ascent); |
|
1287 |
} |
|
1288 |
} |
|
1289 |
if (constraints.baselineResizeBehavior == |
|
1290 |
Component.BaselineResizeBehavior.CONSTANT_DESCENT) { |
|
1291 |
baselineType[curY + curHeight - 1] |= |
|
1292 |
(1 << constraints. |
|
1293 |
baselineResizeBehavior.ordinal()); |
|
1294 |
} |
|
1295 |
else { |
|
1296 |
baselineType[curY] |= (1 << constraints. |
|
1297 |
baselineResizeBehavior.ordinal()); |
|
1298 |
} |
|
1299 |
} |
|
1300 |
break; |
|
1301 |
case GridBagConstraints.ABOVE_BASELINE: |
|
1302 |
case GridBagConstraints.ABOVE_BASELINE_LEADING: |
|
1303 |
case GridBagConstraints.ABOVE_BASELINE_TRAILING: |
|
1304 |
// Component positioned above the baseline. |
|
1305 |
// To make the bottom edge of the component aligned |
|
1306 |
// with the baseline the bottom inset is |
|
1307 |
// added to the descent, the rest to the ascent. |
|
1308 |
pixels_diff = constraints.minHeight + |
|
1309 |
constraints.insets.top + |
|
1310 |
constraints.ipady; |
|
1311 |
maxAscent[curY] = Math.max(maxAscent[curY], |
|
1312 |
pixels_diff); |
|
1313 |
maxDescent[curY] = Math.max(maxDescent[curY], |
|
1314 |
constraints.insets.bottom); |
|
1315 |
break; |
|
1316 |
case GridBagConstraints.BELOW_BASELINE: |
|
1317 |
case GridBagConstraints.BELOW_BASELINE_LEADING: |
|
1318 |
case GridBagConstraints.BELOW_BASELINE_TRAILING: |
|
1319 |
// Component positioned below the baseline. |
|
1320 |
// To make the top edge of the component aligned |
|
1321 |
// with the baseline the top inset is |
|
1322 |
// added to the ascent, the rest to the descent. |
|
1323 |
pixels_diff = constraints.minHeight + |
|
1324 |
constraints.insets.bottom + constraints.ipady; |
|
1325 |
maxDescent[curY] = Math.max(maxDescent[curY], |
|
1326 |
pixels_diff); |
|
1327 |
maxAscent[curY] = Math.max(maxAscent[curY], |
|
1328 |
constraints.insets.top); |
|
1329 |
break; |
|
1330 |
} |
|
1331 |
} |
|
1332 |
} |
|
1333 |
||
1334 |
r.weightX = new double[maximumArrayYIndex]; |
|
1335 |
r.weightY = new double[maximumArrayXIndex]; |
|
1336 |
r.minWidth = new int[maximumArrayYIndex]; |
|
1337 |
r.minHeight = new int[maximumArrayXIndex]; |
|
1338 |
||
1339 |
||
1340 |
/* |
|
1341 |
* Apply minimum row/column dimensions and weights |
|
1342 |
*/ |
|
1343 |
if (columnWidths != null) |
|
1344 |
System.arraycopy(columnWidths, 0, r.minWidth, 0, columnWidths.length); |
|
1345 |
if (rowHeights != null) |
|
1346 |
System.arraycopy(rowHeights, 0, r.minHeight, 0, rowHeights.length); |
|
1347 |
if (columnWeights != null) |
|
1348 |
System.arraycopy(columnWeights, 0, r.weightX, 0, Math.min(r.weightX.length, columnWeights.length)); |
|
1349 |
if (rowWeights != null) |
|
1350 |
System.arraycopy(rowWeights, 0, r.weightY, 0, Math.min(r.weightY.length, rowWeights.length)); |
|
1351 |
||
1352 |
/* |
|
1353 |
* Pass #3 |
|
1354 |
* |
|
1355 |
* Distribute the minimun widths and weights: |
|
1356 |
*/ |
|
1357 |
||
1358 |
nextSize = Integer.MAX_VALUE; |
|
1359 |
||
1360 |
for (i = 1; |
|
1361 |
i != Integer.MAX_VALUE; |
|
1362 |
i = nextSize, nextSize = Integer.MAX_VALUE) { |
|
1363 |
for (compindex = 0 ; compindex < components.length ; compindex++) { |
|
1364 |
comp = components[compindex]; |
|
1365 |
if (!comp.isVisible()) |
|
1366 |
continue; |
|
1367 |
constraints = lookupConstraints(comp); |
|
1368 |
||
1369 |
if (constraints.tempWidth == i) { |
|
1370 |
px = constraints.tempX + constraints.tempWidth; /* right column */ |
|
1371 |
||
1372 |
/* |
|
1373 |
* Figure out if we should use this slave\'s weight. If the weight |
|
1374 |
* is less than the total weight spanned by the width of the cell, |
|
1375 |
* then discard the weight. Otherwise split the difference |
|
1376 |
* according to the existing weights. |
|
1377 |
*/ |
|
1378 |
||
1379 |
weight_diff = constraints.weightx; |
|
1380 |
for (k = constraints.tempX; k < px; k++) |
|
1381 |
weight_diff -= r.weightX[k]; |
|
1382 |
if (weight_diff > 0.0) { |
|
1383 |
weight = 0.0; |
|
1384 |
for (k = constraints.tempX; k < px; k++) |
|
1385 |
weight += r.weightX[k]; |
|
1386 |
for (k = constraints.tempX; weight > 0.0 && k < px; k++) { |
|
1387 |
double wt = r.weightX[k]; |
|
1388 |
double dx = (wt * weight_diff) / weight; |
|
1389 |
r.weightX[k] += dx; |
|
1390 |
weight_diff -= dx; |
|
1391 |
weight -= wt; |
|
1392 |
} |
|
1393 |
/* Assign the remainder to the rightmost cell */ |
|
1394 |
r.weightX[px-1] += weight_diff; |
|
1395 |
} |
|
1396 |
||
1397 |
/* |
|
1398 |
* Calculate the minWidth array values. |
|
1399 |
* First, figure out how wide the current slave needs to be. |
|
1400 |
* Then, see if it will fit within the current minWidth values. |
|
1401 |
* If it will not fit, add the difference according to the |
|
1402 |
* weightX array. |
|
1403 |
*/ |
|
1404 |
||
1405 |
pixels_diff = |
|
1406 |
constraints.minWidth + constraints.ipadx + |
|
1407 |
constraints.insets.left + constraints.insets.right; |
|
1408 |
||
1409 |
for (k = constraints.tempX; k < px; k++) |
|
1410 |
pixels_diff -= r.minWidth[k]; |
|
1411 |
if (pixels_diff > 0) { |
|
1412 |
weight = 0.0; |
|
1413 |
for (k = constraints.tempX; k < px; k++) |
|
1414 |
weight += r.weightX[k]; |
|
1415 |
for (k = constraints.tempX; weight > 0.0 && k < px; k++) { |
|
1416 |
double wt = r.weightX[k]; |
|
1417 |
int dx = (int)((wt * ((double)pixels_diff)) / weight); |
|
1418 |
r.minWidth[k] += dx; |
|
1419 |
pixels_diff -= dx; |
|
1420 |
weight -= wt; |
|
1421 |
} |
|
1422 |
/* Any leftovers go into the rightmost cell */ |
|
1423 |
r.minWidth[px-1] += pixels_diff; |
|
1424 |
} |
|
1425 |
} |
|
1426 |
else if (constraints.tempWidth > i && constraints.tempWidth < nextSize) |
|
1427 |
nextSize = constraints.tempWidth; |
|
1428 |
||
1429 |
||
1430 |
if (constraints.tempHeight == i) { |
|
1431 |
py = constraints.tempY + constraints.tempHeight; /* bottom row */ |
|
1432 |
||
1433 |
/* |
|
1434 |
* Figure out if we should use this slave's weight. If the weight |
|
1435 |
* is less than the total weight spanned by the height of the cell, |
|
1436 |
* then discard the weight. Otherwise split it the difference |
|
1437 |
* according to the existing weights. |
|
1438 |
*/ |
|
1439 |
||
1440 |
weight_diff = constraints.weighty; |
|
1441 |
for (k = constraints.tempY; k < py; k++) |
|
1442 |
weight_diff -= r.weightY[k]; |
|
1443 |
if (weight_diff > 0.0) { |
|
1444 |
weight = 0.0; |
|
1445 |
for (k = constraints.tempY; k < py; k++) |
|
1446 |
weight += r.weightY[k]; |
|
1447 |
for (k = constraints.tempY; weight > 0.0 && k < py; k++) { |
|
1448 |
double wt = r.weightY[k]; |
|
1449 |
double dy = (wt * weight_diff) / weight; |
|
1450 |
r.weightY[k] += dy; |
|
1451 |
weight_diff -= dy; |
|
1452 |
weight -= wt; |
|
1453 |
} |
|
1454 |
/* Assign the remainder to the bottom cell */ |
|
1455 |
r.weightY[py-1] += weight_diff; |
|
1456 |
} |
|
1457 |
||
1458 |
/* |
|
1459 |
* Calculate the minHeight array values. |
|
1460 |
* First, figure out how tall the current slave needs to be. |
|
1461 |
* Then, see if it will fit within the current minHeight values. |
|
1462 |
* If it will not fit, add the difference according to the |
|
1463 |
* weightY array. |
|
1464 |
*/ |
|
1465 |
||
1466 |
pixels_diff = -1; |
|
1467 |
if (hasBaseline) { |
|
1468 |
switch(constraints.anchor) { |
|
1469 |
case GridBagConstraints.BASELINE: |
|
1470 |
case GridBagConstraints.BASELINE_LEADING: |
|
1471 |
case GridBagConstraints.BASELINE_TRAILING: |
|
1472 |
if (constraints.ascent >= 0) { |
|
1473 |
if (constraints.tempHeight == 1) { |
|
1474 |
pixels_diff = |
|
1475 |
maxAscent[constraints.tempY] + |
|
1476 |
maxDescent[constraints.tempY]; |
|
1477 |
} |
|
1478 |
else if (constraints.baselineResizeBehavior != |
|
1479 |
Component.BaselineResizeBehavior. |
|
1480 |
CONSTANT_DESCENT) { |
|
1481 |
pixels_diff = |
|
1482 |
maxAscent[constraints.tempY] + |
|
1483 |
constraints.descent; |
|
1484 |
} |
|
1485 |
else { |
|
1486 |
pixels_diff = constraints.ascent + |
|
1487 |
maxDescent[constraints.tempY + |
|
1488 |
constraints.tempHeight - 1]; |
|
1489 |
} |
|
1490 |
} |
|
1491 |
break; |
|
1492 |
case GridBagConstraints.ABOVE_BASELINE: |
|
1493 |
case GridBagConstraints.ABOVE_BASELINE_LEADING: |
|
1494 |
case GridBagConstraints.ABOVE_BASELINE_TRAILING: |
|
1495 |
pixels_diff = constraints.insets.top + |
|
1496 |
constraints.minHeight + |
|
1497 |
constraints.ipady + |
|
1498 |
maxDescent[constraints.tempY]; |
|
1499 |
break; |
|
1500 |
case GridBagConstraints.BELOW_BASELINE: |
|
1501 |
case GridBagConstraints.BELOW_BASELINE_LEADING: |
|
1502 |
case GridBagConstraints.BELOW_BASELINE_TRAILING: |
|
1503 |
pixels_diff = maxAscent[constraints.tempY] + |
|
1504 |
constraints.minHeight + |
|
1505 |
constraints.insets.bottom + |
|
1506 |
constraints.ipady; |
|
1507 |
break; |
|
1508 |
} |
|
1509 |
} |
|
1510 |
if (pixels_diff == -1) { |
|
1511 |
pixels_diff = |
|
1512 |
constraints.minHeight + constraints.ipady + |
|
1513 |
constraints.insets.top + |
|
1514 |
constraints.insets.bottom; |
|
1515 |
} |
|
1516 |
for (k = constraints.tempY; k < py; k++) |
|
1517 |
pixels_diff -= r.minHeight[k]; |
|
1518 |
if (pixels_diff > 0) { |
|
1519 |
weight = 0.0; |
|
1520 |
for (k = constraints.tempY; k < py; k++) |
|
1521 |
weight += r.weightY[k]; |
|
1522 |
for (k = constraints.tempY; weight > 0.0 && k < py; k++) { |
|
1523 |
double wt = r.weightY[k]; |
|
1524 |
int dy = (int)((wt * ((double)pixels_diff)) / weight); |
|
1525 |
r.minHeight[k] += dy; |
|
1526 |
pixels_diff -= dy; |
|
1527 |
weight -= wt; |
|
1528 |
} |
|
1529 |
/* Any leftovers go into the bottom cell */ |
|
1530 |
r.minHeight[py-1] += pixels_diff; |
|
1531 |
} |
|
1532 |
} |
|
1533 |
else if (constraints.tempHeight > i && |
|
1534 |
constraints.tempHeight < nextSize) |
|
1535 |
nextSize = constraints.tempHeight; |
|
1536 |
} |
|
1537 |
} |
|
1538 |
return r; |
|
1539 |
} |
|
1540 |
} //getLayoutInfo() |
|
1541 |
||
1542 |
/** |
|
1543 |
* Calculate the baseline for the specified component. |
|
1544 |
* If {@code c} is positioned along it's baseline, the baseline is |
|
1545 |
* obtained and the {@code constraints} ascent, descent and |
|
1546 |
* baseline resize behavior are set from the component; and true is |
|
1547 |
* returned. Otherwise false is returned. |
|
1548 |
*/ |
|
1549 |
private boolean calculateBaseline(Component c, |
|
1550 |
GridBagConstraints constraints, |
|
1551 |
Dimension size) { |
|
1552 |
int anchor = constraints.anchor; |
|
1553 |
if (anchor == GridBagConstraints.BASELINE || |
|
1554 |
anchor == GridBagConstraints.BASELINE_LEADING || |
|
1555 |
anchor == GridBagConstraints.BASELINE_TRAILING) { |
|
1556 |
// Apply the padding to the component, then ask for the baseline. |
|
1557 |
int w = size.width + constraints.ipadx; |
|
1558 |
int h = size.height + constraints.ipady; |
|
1559 |
constraints.ascent = c.getBaseline(w, h); |
|
1560 |
if (constraints.ascent >= 0) { |
|
1561 |
// Component has a baseline |
|
1562 |
int baseline = constraints.ascent; |
|
1563 |
// Adjust the ascent and descent to include the insets. |
|
1564 |
constraints.descent = h - constraints.ascent + |
|
1565 |
constraints.insets.bottom; |
|
1566 |
constraints.ascent += constraints.insets.top; |
|
1567 |
constraints.baselineResizeBehavior = |
|
1568 |
c.getBaselineResizeBehavior(); |
|
1569 |
constraints.centerPadding = 0; |
|
1570 |
if (constraints.baselineResizeBehavior == Component. |
|
1571 |
BaselineResizeBehavior.CENTER_OFFSET) { |
|
1572 |
// Component has a baseline resize behavior of |
|
1573 |
// CENTER_OFFSET, calculate centerPadding and |
|
1574 |
// centerOffset (see the description of |
|
1575 |
// CENTER_OFFSET in the enum for detais on this |
|
1576 |
// algorithm). |
|
1577 |
int nextBaseline = c.getBaseline(w, h + 1); |
|
1578 |
constraints.centerOffset = baseline - h / 2; |
|
1579 |
if (h % 2 == 0) { |
|
1580 |
if (baseline != nextBaseline) { |
|
1581 |
constraints.centerPadding = 1; |
|
1582 |
} |
|
1583 |
} |
|
1584 |
else if (baseline == nextBaseline){ |
|
1585 |
constraints.centerOffset--; |
|
1586 |
constraints.centerPadding = 1; |
|
1587 |
} |
|
1588 |
} |
|
1589 |
} |
|
1590 |
return true; |
|
1591 |
} |
|
1592 |
else { |
|
1593 |
constraints.ascent = -1; |
|
1594 |
return false; |
|
1595 |
} |
|
1596 |
} |
|
1597 |
||
1598 |
/** |
|
1599 |
* Adjusts the x, y, width, and height fields to the correct |
|
1600 |
* values depending on the constraint geometry and pads. |
|
1601 |
* This method should only be used internally by |
|
1602 |
* <code>GridBagLayout</code>. |
|
1603 |
* |
|
1604 |
* @param constraints the constraints to be applied |
|
1605 |
* @param r the <code>Rectangle</code> to be adjusted |
|
1606 |
* @since 1.4 |
|
1607 |
*/ |
|
1608 |
protected void adjustForGravity(GridBagConstraints constraints, |
|
1609 |
Rectangle r) { |
|
1610 |
AdjustForGravity(constraints, r); |
|
1611 |
} |
|
1612 |
||
1613 |
/** |
|
1614 |
* This method is obsolete and supplied for backwards |
|
1615 |
* compatability only; new code should call {@link |
|
1616 |
* #adjustForGravity(java.awt.GridBagConstraints, java.awt.Rectangle) |
|
1617 |
* adjustForGravity} instead. |
|
1618 |
* This method is the same as <code>adjustForGravity</code>; |
|
1619 |
* refer to <code>adjustForGravity</code> for details |
|
1620 |
* on parameters. |
|
1621 |
*/ |
|
1622 |
protected void AdjustForGravity(GridBagConstraints constraints, |
|
1623 |
Rectangle r) { |
|
1624 |
int diffx, diffy; |
|
1625 |
int cellY = r.y; |
|
1626 |
int cellHeight = r.height; |
|
1627 |
||
1628 |
if (!rightToLeft) { |
|
1629 |
r.x += constraints.insets.left; |
|
1630 |
} else { |
|
1631 |
r.x -= r.width - constraints.insets.right; |
|
1632 |
} |
|
1633 |
r.width -= (constraints.insets.left + constraints.insets.right); |
|
1634 |
r.y += constraints.insets.top; |
|
1635 |
r.height -= (constraints.insets.top + constraints.insets.bottom); |
|
1636 |
||
1637 |
diffx = 0; |
|
1638 |
if ((constraints.fill != GridBagConstraints.HORIZONTAL && |
|
1639 |
constraints.fill != GridBagConstraints.BOTH) |
|
1640 |
&& (r.width > (constraints.minWidth + constraints.ipadx))) { |
|
1641 |
diffx = r.width - (constraints.minWidth + constraints.ipadx); |
|
1642 |
r.width = constraints.minWidth + constraints.ipadx; |
|
1643 |
} |
|
1644 |
||
1645 |
diffy = 0; |
|
1646 |
if ((constraints.fill != GridBagConstraints.VERTICAL && |
|
1647 |
constraints.fill != GridBagConstraints.BOTH) |
|
1648 |
&& (r.height > (constraints.minHeight + constraints.ipady))) { |
|
1649 |
diffy = r.height - (constraints.minHeight + constraints.ipady); |
|
1650 |
r.height = constraints.minHeight + constraints.ipady; |
|
1651 |
} |
|
1652 |
||
1653 |
switch (constraints.anchor) { |
|
1654 |
case GridBagConstraints.BASELINE: |
|
1655 |
r.x += diffx/2; |
|
1656 |
alignOnBaseline(constraints, r, cellY, cellHeight); |
|
1657 |
break; |
|
1658 |
case GridBagConstraints.BASELINE_LEADING: |
|
1659 |
if (rightToLeft) { |
|
1660 |
r.x += diffx; |
|
1661 |
} |
|
1662 |
alignOnBaseline(constraints, r, cellY, cellHeight); |
|
1663 |
break; |
|
1664 |
case GridBagConstraints.BASELINE_TRAILING: |
|
1665 |
if (!rightToLeft) { |
|
1666 |
r.x += diffx; |
|
1667 |
} |
|
1668 |
alignOnBaseline(constraints, r, cellY, cellHeight); |
|
1669 |
break; |
|
1670 |
case GridBagConstraints.ABOVE_BASELINE: |
|
1671 |
r.x += diffx/2; |
|
1672 |
alignAboveBaseline(constraints, r, cellY, cellHeight); |
|
1673 |
break; |
|
1674 |
case GridBagConstraints.ABOVE_BASELINE_LEADING: |
|
1675 |
if (rightToLeft) { |
|
1676 |
r.x += diffx; |
|
1677 |
} |
|
1678 |
alignAboveBaseline(constraints, r, cellY, cellHeight); |
|
1679 |
break; |
|
1680 |
case GridBagConstraints.ABOVE_BASELINE_TRAILING: |
|
1681 |
if (!rightToLeft) { |
|
1682 |
r.x += diffx; |
|
1683 |
} |
|
1684 |
alignAboveBaseline(constraints, r, cellY, cellHeight); |
|
1685 |
break; |
|
1686 |
case GridBagConstraints.BELOW_BASELINE: |
|
1687 |
r.x += diffx/2; |
|
1688 |
alignBelowBaseline(constraints, r, cellY, cellHeight); |
|
1689 |
break; |
|
1690 |
case GridBagConstraints.BELOW_BASELINE_LEADING: |
|
1691 |
if (rightToLeft) { |
|
1692 |
r.x += diffx; |
|
1693 |
} |
|
1694 |
alignBelowBaseline(constraints, r, cellY, cellHeight); |
|
1695 |
break; |
|
1696 |
case GridBagConstraints.BELOW_BASELINE_TRAILING: |
|
1697 |
if (!rightToLeft) { |
|
1698 |
r.x += diffx; |
|
1699 |
} |
|
1700 |
alignBelowBaseline(constraints, r, cellY, cellHeight); |
|
1701 |
break; |
|
1702 |
case GridBagConstraints.CENTER: |
|
1703 |
r.x += diffx/2; |
|
1704 |
r.y += diffy/2; |
|
1705 |
break; |
|
1706 |
case GridBagConstraints.PAGE_START: |
|
1707 |
case GridBagConstraints.NORTH: |
|
1708 |
r.x += diffx/2; |
|
1709 |
break; |
|
1710 |
case GridBagConstraints.NORTHEAST: |
|
1711 |
r.x += diffx; |
|
1712 |
break; |
|
1713 |
case GridBagConstraints.EAST: |
|
1714 |
r.x += diffx; |
|
1715 |
r.y += diffy/2; |
|
1716 |
break; |
|
1717 |
case GridBagConstraints.SOUTHEAST: |
|
1718 |
r.x += diffx; |
|
1719 |
r.y += diffy; |
|
1720 |
break; |
|
1721 |
case GridBagConstraints.PAGE_END: |
|
1722 |
case GridBagConstraints.SOUTH: |
|
1723 |
r.x += diffx/2; |
|
1724 |
r.y += diffy; |
|
1725 |
break; |
|
1726 |
case GridBagConstraints.SOUTHWEST: |
|
1727 |
r.y += diffy; |
|
1728 |
break; |
|
1729 |
case GridBagConstraints.WEST: |
|
1730 |
r.y += diffy/2; |
|
1731 |
break; |
|
1732 |
case GridBagConstraints.NORTHWEST: |
|
1733 |
break; |
|
1734 |
case GridBagConstraints.LINE_START: |
|
1735 |
if (rightToLeft) { |
|
1736 |
r.x += diffx; |
|
1737 |
} |
|
1738 |
r.y += diffy/2; |
|
1739 |
break; |
|
1740 |
case GridBagConstraints.LINE_END: |
|
1741 |
if (!rightToLeft) { |
|
1742 |
r.x += diffx; |
|
1743 |
} |
|
1744 |
r.y += diffy/2; |
|
1745 |
break; |
|
1746 |
case GridBagConstraints.FIRST_LINE_START: |
|
1747 |
if (rightToLeft) { |
|
1748 |
r.x += diffx; |
|
1749 |
} |
|
1750 |
break; |
|
1751 |
case GridBagConstraints.FIRST_LINE_END: |
|
1752 |
if (!rightToLeft) { |
|
1753 |
r.x += diffx; |
|
1754 |
} |
|
1755 |
break; |
|
1756 |
case GridBagConstraints.LAST_LINE_START: |
|
1757 |
if (rightToLeft) { |
|
1758 |
r.x += diffx; |
|
1759 |
} |
|
1760 |
r.y += diffy; |
|
1761 |
break; |
|
1762 |
case GridBagConstraints.LAST_LINE_END: |
|
1763 |
if (!rightToLeft) { |
|
1764 |
r.x += diffx; |
|
1765 |
} |
|
1766 |
r.y += diffy; |
|
1767 |
break; |
|
1768 |
default: |
|
1769 |
throw new IllegalArgumentException("illegal anchor value"); |
|
1770 |
} |
|
1771 |
} |
|
1772 |
||
1773 |
/** |
|
1774 |
* Positions on the baseline. |
|
1775 |
* |
|
1776 |
* @param cellY the location of the row, does not include insets |
|
1777 |
* @param cellHeight the height of the row, does not take into account |
|
1778 |
* insets |
|
1779 |
* @param r available bounds for the component, is padded by insets and |
|
1780 |
* ipady |
|
1781 |
*/ |
|
1782 |
private void alignOnBaseline(GridBagConstraints cons, Rectangle r, |
|
1783 |
int cellY, int cellHeight) { |
|
1784 |
if (cons.ascent >= 0) { |
|
1785 |
if (cons.baselineResizeBehavior == Component. |
|
1786 |
BaselineResizeBehavior.CONSTANT_DESCENT) { |
|
1787 |
// Anchor to the bottom. |
|
1788 |
// Baseline is at (cellY + cellHeight - maxDescent). |
|
1789 |
// Bottom of component (maxY) is at baseline + descent |
|
1790 |
// of component. We need to subtract the bottom inset here |
|
1791 |
// as the descent in the constraints object includes the |
|
1792 |
// bottom inset. |
|
1793 |
int maxY = cellY + cellHeight - |
|
1794 |
layoutInfo.maxDescent[cons.tempY + cons.tempHeight - 1] + |
|
1795 |
cons.descent - cons.insets.bottom; |
|
1796 |
if (!cons.isVerticallyResizable()) { |
|
1797 |
// Component not resizable, calculate y location |
|
1798 |
// from maxY - height. |
|
1799 |
r.y = maxY - cons.minHeight; |
|
1800 |
r.height = cons.minHeight; |
|
1801 |
} else { |
|
1802 |
// Component is resizable. As brb is constant descent, |
|
1803 |
// can expand component to fill region above baseline. |
|
1804 |
// Subtract out the top inset so that components insets |
|
1805 |
// are honored. |
|
1806 |
r.height = maxY - cellY - cons.insets.top; |
|
1807 |
} |
|
1808 |
} |
|
1809 |
else { |
|
1810 |
// BRB is not constant_descent |
|
1811 |
int baseline; // baseline for the row, relative to cellY |
|
1812 |
// Component baseline, includes insets.top |
|
1813 |
int ascent = cons.ascent; |
|
1814 |
if (layoutInfo.hasConstantDescent(cons.tempY)) { |
|
1815 |
// Mixed ascent/descent in same row, calculate position |
|
1816 |
// off maxDescent |
|
1817 |
baseline = cellHeight - layoutInfo.maxDescent[cons.tempY]; |
|
1818 |
} |
|
1819 |
else { |
|
1820 |
// Only ascents/unknown in this row, anchor to top |
|
1821 |
baseline = layoutInfo.maxAscent[cons.tempY]; |
|
1822 |
} |
|
1823 |
if (cons.baselineResizeBehavior == Component. |
|
1824 |
BaselineResizeBehavior.OTHER) { |
|
1825 |
// BRB is other, which means we can only determine |
|
1826 |
// the baseline by asking for it again giving the |
|
1827 |
// size we plan on using for the component. |
|
1828 |
boolean fits = false; |
|
1829 |
ascent = componentAdjusting.getBaseline(r.width, r.height); |
|
1830 |
if (ascent >= 0) { |
|
1831 |
// Component has a baseline, pad with top inset |
|
1832 |
// (this follows from calculateBaseline which |
|
1833 |
// does the same). |
|
1834 |
ascent += cons.insets.top; |
|
1835 |
} |
|
1836 |
if (ascent >= 0 && ascent <= baseline) { |
|
1837 |
// Components baseline fits within rows baseline. |
|
1838 |
// Make sure the descent fits within the space as well. |
|
1839 |
if (baseline + (r.height - ascent - cons.insets.top) <= |
|
1840 |
cellHeight - cons.insets.bottom) { |
|
1841 |
// It fits, we're good. |
|
1842 |
fits = true; |
|
1843 |
} |
|
1844 |
else if (cons.isVerticallyResizable()) { |
|
1845 |
// Doesn't fit, but it's resizable. Try |
|
1846 |
// again assuming we'll get ascent again. |
|
1847 |
int ascent2 = componentAdjusting.getBaseline( |
|
1848 |
r.width, cellHeight - cons.insets.bottom - |
|
1849 |
baseline + ascent); |
|
1850 |
if (ascent2 >= 0) { |
|
1851 |
ascent2 += cons.insets.top; |
|
1852 |
} |
|
1853 |
if (ascent2 >= 0 && ascent2 <= ascent) { |
|
1854 |
// It'll fit |
|
1855 |
r.height = cellHeight - cons.insets.bottom - |
|
1856 |
baseline + ascent; |
|
1857 |
ascent = ascent2; |
|
1858 |
fits = true; |
|
1859 |
} |
|
1860 |
} |
|
1861 |
} |
|
1862 |
if (!fits) { |
|
1863 |
// Doesn't fit, use min size and original ascent |
|
1864 |
ascent = cons.ascent; |
|
1865 |
r.width = cons.minWidth; |
|
1866 |
r.height = cons.minHeight; |
|
1867 |
} |
|
1868 |
} |
|
1869 |
// Reset the components y location based on |
|
1870 |
// components ascent and baseline for row. Because ascent |
|
1871 |
// includes the baseline |
|
1872 |
r.y = cellY + baseline - ascent + cons.insets.top; |
|
1873 |
if (cons.isVerticallyResizable()) { |
|
1874 |
switch(cons.baselineResizeBehavior) { |
|
1875 |
case CONSTANT_ASCENT: |
|
1876 |
r.height = Math.max(cons.minHeight,cellY + cellHeight - |
|
1877 |
r.y - cons.insets.bottom); |
|
1878 |
break; |
|
1879 |
case CENTER_OFFSET: |
|
1880 |
{ |
|
1881 |
int upper = r.y - cellY - cons.insets.top; |
|
1882 |
int lower = cellY + cellHeight - r.y - |
|
1883 |
cons.minHeight - cons.insets.bottom; |
|
1884 |
int delta = Math.min(upper, lower); |
|
1885 |
delta += delta; |
|
1886 |
if (delta > 0 && |
|
1887 |
(cons.minHeight + cons.centerPadding + |
|
1888 |
delta) / 2 + cons.centerOffset != baseline) { |
|
1889 |
// Off by 1 |
|
1890 |
delta--; |
|
1891 |
} |
|
1892 |
r.height = cons.minHeight + delta; |
|
1893 |
r.y = cellY + baseline - |
|
1894 |
(r.height + cons.centerPadding) / 2 - |
|
1895 |
cons.centerOffset; |
|
1896 |
} |
|
1897 |
break; |
|
1898 |
case OTHER: |
|
1899 |
// Handled above |
|
1900 |
break; |
|
1901 |
default: |
|
1902 |
break; |
|
1903 |
} |
|
1904 |
} |
|
1905 |
} |
|
1906 |
} |
|
1907 |
else { |
|
1908 |
centerVertically(cons, r, cellHeight); |
|
1909 |
} |
|
1910 |
} |
|
1911 |
||
1912 |
/** |
|
1913 |
* Positions the specified component above the baseline. That is |
|
1914 |
* the bottom edge of the component will be aligned along the baseline. |
|
1915 |
* If the row does not have a baseline, this centers the component. |
|
1916 |
*/ |
|
1917 |
private void alignAboveBaseline(GridBagConstraints cons, Rectangle r, |
|
1918 |
int cellY, int cellHeight) { |
|
1919 |
if (layoutInfo.hasBaseline(cons.tempY)) { |
|
1920 |
int maxY; // Baseline for the row |
|
1921 |
if (layoutInfo.hasConstantDescent(cons.tempY)) { |
|
1922 |
// Prefer descent |
|
1923 |
maxY = cellY + cellHeight - layoutInfo.maxDescent[cons.tempY]; |
|
1924 |
} |
|
1925 |
else { |
|
1926 |
// Prefer ascent |
|
1927 |
maxY = cellY + layoutInfo.maxAscent[cons.tempY]; |
|
1928 |
} |
|
1929 |
if (cons.isVerticallyResizable()) { |
|
1930 |
// Component is resizable. Top edge is offset by top |
|
1931 |
// inset, bottom edge on baseline. |
|
1932 |
r.y = cellY + cons.insets.top; |
|
1933 |
r.height = maxY - r.y; |
|
1934 |
} |
|
1935 |
else { |
|
1936 |
// Not resizable. |
|
1937 |
r.height = cons.minHeight + cons.ipady; |
|
1938 |
r.y = maxY - r.height; |
|
1939 |
} |
|
1940 |
} |
|
1941 |
else { |
|
1942 |
centerVertically(cons, r, cellHeight); |
|
1943 |
} |
|
1944 |
} |
|
1945 |
||
1946 |
/** |
|
1947 |
* Positions below the baseline. |
|
1948 |
*/ |
|
1949 |
private void alignBelowBaseline(GridBagConstraints cons, Rectangle r, |
|
1950 |
int cellY, int cellHeight) { |
|
1951 |
if (layoutInfo.hasBaseline(cons.tempY)) { |
|
1952 |
if (layoutInfo.hasConstantDescent(cons.tempY)) { |
|
1953 |
// Prefer descent |
|
1954 |
r.y = cellY + cellHeight - layoutInfo.maxDescent[cons.tempY]; |
|
1955 |
} |
|
1956 |
else { |
|
1957 |
// Prefer ascent |
|
1958 |
r.y = cellY + layoutInfo.maxAscent[cons.tempY]; |
|
1959 |
} |
|
1960 |
if (cons.isVerticallyResizable()) { |
|
1961 |
r.height = cellY + cellHeight - r.y - cons.insets.bottom; |
|
1962 |
} |
|
1963 |
} |
|
1964 |
else { |
|
1965 |
centerVertically(cons, r, cellHeight); |
|
1966 |
} |
|
1967 |
} |
|
1968 |
||
1969 |
private void centerVertically(GridBagConstraints cons, Rectangle r, |
|
1970 |
int cellHeight) { |
|
1971 |
if (!cons.isVerticallyResizable()) { |
|
1972 |
r.y += Math.max(0, (cellHeight - cons.insets.top - |
|
1973 |
cons.insets.bottom - cons.minHeight - |
|
1974 |
cons.ipady) / 2); |
|
1975 |
} |
|
1976 |
} |
|
1977 |
||
1978 |
/** |
|
1979 |
* Figures out the minimum size of the |
|
1980 |
* master based on the information from <code>getLayoutInfo</code>. |
|
1981 |
* This method should only be used internally by |
|
1982 |
* <code>GridBagLayout</code>. |
|
1983 |
* |
|
1984 |
* @param parent the layout container |
|
1985 |
* @param info the layout info for this parent |
|
1986 |
* @return a <code>Dimension</code> object containing the |
|
1987 |
* minimum size |
|
1988 |
* @since 1.4 |
|
1989 |
*/ |
|
1990 |
protected Dimension getMinSize(Container parent, GridBagLayoutInfo info) { |
|
1991 |
return GetMinSize(parent, info); |
|
1992 |
} |
|
1993 |
||
1994 |
/** |
|
1995 |
* This method is obsolete and supplied for backwards |
|
1996 |
* compatability only; new code should call {@link |
|
1997 |
* #getMinSize(java.awt.Container, GridBagLayoutInfo) getMinSize} instead. |
|
1998 |
* This method is the same as <code>getMinSize</code>; |
|
1999 |
* refer to <code>getMinSize</code> for details on parameters |
|
2000 |
* and return value. |
|
2001 |
*/ |
|
2002 |
protected Dimension GetMinSize(Container parent, GridBagLayoutInfo info) { |
|
2003 |
Dimension d = new Dimension(); |
|
2004 |
int i, t; |
|
2005 |
Insets insets = parent.getInsets(); |
|
2006 |
||
2007 |
t = 0; |
|
2008 |
for(i = 0; i < info.width; i++) |
|
2009 |
t += info.minWidth[i]; |
|
2010 |
d.width = t + insets.left + insets.right; |
|
2011 |
||
2012 |
t = 0; |
|
2013 |
for(i = 0; i < info.height; i++) |
|
2014 |
t += info.minHeight[i]; |
|
2015 |
d.height = t + insets.top + insets.bottom; |
|
2016 |
||
2017 |
return d; |
|
2018 |
} |
|
2019 |
||
2020 |
transient boolean rightToLeft = false; |
|
2021 |
||
2022 |
/** |
|
2023 |
* Lays out the grid. |
|
2024 |
* This method should only be used internally by |
|
2025 |
* <code>GridBagLayout</code>. |
|
2026 |
* |
|
2027 |
* @param parent the layout container |
|
2028 |
* @since 1.4 |
|
2029 |
*/ |
|
2030 |
protected void arrangeGrid(Container parent) { |
|
2031 |
ArrangeGrid(parent); |
|
2032 |
} |
|
2033 |
||
2034 |
/** |
|
2035 |
* This method is obsolete and supplied for backwards |
|
2036 |
* compatability only; new code should call {@link |
|
2037 |
* #arrangeGrid(Container) arrangeGrid} instead. |
|
2038 |
* This method is the same as <code>arrangeGrid</code>; |
|
2039 |
* refer to <code>arrangeGrid</code> for details on the |
|
2040 |
* parameter. |
|
2041 |
*/ |
|
2042 |
protected void ArrangeGrid(Container parent) { |
|
2043 |
Component comp; |
|
2044 |
int compindex; |
|
2045 |
GridBagConstraints constraints; |
|
2046 |
Insets insets = parent.getInsets(); |
|
2047 |
Component components[] = parent.getComponents(); |
|
2048 |
Dimension d; |
|
2049 |
Rectangle r = new Rectangle(); |
|
2050 |
int i, diffw, diffh; |
|
2051 |
double weight; |
|
2052 |
GridBagLayoutInfo info; |
|
2053 |
||
2054 |
rightToLeft = !parent.getComponentOrientation().isLeftToRight(); |
|
2055 |
||
2056 |
/* |
|
2057 |
* If the parent has no slaves anymore, then don't do anything |
|
2058 |
* at all: just leave the parent's size as-is. |
|
2059 |
*/ |
|
2060 |
if (components.length == 0 && |
|
2061 |
(columnWidths == null || columnWidths.length == 0) && |
|
2062 |
(rowHeights == null || rowHeights.length == 0)) { |
|
2063 |
return; |
|
2064 |
} |
|
2065 |
||
2066 |
/* |
|
2067 |
* Pass #1: scan all the slaves to figure out the total amount |
|
2068 |
* of space needed. |
|
2069 |
*/ |
|
2070 |
||
2071 |
info = getLayoutInfo(parent, PREFERREDSIZE); |
|
2072 |
d = getMinSize(parent, info); |
|
2073 |
||
2074 |
if (parent.width < d.width || parent.height < d.height) { |
|
2075 |
info = getLayoutInfo(parent, MINSIZE); |
|
2076 |
d = getMinSize(parent, info); |
|
2077 |
} |
|
2078 |
||
2079 |
layoutInfo = info; |
|
2080 |
r.width = d.width; |
|
2081 |
r.height = d.height; |
|
2082 |
||
2083 |
/* |
|
2084 |
* DEBUG |
|
2085 |
* |
|
2086 |
* DumpLayoutInfo(info); |
|
2087 |
* for (compindex = 0 ; compindex < components.length ; compindex++) { |
|
2088 |
* comp = components[compindex]; |
|
2089 |
* if (!comp.isVisible()) |
|
2090 |
* continue; |
|
2091 |
* constraints = lookupConstraints(comp); |
|
2092 |
* DumpConstraints(constraints); |
|
2093 |
* } |
|
2094 |
* System.out.println("minSize " + r.width + " " + r.height); |
|
2095 |
*/ |
|
2096 |
||
2097 |
/* |
|
2098 |
* If the current dimensions of the window don't match the desired |
|
2099 |
* dimensions, then adjust the minWidth and minHeight arrays |
|
2100 |
* according to the weights. |
|
2101 |
*/ |
|
2102 |
||
2103 |
diffw = parent.width - r.width; |
|
2104 |
if (diffw != 0) { |
|
2105 |
weight = 0.0; |
|
2106 |
for (i = 0; i < info.width; i++) |
|
2107 |
weight += info.weightX[i]; |
|
2108 |
if (weight > 0.0) { |
|
2109 |
for (i = 0; i < info.width; i++) { |
|
2110 |
int dx = (int)(( ((double)diffw) * info.weightX[i]) / weight); |
|
2111 |
info.minWidth[i] += dx; |
|
2112 |
r.width += dx; |
|
2113 |
if (info.minWidth[i] < 0) { |
|
2114 |
r.width -= info.minWidth[i]; |
|
2115 |
info.minWidth[i] = 0; |
|
2116 |
} |
|
2117 |
} |
|
2118 |
} |
|
2119 |
diffw = parent.width - r.width; |
|
2120 |
} |
|
2121 |
||
2122 |
else { |
|
2123 |
diffw = 0; |
|
2124 |
} |
|
2125 |
||
2126 |
diffh = parent.height - r.height; |
|
2127 |
if (diffh != 0) { |
|
2128 |
weight = 0.0; |
|
2129 |
for (i = 0; i < info.height; i++) |
|
2130 |
weight += info.weightY[i]; |
|
2131 |
if (weight > 0.0) { |
|
2132 |
for (i = 0; i < info.height; i++) { |
|
2133 |
int dy = (int)(( ((double)diffh) * info.weightY[i]) / weight); |
|
2134 |
info.minHeight[i] += dy; |
|
2135 |
r.height += dy; |
|
2136 |
if (info.minHeight[i] < 0) { |
|
2137 |
r.height -= info.minHeight[i]; |
|
2138 |
info.minHeight[i] = 0; |
|
2139 |
} |
|
2140 |
} |
|
2141 |
} |
|
2142 |
diffh = parent.height - r.height; |
|
2143 |
} |
|
2144 |
||
2145 |
else { |
|
2146 |
diffh = 0; |
|
2147 |
} |
|
2148 |
||
2149 |
/* |
|
2150 |
* DEBUG |
|
2151 |
* |
|
2152 |
* System.out.println("Re-adjusted:"); |
|
2153 |
* DumpLayoutInfo(info); |
|
2154 |
*/ |
|
2155 |
||
2156 |
/* |
|
2157 |
* Now do the actual layout of the slaves using the layout information |
|
2158 |
* that has been collected. |
|
2159 |
*/ |
|
2160 |
||
2161 |
info.startx = diffw/2 + insets.left; |
|
2162 |
info.starty = diffh/2 + insets.top; |
|
2163 |
||
2164 |
for (compindex = 0 ; compindex < components.length ; compindex++) { |
|
2165 |
comp = components[compindex]; |
|
2166 |
if (!comp.isVisible()){ |
|
2167 |
continue; |
|
2168 |
} |
|
2169 |
constraints = lookupConstraints(comp); |
|
2170 |
||
2171 |
if (!rightToLeft) { |
|
2172 |
r.x = info.startx; |
|
2173 |
for(i = 0; i < constraints.tempX; i++) |
|
2174 |
r.x += info.minWidth[i]; |
|
2175 |
} else { |
|
2176 |
r.x = parent.width - (diffw/2 + insets.right); |
|
2177 |
for(i = 0; i < constraints.tempX; i++) |
|
2178 |
r.x -= info.minWidth[i]; |
|
2179 |
} |
|
2180 |
||
2181 |
r.y = info.starty; |
|
2182 |
for(i = 0; i < constraints.tempY; i++) |
|
2183 |
r.y += info.minHeight[i]; |
|
2184 |
||
2185 |
r.width = 0; |
|
2186 |
for(i = constraints.tempX; |
|
2187 |
i < (constraints.tempX + constraints.tempWidth); |
|
2188 |
i++) { |
|
2189 |
r.width += info.minWidth[i]; |
|
2190 |
} |
|
2191 |
||
2192 |
r.height = 0; |
|
2193 |
for(i = constraints.tempY; |
|
2194 |
i < (constraints.tempY + constraints.tempHeight); |
|
2195 |
i++) { |
|
2196 |
r.height += info.minHeight[i]; |
|
2197 |
} |
|
2198 |
||
2199 |
componentAdjusting = comp; |
|
2200 |
adjustForGravity(constraints, r); |
|
2201 |
||
2202 |
/* fix for 4408108 - components were being created outside of the container */ |
|
2203 |
/* fix for 4969409 "-" replaced by "+" */ |
|
2204 |
if (r.x < 0) { |
|
2205 |
r.width += r.x; |
|
2206 |
r.x = 0; |
|
2207 |
} |
|
2208 |
||
2209 |
if (r.y < 0) { |
|
2210 |
r.height += r.y; |
|
2211 |
r.y = 0; |
|
2212 |
} |
|
2213 |
||
2214 |
/* |
|
2215 |
* If the window is too small to be interesting then |
|
2216 |
* unmap it. Otherwise configure it and then make sure |
|
2217 |
* it's mapped. |
|
2218 |
*/ |
|
2219 |
||
2220 |
if ((r.width <= 0) || (r.height <= 0)) { |
|
2221 |
comp.setBounds(0, 0, 0, 0); |
|
2222 |
} |
|
2223 |
else { |
|
2224 |
if (comp.x != r.x || comp.y != r.y || |
|
2225 |
comp.width != r.width || comp.height != r.height) { |
|
2226 |
comp.setBounds(r.x, r.y, r.width, r.height); |
|
2227 |
} |
|
2228 |
} |
|
2229 |
} |
|
2230 |
} |
|
2231 |
||
2232 |
// Added for serial backwards compatability (4348425) |
|
2233 |
static final long serialVersionUID = 8838754796412211005L; |
|
2234 |
} |