1. /*
  2. * @(#)BorderLayout.java 1.53 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. /**
  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.53, 01/23/03
  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. public void addLayoutComponent(String name, Component comp) {
  390. synchronized (comp.getTreeLock()) {
  391. /* Special case: treat null the same as "Center". */
  392. if (name == null) {
  393. name = "Center";
  394. }
  395. /* Assign the component to one of the known regions of the layout.
  396. */
  397. if ("Center".equals(name)) {
  398. center = comp;
  399. } else if ("North".equals(name)) {
  400. north = comp;
  401. } else if ("South".equals(name)) {
  402. south = comp;
  403. } else if ("East".equals(name)) {
  404. east = comp;
  405. } else if ("West".equals(name)) {
  406. west = comp;
  407. } else if (BEFORE_FIRST_LINE.equals(name)) {
  408. firstLine = comp;
  409. } else if (AFTER_LAST_LINE.equals(name)) {
  410. lastLine = comp;
  411. } else if (BEFORE_LINE_BEGINS.equals(name)) {
  412. firstItem = comp;
  413. } else if (AFTER_LINE_ENDS.equals(name)) {
  414. lastItem = comp;
  415. } else {
  416. throw new IllegalArgumentException("cannot add to layout: unknown constraint: " + name);
  417. }
  418. }
  419. }
  420. /**
  421. * Removes the specified component from this border layout. This
  422. * method is called when a container calls its <code>remove</code> or
  423. * <code>removeAll</code> methods. Most applications do not call this
  424. * method directly.
  425. * @param comp the component to be removed.
  426. * @see java.awt.Container#remove(java.awt.Component)
  427. * @see java.awt.Container#removeAll()
  428. */
  429. public void removeLayoutComponent(Component comp) {
  430. synchronized (comp.getTreeLock()) {
  431. if (comp == center) {
  432. center = null;
  433. } else if (comp == north) {
  434. north = null;
  435. } else if (comp == south) {
  436. south = null;
  437. } else if (comp == east) {
  438. east = null;
  439. } else if (comp == west) {
  440. west = null;
  441. }
  442. if (comp == firstLine) {
  443. firstLine = null;
  444. } else if (comp == lastLine) {
  445. lastLine = null;
  446. } else if (comp == firstItem) {
  447. firstItem = null;
  448. } else if (comp == lastItem) {
  449. lastItem = null;
  450. }
  451. }
  452. }
  453. /**
  454. * Determines the minimum size of the <code>target</code> container
  455. * using this layout manager.
  456. * <p>
  457. * This method is called when a container calls its
  458. * <code>getMinimumSize</code> method. Most applications do not call
  459. * this method directly.
  460. * @param target the container in which to do the layout.
  461. * @return the minimum dimensions needed to lay out the subcomponents
  462. * of the specified container.
  463. * @see java.awt.Container
  464. * @see java.awt.BorderLayout#preferredLayoutSize
  465. * @see java.awt.Container#getMinimumSize()
  466. */
  467. public Dimension minimumLayoutSize(Container target) {
  468. synchronized (target.getTreeLock()) {
  469. Dimension dim = new Dimension(0, 0);
  470. boolean ltr = target.getComponentOrientation().isLeftToRight();
  471. Component c = null;
  472. if ((c=getChild(EAST,ltr)) != null) {
  473. Dimension d = c.getMinimumSize();
  474. dim.width += d.width + hgap;
  475. dim.height = Math.max(d.height, dim.height);
  476. }
  477. if ((c=getChild(WEST,ltr)) != null) {
  478. Dimension d = c.getMinimumSize();
  479. dim.width += d.width + hgap;
  480. dim.height = Math.max(d.height, dim.height);
  481. }
  482. if ((c=getChild(CENTER,ltr)) != null) {
  483. Dimension d = c.getMinimumSize();
  484. dim.width += d.width;
  485. dim.height = Math.max(d.height, dim.height);
  486. }
  487. if ((c=getChild(NORTH,ltr)) != null) {
  488. Dimension d = c.getMinimumSize();
  489. dim.width = Math.max(d.width, dim.width);
  490. dim.height += d.height + vgap;
  491. }
  492. if ((c=getChild(SOUTH,ltr)) != null) {
  493. Dimension d = c.getMinimumSize();
  494. dim.width = Math.max(d.width, dim.width);
  495. dim.height += d.height + vgap;
  496. }
  497. Insets insets = target.getInsets();
  498. dim.width += insets.left + insets.right;
  499. dim.height += insets.top + insets.bottom;
  500. return dim;
  501. }
  502. }
  503. /**
  504. * Determines the preferred size of the <code>target</code>
  505. * container using this layout manager, based on the components
  506. * in the container.
  507. * <p>
  508. * Most applications do not call this method directly. This method
  509. * is called when a container calls its <code>getPreferredSize</code>
  510. * method.
  511. * @param target the container in which to do the layout.
  512. * @return the preferred dimensions to lay out the subcomponents
  513. * of the specified container.
  514. * @see java.awt.Container
  515. * @see java.awt.BorderLayout#minimumLayoutSize
  516. * @see java.awt.Container#getPreferredSize()
  517. */
  518. public Dimension preferredLayoutSize(Container target) {
  519. synchronized (target.getTreeLock()) {
  520. Dimension dim = new Dimension(0, 0);
  521. boolean ltr = target.getComponentOrientation().isLeftToRight();
  522. Component c = null;
  523. if ((c=getChild(EAST,ltr)) != null) {
  524. Dimension d = c.getPreferredSize();
  525. dim.width += d.width + hgap;
  526. dim.height = Math.max(d.height, dim.height);
  527. }
  528. if ((c=getChild(WEST,ltr)) != null) {
  529. Dimension d = c.getPreferredSize();
  530. dim.width += d.width + hgap;
  531. dim.height = Math.max(d.height, dim.height);
  532. }
  533. if ((c=getChild(CENTER,ltr)) != null) {
  534. Dimension d = c.getPreferredSize();
  535. dim.width += d.width;
  536. dim.height = Math.max(d.height, dim.height);
  537. }
  538. if ((c=getChild(NORTH,ltr)) != null) {
  539. Dimension d = c.getPreferredSize();
  540. dim.width = Math.max(d.width, dim.width);
  541. dim.height += d.height + vgap;
  542. }
  543. if ((c=getChild(SOUTH,ltr)) != null) {
  544. Dimension d = c.getPreferredSize();
  545. dim.width = Math.max(d.width, dim.width);
  546. dim.height += d.height + vgap;
  547. }
  548. Insets insets = target.getInsets();
  549. dim.width += insets.left + insets.right;
  550. dim.height += insets.top + insets.bottom;
  551. return dim;
  552. }
  553. }
  554. /**
  555. * Returns the maximum dimensions for this layout given the components
  556. * in the specified target container.
  557. * @param target the component which needs to be laid out
  558. * @see Container
  559. * @see #minimumLayoutSize
  560. * @see #preferredLayoutSize
  561. */
  562. public Dimension maximumLayoutSize(Container target) {
  563. return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
  564. }
  565. /**
  566. * Returns the alignment along the x axis. This specifies how
  567. * the component would like to be aligned relative to other
  568. * components. The value should be a number between 0 and 1
  569. * where 0 represents alignment along the origin, 1 is aligned
  570. * the furthest away from the origin, 0.5 is centered, etc.
  571. */
  572. public float getLayoutAlignmentX(Container parent) {
  573. return 0.5f;
  574. }
  575. /**
  576. * Returns the alignment along the y axis. This specifies how
  577. * the component would like to be aligned relative to other
  578. * components. The value should be a number between 0 and 1
  579. * where 0 represents alignment along the origin, 1 is aligned
  580. * the furthest away from the origin, 0.5 is centered, etc.
  581. */
  582. public float getLayoutAlignmentY(Container parent) {
  583. return 0.5f;
  584. }
  585. /**
  586. * Invalidates the layout, indicating that if the layout manager
  587. * has cached information it should be discarded.
  588. */
  589. public void invalidateLayout(Container target) {
  590. }
  591. /**
  592. * Lays out the container argument using this border layout.
  593. * <p>
  594. * This method actually reshapes the components in the specified
  595. * container in order to satisfy the constraints of this
  596. * <code>BorderLayout</code> object. The <code>NORTH</code>
  597. * and <code>SOUTH</code> components, if any, are placed at
  598. * the top and bottom of the container, respectively. The
  599. * <code>WEST</code> and <code>EAST</code> components are
  600. * then placed on the left and right, respectively. Finally,
  601. * the <code>CENTER</code> object is placed in any remaining
  602. * space in the middle.
  603. * <p>
  604. * Most applications do not call this method directly. This method
  605. * is called when a container calls its <code>doLayout</code> method.
  606. * @param target the container in which to do the layout.
  607. * @see java.awt.Container
  608. * @see java.awt.Container#doLayout()
  609. */
  610. public void layoutContainer(Container target) {
  611. synchronized (target.getTreeLock()) {
  612. Insets insets = target.getInsets();
  613. int top = insets.top;
  614. int bottom = target.height - insets.bottom;
  615. int left = insets.left;
  616. int right = target.width - insets.right;
  617. boolean ltr = target.getComponentOrientation().isLeftToRight();
  618. Component c = null;
  619. if ((c=getChild(NORTH,ltr)) != null) {
  620. c.setSize(right - left, c.height);
  621. Dimension d = c.getPreferredSize();
  622. c.setBounds(left, top, right - left, d.height);
  623. top += d.height + vgap;
  624. }
  625. if ((c=getChild(SOUTH,ltr)) != null) {
  626. c.setSize(right - left, c.height);
  627. Dimension d = c.getPreferredSize();
  628. c.setBounds(left, bottom - d.height, right - left, d.height);
  629. bottom -= d.height + vgap;
  630. }
  631. if ((c=getChild(EAST,ltr)) != null) {
  632. c.setSize(c.width, bottom - top);
  633. Dimension d = c.getPreferredSize();
  634. c.setBounds(right - d.width, top, d.width, bottom - top);
  635. right -= d.width + hgap;
  636. }
  637. if ((c=getChild(WEST,ltr)) != null) {
  638. c.setSize(c.width, bottom - top);
  639. Dimension d = c.getPreferredSize();
  640. c.setBounds(left, top, d.width, bottom - top);
  641. left += d.width + hgap;
  642. }
  643. if ((c=getChild(CENTER,ltr)) != null) {
  644. c.setBounds(left, top, right - left, bottom - top);
  645. }
  646. }
  647. }
  648. /**
  649. * Get the component that corresponds to the given constraint location
  650. *
  651. * @param key The desired absolute position,
  652. * either NORTH, SOUTH, EAST, or WEST.
  653. * @param ltr Is the component line direction left-to-right?
  654. */
  655. private Component getChild(String key, boolean ltr) {
  656. Component result = null;
  657. if (key == NORTH) {
  658. result = (firstLine != null) ? firstLine : north;
  659. }
  660. else if (key == SOUTH) {
  661. result = (lastLine != null) ? lastLine : south;
  662. }
  663. else if (key == WEST) {
  664. result = ltr ? firstItem : lastItem;
  665. if (result == null) {
  666. result = west;
  667. }
  668. }
  669. else if (key == EAST) {
  670. result = ltr ? lastItem : firstItem;
  671. if (result == null) {
  672. result = east;
  673. }
  674. }
  675. else if (key == CENTER) {
  676. result = center;
  677. }
  678. if (result != null && !result.visible) {
  679. result = null;
  680. }
  681. return result;
  682. }
  683. /**
  684. * Returns a string representation of the state of this border layout.
  685. * @return a string representation of this border layout.
  686. */
  687. public String toString() {
  688. return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + "]";
  689. }
  690. }