1. /*
  2. * @(#)GridBagLayout.java 1.64 04/06/08
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.awt;
  8. import java.util.Hashtable;
  9. import java.util.Vector;
  10. class GridBagLayoutInfo implements java.io.Serializable {
  11. int width, height; /* number of cells horizontally, vertically */
  12. int startx, starty; /* starting point for layout */
  13. int minWidth[]; /* largest minWidth in each column */
  14. int minHeight[]; /* largest minHeight in each row */
  15. double weightX[]; /* largest weight in each column */
  16. double weightY[]; /* largest weight in each row */
  17. GridBagLayoutInfo () {
  18. /* fix for 5055696 (avoiding AIOOBE by enlarging sizes) */
  19. minWidth = new int[GridBagLayout.MAXGRIDSIZE];
  20. minHeight = new int[GridBagLayout.MAXGRIDSIZE];
  21. weightX = new double[GridBagLayout.MAXGRIDSIZE];
  22. weightY = new double[GridBagLayout.MAXGRIDSIZE];
  23. }
  24. }
  25. /**
  26. * The <code>GridBagLayout</code> class is a flexible layout
  27. * manager that aligns components vertically and horizontally,
  28. * without requiring that the components be of the same size.
  29. * Each <code>GridBagLayout</code> object maintains a dynamic,
  30. * rectangular grid of cells, with each component occupying
  31. * one or more cells, called its <em>display area</em>.
  32. * <p>
  33. * Each component managed by a <code>GridBagLayout</code> is associated with
  34. * an instance of {@link GridBagConstraints}. The constraints object
  35. * specifies where a component's display area should be located on the grid
  36. * and how the component should be positioned within its display area. In
  37. * addition to its constraints object, the <code>GridBagLayout</code> also
  38. * considers each component's minimum and preferred sizes in order to
  39. * determine a component's size.
  40. * <p>
  41. * The overall orientation of the grid depends on the container's
  42. * {@link ComponentOrientation} property. For horizontal left-to-right
  43. * orientations, grid coordinate (0,0) is in the upper left corner of the
  44. * container with x increasing to the right and y increasing downward. For
  45. * horizontal right-to-left orientations, grid coordinate (0,0) is in the upper
  46. * right corner of the container with x increasing to the left and y
  47. * increasing downward.
  48. * <p>
  49. * To use a grid bag layout effectively, you must customize one or more
  50. * of the <code>GridBagConstraints</code> objects that are associated
  51. * with its components. You customize a <code>GridBagConstraints</code>
  52. * object by setting one or more of its instance variables:
  53. * <p>
  54. * <dl>
  55. * <dt>{@link GridBagConstraints#gridx},
  56. * {@link GridBagConstraints#gridy}
  57. * <dd>Specifies the cell containing the leading corner of the component's
  58. * display area, where the cell at the origin of the grid has address
  59. * <code>gridx = 0</code>,
  60. * <code>gridy = 0</code>. For horizontal left-to-right layout,
  61. * a component's leading corner is its upper left. For horizontal
  62. * right-to-left layout, a component's leading corner is its upper right.
  63. * Use <code>GridBagConstraints.RELATIVE</code> (the default value)
  64. * to specify that the component be placed immediately following
  65. * (along the x axis for <code>gridx</code> or the y axis for
  66. * <code>gridy</code>) the component that was added to the container
  67. * just before this component was added.
  68. * <dt>{@link GridBagConstraints#gridwidth},
  69. * {@link GridBagConstraints#gridheight}
  70. * <dd>Specifies the number of cells in a row (for <code>gridwidth</code>)
  71. * or column (for <code>gridheight</code>)
  72. * in the component's display area.
  73. * The default value is 1.
  74. * Use <code>GridBagConstraints.REMAINDER</code> to specify
  75. * that the component's display area will be from <code>gridx</code>
  76. * to the last cell in the row (for <code>gridwidth</code>)
  77. * or from <code>gridy</code> to the last cell in the column
  78. * (for <code>gridheight</code>).
  79. *
  80. * Use <code>GridBagConstraints.RELATIVE</code> to specify
  81. * that the component's display area will be from <code>gridx</code>
  82. * to the next to the last cell in its row (for <code>gridwidth</code>
  83. * or from <code>gridy</code> to the next to the last cell in its
  84. * column (for <code>gridheight</code>).
  85. *
  86. * <dt>{@link GridBagConstraints#fill}
  87. * <dd>Used when the component's display area
  88. * is larger than the component's requested size
  89. * to determine whether (and how) to resize the component.
  90. * Possible values are
  91. * <code>GridBagConstraints.NONE</code> (the default),
  92. * <code>GridBagConstraints.HORIZONTAL</code>
  93. * (make the component wide enough to fill its display area
  94. * horizontally, but don't change its height),
  95. * <code>GridBagConstraints.VERTICAL</code>
  96. * (make the component tall enough to fill its display area
  97. * vertically, but don't change its width), and
  98. * <code>GridBagConstraints.BOTH</code>
  99. * (make the component fill its display area entirely).
  100. * <dt>{@link GridBagConstraints#ipadx},
  101. * {@link GridBagConstraints#ipady}
  102. * <dd>Specifies the component's internal padding within the layout,
  103. * how much to add to the minimum size of the component.
  104. * The width of the component will be at least its minimum width
  105. * plus <code>ipadx</code> pixels. Similarly, the height of
  106. * the component will be at least the minimum height plus
  107. * <code>ipady</code> pixels.
  108. * <dt>{@link GridBagConstraints#insets}
  109. * <dd>Specifies the component's external padding, the minimum
  110. * amount of space between the component and the edges of its display area.
  111. * <dt>{@link GridBagConstraints#anchor}
  112. * <dd>Used when the component is smaller than its display area
  113. * to determine where (within the display area) to place the component.
  114. * There are two kinds of possible values: relative and absolute. Relative
  115. * values are interpreted relative to the container's
  116. * <code>ComponentOrientation</code> property while absolute values
  117. * are not. Valid values are:</dd>
  118. * <p>
  119. * <center><table BORDER=0 COLS=2 WIDTH=800 SUMMARY="absolute and relative values as described above">
  120. * <tr>
  121. * <th><P ALIGN="LEFT">Absolute Values</th>
  122. * <th><P ALIGN="LEFT">Relative Values</th>
  123. * </tr>
  124. * <tr>
  125. * <td>
  126. * <li><code>GridBagConstraints.NORTH</code></li>
  127. * <li><code>GridBagConstraints.SOUTH</code></li>
  128. * <li><code>GridBagConstraints.WEST</code></li>
  129. * <li><code>GridBagConstraints.EAST</code></li>
  130. * <li><code>GridBagConstraints.NORTHWEST</code></li>
  131. * <li><code>GridBagConstraints.NORTHEAST</code></li>
  132. * <li><code>GridBagConstraints.SOUTHWEST</code></li>
  133. * <li><code>GridBagConstraints.SOUTHEAST</code></li>
  134. * <li><code>GridBagConstraints.CENTER</code> (the default)</li>
  135. * </td>
  136. * <td>
  137. * <li><code>GridBagConstraints.PAGE_START</code></li>
  138. * <li><code>GridBagConstraints.PAGE_END</code></li>
  139. * <li><code>GridBagConstraints.LINE_START</code></li>
  140. * <li><code>GridBagConstraints.LINE_END</code></li>
  141. * <li><code>GridBagConstraints.FIRST_LINE_START</code></li>
  142. * <li><code>GridBagConstraints.FIRST_LINE_END</code></li>
  143. * <li><code>GridBagConstraints.LAST_LINE_START</code></li>
  144. * <li><code>GridBagConstraints.LAST_LINE_END</code></li>
  145. * </ul>
  146. * </td>
  147. * </tr>
  148. * </table></center><p>
  149. * <dt>{@link GridBagConstraints#weightx},
  150. * {@link GridBagConstraints#weighty}
  151. * <dd>Used to determine how to distribute space, which is
  152. * important for specifying resizing behavior.
  153. * Unless you specify a weight for at least one component
  154. * in a row (<code>weightx</code>) and column (<code>weighty</code>),
  155. * all the components clump together in the center of their container.
  156. * This is because when the weight is zero (the default),
  157. * the <code>GridBagLayout</code> object puts any extra space
  158. * between its grid of cells and the edges of the container.
  159. * </dl>
  160. * <p>
  161. * The following figures show ten components (all buttons)
  162. * managed by a grid bag layout. Figure 1 shows the layout for a horizontal,
  163. * left-to-right container and Figure 2 shows the layout for a horizontal,
  164. * right-to-left container.
  165. * <p>
  166. * <center><table COLS=2 WIDTH=600 summary="layout">
  167. * <tr ALIGN=CENTER>
  168. * <td>
  169. * <img src="doc-files/GridBagLayout-1.gif" alt="The preceeding text describes this graphic (Figure 1)." ALIGN=center HSPACE=10 VSPACE=7>
  170. * </td>
  171. * <td>
  172. * <img src="doc-files/GridBagLayout-2.gif" alt="The preceeding text describes this graphic (Figure 2)." ALIGN=center HSPACE=10 VSPACE=7>
  173. * </td>
  174. * <tr ALIGN=CENTER>
  175. * <td>Figure 1: Horizontal, Left-to-Right</td>
  176. * <td>Figure 2: Horizontal, Right-to-Left</td>
  177. * </tr>
  178. * </table></center>
  179. * <p>
  180. * Each of the ten components has the <code>fill</code> field
  181. * of its associated <code>GridBagConstraints</code> object
  182. * set to <code>GridBagConstraints.BOTH</code>.
  183. * In addition, the components have the following non-default constraints:
  184. * <p>
  185. * <ul>
  186. * <li>Button1, Button2, Button3: <code>weightx = 1.0</code>
  187. * <li>Button4: <code>weightx = 1.0</code>,
  188. * <code>gridwidth = GridBagConstraints.REMAINDER</code>
  189. * <li>Button5: <code>gridwidth = GridBagConstraints.REMAINDER</code>
  190. * <li>Button6: <code>gridwidth = GridBagConstraints.RELATIVE</code>
  191. * <li>Button7: <code>gridwidth = GridBagConstraints.REMAINDER</code>
  192. * <li>Button8: <code>gridheight = 2</code>,
  193. * <code>weighty = 1.0</code>
  194. * <li>Button9, Button 10:
  195. * <code>gridwidth = GridBagConstraints.REMAINDER</code>
  196. * </ul>
  197. * <p>
  198. * Here is the code that implements the example shown above:
  199. * <p>
  200. * <hr><blockquote><pre>
  201. * import java.awt.*;
  202. * import java.util.*;
  203. * import java.applet.Applet;
  204. *
  205. * public class GridBagEx1 extends Applet {
  206. *
  207. * protected void makebutton(String name,
  208. * GridBagLayout gridbag,
  209. * GridBagConstraints c) {
  210. * Button button = new Button(name);
  211. * gridbag.setConstraints(button, c);
  212. * add(button);
  213. * }
  214. *
  215. * public void init() {
  216. * GridBagLayout gridbag = new GridBagLayout();
  217. * GridBagConstraints c = new GridBagConstraints();
  218. *
  219. * setFont(new Font("SansSerif", Font.PLAIN, 14));
  220. * setLayout(gridbag);
  221. *
  222. * c.fill = GridBagConstraints.BOTH;
  223. * c.weightx = 1.0;
  224. * makebutton("Button1", gridbag, c);
  225. * makebutton("Button2", gridbag, c);
  226. * makebutton("Button3", gridbag, c);
  227. *
  228. * c.gridwidth = GridBagConstraints.REMAINDER; //end row
  229. * makebutton("Button4", gridbag, c);
  230. *
  231. * c.weightx = 0.0; //reset to the default
  232. * makebutton("Button5", gridbag, c); //another row
  233. *
  234. * c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last in row
  235. * makebutton("Button6", gridbag, c);
  236. *
  237. * c.gridwidth = GridBagConstraints.REMAINDER; //end row
  238. * makebutton("Button7", gridbag, c);
  239. *
  240. * c.gridwidth = 1; //reset to the default
  241. * c.gridheight = 2;
  242. * c.weighty = 1.0;
  243. * makebutton("Button8", gridbag, c);
  244. *
  245. * c.weighty = 0.0; //reset to the default
  246. * c.gridwidth = GridBagConstraints.REMAINDER; //end row
  247. * c.gridheight = 1; //reset to the default
  248. * makebutton("Button9", gridbag, c);
  249. * makebutton("Button10", gridbag, c);
  250. *
  251. * setSize(300, 100);
  252. * }
  253. *
  254. * public static void main(String args[]) {
  255. * Frame f = new Frame("GridBag Layout Example");
  256. * GridBagEx1 ex1 = new GridBagEx1();
  257. *
  258. * ex1.init();
  259. *
  260. * f.add("Center", ex1);
  261. * f.pack();
  262. * f.setSize(f.getPreferredSize());
  263. * f.show();
  264. * }
  265. * }
  266. * </pre></blockquote><hr>
  267. * <p>
  268. * @version 1.64, 06/08/04
  269. * @author Doug Stein
  270. * @see java.awt.GridBagConstraints
  271. * @see java.awt.ComponentOrientation
  272. * @since JDK1.0
  273. */
  274. public class GridBagLayout implements LayoutManager2,
  275. java.io.Serializable {
  276. /* Maximum number of grid positions */
  277. protected static final int MAXGRIDSIZE = 512;
  278. /**
  279. * The smallest grid that can be laid out by the grid bag layout.
  280. */
  281. protected static final int MINSIZE = 1;
  282. /**
  283. * The preferred grid size that can be laid out by the grid bag layout.
  284. */
  285. protected static final int PREFERREDSIZE = 2;
  286. /**
  287. * This hashtable maintains the association between
  288. * a component and its gridbag constraints.
  289. * The Keys in <code>comptable</code> are the components and the
  290. * values are the instances of <code>GridBagConstraints</code>.
  291. *
  292. * @serial
  293. * @see java.awt.GridBagConstraints
  294. */
  295. protected Hashtable<Component,GridBagConstraints> comptable;
  296. /**
  297. * This field holds a gridbag constraints instance
  298. * containing the default values, so if a component
  299. * does not have gridbag constraints associated with
  300. * it, then the component will be assigned a
  301. * copy of the <code>defaultConstraints</code>.
  302. *
  303. * @serial
  304. * @see #getConstraints(Component)
  305. * @see #setConstraints(Component, GridBagConstraints)
  306. * @see #lookupConstraints(Component)
  307. */
  308. protected GridBagConstraints defaultConstraints;
  309. /**
  310. * This field holds the layout information
  311. * for the gridbag. The information in this field
  312. * is based on the most recent validation of the
  313. * gridbag.
  314. * If <code>layoutInfo</code> is <code>null</code>
  315. * this indicates that there are no components in
  316. * the gridbag or if there are components, they have
  317. * not yet been validated.
  318. *
  319. * @serial
  320. * @see #getLayoutInfo(Container, int)
  321. */
  322. protected GridBagLayoutInfo layoutInfo;
  323. /**
  324. * This field holds the overrides to the column minimum
  325. * width. If this field is non-<code>null</code> the values are
  326. * applied to the gridbag after all of the minimum columns
  327. * widths have been calculated.
  328. * If columnWidths has more elements than the number of
  329. * columns, columns are added to the gridbag to match
  330. * the number of elements in columnWidth.
  331. *
  332. * @serial
  333. * @see #getLayoutDimensions()
  334. */
  335. public int columnWidths[];
  336. /**
  337. * This field holds the overrides to the row minimum
  338. * heights. If this field is non-</code>null</code> the values are
  339. * applied to the gridbag after all of the minimum row
  340. * heights have been calculated.
  341. * If <code>rowHeights</code> has more elements than the number of
  342. * rows, rowa are added to the gridbag to match
  343. * the number of elements in <code>rowHeights</code>.
  344. *
  345. * @serial
  346. * @see #getLayoutDimensions()
  347. */
  348. public int rowHeights[];
  349. /**
  350. * This field holds the overrides to the column weights.
  351. * If this field is non-<code>null</code> the values are
  352. * applied to the gridbag after all of the columns
  353. * weights have been calculated.
  354. * If <code>columnWeights[i]</code> > weight for column i, then
  355. * column i is assigned the weight in <code>columnWeights[i]</code>.
  356. * If <code>columnWeights</code> has more elements than the number
  357. * of columns, the excess elements are ignored - they do
  358. * not cause more columns to be created.
  359. *
  360. * @serial
  361. */
  362. public double columnWeights[];
  363. /**
  364. * This field holds the overrides to the row weights.
  365. * If this field is non-</code>null</code> the values are
  366. * applied to the gridbag after all of the rows
  367. * weights have been calculated.
  368. * If <code>rowWeights[i]</code> > weight for row i, then
  369. * row i is assigned the weight in <code>rowWeights[i]</code>.
  370. * If <code>rowWeights</code> has more elements than the number
  371. * of rows, the excess elements are ignored - they do
  372. * not cause more rows to be created.
  373. *
  374. * @serial
  375. */
  376. public double rowWeights[];
  377. /**
  378. * Creates a grid bag layout manager.
  379. */
  380. public GridBagLayout () {
  381. comptable = new Hashtable<Component,GridBagConstraints>();
  382. defaultConstraints = new GridBagConstraints();
  383. }
  384. /**
  385. * Sets the constraints for the specified component in this layout.
  386. * @param comp the component to be modified
  387. * @param constraints the constraints to be applied
  388. */
  389. public void setConstraints(Component comp, GridBagConstraints constraints) {
  390. comptable.put(comp, (GridBagConstraints)constraints.clone());
  391. }
  392. /**
  393. * Gets the constraints for the specified component. A copy of
  394. * the actual <code>GridBagConstraints</code> object is returned.
  395. * @param comp the component to be queried
  396. * @return the constraint for the specified component in this
  397. * grid bag layout; a copy of the actual constraint
  398. * object is returned
  399. */
  400. public GridBagConstraints getConstraints(Component comp) {
  401. GridBagConstraints constraints = comptable.get(comp);
  402. if (constraints == null) {
  403. setConstraints(comp, defaultConstraints);
  404. constraints = comptable.get(comp);
  405. }
  406. return (GridBagConstraints)constraints.clone();
  407. }
  408. /**
  409. * Retrieves the constraints for the specified component.
  410. * The return value is not a copy, but is the actual
  411. * <code>GridBagConstraints</code> object used by the layout mechanism.
  412. * <p>
  413. * If <code>comp</code> is not in the <code>GridBagLayout</code>,
  414. * a set of default <code>GridBagConstraints</code> are returned.
  415. * A <code>comp</code> value of <code>null</code> is invalid
  416. * and returns <code>null</code>.
  417. *
  418. * @param comp the component to be queried
  419. * @return the contraints for the specified component
  420. */
  421. protected GridBagConstraints lookupConstraints(Component comp) {
  422. GridBagConstraints constraints = comptable.get(comp);
  423. if (constraints == null) {
  424. setConstraints(comp, defaultConstraints);
  425. constraints = comptable.get(comp);
  426. }
  427. return constraints;
  428. }
  429. /**
  430. * Removes the constraints for the specified component in this layout
  431. * @param comp the component to be modified
  432. */
  433. private void removeConstraints(Component comp) {
  434. comptable.remove(comp);
  435. }
  436. /**
  437. * Determines the origin of the layout area, in the graphics coordinate
  438. * space of the target container. This value represents the pixel
  439. * coordinates of the top-left corner of the layout area regardless of
  440. * the <code>ComponentOrientation</code> value of the container. This
  441. * is distinct from the grid origin given by the cell coordinates (0,0).
  442. * Most applications do not call this method directly.
  443. * @return the graphics origin of the cell in the top-left
  444. * corner of the layout grid
  445. * @see java.awt.ComponentOrientation
  446. * @since JDK1.1
  447. */
  448. public Point getLayoutOrigin () {
  449. Point origin = new Point(0,0);
  450. if (layoutInfo != null) {
  451. origin.x = layoutInfo.startx;
  452. origin.y = layoutInfo.starty;
  453. }
  454. return origin;
  455. }
  456. /**
  457. * Determines column widths and row heights for the layout grid.
  458. * <p>
  459. * Most applications do not call this method directly.
  460. * @return an array of two arrays, containing the widths
  461. * of the layout columns and
  462. * the heights of the layout rows
  463. * @since JDK1.1
  464. */
  465. public int [][] getLayoutDimensions () {
  466. if (layoutInfo == null)
  467. return new int[2][0];
  468. int dim[][] = new int [2][];
  469. dim[0] = new int[layoutInfo.width];
  470. dim[1] = new int[layoutInfo.height];
  471. System.arraycopy(layoutInfo.minWidth, 0, dim[0], 0, layoutInfo.width);
  472. System.arraycopy(layoutInfo.minHeight, 0, dim[1], 0, layoutInfo.height);
  473. return dim;
  474. }
  475. /**
  476. * Determines the weights of the layout grid's columns and rows.
  477. * Weights are used to calculate how much a given column or row
  478. * stretches beyond its preferred size, if the layout has extra
  479. * room to fill.
  480. * <p>
  481. * Most applications do not call this method directly.
  482. * @return an array of two arrays, representing the
  483. * horizontal weights of the layout columns
  484. * and the vertical weights of the layout rows
  485. * @since JDK1.1
  486. */
  487. public double [][] getLayoutWeights () {
  488. if (layoutInfo == null)
  489. return new double[2][0];
  490. double weights[][] = new double [2][];
  491. weights[0] = new double[layoutInfo.width];
  492. weights[1] = new double[layoutInfo.height];
  493. System.arraycopy(layoutInfo.weightX, 0, weights[0], 0, layoutInfo.width);
  494. System.arraycopy(layoutInfo.weightY, 0, weights[1], 0, layoutInfo.height);
  495. return weights;
  496. }
  497. /**
  498. * Determines which cell in the layout grid contains the point
  499. * specified by <code>(x, y)</code>. Each cell is identified
  500. * by its column index (ranging from 0 to the number of columns
  501. * minus 1) and its row index (ranging from 0 to the number of
  502. * rows minus 1).
  503. * <p>
  504. * If the <code>(x, y)</code> point lies
  505. * outside the grid, the following rules are used.
  506. * The column index is returned as zero if <code>x</code> lies to the
  507. * left of the layout for a left-to-right container or to the right of
  508. * the layout for a right-to-left container. The column index is returned
  509. * as the number of columns if <code>x</code> lies
  510. * to the right of the layout in a left-to-right container or to the left
  511. * in a right-to-left container.
  512. * The row index is returned as zero if <code>y</code> lies above the
  513. * layout, and as the number of rows if <code>y</code> lies
  514. * below the layout. The orientation of a container is determined by its
  515. * <code>ComponentOrientation</code> property.
  516. * @param x the <i>x</i> coordinate of a point
  517. * @param y the <i>y</i> coordinate of a point
  518. * @return an ordered pair of indexes that indicate which cell
  519. * in the layout grid contains the point
  520. * (<i>x</i>, <i>y</i>).
  521. * @see java.awt.ComponentOrientation
  522. * @since JDK1.1
  523. */
  524. public Point location(int x, int y) {
  525. Point loc = new Point(0,0);
  526. int i, d;
  527. if (layoutInfo == null)
  528. return loc;
  529. d = layoutInfo.startx;
  530. if (!rightToLeft) {
  531. for (i=0; i<layoutInfo.width; i++) {
  532. d += layoutInfo.minWidth[i];
  533. if (d > x)
  534. break;
  535. }
  536. } else {
  537. for (i=layoutInfo.width-1; i>=0; i--) {
  538. if (d > x)
  539. break;
  540. d += layoutInfo.minWidth[i];
  541. }
  542. i++;
  543. }
  544. loc.x = i;
  545. d = layoutInfo.starty;
  546. for (i=0; i<layoutInfo.height; i++) {
  547. d += layoutInfo.minHeight[i];
  548. if (d > y)
  549. break;
  550. }
  551. loc.y = i;
  552. return loc;
  553. }
  554. /**
  555. * Has no effect, since this layout manager does not use a per-component string.
  556. */
  557. public void addLayoutComponent(String name, Component comp) {
  558. }
  559. /**
  560. * Adds the specified component to the layout, using the specified
  561. * <code>constraints</code> object. Note that constraints
  562. * are mutable and are, therefore, cloned when cached.
  563. *
  564. * @param comp the component to be added
  565. * @param constraints an object that determines how
  566. * the component is added to the layout
  567. * @exception IllegalArgumentException if <code>constraints</code>
  568. * is not a <code>GridBagConstraint</code>
  569. */
  570. public void addLayoutComponent(Component comp, Object constraints) {
  571. if (constraints instanceof GridBagConstraints) {
  572. setConstraints(comp, (GridBagConstraints)constraints);
  573. } else if (constraints != null) {
  574. throw new IllegalArgumentException("cannot add to layout: constraints must be a GridBagConstraint");
  575. }
  576. }
  577. /**
  578. * Removes the specified component from this layout.
  579. * <p>
  580. * Most applications do not call this method directly.
  581. * @param comp the component to be removed.
  582. * @see java.awt.Container#remove(java.awt.Component)
  583. * @see java.awt.Container#removeAll()
  584. */
  585. public void removeLayoutComponent(Component comp) {
  586. removeConstraints(comp);
  587. }
  588. /**
  589. * Determines the preferred size of the <code>parent</code>
  590. * container using this grid bag layout.
  591. * <p>
  592. * Most applications do not call this method directly.
  593. *
  594. * @param parent the container in which to do the layout
  595. * @see java.awt.Container#getPreferredSize
  596. * @return the preferred size of the <code>parent</code>
  597. * container
  598. */
  599. public Dimension preferredLayoutSize(Container parent) {
  600. GridBagLayoutInfo info = getLayoutInfo(parent, PREFERREDSIZE);
  601. return getMinSize(parent, info);
  602. }
  603. /**
  604. * Determines the minimum size of the <code>parent</code> container
  605. * using this grid bag layout.
  606. * <p>
  607. * Most applications do not call this method directly.
  608. * @param parent the container in which to do the layout
  609. * @see java.awt.Container#doLayout
  610. * @return the minimum size of the <code>parent</code> container
  611. */
  612. public Dimension minimumLayoutSize(Container parent) {
  613. GridBagLayoutInfo info = getLayoutInfo(parent, MINSIZE);
  614. return getMinSize(parent, info);
  615. }
  616. /**
  617. * Returns the maximum dimensions for this layout given the components
  618. * in the specified target container.
  619. * @param target the container which needs to be laid out
  620. * @see Container
  621. * @see #minimumLayoutSize(Container)
  622. * @see #preferredLayoutSize(Container)
  623. * @return the maximum dimensions for this layout
  624. */
  625. public Dimension maximumLayoutSize(Container target) {
  626. return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
  627. }
  628. /**
  629. * Returns the alignment along the x axis. This specifies how
  630. * the component would like to be aligned relative to other
  631. * components. The value should be a number between 0 and 1
  632. * where 0 represents alignment along the origin, 1 is aligned
  633. * the furthest away from the origin, 0.5 is centered, etc.
  634. * <p>
  635. * @return the value <code>0.5f</code> to indicate centered
  636. */
  637. public float getLayoutAlignmentX(Container parent) {
  638. return 0.5f;
  639. }
  640. /**
  641. * Returns the alignment along the y axis. This specifies how
  642. * the component would like to be aligned relative to other
  643. * components. The value should be a number between 0 and 1
  644. * where 0 represents alignment along the origin, 1 is aligned
  645. * the furthest away from the origin, 0.5 is centered, etc.
  646. * <p>
  647. * @return the value <code>0.5f</code> to indicate centered
  648. */
  649. public float getLayoutAlignmentY(Container parent) {
  650. return 0.5f;
  651. }
  652. /**
  653. * Invalidates the layout, indicating that if the layout manager
  654. * has cached information it should be discarded.
  655. */
  656. public void invalidateLayout(Container target) {
  657. }
  658. /**
  659. * Lays out the specified container using this grid bag layout.
  660. * This method reshapes components in the specified container in
  661. * order to satisfy the contraints of this <code>GridBagLayout</code>
  662. * object.
  663. * <p>
  664. * Most applications do not call this method directly.
  665. * @param parent the container in which to do the layout
  666. * @see java.awt.Container
  667. * @see java.awt.Container#doLayout
  668. */
  669. public void layoutContainer(Container parent) {
  670. arrangeGrid(parent);
  671. }
  672. /**
  673. * Returns a string representation of this grid bag layout's values.
  674. * @return a string representation of this grid bag layout.
  675. */
  676. public String toString() {
  677. return getClass().getName();
  678. }
  679. /**
  680. * Print the layout information. Useful for debugging.
  681. */
  682. /* DEBUG
  683. *
  684. * protected void dumpLayoutInfo(GridBagLayoutInfo s) {
  685. * int x;
  686. *
  687. * System.out.println("Col\tWidth\tWeight");
  688. * for (x=0; x<s.width; x++) {
  689. * System.out.println(x + "\t" +
  690. * s.minWidth[x] + "\t" +
  691. * s.weightX[x]);
  692. * }
  693. * System.out.println("Row\tHeight\tWeight");
  694. * for (x=0; x<s.height; x++) {
  695. * System.out.println(x + "\t" +
  696. * s.minHeight[x] + "\t" +
  697. * s.weightY[x]);
  698. * }
  699. * }
  700. */
  701. /**
  702. * Print the layout constraints. Useful for debugging.
  703. */
  704. /* DEBUG
  705. *
  706. * protected void dumpConstraints(GridBagConstraints constraints) {
  707. * System.out.println(
  708. * "wt " +
  709. * constraints.weightx +
  710. * " " +
  711. * constraints.weighty +
  712. * ", " +
  713. *
  714. * "box " +
  715. * constraints.gridx +
  716. * " " +
  717. * constraints.gridy +
  718. * " " +
  719. * constraints.gridwidth +
  720. * " " +
  721. * constraints.gridheight +
  722. * ", " +
  723. *
  724. * "min " +
  725. * constraints.minWidth +
  726. * " " +
  727. * constraints.minHeight +
  728. * ", " +
  729. *
  730. * "pad " +
  731. * constraints.insets.bottom +
  732. * " " +
  733. * constraints.insets.left +
  734. * " " +
  735. * constraints.insets.right +
  736. * " " +
  737. * constraints.insets.top +
  738. * " " +
  739. * constraints.ipadx +
  740. * " " +
  741. * constraints.ipady);
  742. * }
  743. */
  744. /**
  745. * Fills in an instance of <code>GridBagLayoutInfo</code> for the
  746. * current set of managed children. This requires three passes through the
  747. * set of children:
  748. *
  749. * <ol>
  750. * <li>Figure out the dimensions of the layout grid.
  751. * <li>Determine which cells the components occupy.
  752. * <li>Distribute the weights and min sizes amoung the rows/columns.
  753. * </ol>
  754. *
  755. * This also caches the minsizes for all the children when they are
  756. * first encountered (so subsequent loops don't need to ask again).
  757. * <p>
  758. * This method should only be used internally by
  759. * <code>GridBagLayout</code>.
  760. *
  761. * @param parent the layout container
  762. * @param sizeflag either <code>PREFERREDSIZE</code> or
  763. * <code>MINSIZE</code>
  764. * @return the <code>GridBagLayoutInfo</code> for the set of children
  765. * @since 1.4
  766. */
  767. protected GridBagLayoutInfo getLayoutInfo(Container parent, int sizeflag) {
  768. return GetLayoutInfo(parent, sizeflag);
  769. }
  770. /**
  771. * This method is obsolete and supplied for backwards
  772. * compatability only; new code should call {@link
  773. * #getLayoutInfo(java.awt.Container, int) getLayoutInfo} instead.
  774. * This method is the same as <code>getLayoutInfo</code>
  775. * refer to <code>getLayoutInfo</code> for details on parameters
  776. * and return value.
  777. */
  778. protected GridBagLayoutInfo GetLayoutInfo(Container parent, int sizeflag) {
  779. synchronized (parent.getTreeLock()) {
  780. GridBagLayoutInfo r = new GridBagLayoutInfo();
  781. Component comp;
  782. GridBagConstraints constraints;
  783. Dimension d;
  784. Component components[] = parent.getComponents();
  785. int compindex, i, j, k, px, py, pixels_diff, nextSize;
  786. int curX, curY, curWidth, curHeight, curRow, curCol;
  787. double weight_diff, weight, start, size;
  788. int xMax[], yMax[];
  789. /*
  790. * Pass #1
  791. *
  792. * Figure out the dimensions of the layout grid (use a value of 1 for
  793. * zero or negative widths and heights).
  794. */
  795. r.width = r.height = 0;
  796. curRow = curCol = -1;
  797. xMax = new int[MAXGRIDSIZE];
  798. yMax = new int[MAXGRIDSIZE];
  799. for (compindex = 0 ; compindex < components.length ; compindex++) {
  800. comp = components[compindex];
  801. if (!comp.isVisible())
  802. continue;
  803. constraints = lookupConstraints(comp);
  804. curX = constraints.gridx;
  805. curY = constraints.gridy;
  806. curWidth = constraints.gridwidth;
  807. if (curWidth <= 0)
  808. curWidth = 1;
  809. curHeight = constraints.gridheight;
  810. if (curHeight <= 0)
  811. curHeight = 1;
  812. /* If x or y is negative, then use relative positioning: */
  813. if (curX < 0 && curY < 0) {
  814. if (curRow >= 0)
  815. curY = curRow;
  816. else if (curCol >= 0)
  817. curX = curCol;
  818. else
  819. curY = 0;
  820. }
  821. if (curX < 0) {
  822. px = 0;
  823. for (i = curY; i < (curY + curHeight); i++) {
  824. px = Math.max(px, xMax[i]);
  825. }
  826. curX = px - curX - 1;
  827. if(curX < 0)
  828. curX = 0;
  829. }
  830. else if (curY < 0) {
  831. py = 0;
  832. for (i = curX; i < (curX + curWidth); i++) {
  833. py = Math.max(py, yMax[i]);
  834. }
  835. curY = py - curY - 1;
  836. if(curY < 0)
  837. curY = 0;
  838. }
  839. /* Adjust the grid width and height */
  840. for (px = curX + curWidth; r.width < px; r.width++);
  841. for (py = curY + curHeight; r.height < py; r.height++);
  842. /* Adjust xMax and yMax */
  843. for (i = curX; i < (curX + curWidth); i++) {
  844. yMax[i] = py;
  845. }
  846. for (i = curY; i < (curY + curHeight); i++) {
  847. xMax[i] = px;
  848. }
  849. /* Cache the current slave's size. */
  850. if (sizeflag == PREFERREDSIZE)
  851. d = comp.getPreferredSize();
  852. else
  853. d = comp.getMinimumSize();
  854. constraints.minWidth = d.width;
  855. constraints.minHeight = d.height;
  856. /* Zero width and height must mean that this is the last item (or
  857. * else something is wrong). */
  858. if (constraints.gridheight == 0 && constraints.gridwidth == 0)
  859. curRow = curCol = -1;
  860. /* Zero width starts a new row */
  861. if (constraints.gridheight == 0 && curRow < 0)
  862. curCol = curX + curWidth;
  863. /* Zero height starts a new column */
  864. else if (constraints.gridwidth == 0 && curCol < 0)
  865. curRow = curY + curHeight;
  866. }
  867. /*
  868. * Apply minimum row/column dimensions
  869. */
  870. if (columnWidths != null && r.width < columnWidths.length)
  871. r.width = columnWidths.length;
  872. if (rowHeights != null && r.height < rowHeights.length)
  873. r.height = rowHeights.length;
  874. /*
  875. * Pass #2
  876. *
  877. * Negative values for gridX are filled in with the current x value.
  878. * Negative values for gridY are filled in with the current y value.
  879. * Negative or zero values for gridWidth and gridHeight end the current
  880. * row or column, respectively.
  881. */
  882. curRow = curCol = -1;
  883. xMax = new int[MAXGRIDSIZE];
  884. yMax = new int[MAXGRIDSIZE];
  885. for (compindex = 0 ; compindex < components.length ; compindex++) {
  886. comp = components[compindex];
  887. if (!comp.isVisible())
  888. continue;
  889. constraints = lookupConstraints(comp);
  890. curX = constraints.gridx;
  891. curY = constraints.gridy;
  892. curWidth = constraints.gridwidth;
  893. curHeight = constraints.gridheight;
  894. /* If x or y is negative, then use relative positioning: */
  895. if (curX < 0 && curY < 0) {
  896. if(curRow >= 0)
  897. curY = curRow;
  898. else if(curCol >= 0)
  899. curX = curCol;
  900. else
  901. curY = 0;
  902. }
  903. if (curX < 0) {
  904. if (curHeight <= 0) {
  905. curHeight += r.height - curY;
  906. if (curHeight < 1)
  907. curHeight = 1;
  908. }
  909. px = 0;
  910. for (i = curY; i < (curY + curHeight); i++)
  911. px = Math.max(px, xMax[i]);
  912. curX = px - curX - 1;
  913. if(curX < 0)
  914. curX = 0;
  915. }
  916. else if (curY < 0) {
  917. if (curWidth <= 0) {
  918. curWidth += r.width - curX;
  919. if (curWidth < 1)
  920. curWidth = 1;
  921. }
  922. py = 0;
  923. for (i = curX; i < (curX + curWidth); i++)
  924. py = Math.max(py, yMax[i]);
  925. curY = py - curY - 1;
  926. if(curY < 0)
  927. curY = 0;
  928. }
  929. if (curWidth <= 0) {
  930. curWidth += r.width - curX;
  931. if (curWidth < 1)
  932. curWidth = 1;
  933. }
  934. if (curHeight <= 0) {
  935. curHeight += r.height - curY;
  936. if (curHeight < 1)
  937. curHeight = 1;
  938. }
  939. px = curX + curWidth;
  940. py = curY + curHeight;
  941. for (i = curX; i < (curX + curWidth); i++) { yMax[i] = py; }
  942. for (i = curY; i < (curY + curHeight); i++) { xMax[i] = px; }
  943. /* Make negative sizes start a new row/column */
  944. if (constraints.gridheight == 0 && constraints.gridwidth == 0)
  945. curRow = curCol = -1;
  946. if (constraints.gridheight == 0 && curRow < 0)
  947. curCol = curX + curWidth;
  948. else if (constraints.gridwidth == 0 && curCol < 0)
  949. curRow = curY + curHeight;
  950. /* Assign the new values to the gridbag slave */
  951. constraints.tempX = curX;
  952. constraints.tempY = curY;
  953. constraints.tempWidth = curWidth;
  954. constraints.tempHeight = curHeight;
  955. }
  956. /*
  957. * Apply minimum row/column dimensions and weights
  958. */
  959. if (columnWidths != null)
  960. System.arraycopy(columnWidths, 0, r.minWidth, 0, columnWidths.length);
  961. if (rowHeights != null)
  962. System.arraycopy(rowHeights, 0, r.minHeight, 0, rowHeights.length);
  963. if (columnWeights != null)
  964. System.arraycopy(columnWeights, 0, r.weightX, 0, Math.min(r.weightX.length, columnWeights.length));
  965. if (rowWeights != null)
  966. System.arraycopy(rowWeights, 0, r.weightY, 0, Math.min(r.weightY.length, rowWeights.length));
  967. /*
  968. * Pass #3
  969. *
  970. * Distribute the minimun widths and weights:
  971. */
  972. nextSize = Integer.MAX_VALUE;
  973. for (i = 1;
  974. i != Integer.MAX_VALUE;
  975. i = nextSize, nextSize = Integer.MAX_VALUE) {
  976. for (compindex = 0 ; compindex < components.length ; compindex++) {
  977. comp = components[compindex];
  978. if (!comp.isVisible())
  979. continue;
  980. constraints = lookupConstraints(comp);
  981. if (constraints.tempWidth == i) {
  982. px = constraints.tempX + constraints.tempWidth; /* right column */
  983. /*
  984. * Figure out if we should use this slave\'s weight. If the weight
  985. * is less than the total weight spanned by the width of the cell,
  986. * then discard the weight. Otherwise split the difference
  987. * according to the existing weights.
  988. */
  989. weight_diff = constraints.weightx;
  990. for (k = constraints.tempX; k < px; k++)
  991. weight_diff -= r.weightX[k];
  992. if (weight_diff > 0.0) {
  993. weight = 0.0;
  994. for (k = constraints.tempX; k < px; k++)
  995. weight += r.weightX[k];
  996. for (k = constraints.tempX; weight > 0.0 && k < px; k++) {
  997. double wt = r.weightX[k];
  998. double dx = (wt * weight_diff) / weight;
  999. r.weightX[k] += dx;
  1000. weight_diff -= dx;
  1001. weight -= wt;
  1002. }
  1003. /* Assign the remainder to the rightmost cell */
  1004. r.weightX[px-1] += weight_diff;
  1005. }
  1006. /*
  1007. * Calculate the minWidth array values.
  1008. * First, figure out how wide the current slave needs to be.
  1009. * Then, see if it will fit within the current minWidth values.
  1010. * If it will not fit, add the difference according to the
  1011. * weightX array.
  1012. */
  1013. pixels_diff =
  1014. constraints.minWidth + constraints.ipadx +
  1015. constraints.insets.left + constraints.insets.right;
  1016. for (k = constraints.tempX; k < px; k++)
  1017. pixels_diff -= r.minWidth[k];
  1018. if (pixels_diff > 0) {
  1019. weight = 0.0;
  1020. for (k = constraints.tempX; k < px; k++)
  1021. weight += r.weightX[k];
  1022. for (k = constraints.tempX; weight > 0.0 && k < px; k++) {
  1023. double wt = r.weightX[k];
  1024. int dx = (int)((wt * ((double)pixels_diff)) / weight);
  1025. r.minWidth[k] += dx;
  1026. pixels_diff -= dx;
  1027. weight -= wt;
  1028. }
  1029. /* Any leftovers go into the rightmost cell */
  1030. r.minWidth[px-1] += pixels_diff;
  1031. }
  1032. }
  1033. else if (constraints.tempWidth > i && constraints.tempWidth < nextSize)
  1034. nextSize = constraints.tempWidth;
  1035. if (constraints.tempHeight == i) {
  1036. py = constraints.tempY + constraints.tempHeight; /* bottom row */
  1037. /*
  1038. * Figure out if we should use this slave's weight. If the weight
  1039. * is less than the total weight spanned by the height of the cell,
  1040. * then discard the weight. Otherwise split it the difference
  1041. * according to the existing weights.
  1042. */
  1043. weight_diff = constraints.weighty;
  1044. for (k = constraints.tempY; k < py; k++)
  1045. weight_diff -= r.weightY[k];
  1046. if (weight_diff > 0.0) {
  1047. weight = 0.0;
  1048. for (k = constraints.tempY; k < py; k++)
  1049. weight += r.weightY[k];
  1050. for (k = constraints.tempY; weight > 0.0 && k < py; k++) {
  1051. double wt = r.weightY[k];
  1052. double dy = (wt * weight_diff) / weight;
  1053. r.weightY[k] += dy;
  1054. weight_diff -= dy;
  1055. weight -= wt;
  1056. }
  1057. /* Assign the remainder to the bottom cell */
  1058. r.weightY[py-1] += weight_diff;
  1059. }
  1060. /*
  1061. * Calculate the minHeight array values.
  1062. * First, figure out how tall the current slave needs to be.
  1063. * Then, see if it will fit within the current minHeight values.
  1064. * If it will not fit, add the difference according to the
  1065. * weightY array.
  1066. */
  1067. pixels_diff =
  1068. constraints.minHeight + constraints.ipady +
  1069. constraints.insets.top + constraints.insets.bottom;
  1070. for (k = constraints.tempY; k < py; k++)
  1071. pixels_diff -= r.minHeight[k];
  1072. if (pixels_diff > 0) {
  1073. weight = 0.0;
  1074. for (k = constraints.tempY; k < py; k++)
  1075. weight += r.weightY[k];
  1076. for (k = constraints.tempY; weight > 0.0 && k < py; k++) {
  1077. double wt = r.weightY[k];
  1078. int dy = (int)((wt * ((double)pixels_diff)) / weight);
  1079. r.minHeight[k] += dy;
  1080. pixels_diff -= dy;
  1081. weight -= wt;
  1082. }
  1083. /* Any leftovers go into the bottom cell */
  1084. r.minHeight[py-1] += pixels_diff;
  1085. }
  1086. }
  1087. else if (constraints.tempHeight > i &&
  1088. constraints.tempHeight < nextSize)
  1089. nextSize = constraints.tempHeight;
  1090. }
  1091. }
  1092. return r;
  1093. }
  1094. }
  1095. /**
  1096. * Adjusts the x, y, width, and height fields to the correct
  1097. * values depending on the constraint geometry and pads.
  1098. * This method should only be used internally by
  1099. * <code>GridBagLayout</code>.
  1100. *
  1101. * @param constraints the constraints to be applied
  1102. * @param r the <code>Rectangle</code> to be adjusted
  1103. * @since 1.4
  1104. */
  1105. protected void adjustForGravity(GridBagConstraints constraints,
  1106. Rectangle r) {
  1107. AdjustForGravity(constraints, r);
  1108. }
  1109. /**
  1110. * This method is obsolete and supplied for backwards
  1111. * compatability only; new code should call {@link
  1112. * #adjustForGravity(java.awt.GridBagConstraints, java.awt.Rectangle)
  1113. * adjustForGravity} instead.
  1114. * This method is the same as <code>adjustForGravity</code>
  1115. * refer to <code>adjustForGravity</code> for details
  1116. * on parameters.
  1117. */
  1118. protected void AdjustForGravity(GridBagConstraints constraints,
  1119. Rectangle r) {
  1120. int diffx, diffy;
  1121. if (!rightToLeft) {
  1122. r.x += constraints.insets.left;
  1123. } else {
  1124. r.x -= r.width - constraints.insets.right;
  1125. }
  1126. r.width -= (constraints.insets.left + constraints.insets.right);
  1127. r.y += constraints.insets.top;
  1128. r.height -= (constraints.insets.top + constraints.insets.bottom);
  1129. diffx = 0;
  1130. if ((constraints.fill != GridBagConstraints.HORIZONTAL &&
  1131. constraints.fill != GridBagConstraints.BOTH)
  1132. && (r.width > (constraints.minWidth + constraints.ipadx))) {
  1133. diffx = r.width - (constraints.minWidth + constraints.ipadx);
  1134. r.width = constraints.minWidth + constraints.ipadx;
  1135. }
  1136. diffy = 0;
  1137. if ((constraints.fill != GridBagConstraints.VERTICAL &&
  1138. constraints.fill != GridBagConstraints.BOTH)
  1139. && (r.height > (constraints.minHeight + constraints.ipady))) {
  1140. diffy = r.height - (constraints.minHeight + constraints.ipady);
  1141. r.height = constraints.minHeight + constraints.ipady;
  1142. }
  1143. switch (constraints.anchor) {
  1144. case GridBagConstraints.CENTER:
  1145. r.x += diffx2;
  1146. r.y += diffy2;
  1147. break;
  1148. case GridBagConstraints.PAGE_START:
  1149. case GridBagConstraints.NORTH:
  1150. r.x += diffx2;
  1151. break;
  1152. case GridBagConstraints.NORTHEAST:
  1153. r.x += diffx;
  1154. break;
  1155. case GridBagConstraints.EAST:
  1156. r.x += diffx;
  1157. r.y += diffy2;
  1158. break;
  1159. case GridBagConstraints.SOUTHEAST:
  1160. r.x += diffx;
  1161. r.y += diffy;
  1162. break;
  1163. case GridBagConstraints.PAGE_END:
  1164. case GridBagConstraints.SOUTH:
  1165. r.x += diffx2;
  1166. r.y += diffy;
  1167. break;
  1168. case GridBagConstraints.SOUTHWEST:
  1169. r.y += diffy;
  1170. break;
  1171. case GridBagConstraints.WEST:
  1172. r.y += diffy2;
  1173. break;
  1174. case GridBagConstraints.NORTHWEST:
  1175. break;
  1176. case GridBagConstraints.LINE_START:
  1177. if (rightToLeft) {
  1178. r.x += diffx;
  1179. }
  1180. r.y += diffy2;
  1181. break;
  1182. case GridBagConstraints.LINE_END:
  1183. if (!rightToLeft) {
  1184. r.x += diffx;
  1185. }
  1186. r.y += diffy2;
  1187. break;
  1188. case GridBagConstraints.FIRST_LINE_START:
  1189. if (rightToLeft) {
  1190. r.x += diffx;
  1191. }
  1192. break;
  1193. case GridBagConstraints.FIRST_LINE_END:
  1194. if (!rightToLeft) {
  1195. r.x += diffx;
  1196. }
  1197. break;
  1198. case GridBagConstraints.LAST_LINE_START:
  1199. if (rightToLeft) {
  1200. r.x += diffx;
  1201. }
  1202. r.y += diffy;
  1203. break;
  1204. case GridBagConstraints.LAST_LINE_END:
  1205. if (!rightToLeft) {
  1206. r.x += diffx;
  1207. }
  1208. r.y += diffy;
  1209. break;
  1210. default:
  1211. throw new IllegalArgumentException("illegal anchor value");
  1212. }
  1213. }
  1214. /**
  1215. * Figures out the minimum size of the
  1216. * master based on the information from <code>getLayoutInfo</code>.
  1217. * This method should only be used internally by
  1218. * <code>GridBagLayout</code>.
  1219. *
  1220. * @param parent the layout container
  1221. * @param info the layout info for this parent
  1222. * @return a <code>Dimension</code> object containing the
  1223. * minimum size
  1224. * @since 1.4
  1225. */
  1226. protected Dimension getMinSize(Container parent, GridBagLayoutInfo info) {
  1227. return GetMinSize(parent, info);
  1228. }
  1229. /**
  1230. * This method is obsolete and supplied for backwards
  1231. * compatability only; new code should call {@link
  1232. * #getMinSize(java.awt.Container, GridBagLayoutInfo) getMinSize} instead.
  1233. * This method is the same as <code>getMinSize</code>
  1234. * refer to <code>getMinSize</code> for details on parameters
  1235. * and return value.
  1236. */
  1237. protected Dimension GetMinSize(Container parent, GridBagLayoutInfo info) {
  1238. Dimension d = new Dimension();
  1239. int i, t;
  1240. Insets insets = parent.getInsets();
  1241. t = 0;
  1242. for(i = 0; i < info.width; i++)
  1243. t += info.minWidth[i];
  1244. d.width = t + insets.left + insets.right;
  1245. t = 0;
  1246. for(i = 0; i < info.height; i++)
  1247. t += info.minHeight[i];
  1248. d.height = t + insets.top + insets.bottom;
  1249. return d;
  1250. }
  1251. transient boolean rightToLeft = false;
  1252. /**
  1253. * Lays out the grid.
  1254. * This method should only be used internally by
  1255. * <code>GridBagLayout</code>.
  1256. *
  1257. * @param parent the layout container
  1258. * @since 1.4
  1259. */
  1260. protected void arrangeGrid(Container parent) {
  1261. ArrangeGrid(parent);
  1262. }
  1263. /**
  1264. * This method is obsolete and supplied for backwards
  1265. * compatability only; new code should call {@link
  1266. * #arrangeGrid(Container) arrangeGrid} instead.
  1267. * This method is the same as <code>arrangeGrid</code>
  1268. * refer to <code>arrangeGrid</code> for details on the
  1269. * parameter.
  1270. */
  1271. protected void ArrangeGrid(Container parent) {
  1272. Component comp;
  1273. int compindex;
  1274. GridBagConstraints constraints;
  1275. Insets insets = parent.getInsets();
  1276. Component components[] = parent.getComponents();
  1277. Dimension d;
  1278. Rectangle r = new Rectangle();
  1279. int i, diffw, diffh;
  1280. double weight;
  1281. GridBagLayoutInfo info;
  1282. rightToLeft = !parent.getComponentOrientation().isLeftToRight();
  1283. /*
  1284. * If the parent has no slaves anymore, then don't do anything
  1285. * at all: just leave the parent's size as-is.
  1286. */
  1287. if (components.length == 0 &&
  1288. (columnWidths == null || columnWidths.length == 0) &&
  1289. (rowHeights == null || rowHeights.length == 0)) {
  1290. return;
  1291. }
  1292. /*
  1293. * Pass #1: scan all the slaves to figure out the total amount
  1294. * of space needed.
  1295. */
  1296. info = getLayoutInfo(parent, PREFERREDSIZE);
  1297. d = getMinSize(parent, info);
  1298. if (parent.width < d.width || parent.height < d.height) {
  1299. info = getLayoutInfo(parent, MINSIZE);
  1300. d = getMinSize(parent, info);
  1301. }
  1302. layoutInfo = info;
  1303. r.width = d.width;
  1304. r.height = d.height;
  1305. /*
  1306. * DEBUG
  1307. *
  1308. * DumpLayoutInfo(info);
  1309. * for (compindex = 0 ; compindex < components.length ; compindex++) {
  1310. * comp = components[compindex];
  1311. * if (!comp.isVisible())
  1312. * continue;
  1313. * constraints = lookupConstraints(comp);
  1314. * DumpConstraints(constraints);
  1315. * }
  1316. * System.out.println("minSize " + r.width + " " + r.height);
  1317. */
  1318. /*
  1319. * If the current dimensions of the window don't match the desired
  1320. * dimensions, then adjust the minWidth and minHeight arrays
  1321. * according to the weights.
  1322. */
  1323. diffw = parent.width - r.width;
  1324. if (diffw != 0) {
  1325. weight = 0.0;
  1326. for (i = 0; i < info.width; i++)
  1327. weight += info.weightX[i];
  1328. if (weight > 0.0) {
  1329. for (i = 0; i < info.width; i++) {
  1330. int dx = (int)(( ((double)diffw) * info.weightX[i]) / weight);
  1331. info.minWidth[i] += dx;
  1332. r.width += dx;
  1333. if (info.minWidth[i] < 0) {
  1334. r.width -= info.minWidth[i];
  1335. info.minWidth[i] = 0;
  1336. }
  1337. }
  1338. }
  1339. diffw = parent.width - r.width;
  1340. }
  1341. else {
  1342. diffw = 0;
  1343. }
  1344. diffh = parent.height - r.height;
  1345. if (diffh != 0) {
  1346. weight = 0.0;
  1347. for (i = 0; i < info.height; i++)
  1348. weight += info.weightY[i];
  1349. if (weight > 0.0) {
  1350. for (i = 0; i < info.height; i++) {
  1351. int dy = (int)(( ((double)diffh) * info.weightY[i]) / weight);
  1352. info.minHeight[i] += dy;
  1353. r.height += dy;
  1354. if (info.minHeight[i] < 0) {
  1355. r.height -= info.minHeight[i];
  1356. info.minHeight[i] = 0;
  1357. }
  1358. }
  1359. }
  1360. diffh = parent.height - r.height;
  1361. }
  1362. else {
  1363. diffh = 0;
  1364. }
  1365. /*
  1366. * DEBUG
  1367. *
  1368. * System.out.println("Re-adjusted:");
  1369. * DumpLayoutInfo(info);
  1370. */
  1371. /*
  1372. * Now do the actual layout of the slaves using the layout information
  1373. * that has been collected.
  1374. */
  1375. info.startx = diffw2 + insets.left;
  1376. info.starty = diffh2 + insets.top;
  1377. for (compindex = 0 ; compindex < components.length ; compindex++) {
  1378. comp = components[compindex];
  1379. if (!comp.isVisible())
  1380. continue;
  1381. constraints = lookupConstraints(comp);
  1382. if (!rightToLeft) {
  1383. r.x = info.startx;
  1384. for(i = 0; i < constraints.tempX; i++)
  1385. r.x += info.minWidth[i];
  1386. } else {
  1387. r.x = parent.width - (diffw2 + insets.right);
  1388. for(i = 0; i < constraints.tempX; i++)
  1389. r.x -= info.minWidth[i];
  1390. }
  1391. r.y = info.starty;
  1392. for(i = 0; i < constraints.tempY; i++)
  1393. r.y += info.minHeight[i];
  1394. r.width = 0;
  1395. for(i = constraints.tempX;
  1396. i < (constraints.tempX + constraints.tempWidth);
  1397. i++) {
  1398. r.width += info.minWidth[i];
  1399. }
  1400. r.height = 0;
  1401. for(i = constraints.tempY;
  1402. i < (constraints.tempY + constraints.tempHeight);
  1403. i++) {
  1404. r.height += info.minHeight[i];
  1405. }
  1406. adjustForGravity(constraints, r);
  1407. /* fix for 4408108 - components were being created outside of the container */
  1408. /* fix for 4969409 "-" replaced by "+" */
  1409. if (r.x < 0) {
  1410. r.width += r.x;
  1411. r.x = 0;
  1412. }
  1413. if (r.y < 0) {
  1414. r.height += r.y;
  1415. r.y = 0;
  1416. }
  1417. /*
  1418. * If the window is too small to be interesting then
  1419. * unmap it. Otherwise configure it and then make sure
  1420. * it's mapped.
  1421. */
  1422. if ((r.width <= 0) || (r.height <= 0)) {
  1423. comp.setBounds(0, 0, 0, 0);
  1424. }
  1425. else {
  1426. if (comp.x != r.x || comp.y != r.y ||
  1427. comp.width != r.width || comp.height != r.height) {
  1428. comp.setBounds(r.x, r.y, r.width, r.height);
  1429. }
  1430. }
  1431. }
  1432. }
  1433. // Added for serial backwards compatability (4348425)
  1434. static final long serialVersionUID = 8838754796412211005L;
  1435. }