1/* 2 * Copyright (c) 1995, 2014, 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 26package java.awt; 27 28import 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, 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 */ 124public 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 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} 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 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} 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. 380 * 381 * @param hgap the horizontal gap between components 382 * @since 1.1 383 */ 384 public void setHgap(int hgap) { 385 this.hgap = hgap; 386 } 387 388 /** 389 * Returns the vertical gap between components. 390 * 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 } 584 } else if (EAST.equals(constraints)) { 585 result = ltr ? lastItem : firstItem; 586 if (result == null) { 587 result = east; 588 } 589 } else if (CENTER.equals(constraints)) { 590 result = center; 591 } else { 592 throw new IllegalArgumentException("cannot get component: invalid constraint: " + constraints); 593 } 594 595 return result; 596 } 597 598 599 /** 600 * Gets the constraints for the specified component 601 * 602 * @param comp the component to be queried 603 * @return the constraint for the specified component, 604 * or null if component is null or is not present 605 * in this layout 606 * @see #addLayoutComponent(java.awt.Component, java.lang.Object) 607 * @since 1.5 608 */ 609 public Object getConstraints(Component comp) { 610 //fix for 6242148 : API method java.awt.BorderLayout.getConstraints(null) should return null 611 if (comp == null){ 612 return null; 613 } 614 if (comp == center) { 615 return CENTER; 616 } else if (comp == north) { 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 } 662 if ((c=getChild(WEST,ltr)) != null) { 663 Dimension d = c.getMinimumSize(); 664 dim.width += d.width + hgap; 665 dim.height = Math.max(d.height, dim.height); 666 } 667 if ((c=getChild(CENTER,ltr)) != null) { 668 Dimension d = c.getMinimumSize(); 669 dim.width += d.width; 670 dim.height = Math.max(d.height, dim.height); 671 } 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 } 718 if ((c=getChild(WEST,ltr)) != null) { 719 Dimension d = c.getPreferredSize(); 720 dim.width += d.width + hgap; 721 dim.height = Math.max(d.height, dim.height); 722 } 723 if ((c=getChild(CENTER,ltr)) != null) { 724 Dimension d = c.getPreferredSize(); 725 dim.width += d.width; 726 dim.height = Math.max(d.height, dim.height); 727 } 728 if ((c=getChild(NORTH,ltr)) != null) { 729 Dimension d = c.getPreferredSize(); 730 dim.width = Math.max(d.width, dim.width); 731 dim.height += d.height + vgap; 732 } 733 if ((c=getChild(SOUTH,ltr)) != null) { 734 Dimension d = c.getPreferredSize(); 735 dim.width = Math.max(d.width, dim.width); 736 dim.height += d.height + vgap; 737 } 738 739 Insets insets = target.getInsets(); 740 dim.width += insets.left + insets.right; 741 dim.height += insets.top + insets.bottom; 742 743 return dim; 744 } 745 } 746 747 /** 748 * Returns the maximum dimensions for this layout given the components 749 * in the specified target container. 750 * @param target the component which needs to be laid out 751 * @see Container 752 * @see #minimumLayoutSize 753 * @see #preferredLayoutSize 754 */ 755 public Dimension maximumLayoutSize(Container target) { 756 return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); 757 } 758 759 /** 760 * Returns the alignment along the x axis. This specifies how 761 * the component would like to be aligned relative to other 762 * components. The value should be a number between 0 and 1 763 * where 0 represents alignment along the origin, 1 is aligned 764 * the furthest away from the origin, 0.5 is centered, etc. 765 */ 766 public float getLayoutAlignmentX(Container parent) { 767 return 0.5f; 768 } 769 770 /** 771 * Returns the alignment along the y axis. This specifies how 772 * the component would like to be aligned relative to other 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; 823 } 824 if ((c=getChild(SOUTH,ltr)) != null) { 825 c.setSize(right - left, c.height); 826 Dimension d = c.getPreferredSize(); 827 c.setBounds(left, bottom - d.height, right - left, d.height); 828 bottom -= d.height + vgap; 829 } 830 if ((c=getChild(EAST,ltr)) != null) { 831 c.setSize(c.width, bottom - top); 832 Dimension d = c.getPreferredSize(); 833 c.setBounds(right - d.width, top, d.width, bottom - top); 834 right -= d.width + hgap; 835 } 836 if ((c=getChild(WEST,ltr)) != null) { 837 c.setSize(c.width, bottom - top); 838 Dimension d = c.getPreferredSize(); 839 c.setBounds(left, top, d.width, bottom - top); 840 left += d.width + hgap; 841 } 842 if ((c=getChild(CENTER,ltr)) != null) { 843 c.setBounds(left, top, right - left, bottom - top); 844 } 845 } 846 } 847 848 /** 849 * Get the component that corresponds to the given constraint location 850 * 851 * @param key The desired absolute position, 852 * either NORTH, SOUTH, EAST, or WEST. 853 * @param ltr Is the component line direction left-to-right? 854 */ 855 private Component getChild(String key, boolean ltr) { 856 Component result = null; 857 858 if (key == NORTH) { 859 result = (firstLine != null) ? firstLine : north; 860 } 861 else if (key == SOUTH) { 862 result = (lastLine != null) ? lastLine : south; 863 } 864 else if (key == WEST) { 865 result = ltr ? firstItem : lastItem; 866 if (result == null) { 867 result = west; 868 } 869 } 870 else if (key == EAST) { 871 result = ltr ? lastItem : firstItem; 872 if (result == null) { 873 result = east; 874 } 875 } 876 else if (key == CENTER) { 877 result = center; 878 } 879 if (result != null && !result.visible) { 880 result = null; 881 } 882 return result; 883 } 884 885 /** 886 * Returns a string representation of the state of this border layout. 887 * @return a string representation of this border layout. 888 */ 889 public String toString() { 890 return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + "]"; 891 } 892} 893