1. /*
  2. * @(#)BorderLayout.java 1.56 04/05/18
  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. /**
  10. * A border layout lays out a container, arranging and resizing
  11. * its components to fit in five regions:
  12. * north, south, east, west, and center.
  13. * Each region may contain no more than one component, and
  14. * is identified by a corresponding constant:
  15. * <code>NORTH</code>, <code>SOUTH</code>, <code>EAST</code>,
  16. * <code>WEST</code>, and <code>CENTER</code>. When adding a
  17. * component to a container with a border layout, use one of these
  18. * five constants, for example:
  19. * <pre>
  20. * Panel p = new Panel();
  21. * p.setLayout(new BorderLayout());
  22. * p.add(new Button("Okay"), BorderLayout.SOUTH);
  23. * </pre>
  24. * As a convenience, <code>BorderLayout</code> interprets the
  25. * absence of a string specification the same as the constant
  26. * <code>CENTER</code>:
  27. * <pre>
  28. * Panel p2 = new Panel();
  29. * p2.setLayout(new BorderLayout());
  30. * p2.add(new TextArea()); // Same as p.add(new TextArea(), BorderLayout.CENTER);
  31. * </pre>
  32. * <p>
  33. * In addition, <code>BorderLayout</code> supports the relative
  34. * positioning constants, <code>PAGE_START</code>, <code>PAGE_END</code>,
  35. * <code>LINE_START</code>, and <code>LINE_END</code>.
  36. * In a container whose <code>ComponentOrientation</code> is set to
  37. * <code>ComponentOrientation.LEFT_TO_RIGHT</code>, these constants map to
  38. * <code>NORTH</code>, <code>SOUTH</code>, <code>WEST</code>, and
  39. * <code>EAST</code>, respectively.
  40. * <p>
  41. * For compatibility with previous releases, <code>BorderLayout</code>
  42. * also includes the relative positioning constants <code>BEFORE_FIRST_LINE</code>,
  43. * <code>AFTER_LAST_LINE</code>, <code>BEFORE_LINE_BEGINS</code> and
  44. * <code>AFTER_LINE_ENDS</code>. These are equivalent to
  45. * <code>PAGE_START</code>, <code>PAGE_END</code>, <code>LINE_START</code>
  46. * and <code>LINE_END</code> respectively. For
  47. * consistency with the relative positioning constants used by other
  48. * components, the latter constants are preferred.
  49. * <p>
  50. * Mixing both absolute and relative positioning constants can lead to
  51. * unpredicable results. If
  52. * you use both types, the relative constants will take precedence.
  53. * For example, if you add components using both the <code>NORTH</code>
  54. * and <code>PAGE_START</code> constants in a container whose
  55. * orientation is <code>LEFT_TO_RIGHT</code>, only the
  56. * <code>PAGE_START</code> will be layed out.
  57. * <p>
  58. * NOTE: Currently (in the Java 2 platform v1.2),
  59. * <code>BorderLayout</code> does not support vertical
  60. * orientations. The <code>isVertical</code> setting on the container's
  61. * <code>ComponentOrientation</code> is not respected.
  62. * <p>
  63. * The components are laid out according to their
  64. * preferred sizes and the constraints of the container's size.
  65. * The <code>NORTH</code> and <code>SOUTH</code> components may
  66. * be stretched horizontally; the <code>EAST</code> and
  67. * <code>WEST</code> components may be stretched vertically;
  68. * the <code>CENTER</code> component may stretch both horizontally
  69. * and vertically to fill any space left over.
  70. * <p>
  71. * Here is an example of five buttons in an applet laid out using
  72. * the <code>BorderLayout</code> layout manager:
  73. * <p>
  74. * <img src="doc-files/BorderLayout-1.gif"
  75. * alt="Diagram of an applet demonstrating BorderLayout.
  76. * Each section of the BorderLayout contains a Button corresponding to its position in the layout, one of:
  77. * North, West, Center, East, or South."
  78. * ALIGN=center HSPACE=10 VSPACE=7>
  79. * <p>
  80. * The code for this applet is as follows:
  81. * <p>
  82. * <hr><blockquote><pre>
  83. * import java.awt.*;
  84. * import java.applet.Applet;
  85. *
  86. * public class buttonDir extends Applet {
  87. * public void init() {
  88. * setLayout(new BorderLayout());
  89. * add(new Button("North"), BorderLayout.NORTH);
  90. * add(new Button("South"), BorderLayout.SOUTH);
  91. * add(new Button("East"), BorderLayout.EAST);
  92. * add(new Button("West"), BorderLayout.WEST);
  93. * add(new Button("Center"), BorderLayout.CENTER);
  94. * }
  95. * }
  96. * </pre></blockquote><hr>
  97. * <p>
  98. * @version 1.56, 05/18/04
  99. * @author Arthur van Hoff
  100. * @see java.awt.Container#add(String, Component)
  101. * @see java.awt.ComponentOrientation
  102. * @since JDK1.0
  103. */
  104. public class BorderLayout implements LayoutManager2,
  105. java.io.Serializable {
  106. /**
  107. * Constructs a border layout with the horizontal gaps
  108. * between components.
  109. * The horizontal gap is specified by <code>hgap</code>.
  110. *
  111. * @see #getHgap()
  112. * @see #setHgap(int)
  113. *
  114. * @serial
  115. */
  116. int hgap;
  117. /**
  118. * Constructs a border layout with the vertical gaps
  119. * between components.
  120. * The vertical gap is specified by <code>vgap</code>.
  121. *
  122. * @see #getVgap()
  123. * @see #setVgap(int)
  124. * @serial
  125. */
  126. int vgap;
  127. /**
  128. * Constant to specify components location to be the
  129. * north portion of the border layout.
  130. * @serial
  131. * @see #getChild(String, boolean)
  132. * @see #addLayoutComponent
  133. * @see #getLayoutAlignmentX
  134. * @see #getLayoutAlignmentY
  135. * @see #removeLayoutComponent
  136. */
  137. Component north;
  138. /**
  139. * Constant to specify components location to be the
  140. * west portion of the border layout.
  141. * @serial
  142. * @see #getChild(String, boolean)
  143. * @see #addLayoutComponent
  144. * @see #getLayoutAlignmentX
  145. * @see #getLayoutAlignmentY
  146. * @see #removeLayoutComponent
  147. */
  148. Component west;
  149. /**
  150. * Constant to specify components location to be the
  151. * east portion of the border layout.
  152. * @serial
  153. * @see #getChild(String, boolean)
  154. * @see #addLayoutComponent
  155. * @see #getLayoutAlignmentX
  156. * @see #getLayoutAlignmentY
  157. * @see #removeLayoutComponent
  158. */
  159. Component east;
  160. /**
  161. * Constant to specify components location to be the
  162. * south portion of the border layout.
  163. * @serial
  164. * @see #getChild(String, boolean)
  165. * @see #addLayoutComponent
  166. * @see #getLayoutAlignmentX
  167. * @see #getLayoutAlignmentY
  168. * @see #removeLayoutComponent
  169. */
  170. Component south;
  171. /**
  172. * Constant to specify components location to be the
  173. * center portion of the border layout.
  174. * @serial
  175. * @see #getChild(String, boolean)
  176. * @see #addLayoutComponent
  177. * @see #getLayoutAlignmentX
  178. * @see #getLayoutAlignmentY
  179. * @see #removeLayoutComponent
  180. */
  181. Component center;
  182. /**
  183. *
  184. * A relative positioning constant, that can be used instead of
  185. * north, south, east, west or center.
  186. * mixing the two types of constants can lead to unpredicable results. If
  187. * you use both types, the relative constants will take precedence.
  188. * For example, if you add components using both the <code>NORTH</code>
  189. * and <code>BEFORE_FIRST_LINE</code> constants in a container whose
  190. * orientation is <code>LEFT_TO_RIGHT</code>, only the
  191. * <code>BEFORE_FIRST_LINE</code> will be layed out.
  192. * This will be the same for lastLine, firstItem, lastItem.
  193. * @serial
  194. */
  195. Component firstLine;
  196. /**
  197. * A relative positioning constant, that can be used instead of
  198. * north, south, east, west or center.
  199. * Please read Description for firstLine.
  200. * @serial
  201. */
  202. Component lastLine;
  203. /**
  204. * A relative positioning constant, that can be used instead of
  205. * north, south, east, west or center.
  206. * Please read Description for firstLine.
  207. * @serial
  208. */
  209. Component firstItem;
  210. /**
  211. * A relative positioning constant, that can be used instead of
  212. * north, south, east, west or center.
  213. * Please read Description for firstLine.
  214. * @serial
  215. */
  216. Component lastItem;
  217. /**
  218. * The north layout constraint (top of container).
  219. */
  220. public static final String NORTH = "North";
  221. /**
  222. * The south layout constraint (bottom of container).
  223. */
  224. public static final String SOUTH = "South";
  225. /**
  226. * The east layout constraint (right side of container).
  227. */
  228. public static final String EAST = "East";
  229. /**
  230. * The west layout constraint (left side of container).
  231. */
  232. public static final String WEST = "West";
  233. /**
  234. * The center layout constraint (middle of container).
  235. */
  236. public static final String CENTER = "Center";
  237. /**
  238. * Synonym for PAGE_START. Exists for compatibility with previous
  239. * versions. PAGE_START is preferred.
  240. *
  241. * @see #PAGE_START
  242. * @since 1.2
  243. */
  244. public static final String BEFORE_FIRST_LINE = "First";
  245. /**
  246. * Synonym for PAGE_END. Exists for compatibility with previous
  247. * versions. PAGE_END is preferred.
  248. *
  249. * @see #PAGE_END
  250. * @since 1.2
  251. */
  252. public static final String AFTER_LAST_LINE = "Last";
  253. /**
  254. * Synonym for LINE_START. Exists for compatibility with previous
  255. * versions. LINE_START is preferred.
  256. *
  257. * @see #LINE_START
  258. * @since 1.2
  259. */
  260. public static final String BEFORE_LINE_BEGINS = "Before";
  261. /**
  262. * Synonym for LINE_END. Exists for compatibility with previous
  263. * versions. LINE_END is preferred.
  264. *
  265. * @see #LINE_END
  266. * @since 1.2
  267. */
  268. public static final String AFTER_LINE_ENDS = "After";
  269. /**
  270. * The component comes before the first line of the layout's content.
  271. * For Western, left-to-right and top-to-bottom orientations, this is
  272. * equivalent to NORTH.
  273. *
  274. * @see java.awt.Component#getComponentOrientation
  275. * @since 1.4
  276. */
  277. public static final String PAGE_START = BEFORE_FIRST_LINE;
  278. /**
  279. * The component comes after the last line of the layout's content.
  280. * For Western, left-to-right and top-to-bottom orientations, this is
  281. * equivalent to SOUTH.
  282. *
  283. * @see java.awt.Component#getComponentOrientation
  284. * @since 1.4
  285. */
  286. public static final String PAGE_END = AFTER_LAST_LINE;
  287. /**
  288. * The component goes at the beginning of the line direction for the
  289. * layout. For Western, left-to-right and top-to-bottom orientations,
  290. * this is equivalent to WEST.
  291. *
  292. * @see java.awt.Component#getComponentOrientation
  293. * @since 1.4
  294. */
  295. public static final String LINE_START = BEFORE_LINE_BEGINS;
  296. /**
  297. * The component goes at the end of the line direction for the
  298. * layout. For Western, left-to-right and top-to-bottom orientations,
  299. * this is equivalent to EAST.
  300. *
  301. * @see java.awt.Component#getComponentOrientation
  302. * @since 1.4
  303. */
  304. public static final String LINE_END = AFTER_LINE_ENDS;
  305. /*
  306. * JDK 1.1 serialVersionUID
  307. */
  308. private static final long serialVersionUID = -8658291919501921765L;
  309. /**
  310. * Constructs a new border layout with
  311. * no gaps between components.
  312. */
  313. public BorderLayout() {
  314. this(0, 0);
  315. }
  316. /**
  317. * Constructs a border layout with the specified gaps
  318. * between components.
  319. * The horizontal gap is specified by <code>hgap</code>
  320. * and the vertical gap is specified by <code>vgap</code>.
  321. * @param hgap the horizontal gap.
  322. * @param vgap the vertical gap.
  323. */
  324. public BorderLayout(int hgap, int vgap) {
  325. this.hgap = hgap;
  326. this.vgap = vgap;
  327. }
  328. /**
  329. * Returns the horizontal gap between components.
  330. * @since JDK1.1
  331. */
  332. public int getHgap() {
  333. return hgap;
  334. }
  335. /**
  336. * Sets the horizontal gap between components.
  337. * @param hgap the horizontal gap between components
  338. * @since JDK1.1
  339. */
  340. public void setHgap(int hgap) {
  341. this.hgap = hgap;
  342. }
  343. /**
  344. * Returns the vertical gap between components.
  345. * @since JDK1.1
  346. */
  347. public int getVgap() {
  348. return vgap;
  349. }
  350. /**
  351. * Sets the vertical gap between components.
  352. * @param vgap the vertical gap between components
  353. * @since JDK1.1
  354. */
  355. public void setVgap(int vgap) {
  356. this.vgap = vgap;
  357. }
  358. /**
  359. * Adds the specified component to the layout, using the specified
  360. * constraint object. For border layouts, the constraint must be
  361. * one of the following constants: <code>NORTH</code>,
  362. * <code>SOUTH</code>, <code>EAST</code>,
  363. * <code>WEST</code>, or <code>CENTER</code>.
  364. * <p>
  365. * Most applications do not call this method directly. This method
  366. * is called when a component is added to a container using the
  367. * <code>Container.add</code> method with the same argument types.
  368. * @param comp the component to be added.
  369. * @param constraints an object that specifies how and where
  370. * the component is added to the layout.
  371. * @see java.awt.Container#add(java.awt.Component, java.lang.Object)
  372. * @exception IllegalArgumentException if the constraint object is not
  373. * a string, or if it not one of the five specified
  374. * constants.
  375. * @since JDK1.1
  376. */
  377. public void addLayoutComponent(Component comp, Object constraints) {
  378. synchronized (comp.getTreeLock()) {
  379. if ((constraints == null) || (constraints instanceof String)) {
  380. addLayoutComponent((String)constraints, comp);
  381. } else {
  382. throw new IllegalArgumentException("cannot add to layout: constraint must be a string (or null)");
  383. }
  384. }
  385. }
  386. /**
  387. * @deprecated replaced by <code>addLayoutComponent(Component, Object)</code>.
  388. */
  389. @Deprecated
  390. public void addLayoutComponent(String name, Component comp) {
  391. synchronized (comp.getTreeLock()) {
  392. /* Special case: treat null the same as "Center". */
  393. if (name == null) {
  394. name = "Center";
  395. }
  396. /* Assign the component to one of the known regions of the layout.
  397. */
  398. if ("Center".equals(name)) {
  399. center = comp;
  400. } else if ("North".equals(name)) {
  401. north = comp;
  402. } else if ("South".equals(name)) {
  403. south = comp;
  404. } else if ("East".equals(name)) {
  405. east = comp;
  406. } else if ("West".equals(name)) {
  407. west = comp;
  408. } else if (BEFORE_FIRST_LINE.equals(name)) {
  409. firstLine = comp;
  410. } else if (AFTER_LAST_LINE.equals(name)) {
  411. lastLine = comp;
  412. } else if (BEFORE_LINE_BEGINS.equals(name)) {
  413. firstItem = comp;
  414. } else if (AFTER_LINE_ENDS.equals(name)) {
  415. lastItem = comp;
  416. } else {
  417. throw new IllegalArgumentException("cannot add to layout: unknown constraint: " + name);
  418. }
  419. }
  420. }
  421. /**
  422. * Removes the specified component from this border layout. This
  423. * method is called when a container calls its <code>remove</code> or
  424. * <code>removeAll</code> methods. Most applications do not call this
  425. * method directly.
  426. * @param comp the component to be removed.
  427. * @see java.awt.Container#remove(java.awt.Component)
  428. * @see java.awt.Container#removeAll()
  429. */
  430. public void removeLayoutComponent(Component comp) {
  431. synchronized (comp.getTreeLock()) {
  432. if (comp == center) {
  433. center = null;
  434. } else if (comp == north) {
  435. north = null;
  436. } else if (comp == south) {
  437. south = null;
  438. } else if (comp == east) {
  439. east = null;
  440. } else if (comp == west) {
  441. west = null;
  442. }
  443. if (comp == firstLine) {
  444. firstLine = null;
  445. } else if (comp == lastLine) {
  446. lastLine = null;
  447. } else if (comp == firstItem) {
  448. firstItem = null;
  449. } else if (comp == lastItem) {
  450. lastItem = null;
  451. }
  452. }
  453. }
  454. /**
  455. * Gets the component that was added using the given constraint
  456. *
  457. * @param constraints the desired constraint, one of <code>CENTER</code>,
  458. * <code>NORTH</code>, <code>SOUTH</code>,
  459. * <code>WEST</code>, <code>EAST</code>,
  460. * <code>PAGE_START</code>, <code>PAGE_END</code>,
  461. * <code>LINE_START</code>, <code>LINE_END</code>
  462. * @return the component at the given location, or </code>null</code> if
  463. * the location is empty
  464. * @exception IllegalArgumentException if the constraint object is
  465. * not one of the nine specified constants
  466. * @see #addLayoutComponent(java.awt.Component, java.lang.Object)
  467. * @since 1.5
  468. */
  469. public Component getLayoutComponent(Object constraints) {
  470. if (CENTER.equals(constraints)) {
  471. return center;
  472. } else if (NORTH.equals(constraints)) {
  473. return north;
  474. } else if (SOUTH.equals(constraints)) {
  475. return south;
  476. } else if (WEST.equals(constraints)) {
  477. return west;
  478. } else if (EAST.equals(constraints)) {
  479. return east;
  480. } else if (PAGE_START.equals(constraints)) {
  481. return firstLine;
  482. } else if (PAGE_END.equals(constraints)) {
  483. return lastLine;
  484. } else if (LINE_START.equals(constraints)) {
  485. return firstItem;
  486. } else if (LINE_END.equals(constraints)) {
  487. return lastItem;
  488. } else {
  489. throw new IllegalArgumentException("cannot get component: unknown constraint: " + constraints);
  490. }
  491. }
  492. /**
  493. * Gets the component that corresponds to the given constraint location
  494. * based on the target Container's component orientation
  495. *
  496. * @param constraints the desired absolute position, one of <code>CENTER</code>,
  497. * one of <code>NORTH</code>, <code>SOUTH</code>,
  498. * <code>EAST</code>, <code>WEST</code>
  499. * @param target the <code>Container</code> using this <code>BorderLayout</code>
  500. * @return the component at the given location, or </code>null</code> if
  501. * the location is empty
  502. * @exception IllegalArgumentException if the constraint object is
  503. * not one of the five specified constants
  504. * @exception NullPointerException if the target parameter is null
  505. * @see #addLayoutComponent(java.awt.Component, java.lang.Object)
  506. * @since 1.5
  507. */
  508. public Component getLayoutComponent(Container target, Object constraints) {
  509. boolean ltr = target.getComponentOrientation().isLeftToRight();
  510. Component result = null;
  511. if (NORTH.equals(constraints)) {
  512. result = (firstLine != null) ? firstLine : north;
  513. } else if (SOUTH.equals(constraints)) {
  514. result = (lastLine != null) ? lastLine : south;
  515. } else if (WEST.equals(constraints)) {
  516. result = ltr ? firstItem : lastItem;
  517. if (result == null) {
  518. result = west;
  519. }
  520. } else if (EAST.equals(constraints)) {
  521. result = ltr ? lastItem : firstItem;
  522. if (result == null) {
  523. result = east;
  524. }
  525. } else if (CENTER.equals(constraints)) {
  526. result = center;
  527. } else {
  528. throw new IllegalArgumentException("cannot get component: invalid constraint: " + constraints);
  529. }
  530. return result;
  531. }
  532. /**
  533. * Gets the constraints for the specified component
  534. *
  535. * @param comp the component to be queried
  536. * @return the constraint for the specified component,
  537. * or null if component is null or is not present
  538. * in this layout
  539. * @see #addLayoutComponent(java.awt.Component, java.lang.Object)
  540. * @since 1.5
  541. */
  542. public Object getConstraints(Component comp) {
  543. if (comp == center) {
  544. return CENTER;
  545. } else if (comp == north) {
  546. return NORTH;
  547. } else if (comp == south) {
  548. return SOUTH;
  549. } else if (comp == west) {
  550. return WEST;
  551. } else if (comp == east) {
  552. return EAST;
  553. } else if (comp == firstLine) {
  554. return PAGE_START;
  555. } else if (comp == lastLine) {
  556. return PAGE_END;
  557. } else if (comp == firstItem) {
  558. return LINE_START;
  559. } else if (comp == lastItem) {
  560. return LINE_END;
  561. }
  562. return null;
  563. }
  564. /**
  565. * Determines the minimum size of the <code>target</code> container
  566. * using this layout manager.
  567. * <p>
  568. * This method is called when a container calls its
  569. * <code>getMinimumSize</code> method. Most applications do not call
  570. * this method directly.
  571. * @param target the container in which to do the layout.
  572. * @return the minimum dimensions needed to lay out the subcomponents
  573. * of the specified container.
  574. * @see java.awt.Container
  575. * @see java.awt.BorderLayout#preferredLayoutSize
  576. * @see java.awt.Container#getMinimumSize()
  577. */
  578. public Dimension minimumLayoutSize(Container target) {
  579. synchronized (target.getTreeLock()) {
  580. Dimension dim = new Dimension(0, 0);
  581. boolean ltr = target.getComponentOrientation().isLeftToRight();
  582. Component c = null;
  583. if ((c=getChild(EAST,ltr)) != null) {
  584. Dimension d = c.getMinimumSize();
  585. dim.width += d.width + hgap;
  586. dim.height = Math.max(d.height, dim.height);
  587. }
  588. if ((c=getChild(WEST,ltr)) != null) {
  589. Dimension d = c.getMinimumSize();
  590. dim.width += d.width + hgap;
  591. dim.height = Math.max(d.height, dim.height);
  592. }
  593. if ((c=getChild(CENTER,ltr)) != null) {
  594. Dimension d = c.getMinimumSize();
  595. dim.width += d.width;
  596. dim.height = Math.max(d.height, dim.height);
  597. }
  598. if ((c=getChild(NORTH,ltr)) != null) {
  599. Dimension d = c.getMinimumSize();
  600. dim.width = Math.max(d.width, dim.width);
  601. dim.height += d.height + vgap;
  602. }
  603. if ((c=getChild(SOUTH,ltr)) != null) {
  604. Dimension d = c.getMinimumSize();
  605. dim.width = Math.max(d.width, dim.width);
  606. dim.height += d.height + vgap;
  607. }
  608. Insets insets = target.getInsets();
  609. dim.width += insets.left + insets.right;
  610. dim.height += insets.top + insets.bottom;
  611. return dim;
  612. }
  613. }
  614. /**
  615. * Determines the preferred size of the <code>target</code>
  616. * container using this layout manager, based on the components
  617. * in the container.
  618. * <p>
  619. * Most applications do not call this method directly. This method
  620. * is called when a container calls its <code>getPreferredSize</code>
  621. * method.
  622. * @param target the container in which to do the layout.
  623. * @return the preferred dimensions to lay out the subcomponents
  624. * of the specified container.
  625. * @see java.awt.Container
  626. * @see java.awt.BorderLayout#minimumLayoutSize
  627. * @see java.awt.Container#getPreferredSize()
  628. */
  629. public Dimension preferredLayoutSize(Container target) {
  630. synchronized (target.getTreeLock()) {
  631. Dimension dim = new Dimension(0, 0);
  632. boolean ltr = target.getComponentOrientation().isLeftToRight();
  633. Component c = null;
  634. if ((c=getChild(EAST,ltr)) != null) {
  635. Dimension d = c.getPreferredSize();
  636. dim.width += d.width + hgap;
  637. dim.height = Math.max(d.height, dim.height);
  638. }
  639. if ((c=getChild(WEST,ltr)) != null) {
  640. Dimension d = c.getPreferredSize();
  641. dim.width += d.width + hgap;
  642. dim.height = Math.max(d.height, dim.height);
  643. }
  644. if ((c=getChild(CENTER,ltr)) != null) {
  645. Dimension d = c.getPreferredSize();
  646. dim.width += d.width;
  647. dim.height = Math.max(d.height, dim.height);
  648. }
  649. if ((c=getChild(NORTH,ltr)) != null) {
  650. Dimension d = c.getPreferredSize();
  651. dim.width = Math.max(d.width, dim.width);
  652. dim.height += d.height + vgap;
  653. }
  654. if ((c=getChild(SOUTH,ltr)) != null) {
  655. Dimension d = c.getPreferredSize();
  656. dim.width = Math.max(d.width, dim.width);
  657. dim.height += d.height + vgap;
  658. }
  659. Insets insets = target.getInsets();
  660. dim.width += insets.left + insets.right;
  661. dim.height += insets.top + insets.bottom;
  662. return dim;
  663. }
  664. }
  665. /**
  666. * Returns the maximum dimensions for this layout given the components
  667. * in the specified target container.
  668. * @param target the component which needs to be laid out
  669. * @see Container
  670. * @see #minimumLayoutSize
  671. * @see #preferredLayoutSize
  672. */
  673. public Dimension maximumLayoutSize(Container target) {
  674. return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
  675. }
  676. /**
  677. * Returns the alignment along the x axis. This specifies how
  678. * the component would like to be aligned relative to other
  679. * components. The value should be a number between 0 and 1
  680. * where 0 represents alignment along the origin, 1 is aligned
  681. * the furthest away from the origin, 0.5 is centered, etc.
  682. */
  683. public float getLayoutAlignmentX(Container parent) {
  684. return 0.5f;
  685. }
  686. /**
  687. * Returns the alignment along the y axis. This specifies how
  688. * the component would like to be aligned relative to other
  689. * components. The value should be a number between 0 and 1
  690. * where 0 represents alignment along the origin, 1 is aligned
  691. * the furthest away from the origin, 0.5 is centered, etc.
  692. */
  693. public float getLayoutAlignmentY(Container parent) {
  694. return 0.5f;
  695. }
  696. /**
  697. * Invalidates the layout, indicating that if the layout manager
  698. * has cached information it should be discarded.
  699. */
  700. public void invalidateLayout(Container target) {
  701. }
  702. /**
  703. * Lays out the container argument using this border layout.
  704. * <p>
  705. * This method actually reshapes the components in the specified
  706. * container in order to satisfy the constraints of this
  707. * <code>BorderLayout</code> object. The <code>NORTH</code>
  708. * and <code>SOUTH</code> components, if any, are placed at
  709. * the top and bottom of the container, respectively. The
  710. * <code>WEST</code> and <code>EAST</code> components are
  711. * then placed on the left and right, respectively. Finally,
  712. * the <code>CENTER</code> object is placed in any remaining
  713. * space in the middle.
  714. * <p>
  715. * Most applications do not call this method directly. This method
  716. * is called when a container calls its <code>doLayout</code> method.
  717. * @param target the container in which to do the layout.
  718. * @see java.awt.Container
  719. * @see java.awt.Container#doLayout()
  720. */
  721. public void layoutContainer(Container target) {
  722. synchronized (target.getTreeLock()) {
  723. Insets insets = target.getInsets();
  724. int top = insets.top;
  725. int bottom = target.height - insets.bottom;
  726. int left = insets.left;
  727. int right = target.width - insets.right;
  728. boolean ltr = target.getComponentOrientation().isLeftToRight();
  729. Component c = null;
  730. if ((c=getChild(NORTH,ltr)) != null) {
  731. c.setSize(right - left, c.height);
  732. Dimension d = c.getPreferredSize();
  733. c.setBounds(left, top, right - left, d.height);
  734. top += d.height + vgap;
  735. }
  736. if ((c=getChild(SOUTH,ltr)) != null) {
  737. c.setSize(right - left, c.height);
  738. Dimension d = c.getPreferredSize();
  739. c.setBounds(left, bottom - d.height, right - left, d.height);
  740. bottom -= d.height + vgap;
  741. }
  742. if ((c=getChild(EAST,ltr)) != null) {
  743. c.setSize(c.width, bottom - top);
  744. Dimension d = c.getPreferredSize();
  745. c.setBounds(right - d.width, top, d.width, bottom - top);
  746. right -= d.width + hgap;
  747. }
  748. if ((c=getChild(WEST,ltr)) != null) {
  749. c.setSize(c.width, bottom - top);
  750. Dimension d = c.getPreferredSize();
  751. c.setBounds(left, top, d.width, bottom - top);
  752. left += d.width + hgap;
  753. }
  754. if ((c=getChild(CENTER,ltr)) != null) {
  755. c.setBounds(left, top, right - left, bottom - top);
  756. }
  757. }
  758. }
  759. /**
  760. * Get the component that corresponds to the given constraint location
  761. *
  762. * @param key The desired absolute position,
  763. * either NORTH, SOUTH, EAST, or WEST.
  764. * @param ltr Is the component line direction left-to-right?
  765. */
  766. private Component getChild(String key, boolean ltr) {
  767. Component result = null;
  768. if (key == NORTH) {
  769. result = (firstLine != null) ? firstLine : north;
  770. }
  771. else if (key == SOUTH) {
  772. result = (lastLine != null) ? lastLine : south;
  773. }
  774. else if (key == WEST) {
  775. result = ltr ? firstItem : lastItem;
  776. if (result == null) {
  777. result = west;
  778. }
  779. }
  780. else if (key == EAST) {
  781. result = ltr ? lastItem : firstItem;
  782. if (result == null) {
  783. result = east;
  784. }
  785. }
  786. else if (key == CENTER) {
  787. result = center;
  788. }
  789. if (result != null && !result.visible) {
  790. result = null;
  791. }
  792. return result;
  793. }
  794. /**
  795. * Returns a string representation of the state of this border layout.
  796. * @return a string representation of this border layout.
  797. */
  798. public String toString() {
  799. return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + "]";
  800. }
  801. }