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