1 /* 2 * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 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 layed 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 JDK1.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 162 * west 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 west; 171 /** 172 * Constant to specify components location to be the 173 * east 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 east; 182 /** 183 * Constant to specify components location to be the 184 * south portion of the border layout. 185 * @serial 186 * @see #getChild(String, boolean) 187 * @see #addLayoutComponent 188 * @see #getLayoutAlignmentX 189 * @see #getLayoutAlignmentY 190 * @see #removeLayoutComponent 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 layed 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 235 * north, south, east, west or center. 236 * Please read Description for firstLine. 237 * @serial 238 */ 239 Component lastItem; 240 241 /** 242 * The north layout constraint (top of container). 243 */ 244 public static final String NORTH = "North"; 245 246 /** 247 * The south layout constraint (bottom of container). 248 */ 249 public static final String SOUTH = "South"; 250 251 /** 252 * The east layout constraint (right side of container). 253 */ 254 public static final String EAST = "East"; 255 256 /** 257 * The west layout constraint (left side of container). 258 */ 259 public static final String WEST = "West"; 260 261 /** 262 * The center layout constraint (middle of container). 263 */ 264 public static final String CENTER = "Center"; 265 266 /** 267 * Synonym for PAGE_START. Exists for compatibility with previous 268 * versions. PAGE_START is preferred. 269 * 270 * @see #PAGE_START 271 * @since 1.2 272 */ 273 public static final String BEFORE_FIRST_LINE = "First"; 274 275 /** 276 * Synonym for PAGE_END. Exists for compatibility with previous 277 * versions. PAGE_END is preferred. 278 * 279 * @see #PAGE_END 280 * @since 1.2 281 */ 282 public static final String AFTER_LAST_LINE = "Last"; 283 284 /** 285 * Synonym for LINE_START. Exists for compatibility with previous 286 * versions. LINE_START is preferred. 287 * 288 * @see #LINE_START 289 * @since 1.2 290 */ 291 public static final String BEFORE_LINE_BEGINS = "Before"; 292 293 /** 294 * Synonym for LINE_END. Exists for compatibility with previous 295 * versions. LINE_END is preferred. 296 * 297 * @see #LINE_END 298 * @since 1.2 299 */ 300 public static final String AFTER_LINE_ENDS = "After"; 301 302 /** 303 * The component comes before the first line of the layout's content. 304 * For Western, left-to-right and top-to-bottom orientations, this is 305 * equivalent to NORTH. 306 * 307 * @see java.awt.Component#getComponentOrientation 308 * @since 1.4 309 */ 310 public static final String PAGE_START = BEFORE_FIRST_LINE; 311 312 /** 313 * The component comes after the last line of the layout's content. 314 * For Western, left-to-right and top-to-bottom orientations, this is 315 * equivalent to SOUTH. 316 * 317 * @see java.awt.Component#getComponentOrientation 318 * @since 1.4 319 */ 320 public static final String PAGE_END = AFTER_LAST_LINE; 321 322 /** 323 * The component goes at the beginning of the line direction for the 324 * layout. For Western, left-to-right and top-to-bottom orientations, 325 * this is equivalent to WEST. 326 * 327 * @see java.awt.Component#getComponentOrientation 328 * @since 1.4 329 */ 330 public static final String LINE_START = BEFORE_LINE_BEGINS; 331 332 /** 333 * The component goes at the end of the line direction for the 334 * layout. For Western, left-to-right and top-to-bottom orientations, 335 * this is equivalent to EAST. 336 * 337 * @see java.awt.Component#getComponentOrientation 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 * @since JDK1.1 371 */ 372 public int getHgap() { 373 return hgap; 374 } 375 376 /** 377 * Sets the horizontal gap between components. 378 * @param hgap the horizontal gap between components 379 * @since JDK1.1 380 */ 381 public void setHgap(int hgap) { 382 this.hgap = hgap; 383 } 384 385 /** 386 * Returns the vertical gap between components. 387 * @since JDK1.1 388 */ 389 public int getVgap() { 390 return vgap; 391 } 392 393 /** 394 * Sets the vertical gap between components. 395 * @param vgap the vertical gap between components 396 * @since JDK1.1 397 */ 398 public void setVgap(int vgap) { 399 this.vgap = vgap; 400 } 401 402 /** 403 * Adds the specified component to the layout, using the specified 404 * constraint object. For border layouts, the constraint must be 405 * one of the following constants: <code>NORTH</code>, 406 * <code>SOUTH</code>, <code>EAST</code>, 407 * <code>WEST</code>, or <code>CENTER</code>. 408 * <p> 409 * Most applications do not call this method directly. This method 410 * is called when a component is added to a container using the 411 * <code>Container.add</code> method with the same argument types. 412 * @param comp the component to be added. 413 * @param constraints an object that specifies how and where 414 * the component is added to the layout. 415 * @see java.awt.Container#add(java.awt.Component, java.lang.Object) 416 * @exception IllegalArgumentException if the constraint object is not 417 * a string, or if it not one of the five specified constants. 418 * @since JDK1.1 419 */ 420 public void addLayoutComponent(Component comp, Object constraints) { 421 synchronized (comp.getTreeLock()) { 422 if ((constraints == null) || (constraints instanceof String)) { 423 addLayoutComponent((String)constraints, comp); 424 } else { 425 throw new IllegalArgumentException("cannot add to layout: constraint must be a string (or null)"); 426 } 427 } 428 } 429 430 /** 431 * @deprecated replaced by <code>addLayoutComponent(Component, Object)</code>. 432 */ 433 @Deprecated 434 public void addLayoutComponent(String name, Component comp) { 435 synchronized (comp.getTreeLock()) { 436 /* Special case: treat null the same as "Center". */ 437 if (name == null) { 438 name = "Center"; 439 } 440 441 /* Assign the component to one of the known regions of the layout. 442 */ 443 if ("Center".equals(name)) { 444 center = comp; 445 } else if ("North".equals(name)) { 446 north = comp; 447 } else if ("South".equals(name)) { 448 south = comp; 449 } else if ("East".equals(name)) { 450 east = comp; 451 } else if ("West".equals(name)) { 452 west = comp; 453 } else if (BEFORE_FIRST_LINE.equals(name)) { 454 firstLine = comp; 455 } else if (AFTER_LAST_LINE.equals(name)) { 456 lastLine = comp; 457 } else if (BEFORE_LINE_BEGINS.equals(name)) { 458 firstItem = comp; 459 } else if (AFTER_LINE_ENDS.equals(name)) { 460 lastItem = comp; 461 } else { 462 throw new IllegalArgumentException("cannot add to layout: unknown constraint: " + name); 463 } 464 } 465 } 466 467 /** 468 * Removes the specified component from this border layout. This 469 * method is called when a container calls its <code>remove</code> or 470 * <code>removeAll</code> methods. Most applications do not call this 471 * method directly. 472 * @param comp the component to be removed. 473 * @see java.awt.Container#remove(java.awt.Component) 474 * @see java.awt.Container#removeAll() 475 */ 476 public void removeLayoutComponent(Component comp) { 477 synchronized (comp.getTreeLock()) { 478 if (comp == center) { 479 center = null; 480 } else if (comp == north) { 481 north = null; 482 } else if (comp == south) { 483 south = null; 484 } else if (comp == east) { 485 east = null; 486 } else if (comp == west) { 487 west = null; 488 } 489 if (comp == firstLine) { 490 firstLine = null; 491 } else if (comp == lastLine) { 492 lastLine = null; 493 } else if (comp == firstItem) { 494 firstItem = null; 495 } else if (comp == lastItem) { 496 lastItem = null; 497 } 498 } 499 } 500 501 /** 502 * Gets the component that was added using the given constraint 503 * 504 * @param constraints the desired constraint, one of <code>CENTER</code>, 505 * <code>NORTH</code>, <code>SOUTH</code>, 506 * <code>WEST</code>, <code>EAST</code>, 507 * <code>PAGE_START</code>, <code>PAGE_END</code>, 508 * <code>LINE_START</code>, <code>LINE_END</code> 509 * @return the component at the given location, or <code>null</code> if 510 * the location is empty 511 * @exception IllegalArgumentException if the constraint object is 512 * not one of the nine specified constants 513 * @see #addLayoutComponent(java.awt.Component, java.lang.Object) 514 * @since 1.5 515 */ 516 public Component getLayoutComponent(Object constraints) { 517 if (CENTER.equals(constraints)) { 518 return center; 519 } else if (NORTH.equals(constraints)) { 520 return north; 521 } else if (SOUTH.equals(constraints)) { 522 return south; 523 } else if (WEST.equals(constraints)) { 524 return west; 525 } else if (EAST.equals(constraints)) { 526 return east; 527 } else if (PAGE_START.equals(constraints)) { 528 return firstLine; 529 } else if (PAGE_END.equals(constraints)) { 530 return lastLine; 531 } else if (LINE_START.equals(constraints)) { 532 return firstItem; 533 } else if (LINE_END.equals(constraints)) { 534 return lastItem; 535 } else { 536 throw new IllegalArgumentException("cannot get component: unknown constraint: " + constraints); 537 } 538 } 539 540 541 /** 542 * Returns the component that corresponds to the given constraint location 543 * based on the target <code>Container</code>'s component orientation. 544 * Components added with the relative constraints <code>PAGE_START</code>, 545 * <code>PAGE_END</code>, <code>LINE_START</code>, and <code>LINE_END</code> 546 * take precedence over components added with the explicit constraints 547 * <code>NORTH</code>, <code>SOUTH</code>, <code>WEST</code>, and <code>EAST</code>. 548 * The <code>Container</code>'s component orientation is used to determine the location of components 549 * added with <code>LINE_START</code> and <code>LINE_END</code>. 550 * 551 * @param constraints the desired absolute position, one of <code>CENTER</code>, 552 * <code>NORTH</code>, <code>SOUTH</code>, 553 * <code>EAST</code>, <code>WEST</code> 554 * @param target the {@code Container} used to obtain 555 * the constraint location based on the target 556 * {@code Container}'s component orientation. 557 * @return the component at the given location, or <code>null</code> if 558 * the location is empty 559 * @exception IllegalArgumentException if the constraint object is 560 * not one of the five specified constants 561 * @exception NullPointerException if the target parameter is null 562 * @see #addLayoutComponent(java.awt.Component, java.lang.Object) 563 * @since 1.5 564 */ 565 public Component getLayoutComponent(Container target, Object constraints) { 566 boolean ltr = target.getComponentOrientation().isLeftToRight(); 567 Component result = null; 568 569 if (NORTH.equals(constraints)) { 570 result = (firstLine != null) ? firstLine : north; 571 } else if (SOUTH.equals(constraints)) { 572 result = (lastLine != null) ? lastLine : south; 573 } else if (WEST.equals(constraints)) { 574 result = ltr ? firstItem : lastItem; 575 if (result == null) { 576 result = west; 577 } 578 } else if (EAST.equals(constraints)) { 579 result = ltr ? lastItem : firstItem; 580 if (result == null) { 581 result = east; 582 } 583 } else if (CENTER.equals(constraints)) { 584 result = center; 585 } else { 586 throw new IllegalArgumentException("cannot get component: invalid constraint: " + constraints); 587 } 588 589 return result; 590 } 591 592 593 /** 594 * Gets the constraints for the specified component 595 * 596 * @param comp the component to be queried 597 * @return the constraint for the specified component, 598 * or null if component is null or is not present 599 * in this layout 600 * @see #addLayoutComponent(java.awt.Component, java.lang.Object) 601 * @since 1.5 602 */ 603 public Object getConstraints(Component comp) { 604 //fix for 6242148 : API method java.awt.BorderLayout.getConstraints(null) should return null 605 if (comp == null){ 606 return null; 607 } 608 if (comp == center) { 609 return CENTER; 610 } else if (comp == north) { 611 return NORTH; 612 } else if (comp == south) { 613 return SOUTH; 614 } else if (comp == west) { 615 return WEST; 616 } else if (comp == east) { 617 return EAST; 618 } else if (comp == firstLine) { 619 return PAGE_START; 620 } else if (comp == lastLine) { 621 return PAGE_END; 622 } else if (comp == firstItem) { 623 return LINE_START; 624 } else if (comp == lastItem) { 625 return LINE_END; 626 } 627 return null; 628 } 629 630 /** 631 * Determines the minimum size of the <code>target</code> container 632 * using this layout manager. 633 * <p> 634 * This method is called when a container calls its 635 * <code>getMinimumSize</code> method. Most applications do not call 636 * this method directly. 637 * @param target the container in which to do the layout. 638 * @return the minimum dimensions needed to lay out the subcomponents 639 * of the specified container. 640 * @see java.awt.Container 641 * @see java.awt.BorderLayout#preferredLayoutSize 642 * @see java.awt.Container#getMinimumSize() 643 */ 644 public Dimension minimumLayoutSize(Container target) { 645 synchronized (target.getTreeLock()) { 646 Dimension dim = new Dimension(0, 0); 647 648 boolean ltr = target.getComponentOrientation().isLeftToRight(); 649 Component c = null; 650 651 if ((c=getChild(EAST,ltr)) != null) { 652 Dimension d = c.getMinimumSize(); 653 dim.width += d.width + hgap; 654 dim.height = Math.max(d.height, dim.height); 655 } 656 if ((c=getChild(WEST,ltr)) != null) { 657 Dimension d = c.getMinimumSize(); 658 dim.width += d.width + hgap; 659 dim.height = Math.max(d.height, dim.height); 660 } 661 if ((c=getChild(CENTER,ltr)) != null) { 662 Dimension d = c.getMinimumSize(); 663 dim.width += d.width; 664 dim.height = Math.max(d.height, dim.height); 665 } 666 if ((c=getChild(NORTH,ltr)) != null) { 667 Dimension d = c.getMinimumSize(); 668 dim.width = Math.max(d.width, dim.width); 669 dim.height += d.height + vgap; 670 } 671 if ((c=getChild(SOUTH,ltr)) != null) { 672 Dimension d = c.getMinimumSize(); 673 dim.width = Math.max(d.width, dim.width); 674 dim.height += d.height + vgap; 675 } 676 677 Insets insets = target.getInsets(); 678 dim.width += insets.left + insets.right; 679 dim.height += insets.top + insets.bottom; 680 681 return dim; 682 } 683 } 684 685 /** 686 * Determines the preferred size of the <code>target</code> 687 * container using this layout manager, based on the components 688 * in the container. 689 * <p> 690 * Most applications do not call this method directly. This method 691 * is called when a container calls its <code>getPreferredSize</code> 692 * method. 693 * @param target the container in which to do the layout. 694 * @return the preferred dimensions to lay out the subcomponents 695 * of the specified container. 696 * @see java.awt.Container 697 * @see java.awt.BorderLayout#minimumLayoutSize 698 * @see java.awt.Container#getPreferredSize() 699 */ 700 public Dimension preferredLayoutSize(Container target) { 701 synchronized (target.getTreeLock()) { 702 Dimension dim = new Dimension(0, 0); 703 704 boolean ltr = target.getComponentOrientation().isLeftToRight(); 705 Component c = null; 706 707 if ((c=getChild(EAST,ltr)) != null) { 708 Dimension d = c.getPreferredSize(); 709 dim.width += d.width + hgap; 710 dim.height = Math.max(d.height, dim.height); 711 } 712 if ((c=getChild(WEST,ltr)) != null) { 713 Dimension d = c.getPreferredSize(); 714 dim.width += d.width + hgap; 715 dim.height = Math.max(d.height, dim.height); 716 } 717 if ((c=getChild(CENTER,ltr)) != null) { 718 Dimension d = c.getPreferredSize(); 719 dim.width += d.width; 720 dim.height = Math.max(d.height, dim.height); 721 } 722 if ((c=getChild(NORTH,ltr)) != null) { 723 Dimension d = c.getPreferredSize(); 724 dim.width = Math.max(d.width, dim.width); 725 dim.height += d.height + vgap; 726 } 727 if ((c=getChild(SOUTH,ltr)) != null) { 728 Dimension d = c.getPreferredSize(); 729 dim.width = Math.max(d.width, dim.width); 730 dim.height += d.height + vgap; 731 } 732 733 Insets insets = target.getInsets(); 734 dim.width += insets.left + insets.right; 735 dim.height += insets.top + insets.bottom; 736 737 return dim; 738 } 739 } 740 741 /** 742 * Returns the maximum dimensions for this layout given the components 743 * in the specified target container. 744 * @param target the component which needs to be laid out 745 * @see Container 746 * @see #minimumLayoutSize 747 * @see #preferredLayoutSize 748 */ 749 public Dimension maximumLayoutSize(Container target) { 750 return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); 751 } 752 753 /** 754 * Returns the alignment along the x axis. This specifies how 755 * the component would like to be aligned relative to other 756 * components. The value should be a number between 0 and 1 757 * where 0 represents alignment along the origin, 1 is aligned 758 * the furthest away from the origin, 0.5 is centered, etc. 759 */ 760 public float getLayoutAlignmentX(Container parent) { 761 return 0.5f; 762 } 763 764 /** 765 * Returns the alignment along the y axis. This specifies how 766 * the component would like to be aligned relative to other 767 * components. The value should be a number between 0 and 1 768 * where 0 represents alignment along the origin, 1 is aligned 769 * the furthest away from the origin, 0.5 is centered, etc. 770 */ 771 public float getLayoutAlignmentY(Container parent) { 772 return 0.5f; 773 } 774 775 /** 776 * Invalidates the layout, indicating that if the layout manager 777 * has cached information it should be discarded. 778 */ 779 public void invalidateLayout(Container target) { 780 } 781 782 /** 783 * Lays out the container argument using this border layout. 784 * <p> 785 * This method actually reshapes the components in the specified 786 * container in order to satisfy the constraints of this 787 * <code>BorderLayout</code> object. The <code>NORTH</code> 788 * and <code>SOUTH</code> components, if any, are placed at 789 * the top and bottom of the container, respectively. The 790 * <code>WEST</code> and <code>EAST</code> components are 791 * then placed on the left and right, respectively. Finally, 792 * the <code>CENTER</code> object is placed in any remaining 793 * space in the middle. 794 * <p> 795 * Most applications do not call this method directly. This method 796 * is called when a container calls its <code>doLayout</code> method. 797 * @param target the container in which to do the layout. 798 * @see java.awt.Container 799 * @see java.awt.Container#doLayout() 800 */ 801 public void layoutContainer(Container target) { 802 synchronized (target.getTreeLock()) { 803 Insets insets = target.getInsets(); 804 int top = insets.top; 805 int bottom = target.height - insets.bottom; 806 int left = insets.left; 807 int right = target.width - insets.right; 808 809 boolean ltr = target.getComponentOrientation().isLeftToRight(); 810 Component c = null; 811 812 if ((c=getChild(NORTH,ltr)) != null) { 813 c.setSize(right - left, c.height); 814 Dimension d = c.getPreferredSize(); 815 c.setBounds(left, top, right - left, d.height); 816 top += d.height + vgap; 817 } 818 if ((c=getChild(SOUTH,ltr)) != null) { 819 c.setSize(right - left, c.height); 820 Dimension d = c.getPreferredSize(); 821 c.setBounds(left, bottom - d.height, right - left, d.height); 822 bottom -= d.height + vgap; 823 } 824 if ((c=getChild(EAST,ltr)) != null) { 825 c.setSize(c.width, bottom - top); 826 Dimension d = c.getPreferredSize(); 827 c.setBounds(right - d.width, top, d.width, bottom - top); 828 right -= d.width + hgap; 829 } 830 if ((c=getChild(WEST,ltr)) != null) { 831 c.setSize(c.width, bottom - top); 832 Dimension d = c.getPreferredSize(); 833 c.setBounds(left, top, d.width, bottom - top); 834 left += d.width + hgap; 835 } 836 if ((c=getChild(CENTER,ltr)) != null) { 837 c.setBounds(left, top, right - left, bottom - top); 838 } 839 } 840 } 841 842 /** 843 * Get the component that corresponds to the given constraint location 844 * 845 * @param key The desired absolute position, 846 * either NORTH, SOUTH, EAST, or WEST. 847 * @param ltr Is the component line direction left-to-right? 848 */ 849 private Component getChild(String key, boolean ltr) { 850 Component result = null; 851 852 if (key == NORTH) { 853 result = (firstLine != null) ? firstLine : north; 854 } 855 else if (key == SOUTH) { 856 result = (lastLine != null) ? lastLine : south; 857 } 858 else if (key == WEST) { 859 result = ltr ? firstItem : lastItem; 860 if (result == null) { 861 result = west; 862 } 863 } 864 else if (key == EAST) { 865 result = ltr ? lastItem : firstItem; 866 if (result == null) { 867 result = east; 868 } 869 } 870 else if (key == CENTER) { 871 result = center; 872 } 873 if (result != null && !result.visible) { 874 result = null; 875 } 876 return result; 877 } 878 879 /** 880 * Returns a string representation of the state of this border layout. 881 * @return a string representation of this border layout. 882 */ 883 public String toString() { 884 return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + "]"; 885 } 886 }