< prev index next >

src/java.desktop/share/classes/java/awt/BorderLayout.java

Print this page




  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.awt;
  27 
  28 import java.util.Hashtable;
  29 
  30 /**
  31  * A border layout lays out a container, arranging and resizing
  32  * its components to fit in five regions:
  33  * north, south, east, west, and center.
  34  * Each region may contain no more than one component, and
  35  * is identified by a corresponding constant:
  36  * <code>NORTH</code>, <code>SOUTH</code>, <code>EAST</code>,
  37  * <code>WEST</code>, and <code>CENTER</code>.  When adding a
  38  * component to a container with a border layout, use one of these
  39  * five constants, for example:
  40  * <pre>
  41  *    Panel p = new Panel();
  42  *    p.setLayout(new BorderLayout());
  43  *    p.add(new Button("Okay"), BorderLayout.SOUTH);
  44  * </pre>
  45  * As a convenience, <code>BorderLayout</code> interprets the
  46  * absence of a string specification the same as the constant
  47  * <code>CENTER</code>:
  48  * <pre>
  49  *    Panel p2 = new Panel();
  50  *    p2.setLayout(new BorderLayout());
  51  *    p2.add(new TextArea());  // Same as p.add(new TextArea(), BorderLayout.CENTER);
  52  * </pre>
  53  * <p>
  54  * In addition, <code>BorderLayout</code> supports the relative
  55  * positioning constants, <code>PAGE_START</code>, <code>PAGE_END</code>,
  56  * <code>LINE_START</code>, and <code>LINE_END</code>.
  57  * In a container whose <code>ComponentOrientation</code> is set to
  58  * <code>ComponentOrientation.LEFT_TO_RIGHT</code>, these constants map to
  59  * <code>NORTH</code>, <code>SOUTH</code>, <code>WEST</code>, and
  60  * <code>EAST</code>, respectively.
  61  * <p>
  62  * For compatibility with previous releases, <code>BorderLayout</code>
  63  * also includes the relative positioning constants <code>BEFORE_FIRST_LINE</code>,
  64  * <code>AFTER_LAST_LINE</code>, <code>BEFORE_LINE_BEGINS</code> and
  65  * <code>AFTER_LINE_ENDS</code>.  These are equivalent to
  66  * <code>PAGE_START</code>, <code>PAGE_END</code>, <code>LINE_START</code>
  67  * and <code>LINE_END</code> respectively.  For
  68  * consistency with the relative positioning constants used by other
  69  * components, the latter constants are preferred.
  70  * <p>
  71  * Mixing both absolute and relative positioning constants can lead to
  72  * unpredictable results.  If
  73  * you use both types, the relative constants will take precedence.
  74  * For example, if you add components using both the <code>NORTH</code>
  75  * and <code>PAGE_START</code> constants in a container whose
  76  * orientation is <code>LEFT_TO_RIGHT</code>, only the
  77  * <code>PAGE_START</code> will be laid out.
  78  * <p>
  79  * NOTE: Currently (in the Java 2 platform v1.2),
  80  * <code>BorderLayout</code> does not support vertical
  81  * orientations.  The <code>isVertical</code> setting on the container's
  82  * <code>ComponentOrientation</code> is not respected.
  83  * <p>
  84  * The components are laid out according to their
  85  * preferred sizes and the constraints of the container's size.
  86  * The <code>NORTH</code> and <code>SOUTH</code> components may
  87  * be stretched horizontally; the <code>EAST</code> and
  88  * <code>WEST</code> components may be stretched vertically;
  89  * the <code>CENTER</code> component may stretch both horizontally
  90  * and vertically to fill any space left over.
  91  * <p>
  92  * Here is an example of five buttons in an applet laid out using
  93  * the <code>BorderLayout</code> layout manager:
  94  * <p>
  95  * <img src="doc-files/BorderLayout-1.gif"
  96  * alt="Diagram of an applet demonstrating BorderLayout.
  97  *      Each section of the BorderLayout contains a Button corresponding to its position in the layout, one of:
  98  *      North, West, Center, East, or South."
  99  * style="float:center; margin: 7px 10px;">
 100  * <p>
 101  * The code for this applet is as follows:
 102  *
 103  * <hr><blockquote><pre>
 104  * import java.awt.*;
 105  * import java.applet.Applet;
 106  *
 107  * public class buttonDir extends Applet {
 108  *   public void init() {
 109  *     setLayout(new BorderLayout());
 110  *     add(new Button("North"), BorderLayout.NORTH);
 111  *     add(new Button("South"), BorderLayout.SOUTH);
 112  *     add(new Button("East"), BorderLayout.EAST);
 113  *     add(new Button("West"), BorderLayout.WEST);
 114  *     add(new Button("Center"), BorderLayout.CENTER);
 115  *   }
 116  * }
 117  * </pre></blockquote><hr>
 118  *
 119  * @author      Arthur van Hoff
 120  * @see         java.awt.Container#add(String, Component)
 121  * @see         java.awt.ComponentOrientation
 122  * @since       1.0
 123  */
 124 public class BorderLayout implements LayoutManager2,
 125                                      java.io.Serializable {
 126     /**
 127      * Constructs a border layout with the horizontal gaps
 128      * between components.
 129      * The horizontal gap is specified by <code>hgap</code>.
 130      *
 131      * @see #getHgap()
 132      * @see #setHgap(int)
 133      *
 134      * @serial
 135      */
 136         int hgap;
 137 
 138     /**
 139      * Constructs a border layout with the vertical gaps
 140      * between components.
 141      * The vertical gap is specified by <code>vgap</code>.
 142      *
 143      * @see #getVgap()
 144      * @see #setVgap(int)
 145      * @serial
 146      */
 147         int vgap;
 148 
 149     /**
 150      * Constant to specify components location to be the
 151      *      north 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 north;
 160      /**
 161      * Constant to specify components location to be the


 191      */
 192     Component south;
 193     /**
 194      * Constant to specify components location to be the
 195      *      center portion of the border layout.
 196      * @serial
 197      * @see #getChild(String, boolean)
 198      * @see #addLayoutComponent
 199      * @see #getLayoutAlignmentX
 200      * @see #getLayoutAlignmentY
 201      * @see #removeLayoutComponent
 202      */
 203         Component center;
 204 
 205     /**
 206      *
 207      * A relative positioning constant, that can be used instead of
 208      * north, south, east, west or center.
 209      * mixing the two types of constants can lead to unpredictable results.  If
 210      * you use both types, the relative constants will take precedence.
 211      * For example, if you add components using both the <code>NORTH</code>
 212      * and <code>BEFORE_FIRST_LINE</code> constants in a container whose
 213      * orientation is <code>LEFT_TO_RIGHT</code>, only the
 214      * <code>BEFORE_FIRST_LINE</code> will be laid out.
 215      * This will be the same for lastLine, firstItem, lastItem.
 216      * @serial
 217      */
 218     Component firstLine;
 219      /**
 220      * A relative positioning constant, that can be used instead of
 221      * north, south, east, west or center.
 222      * Please read Description for firstLine.
 223      * @serial
 224      */
 225         Component lastLine;
 226      /**
 227      * A relative positioning constant, that can be used instead of
 228      * north, south, east, west or center.
 229      * Please read Description for firstLine.
 230      * @serial
 231      */
 232         Component firstItem;
 233     /**
 234      * A relative positioning constant, that can be used instead of


 338      * @since 1.4
 339      */
 340     public static final String LINE_END = AFTER_LINE_ENDS;
 341 
 342     /*
 343      * JDK 1.1 serialVersionUID
 344      */
 345      private static final long serialVersionUID = -8658291919501921765L;
 346 
 347     /**
 348      * Constructs a new border layout with
 349      * no gaps between components.
 350      */
 351     public BorderLayout() {
 352         this(0, 0);
 353     }
 354 
 355     /**
 356      * Constructs a border layout with the specified gaps
 357      * between components.
 358      * The horizontal gap is specified by <code>hgap</code>
 359      * and the vertical gap is specified by <code>vgap</code>.
 360      * @param   hgap   the horizontal gap.
 361      * @param   vgap   the vertical gap.
 362      */
 363     public BorderLayout(int hgap, int vgap) {
 364         this.hgap = hgap;
 365         this.vgap = vgap;
 366     }
 367 
 368     /**
 369      * Returns the horizontal gap between components.
 370      *
 371      * @return the horizontal gap between components
 372      * @since   1.1
 373      */
 374     public int getHgap() {
 375         return hgap;
 376     }
 377 
 378     /**
 379      * Sets the horizontal gap between components.


 391      * @return the vertical gap between components
 392      * @since   1.1
 393      */
 394     public int getVgap() {
 395         return vgap;
 396     }
 397 
 398     /**
 399      * Sets the vertical gap between components.
 400      *
 401      * @param vgap the vertical gap between components
 402      * @since   1.1
 403      */
 404     public void setVgap(int vgap) {
 405         this.vgap = vgap;
 406     }
 407 
 408     /**
 409      * Adds the specified component to the layout, using the specified
 410      * constraint object.  For border layouts, the constraint must be
 411      * one of the following constants:  <code>NORTH</code>,
 412      * <code>SOUTH</code>, <code>EAST</code>,
 413      * <code>WEST</code>, or <code>CENTER</code>.
 414      * <p>
 415      * Most applications do not call this method directly. This method
 416      * is called when a component is added to a container using the
 417      * <code>Container.add</code> method with the same argument types.
 418      * @param   comp         the component to be added.
 419      * @param   constraints  an object that specifies how and where
 420      *                       the component is added to the layout.
 421      * @see     java.awt.Container#add(java.awt.Component, java.lang.Object)
 422      * @exception   IllegalArgumentException  if the constraint object is not
 423      *              a string, or if it not one of the five specified constants.
 424      * @since   1.1
 425      */
 426     public void addLayoutComponent(Component comp, Object constraints) {
 427       synchronized (comp.getTreeLock()) {
 428         if ((constraints == null) || (constraints instanceof String)) {
 429             addLayoutComponent((String)constraints, comp);
 430         } else {
 431             throw new IllegalArgumentException("cannot add to layout: constraint must be a string (or null)");
 432         }
 433       }
 434     }
 435 
 436     /**
 437      * @deprecated  replaced by <code>addLayoutComponent(Component, Object)</code>.
 438      */
 439     @Deprecated
 440     public void addLayoutComponent(String name, Component comp) {
 441       synchronized (comp.getTreeLock()) {
 442         /* Special case:  treat null the same as "Center". */
 443         if (name == null) {
 444             name = "Center";
 445         }
 446 
 447         /* Assign the component to one of the known regions of the layout.
 448          */
 449         if ("Center".equals(name)) {
 450             center = comp;
 451         } else if ("North".equals(name)) {
 452             north = comp;
 453         } else if ("South".equals(name)) {
 454             south = comp;
 455         } else if ("East".equals(name)) {
 456             east = comp;
 457         } else if ("West".equals(name)) {
 458             west = comp;
 459         } else if (BEFORE_FIRST_LINE.equals(name)) {
 460             firstLine = comp;
 461         } else if (AFTER_LAST_LINE.equals(name)) {
 462             lastLine = comp;
 463         } else if (BEFORE_LINE_BEGINS.equals(name)) {
 464             firstItem = comp;
 465         } else if (AFTER_LINE_ENDS.equals(name)) {
 466             lastItem = comp;
 467         } else {
 468             throw new IllegalArgumentException("cannot add to layout: unknown constraint: " + name);
 469         }
 470       }
 471     }
 472 
 473     /**
 474      * Removes the specified component from this border layout. This
 475      * method is called when a container calls its <code>remove</code> or
 476      * <code>removeAll</code> methods. Most applications do not call this
 477      * method directly.
 478      * @param   comp   the component to be removed.
 479      * @see     java.awt.Container#remove(java.awt.Component)
 480      * @see     java.awt.Container#removeAll()
 481      */
 482     public void removeLayoutComponent(Component comp) {
 483       synchronized (comp.getTreeLock()) {
 484         if (comp == center) {
 485             center = null;
 486         } else if (comp == north) {
 487             north = null;
 488         } else if (comp == south) {
 489             south = null;
 490         } else if (comp == east) {
 491             east = null;
 492         } else if (comp == west) {
 493             west = null;
 494         }
 495         if (comp == firstLine) {
 496             firstLine = null;
 497         } else if (comp == lastLine) {
 498             lastLine = null;
 499         } else if (comp == firstItem) {
 500             firstItem = null;
 501         } else if (comp == lastItem) {
 502             lastItem = null;
 503         }
 504       }
 505     }
 506 
 507     /**
 508      * Gets the component that was added using the given constraint
 509      *
 510      * @param   constraints  the desired constraint, one of <code>CENTER</code>,
 511      *                       <code>NORTH</code>, <code>SOUTH</code>,
 512      *                       <code>WEST</code>, <code>EAST</code>,
 513      *                       <code>PAGE_START</code>, <code>PAGE_END</code>,
 514      *                       <code>LINE_START</code>, <code>LINE_END</code>
 515      * @return  the component at the given location, or <code>null</code> if
 516      *          the location is empty
 517      * @exception   IllegalArgumentException  if the constraint object is
 518      *              not one of the nine specified constants
 519      * @see     #addLayoutComponent(java.awt.Component, java.lang.Object)
 520      * @since 1.5
 521      */
 522     public Component getLayoutComponent(Object constraints) {
 523         if (CENTER.equals(constraints)) {
 524             return center;
 525         } else if (NORTH.equals(constraints)) {
 526             return north;
 527         } else if (SOUTH.equals(constraints)) {
 528             return south;
 529         } else if (WEST.equals(constraints)) {
 530             return west;
 531         } else if (EAST.equals(constraints)) {
 532             return east;
 533         } else if (PAGE_START.equals(constraints)) {
 534             return firstLine;
 535         } else if (PAGE_END.equals(constraints)) {
 536             return lastLine;
 537         } else if (LINE_START.equals(constraints)) {
 538             return firstItem;
 539         } else if (LINE_END.equals(constraints)) {
 540             return lastItem;
 541         } else {
 542             throw new IllegalArgumentException("cannot get component: unknown constraint: " + constraints);
 543         }
 544     }
 545 
 546 
 547     /**
 548      * Returns the component that corresponds to the given constraint location
 549      * based on the target <code>Container</code>'s component orientation.
 550      * Components added with the relative constraints <code>PAGE_START</code>,
 551      * <code>PAGE_END</code>, <code>LINE_START</code>, and <code>LINE_END</code>
 552      * take precedence over components added with the explicit constraints
 553      * <code>NORTH</code>, <code>SOUTH</code>, <code>WEST</code>, and <code>EAST</code>.
 554      * The <code>Container</code>'s component orientation is used to determine the location of components
 555      * added with <code>LINE_START</code> and <code>LINE_END</code>.
 556      *
 557      * @param   constraints     the desired absolute position, one of <code>CENTER</code>,
 558      *                          <code>NORTH</code>, <code>SOUTH</code>,
 559      *                          <code>EAST</code>, <code>WEST</code>
 560      * @param   target     the {@code Container} used to obtain
 561      *                     the constraint location based on the target
 562      *                     {@code Container}'s component orientation.
 563      * @return  the component at the given location, or <code>null</code> if
 564      *          the location is empty
 565      * @exception   IllegalArgumentException  if the constraint object is
 566      *              not one of the five specified constants
 567      * @exception   NullPointerException  if the target parameter is null
 568      * @see     #addLayoutComponent(java.awt.Component, java.lang.Object)
 569      * @since 1.5
 570      */
 571     public Component getLayoutComponent(Container target, Object constraints) {
 572         boolean ltr = target.getComponentOrientation().isLeftToRight();
 573         Component result = null;
 574 
 575         if (NORTH.equals(constraints)) {
 576             result = (firstLine != null) ? firstLine : north;
 577         } else if (SOUTH.equals(constraints)) {
 578             result = (lastLine != null) ? lastLine : south;
 579         } else if (WEST.equals(constraints)) {
 580             result = ltr ? firstItem : lastItem;
 581             if (result == null) {
 582                 result = west;
 583             }


 617             return NORTH;
 618         } else if (comp == south) {
 619             return SOUTH;
 620         } else if (comp == west) {
 621             return WEST;
 622         } else if (comp == east) {
 623             return EAST;
 624         } else if (comp == firstLine) {
 625             return PAGE_START;
 626         } else if (comp == lastLine) {
 627             return PAGE_END;
 628         } else if (comp == firstItem) {
 629             return LINE_START;
 630         } else if (comp == lastItem) {
 631             return LINE_END;
 632         }
 633         return null;
 634     }
 635 
 636     /**
 637      * Determines the minimum size of the <code>target</code> container
 638      * using this layout manager.
 639      * <p>
 640      * This method is called when a container calls its
 641      * <code>getMinimumSize</code> method. Most applications do not call
 642      * this method directly.
 643      * @param   target   the container in which to do the layout.
 644      * @return  the minimum dimensions needed to lay out the subcomponents
 645      *          of the specified container.
 646      * @see     java.awt.Container
 647      * @see     java.awt.BorderLayout#preferredLayoutSize
 648      * @see     java.awt.Container#getMinimumSize()
 649      */
 650     public Dimension minimumLayoutSize(Container target) {
 651       synchronized (target.getTreeLock()) {
 652         Dimension dim = new Dimension(0, 0);
 653 
 654         boolean ltr = target.getComponentOrientation().isLeftToRight();
 655         Component c = null;
 656 
 657         if ((c=getChild(EAST,ltr)) != null) {
 658             Dimension d = c.getMinimumSize();
 659             dim.width += d.width + hgap;
 660             dim.height = Math.max(d.height, dim.height);
 661         }


 672         if ((c=getChild(NORTH,ltr)) != null) {
 673             Dimension d = c.getMinimumSize();
 674             dim.width = Math.max(d.width, dim.width);
 675             dim.height += d.height + vgap;
 676         }
 677         if ((c=getChild(SOUTH,ltr)) != null) {
 678             Dimension d = c.getMinimumSize();
 679             dim.width = Math.max(d.width, dim.width);
 680             dim.height += d.height + vgap;
 681         }
 682 
 683         Insets insets = target.getInsets();
 684         dim.width += insets.left + insets.right;
 685         dim.height += insets.top + insets.bottom;
 686 
 687         return dim;
 688       }
 689     }
 690 
 691     /**
 692      * Determines the preferred size of the <code>target</code>
 693      * container using this layout manager, based on the components
 694      * in the container.
 695      * <p>
 696      * Most applications do not call this method directly. This method
 697      * is called when a container calls its <code>getPreferredSize</code>
 698      * method.
 699      * @param   target   the container in which to do the layout.
 700      * @return  the preferred dimensions to lay out the subcomponents
 701      *          of the specified container.
 702      * @see     java.awt.Container
 703      * @see     java.awt.BorderLayout#minimumLayoutSize
 704      * @see     java.awt.Container#getPreferredSize()
 705      */
 706     public Dimension preferredLayoutSize(Container target) {
 707       synchronized (target.getTreeLock()) {
 708         Dimension dim = new Dimension(0, 0);
 709 
 710         boolean ltr = target.getComponentOrientation().isLeftToRight();
 711         Component c = null;
 712 
 713         if ((c=getChild(EAST,ltr)) != null) {
 714             Dimension d = c.getPreferredSize();
 715             dim.width += d.width + hgap;
 716             dim.height = Math.max(d.height, dim.height);
 717         }


 773      * components.  The value should be a number between 0 and 1
 774      * where 0 represents alignment along the origin, 1 is aligned
 775      * the furthest away from the origin, 0.5 is centered, etc.
 776      */
 777     public float getLayoutAlignmentY(Container parent) {
 778         return 0.5f;
 779     }
 780 
 781     /**
 782      * Invalidates the layout, indicating that if the layout manager
 783      * has cached information it should be discarded.
 784      */
 785     public void invalidateLayout(Container target) {
 786     }
 787 
 788     /**
 789      * Lays out the container argument using this border layout.
 790      * <p>
 791      * This method actually reshapes the components in the specified
 792      * container in order to satisfy the constraints of this
 793      * <code>BorderLayout</code> object. The <code>NORTH</code>
 794      * and <code>SOUTH</code> components, if any, are placed at
 795      * the top and bottom of the container, respectively. The
 796      * <code>WEST</code> and <code>EAST</code> components are
 797      * then placed on the left and right, respectively. Finally,
 798      * the <code>CENTER</code> object is placed in any remaining
 799      * space in the middle.
 800      * <p>
 801      * Most applications do not call this method directly. This method
 802      * is called when a container calls its <code>doLayout</code> method.
 803      * @param   target   the container in which to do the layout.
 804      * @see     java.awt.Container
 805      * @see     java.awt.Container#doLayout()
 806      */
 807     public void layoutContainer(Container target) {
 808       synchronized (target.getTreeLock()) {
 809         Insets insets = target.getInsets();
 810         int top = insets.top;
 811         int bottom = target.height - insets.bottom;
 812         int left = insets.left;
 813         int right = target.width - insets.right;
 814 
 815         boolean ltr = target.getComponentOrientation().isLeftToRight();
 816         Component c = null;
 817 
 818         if ((c=getChild(NORTH,ltr)) != null) {
 819             c.setSize(right - left, c.height);
 820             Dimension d = c.getPreferredSize();
 821             c.setBounds(left, top, right - left, d.height);
 822             top += d.height + vgap;




  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.awt;
  27 
  28 import java.util.Hashtable;
  29 
  30 /**
  31  * A border layout lays out a container, arranging and resizing
  32  * its components to fit in five regions:
  33  * north, south, east, west, and center.
  34  * Each region may contain no more than one component, and
  35  * is identified by a corresponding constant:
  36  * {@code NORTH}, {@code SOUTH}, {@code EAST},
  37  * {@code WEST}, and {@code CENTER}.  When adding a
  38  * component to a container with a border layout, use one of these
  39  * five constants, for example:
  40  * <pre>
  41  *    Panel p = new Panel();
  42  *    p.setLayout(new BorderLayout());
  43  *    p.add(new Button("Okay"), BorderLayout.SOUTH);
  44  * </pre>
  45  * As a convenience, {@code BorderLayout} interprets the
  46  * absence of a string specification the same as the constant
  47  * {@code CENTER}:
  48  * <pre>
  49  *    Panel p2 = new Panel();
  50  *    p2.setLayout(new BorderLayout());
  51  *    p2.add(new TextArea());  // Same as p.add(new TextArea(), BorderLayout.CENTER);
  52  * </pre>
  53  * <p>
  54  * In addition, {@code BorderLayout} supports the relative
  55  * positioning constants, {@code PAGE_START}, {@code PAGE_END},
  56  * {@code LINE_START}, and {@code LINE_END}.
  57  * In a container whose {@code ComponentOrientation} is set to
  58  * {@code ComponentOrientation.LEFT_TO_RIGHT}, these constants map to
  59  * {@code NORTH}, {@code SOUTH}, {@code WEST}, and
  60  * {@code EAST}, respectively.
  61  * <p>
  62  * For compatibility with previous releases, {@code BorderLayout}
  63  * also includes the relative positioning constants {@code BEFORE_FIRST_LINE},
  64  * {@code AFTER_LAST_LINE}, {@code BEFORE_LINE_BEGINS} and
  65  * {@code AFTER_LINE_ENDS}.  These are equivalent to
  66  * {@code PAGE_START}, {@code PAGE_END}, {@code LINE_START}
  67  * and {@code LINE_END} respectively.  For
  68  * consistency with the relative positioning constants used by other
  69  * components, the latter constants are preferred.
  70  * <p>
  71  * Mixing both absolute and relative positioning constants can lead to
  72  * unpredictable results.  If
  73  * you use both types, the relative constants will take precedence.
  74  * For example, if you add components using both the {@code NORTH}
  75  * and {@code PAGE_START} constants in a container whose
  76  * orientation is {@code LEFT_TO_RIGHT}, only the
  77  * {@code PAGE_START} will be laid out.
  78  * <p>
  79  * NOTE: Currently (in the Java 2 platform v1.2),
  80  * {@code BorderLayout} does not support vertical
  81  * orientations.  The {@code isVertical} setting on the container's
  82  * {@code ComponentOrientation} is not respected.
  83  * <p>
  84  * The components are laid out according to their
  85  * preferred sizes and the constraints of the container's size.
  86  * The {@code NORTH} and {@code SOUTH} components may
  87  * be stretched horizontally; the {@code EAST} and
  88  * {@code WEST} components may be stretched vertically;
  89  * the {@code CENTER} component may stretch both horizontally
  90  * and vertically to fill any space left over.
  91  * <p>
  92  * Here is an example of five buttons in an applet laid out using
  93  * the {@code BorderLayout} layout manager:
  94  * <p>
  95  * <img src="doc-files/BorderLayout-1.gif"
  96  * alt="Diagram of an applet demonstrating BorderLayout.
  97  *      Each section of the BorderLayout contains a Button corresponding to its position in the layout, one of:
  98  *      North, West, Center, East, or South."
  99  * style="float:center; margin: 7px 10px;">
 100  * <p>
 101  * The code for this applet is as follows:
 102  *
 103  * <hr><blockquote><pre>
 104  * import java.awt.*;
 105  * import java.applet.Applet;
 106  *
 107  * public class buttonDir extends Applet {
 108  *   public void init() {
 109  *     setLayout(new BorderLayout());
 110  *     add(new Button("North"), BorderLayout.NORTH);
 111  *     add(new Button("South"), BorderLayout.SOUTH);
 112  *     add(new Button("East"), BorderLayout.EAST);
 113  *     add(new Button("West"), BorderLayout.WEST);
 114  *     add(new Button("Center"), BorderLayout.CENTER);
 115  *   }
 116  * }
 117  * </pre></blockquote><hr>
 118  *
 119  * @author      Arthur van Hoff
 120  * @see         java.awt.Container#add(String, Component)
 121  * @see         java.awt.ComponentOrientation
 122  * @since       1.0
 123  */
 124 public class BorderLayout implements LayoutManager2,
 125                                      java.io.Serializable {
 126     /**
 127      * Constructs a border layout with the horizontal gaps
 128      * between components.
 129      * The horizontal gap is specified by {@code hgap}.
 130      *
 131      * @see #getHgap()
 132      * @see #setHgap(int)
 133      *
 134      * @serial
 135      */
 136         int hgap;
 137 
 138     /**
 139      * Constructs a border layout with the vertical gaps
 140      * between components.
 141      * The vertical gap is specified by {@code vgap}.
 142      *
 143      * @see #getVgap()
 144      * @see #setVgap(int)
 145      * @serial
 146      */
 147         int vgap;
 148 
 149     /**
 150      * Constant to specify components location to be the
 151      *      north 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 north;
 160      /**
 161      * Constant to specify components location to be the


 191      */
 192     Component south;
 193     /**
 194      * Constant to specify components location to be the
 195      *      center portion of the border layout.
 196      * @serial
 197      * @see #getChild(String, boolean)
 198      * @see #addLayoutComponent
 199      * @see #getLayoutAlignmentX
 200      * @see #getLayoutAlignmentY
 201      * @see #removeLayoutComponent
 202      */
 203         Component center;
 204 
 205     /**
 206      *
 207      * A relative positioning constant, that can be used instead of
 208      * north, south, east, west or center.
 209      * mixing the two types of constants can lead to unpredictable results.  If
 210      * you use both types, the relative constants will take precedence.
 211      * For example, if you add components using both the {@code NORTH}
 212      * and {@code BEFORE_FIRST_LINE} constants in a container whose
 213      * orientation is {@code LEFT_TO_RIGHT}, only the
 214      * {@code BEFORE_FIRST_LINE} will be laid out.
 215      * This will be the same for lastLine, firstItem, lastItem.
 216      * @serial
 217      */
 218     Component firstLine;
 219      /**
 220      * A relative positioning constant, that can be used instead of
 221      * north, south, east, west or center.
 222      * Please read Description for firstLine.
 223      * @serial
 224      */
 225         Component lastLine;
 226      /**
 227      * A relative positioning constant, that can be used instead of
 228      * north, south, east, west or center.
 229      * Please read Description for firstLine.
 230      * @serial
 231      */
 232         Component firstItem;
 233     /**
 234      * A relative positioning constant, that can be used instead of


 338      * @since 1.4
 339      */
 340     public static final String LINE_END = AFTER_LINE_ENDS;
 341 
 342     /*
 343      * JDK 1.1 serialVersionUID
 344      */
 345      private static final long serialVersionUID = -8658291919501921765L;
 346 
 347     /**
 348      * Constructs a new border layout with
 349      * no gaps between components.
 350      */
 351     public BorderLayout() {
 352         this(0, 0);
 353     }
 354 
 355     /**
 356      * Constructs a border layout with the specified gaps
 357      * between components.
 358      * The horizontal gap is specified by {@code hgap}
 359      * and the vertical gap is specified by {@code vgap}.
 360      * @param   hgap   the horizontal gap.
 361      * @param   vgap   the vertical gap.
 362      */
 363     public BorderLayout(int hgap, int vgap) {
 364         this.hgap = hgap;
 365         this.vgap = vgap;
 366     }
 367 
 368     /**
 369      * Returns the horizontal gap between components.
 370      *
 371      * @return the horizontal gap between components
 372      * @since   1.1
 373      */
 374     public int getHgap() {
 375         return hgap;
 376     }
 377 
 378     /**
 379      * Sets the horizontal gap between components.


 391      * @return the vertical gap between components
 392      * @since   1.1
 393      */
 394     public int getVgap() {
 395         return vgap;
 396     }
 397 
 398     /**
 399      * Sets the vertical gap between components.
 400      *
 401      * @param vgap the vertical gap between components
 402      * @since   1.1
 403      */
 404     public void setVgap(int vgap) {
 405         this.vgap = vgap;
 406     }
 407 
 408     /**
 409      * Adds the specified component to the layout, using the specified
 410      * constraint object.  For border layouts, the constraint must be
 411      * one of the following constants:  {@code NORTH},
 412      * {@code SOUTH}, {@code EAST},
 413      * {@code WEST}, or {@code CENTER}.
 414      * <p>
 415      * Most applications do not call this method directly. This method
 416      * is called when a component is added to a container using the
 417      * {@code Container.add} method with the same argument types.
 418      * @param   comp         the component to be added.
 419      * @param   constraints  an object that specifies how and where
 420      *                       the component is added to the layout.
 421      * @see     java.awt.Container#add(java.awt.Component, java.lang.Object)
 422      * @exception   IllegalArgumentException  if the constraint object is not
 423      *              a string, or if it not one of the five specified constants.
 424      * @since   1.1
 425      */
 426     public void addLayoutComponent(Component comp, Object constraints) {
 427       synchronized (comp.getTreeLock()) {
 428         if ((constraints == null) || (constraints instanceof String)) {
 429             addLayoutComponent((String)constraints, comp);
 430         } else {
 431             throw new IllegalArgumentException("cannot add to layout: constraint must be a string (or null)");
 432         }
 433       }
 434     }
 435 
 436     /**
 437      * @deprecated  replaced by {@code addLayoutComponent(Component, Object)}.
 438      */
 439     @Deprecated
 440     public void addLayoutComponent(String name, Component comp) {
 441       synchronized (comp.getTreeLock()) {
 442         /* Special case:  treat null the same as "Center". */
 443         if (name == null) {
 444             name = "Center";
 445         }
 446 
 447         /* Assign the component to one of the known regions of the layout.
 448          */
 449         if ("Center".equals(name)) {
 450             center = comp;
 451         } else if ("North".equals(name)) {
 452             north = comp;
 453         } else if ("South".equals(name)) {
 454             south = comp;
 455         } else if ("East".equals(name)) {
 456             east = comp;
 457         } else if ("West".equals(name)) {
 458             west = comp;
 459         } else if (BEFORE_FIRST_LINE.equals(name)) {
 460             firstLine = comp;
 461         } else if (AFTER_LAST_LINE.equals(name)) {
 462             lastLine = comp;
 463         } else if (BEFORE_LINE_BEGINS.equals(name)) {
 464             firstItem = comp;
 465         } else if (AFTER_LINE_ENDS.equals(name)) {
 466             lastItem = comp;
 467         } else {
 468             throw new IllegalArgumentException("cannot add to layout: unknown constraint: " + name);
 469         }
 470       }
 471     }
 472 
 473     /**
 474      * Removes the specified component from this border layout. This
 475      * method is called when a container calls its {@code remove} or
 476      * {@code removeAll} methods. Most applications do not call this
 477      * method directly.
 478      * @param   comp   the component to be removed.
 479      * @see     java.awt.Container#remove(java.awt.Component)
 480      * @see     java.awt.Container#removeAll()
 481      */
 482     public void removeLayoutComponent(Component comp) {
 483       synchronized (comp.getTreeLock()) {
 484         if (comp == center) {
 485             center = null;
 486         } else if (comp == north) {
 487             north = null;
 488         } else if (comp == south) {
 489             south = null;
 490         } else if (comp == east) {
 491             east = null;
 492         } else if (comp == west) {
 493             west = null;
 494         }
 495         if (comp == firstLine) {
 496             firstLine = null;
 497         } else if (comp == lastLine) {
 498             lastLine = null;
 499         } else if (comp == firstItem) {
 500             firstItem = null;
 501         } else if (comp == lastItem) {
 502             lastItem = null;
 503         }
 504       }
 505     }
 506 
 507     /**
 508      * Gets the component that was added using the given constraint
 509      *
 510      * @param   constraints  the desired constraint, one of {@code CENTER},
 511      *                       {@code NORTH}, {@code SOUTH},
 512      *                       {@code WEST}, {@code EAST},
 513      *                       {@code PAGE_START}, {@code PAGE_END},
 514      *                       {@code LINE_START}, {@code LINE_END}
 515      * @return  the component at the given location, or {@code null} if
 516      *          the location is empty
 517      * @exception   IllegalArgumentException  if the constraint object is
 518      *              not one of the nine specified constants
 519      * @see     #addLayoutComponent(java.awt.Component, java.lang.Object)
 520      * @since 1.5
 521      */
 522     public Component getLayoutComponent(Object constraints) {
 523         if (CENTER.equals(constraints)) {
 524             return center;
 525         } else if (NORTH.equals(constraints)) {
 526             return north;
 527         } else if (SOUTH.equals(constraints)) {
 528             return south;
 529         } else if (WEST.equals(constraints)) {
 530             return west;
 531         } else if (EAST.equals(constraints)) {
 532             return east;
 533         } else if (PAGE_START.equals(constraints)) {
 534             return firstLine;
 535         } else if (PAGE_END.equals(constraints)) {
 536             return lastLine;
 537         } else if (LINE_START.equals(constraints)) {
 538             return firstItem;
 539         } else if (LINE_END.equals(constraints)) {
 540             return lastItem;
 541         } else {
 542             throw new IllegalArgumentException("cannot get component: unknown constraint: " + constraints);
 543         }
 544     }
 545 
 546 
 547     /**
 548      * Returns the component that corresponds to the given constraint location
 549      * based on the target {@code Container}'s component orientation.
 550      * Components added with the relative constraints {@code PAGE_START},
 551      * {@code PAGE_END}, {@code LINE_START}, and {@code LINE_END}
 552      * take precedence over components added with the explicit constraints
 553      * {@code NORTH}, {@code SOUTH}, {@code WEST}, and {@code EAST}.
 554      * The {@code Container}'s component orientation is used to determine the location of components
 555      * added with {@code LINE_START} and {@code LINE_END}.
 556      *
 557      * @param   constraints     the desired absolute position, one of {@code CENTER},
 558      *                          {@code NORTH}, {@code SOUTH},
 559      *                          {@code EAST}, {@code WEST}
 560      * @param   target     the {@code Container} used to obtain
 561      *                     the constraint location based on the target
 562      *                     {@code Container}'s component orientation.
 563      * @return  the component at the given location, or {@code null} if
 564      *          the location is empty
 565      * @exception   IllegalArgumentException  if the constraint object is
 566      *              not one of the five specified constants
 567      * @exception   NullPointerException  if the target parameter is null
 568      * @see     #addLayoutComponent(java.awt.Component, java.lang.Object)
 569      * @since 1.5
 570      */
 571     public Component getLayoutComponent(Container target, Object constraints) {
 572         boolean ltr = target.getComponentOrientation().isLeftToRight();
 573         Component result = null;
 574 
 575         if (NORTH.equals(constraints)) {
 576             result = (firstLine != null) ? firstLine : north;
 577         } else if (SOUTH.equals(constraints)) {
 578             result = (lastLine != null) ? lastLine : south;
 579         } else if (WEST.equals(constraints)) {
 580             result = ltr ? firstItem : lastItem;
 581             if (result == null) {
 582                 result = west;
 583             }


 617             return NORTH;
 618         } else if (comp == south) {
 619             return SOUTH;
 620         } else if (comp == west) {
 621             return WEST;
 622         } else if (comp == east) {
 623             return EAST;
 624         } else if (comp == firstLine) {
 625             return PAGE_START;
 626         } else if (comp == lastLine) {
 627             return PAGE_END;
 628         } else if (comp == firstItem) {
 629             return LINE_START;
 630         } else if (comp == lastItem) {
 631             return LINE_END;
 632         }
 633         return null;
 634     }
 635 
 636     /**
 637      * Determines the minimum size of the {@code target} container
 638      * using this layout manager.
 639      * <p>
 640      * This method is called when a container calls its
 641      * {@code getMinimumSize} method. Most applications do not call
 642      * this method directly.
 643      * @param   target   the container in which to do the layout.
 644      * @return  the minimum dimensions needed to lay out the subcomponents
 645      *          of the specified container.
 646      * @see     java.awt.Container
 647      * @see     java.awt.BorderLayout#preferredLayoutSize
 648      * @see     java.awt.Container#getMinimumSize()
 649      */
 650     public Dimension minimumLayoutSize(Container target) {
 651       synchronized (target.getTreeLock()) {
 652         Dimension dim = new Dimension(0, 0);
 653 
 654         boolean ltr = target.getComponentOrientation().isLeftToRight();
 655         Component c = null;
 656 
 657         if ((c=getChild(EAST,ltr)) != null) {
 658             Dimension d = c.getMinimumSize();
 659             dim.width += d.width + hgap;
 660             dim.height = Math.max(d.height, dim.height);
 661         }


 672         if ((c=getChild(NORTH,ltr)) != null) {
 673             Dimension d = c.getMinimumSize();
 674             dim.width = Math.max(d.width, dim.width);
 675             dim.height += d.height + vgap;
 676         }
 677         if ((c=getChild(SOUTH,ltr)) != null) {
 678             Dimension d = c.getMinimumSize();
 679             dim.width = Math.max(d.width, dim.width);
 680             dim.height += d.height + vgap;
 681         }
 682 
 683         Insets insets = target.getInsets();
 684         dim.width += insets.left + insets.right;
 685         dim.height += insets.top + insets.bottom;
 686 
 687         return dim;
 688       }
 689     }
 690 
 691     /**
 692      * Determines the preferred size of the {@code target}
 693      * container using this layout manager, based on the components
 694      * in the container.
 695      * <p>
 696      * Most applications do not call this method directly. This method
 697      * is called when a container calls its {@code getPreferredSize}
 698      * method.
 699      * @param   target   the container in which to do the layout.
 700      * @return  the preferred dimensions to lay out the subcomponents
 701      *          of the specified container.
 702      * @see     java.awt.Container
 703      * @see     java.awt.BorderLayout#minimumLayoutSize
 704      * @see     java.awt.Container#getPreferredSize()
 705      */
 706     public Dimension preferredLayoutSize(Container target) {
 707       synchronized (target.getTreeLock()) {
 708         Dimension dim = new Dimension(0, 0);
 709 
 710         boolean ltr = target.getComponentOrientation().isLeftToRight();
 711         Component c = null;
 712 
 713         if ((c=getChild(EAST,ltr)) != null) {
 714             Dimension d = c.getPreferredSize();
 715             dim.width += d.width + hgap;
 716             dim.height = Math.max(d.height, dim.height);
 717         }


 773      * components.  The value should be a number between 0 and 1
 774      * where 0 represents alignment along the origin, 1 is aligned
 775      * the furthest away from the origin, 0.5 is centered, etc.
 776      */
 777     public float getLayoutAlignmentY(Container parent) {
 778         return 0.5f;
 779     }
 780 
 781     /**
 782      * Invalidates the layout, indicating that if the layout manager
 783      * has cached information it should be discarded.
 784      */
 785     public void invalidateLayout(Container target) {
 786     }
 787 
 788     /**
 789      * Lays out the container argument using this border layout.
 790      * <p>
 791      * This method actually reshapes the components in the specified
 792      * container in order to satisfy the constraints of this
 793      * {@code BorderLayout} object. The {@code NORTH}
 794      * and {@code SOUTH} components, if any, are placed at
 795      * the top and bottom of the container, respectively. The
 796      * {@code WEST} and {@code EAST} components are
 797      * then placed on the left and right, respectively. Finally,
 798      * the {@code CENTER} object is placed in any remaining
 799      * space in the middle.
 800      * <p>
 801      * Most applications do not call this method directly. This method
 802      * is called when a container calls its {@code doLayout} method.
 803      * @param   target   the container in which to do the layout.
 804      * @see     java.awt.Container
 805      * @see     java.awt.Container#doLayout()
 806      */
 807     public void layoutContainer(Container target) {
 808       synchronized (target.getTreeLock()) {
 809         Insets insets = target.getInsets();
 810         int top = insets.top;
 811         int bottom = target.height - insets.bottom;
 812         int left = insets.left;
 813         int right = target.width - insets.right;
 814 
 815         boolean ltr = target.getComponentOrientation().isLeftToRight();
 816         Component c = null;
 817 
 818         if ((c=getChild(NORTH,ltr)) != null) {
 819             c.setSize(right - left, c.height);
 820             Dimension d = c.getPreferredSize();
 821             c.setBounds(left, top, right - left, d.height);
 822             top += d.height + vgap;


< prev index next >