001 /*
002 * Copyright 1995-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package java.awt;
027
028 import java.util.Hashtable;
029
030 /**
031 * A border layout lays out a container, arranging and resizing
032 * its components to fit in five regions:
033 * north, south, east, west, and center.
034 * Each region may contain no more than one component, and
035 * is identified by a corresponding constant:
036 * <code>NORTH</code>, <code>SOUTH</code>, <code>EAST</code>,
037 * <code>WEST</code>, and <code>CENTER</code>. When adding a
038 * component to a container with a border layout, use one of these
039 * five constants, for example:
040 * <pre>
041 * Panel p = new Panel();
042 * p.setLayout(new BorderLayout());
043 * p.add(new Button("Okay"), BorderLayout.SOUTH);
044 * </pre>
045 * As a convenience, <code>BorderLayout</code> interprets the
046 * absence of a string specification the same as the constant
047 * <code>CENTER</code>:
048 * <pre>
049 * Panel p2 = new Panel();
050 * p2.setLayout(new BorderLayout());
051 * p2.add(new TextArea()); // Same as p.add(new TextArea(), BorderLayout.CENTER);
052 * </pre>
053 * <p>
054 * In addition, <code>BorderLayout</code> supports the relative
055 * positioning constants, <code>PAGE_START</code>, <code>PAGE_END</code>,
056 * <code>LINE_START</code>, and <code>LINE_END</code>.
057 * In a container whose <code>ComponentOrientation</code> is set to
058 * <code>ComponentOrientation.LEFT_TO_RIGHT</code>, these constants map to
059 * <code>NORTH</code>, <code>SOUTH</code>, <code>WEST</code>, and
060 * <code>EAST</code>, respectively.
061 * <p>
062 * For compatibility with previous releases, <code>BorderLayout</code>
063 * also includes the relative positioning constants <code>BEFORE_FIRST_LINE</code>,
064 * <code>AFTER_LAST_LINE</code>, <code>BEFORE_LINE_BEGINS</code> and
065 * <code>AFTER_LINE_ENDS</code>. These are equivalent to
066 * <code>PAGE_START</code>, <code>PAGE_END</code>, <code>LINE_START</code>
067 * and <code>LINE_END</code> respectively. For
068 * consistency with the relative positioning constants used by other
069 * components, the latter constants are preferred.
070 * <p>
071 * Mixing both absolute and relative positioning constants can lead to
072 * unpredicable results. If
073 * you use both types, the relative constants will take precedence.
074 * For example, if you add components using both the <code>NORTH</code>
075 * and <code>PAGE_START</code> constants in a container whose
076 * orientation is <code>LEFT_TO_RIGHT</code>, only the
077 * <code>PAGE_START</code> will be layed out.
078 * <p>
079 * NOTE: Currently (in the Java 2 platform v1.2),
080 * <code>BorderLayout</code> does not support vertical
081 * orientations. The <code>isVertical</code> setting on the container's
082 * <code>ComponentOrientation</code> is not respected.
083 * <p>
084 * The components are laid out according to their
085 * preferred sizes and the constraints of the container's size.
086 * The <code>NORTH</code> and <code>SOUTH</code> components may
087 * be stretched horizontally; the <code>EAST</code> and
088 * <code>WEST</code> components may be stretched vertically;
089 * the <code>CENTER</code> component may stretch both horizontally
090 * and vertically to fill any space left over.
091 * <p>
092 * Here is an example of five buttons in an applet laid out using
093 * the <code>BorderLayout</code> layout manager:
094 * <p>
095 * <img src="doc-files/BorderLayout-1.gif"
096 * alt="Diagram of an applet demonstrating BorderLayout.
097 * Each section of the BorderLayout contains a Button corresponding to its position in the layout, one of:
098 * North, West, Center, East, or South."
099 * ALIGN=center HSPACE=10 VSPACE=7>
100 * <p>
101 * The code for this applet is as follows:
102 * <p>
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 * <p>
119 * @version 1.66, 05/05/07
120 * @author Arthur van Hoff
121 * @see java.awt.Container#add(String, Component)
122 * @see java.awt.ComponentOrientation
123 * @since JDK1.0
124 */
125 public class BorderLayout implements LayoutManager2,
126 java.io.Serializable {
127 /**
128 * Constructs a border layout with the horizontal gaps
129 * between components.
130 * The horizontal gap is specified by <code>hgap</code>.
131 *
132 * @see #getHgap()
133 * @see #setHgap(int)
134 *
135 * @serial
136 */
137 int hgap;
138
139 /**
140 * Constructs a border layout with the vertical gaps
141 * between components.
142 * The vertical gap is specified by <code>vgap</code>.
143 *
144 * @see #getVgap()
145 * @see #setVgap(int)
146 * @serial
147 */
148 int vgap;
149
150 /**
151 * Constant to specify components location to be the
152 * north portion of the border layout.
153 * @serial
154 * @see #getChild(String, boolean)
155 * @see #addLayoutComponent
156 * @see #getLayoutAlignmentX
157 * @see #getLayoutAlignmentY
158 * @see #removeLayoutComponent
159 */
160 Component north;
161 /**
162 * Constant to specify components location to be the
163 * west portion of the border layout.
164 * @serial
165 * @see #getChild(String, boolean)
166 * @see #addLayoutComponent
167 * @see #getLayoutAlignmentX
168 * @see #getLayoutAlignmentY
169 * @see #removeLayoutComponent
170 */
171 Component west;
172 /**
173 * Constant to specify components location to be the
174 * east portion of the border layout.
175 * @serial
176 * @see #getChild(String, boolean)
177 * @see #addLayoutComponent
178 * @see #getLayoutAlignmentX
179 * @see #getLayoutAlignmentY
180 * @see #removeLayoutComponent
181 */
182 Component east;
183 /**
184 * Constant to specify components location to be the
185 * south portion of the border layout.
186 * @serial
187 * @see #getChild(String, boolean)
188 * @see #addLayoutComponent
189 * @see #getLayoutAlignmentX
190 * @see #getLayoutAlignmentY
191 * @see #removeLayoutComponent
192 */
193 Component south;
194 /**
195 * Constant to specify components location to be the
196 * center portion of the border layout.
197 * @serial
198 * @see #getChild(String, boolean)
199 * @see #addLayoutComponent
200 * @see #getLayoutAlignmentX
201 * @see #getLayoutAlignmentY
202 * @see #removeLayoutComponent
203 */
204 Component center;
205
206 /**
207 *
208 * A relative positioning constant, that can be used instead of
209 * north, south, east, west or center.
210 * mixing the two types of constants can lead to unpredicable results. If
211 * you use both types, the relative constants will take precedence.
212 * For example, if you add components using both the <code>NORTH</code>
213 * and <code>BEFORE_FIRST_LINE</code> constants in a container whose
214 * orientation is <code>LEFT_TO_RIGHT</code>, only the
215 * <code>BEFORE_FIRST_LINE</code> will be layed out.
216 * This will be the same for lastLine, firstItem, lastItem.
217 * @serial
218 */
219 Component firstLine;
220 /**
221 * A relative positioning constant, that can be used instead of
222 * north, south, east, west or center.
223 * Please read Description for firstLine.
224 * @serial
225 */
226 Component lastLine;
227 /**
228 * A relative positioning constant, that can be used instead of
229 * north, south, east, west or center.
230 * Please read Description for firstLine.
231 * @serial
232 */
233 Component firstItem;
234 /**
235 * A relative positioning constant, that can be used instead of
236 * north, south, east, west or center.
237 * Please read Description for firstLine.
238 * @serial
239 */
240 Component lastItem;
241
242 /**
243 * The north layout constraint (top of container).
244 */
245 public static final String NORTH = "North";
246
247 /**
248 * The south layout constraint (bottom of container).
249 */
250 public static final String SOUTH = "South";
251
252 /**
253 * The east layout constraint (right side of container).
254 */
255 public static final String EAST = "East";
256
257 /**
258 * The west layout constraint (left side of container).
259 */
260 public static final String WEST = "West";
261
262 /**
263 * The center layout constraint (middle of container).
264 */
265 public static final String CENTER = "Center";
266
267 /**
268 * Synonym for PAGE_START. Exists for compatibility with previous
269 * versions. PAGE_START is preferred.
270 *
271 * @see #PAGE_START
272 * @since 1.2
273 */
274 public static final String BEFORE_FIRST_LINE = "First";
275
276 /**
277 * Synonym for PAGE_END. Exists for compatibility with previous
278 * versions. PAGE_END is preferred.
279 *
280 * @see #PAGE_END
281 * @since 1.2
282 */
283 public static final String AFTER_LAST_LINE = "Last";
284
285 /**
286 * Synonym for LINE_START. Exists for compatibility with previous
287 * versions. LINE_START is preferred.
288 *
289 * @see #LINE_START
290 * @since 1.2
291 */
292 public static final String BEFORE_LINE_BEGINS = "Before";
293
294 /**
295 * Synonym for LINE_END. Exists for compatibility with previous
296 * versions. LINE_END is preferred.
297 *
298 * @see #LINE_END
299 * @since 1.2
300 */
301 public static final String AFTER_LINE_ENDS = "After";
302
303 /**
304 * The component comes before the first line of the layout's content.
305 * For Western, left-to-right and top-to-bottom orientations, this is
306 * equivalent to NORTH.
307 *
308 * @see java.awt.Component#getComponentOrientation
309 * @since 1.4
310 */
311 public static final String PAGE_START = BEFORE_FIRST_LINE;
312
313 /**
314 * The component comes after the last line of the layout's content.
315 * For Western, left-to-right and top-to-bottom orientations, this is
316 * equivalent to SOUTH.
317 *
318 * @see java.awt.Component#getComponentOrientation
319 * @since 1.4
320 */
321 public static final String PAGE_END = AFTER_LAST_LINE;
322
323 /**
324 * The component goes at the beginning of the line direction for the
325 * layout. For Western, left-to-right and top-to-bottom orientations,
326 * this is equivalent to WEST.
327 *
328 * @see java.awt.Component#getComponentOrientation
329 * @since 1.4
330 */
331 public static final String LINE_START = BEFORE_LINE_BEGINS;
332
333 /**
334 * The component goes at the end of the line direction for the
335 * layout. For Western, left-to-right and top-to-bottom orientations,
336 * this is equivalent to EAST.
337 *
338 * @see java.awt.Component#getComponentOrientation
339 * @since 1.4
340 */
341 public static final String LINE_END = AFTER_LINE_ENDS;
342
343 /*
344 * JDK 1.1 serialVersionUID
345 */
346 private static final long serialVersionUID = -8658291919501921765L;
347
348 /**
349 * Constructs a new border layout with
350 * no gaps between components.
351 */
352 public BorderLayout() {
353 this (0, 0);
354 }
355
356 /**
357 * Constructs a border layout with the specified gaps
358 * between components.
359 * The horizontal gap is specified by <code>hgap</code>
360 * and the vertical gap is specified by <code>vgap</code>.
361 * @param hgap the horizontal gap.
362 * @param vgap the vertical gap.
363 */
364 public BorderLayout(int hgap, int vgap) {
365 this .hgap = hgap;
366 this .vgap = vgap;
367 }
368
369 /**
370 * Returns the horizontal gap between components.
371 * @since JDK1.1
372 */
373 public int getHgap() {
374 return hgap;
375 }
376
377 /**
378 * Sets the horizontal gap between components.
379 * @param hgap the horizontal gap between components
380 * @since JDK1.1
381 */
382 public void setHgap(int hgap) {
383 this .hgap = hgap;
384 }
385
386 /**
387 * Returns the vertical gap between components.
388 * @since JDK1.1
389 */
390 public int getVgap() {
391 return vgap;
392 }
393
394 /**
395 * Sets the vertical gap between components.
396 * @param vgap the vertical gap between components
397 * @since JDK1.1
398 */
399 public void setVgap(int vgap) {
400 this .vgap = vgap;
401 }
402
403 /**
404 * Adds the specified component to the layout, using the specified
405 * constraint object. For border layouts, the constraint must be
406 * one of the following constants: <code>NORTH</code>,
407 * <code>SOUTH</code>, <code>EAST</code>,
408 * <code>WEST</code>, or <code>CENTER</code>.
409 * <p>
410 * Most applications do not call this method directly. This method
411 * is called when a component is added to a container using the
412 * <code>Container.add</code> method with the same argument types.
413 * @param comp the component to be added.
414 * @param constraints an object that specifies how and where
415 * the component is added to the layout.
416 * @see java.awt.Container#add(java.awt.Component, java.lang.Object)
417 * @exception IllegalArgumentException if the constraint object is not
418 * a string, or if it not one of the five specified
419 * constants.
420 * @since JDK1.1
421 */
422 public void addLayoutComponent(Component comp, Object constraints) {
423 synchronized (comp.getTreeLock()) {
424 if ((constraints == null)
425 || (constraints instanceof String)) {
426 addLayoutComponent((String) constraints, comp);
427 } else {
428 throw new IllegalArgumentException(
429 "cannot add to layout: constraint must be a string (or null)");
430 }
431 }
432 }
433
434 /**
435 * @deprecated replaced by <code>addLayoutComponent(Component, Object)</code>.
436 */
437 @Deprecated
438 public void addLayoutComponent(String name, Component comp) {
439 synchronized (comp.getTreeLock()) {
440 /* Special case: treat null the same as "Center". */
441 if (name == null) {
442 name = "Center";
443 }
444
445 /* Assign the component to one of the known regions of the layout.
446 */
447 if ("Center".equals(name)) {
448 center = comp;
449 } else if ("North".equals(name)) {
450 north = comp;
451 } else if ("South".equals(name)) {
452 south = comp;
453 } else if ("East".equals(name)) {
454 east = comp;
455 } else if ("West".equals(name)) {
456 west = comp;
457 } else if (BEFORE_FIRST_LINE.equals(name)) {
458 firstLine = comp;
459 } else if (AFTER_LAST_LINE.equals(name)) {
460 lastLine = comp;
461 } else if (BEFORE_LINE_BEGINS.equals(name)) {
462 firstItem = comp;
463 } else if (AFTER_LINE_ENDS.equals(name)) {
464 lastItem = comp;
465 } else {
466 throw new IllegalArgumentException(
467 "cannot add to layout: unknown constraint: "
468 + 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(
543 "cannot get component: unknown constraint: "
544 + constraints);
545 }
546 }
547
548 /**
549 * Returns the component that corresponds to the given constraint location
550 * based on the target <code>Container</code>'s component orientation.
551 * Components added with the relative constraints <code>PAGE_START</code>,
552 * <code>PAGE_END</code>, <code>LINE_START</code>, and <code>LINE_END</code>
553 * take precedence over components added with the explicit constraints
554 * <code>NORTH</code>, <code>SOUTH</code>, <code>WEST</code>, and <code>EAST</code>.
555 * The <code>Container</code>'s component orientation is used to determine the location of components
556 * added with <code>LINE_START</code> and <code>LINE_END</code>.
557 *
558 * @param constraints the desired absolute position, one of <code>CENTER</code>,
559 * <code>NORTH</code>, <code>SOUTH</code>,
560 * <code>EAST</code>, <code>WEST</code>
561 * @param target the {@code Container} used to obtain
562 * the constraint location based on the target
563 * {@code Container}'s component orientation.
564 * @return the component at the given location, or <code>null</code> if
565 * the location is empty
566 * @exception IllegalArgumentException if the constraint object is
567 * not one of the five specified constants
568 * @exception NullPointerException if the target parameter is null
569 * @see #addLayoutComponent(java.awt.Component, java.lang.Object)
570 * @since 1.5
571 */
572 public Component getLayoutComponent(Container target,
573 Object constraints) {
574 boolean ltr = target.getComponentOrientation().isLeftToRight();
575 Component result = null;
576
577 if (NORTH.equals(constraints)) {
578 result = (firstLine != null) ? firstLine : north;
579 } else if (SOUTH.equals(constraints)) {
580 result = (lastLine != null) ? lastLine : south;
581 } else if (WEST.equals(constraints)) {
582 result = ltr ? firstItem : lastItem;
583 if (result == null) {
584 result = west;
585 }
586 } else if (EAST.equals(constraints)) {
587 result = ltr ? lastItem : firstItem;
588 if (result == null) {
589 result = east;
590 }
591 } else if (CENTER.equals(constraints)) {
592 result = center;
593 } else {
594 throw new IllegalArgumentException(
595 "cannot get component: invalid constraint: "
596 + constraints);
597 }
598
599 return result;
600 }
601
602 /**
603 * Gets the constraints for the specified component
604 *
605 * @param comp the component to be queried
606 * @return the constraint for the specified component,
607 * or null if component is null or is not present
608 * in this layout
609 * @see #addLayoutComponent(java.awt.Component, java.lang.Object)
610 * @since 1.5
611 */
612 public Object getConstraints(Component comp) {
613 //fix for 6242148 : API method java.awt.BorderLayout.getConstraints(null) should return null
614 if (comp == null) {
615 return null;
616 }
617 if (comp == center) {
618 return CENTER;
619 } else if (comp == north) {
620 return NORTH;
621 } else if (comp == south) {
622 return SOUTH;
623 } else if (comp == west) {
624 return WEST;
625 } else if (comp == east) {
626 return EAST;
627 } else if (comp == firstLine) {
628 return PAGE_START;
629 } else if (comp == lastLine) {
630 return PAGE_END;
631 } else if (comp == firstItem) {
632 return LINE_START;
633 } else if (comp == lastItem) {
634 return LINE_END;
635 }
636 return null;
637 }
638
639 /**
640 * Determines the minimum size of the <code>target</code> container
641 * using this layout manager.
642 * <p>
643 * This method is called when a container calls its
644 * <code>getMinimumSize</code> method. Most applications do not call
645 * this method directly.
646 * @param target the container in which to do the layout.
647 * @return the minimum dimensions needed to lay out the subcomponents
648 * of the specified container.
649 * @see java.awt.Container
650 * @see java.awt.BorderLayout#preferredLayoutSize
651 * @see java.awt.Container#getMinimumSize()
652 */
653 public Dimension minimumLayoutSize(Container target) {
654 synchronized (target.getTreeLock()) {
655 Dimension dim = new Dimension(0, 0);
656
657 boolean ltr = target.getComponentOrientation()
658 .isLeftToRight();
659 Component c = null;
660
661 if ((c = getChild(EAST, ltr)) != null) {
662 Dimension d = c.getMinimumSize();
663 dim.width += d.width + hgap;
664 dim.height = Math.max(d.height, dim.height);
665 }
666 if ((c = getChild(WEST, ltr)) != null) {
667 Dimension d = c.getMinimumSize();
668 dim.width += d.width + hgap;
669 dim.height = Math.max(d.height, dim.height);
670 }
671 if ((c = getChild(CENTER, ltr)) != null) {
672 Dimension d = c.getMinimumSize();
673 dim.width += d.width;
674 dim.height = Math.max(d.height, dim.height);
675 }
676 if ((c = getChild(NORTH, ltr)) != null) {
677 Dimension d = c.getMinimumSize();
678 dim.width = Math.max(d.width, dim.width);
679 dim.height += d.height + vgap;
680 }
681 if ((c = getChild(SOUTH, ltr)) != null) {
682 Dimension d = c.getMinimumSize();
683 dim.width = Math.max(d.width, dim.width);
684 dim.height += d.height + vgap;
685 }
686
687 Insets insets = target.getInsets();
688 dim.width += insets.left + insets.right;
689 dim.height += insets.top + insets.bottom;
690
691 return dim;
692 }
693 }
694
695 /**
696 * Determines the preferred size of the <code>target</code>
697 * container using this layout manager, based on the components
698 * in the container.
699 * <p>
700 * Most applications do not call this method directly. This method
701 * is called when a container calls its <code>getPreferredSize</code>
702 * method.
703 * @param target the container in which to do the layout.
704 * @return the preferred dimensions to lay out the subcomponents
705 * of the specified container.
706 * @see java.awt.Container
707 * @see java.awt.BorderLayout#minimumLayoutSize
708 * @see java.awt.Container#getPreferredSize()
709 */
710 public Dimension preferredLayoutSize(Container target) {
711 synchronized (target.getTreeLock()) {
712 Dimension dim = new Dimension(0, 0);
713
714 boolean ltr = target.getComponentOrientation()
715 .isLeftToRight();
716 Component c = null;
717
718 if ((c = getChild(EAST, 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(WEST, ltr)) != null) {
724 Dimension d = c.getPreferredSize();
725 dim.width += d.width + hgap;
726 dim.height = Math.max(d.height, dim.height);
727 }
728 if ((c = getChild(CENTER, ltr)) != null) {
729 Dimension d = c.getPreferredSize();
730 dim.width += d.width;
731 dim.height = Math.max(d.height, dim.height);
732 }
733 if ((c = getChild(NORTH, ltr)) != null) {
734 Dimension d = c.getPreferredSize();
735 dim.width = Math.max(d.width, dim.width);
736 dim.height += d.height + vgap;
737 }
738 if ((c = getChild(SOUTH, ltr)) != null) {
739 Dimension d = c.getPreferredSize();
740 dim.width = Math.max(d.width, dim.width);
741 dim.height += d.height + vgap;
742 }
743
744 Insets insets = target.getInsets();
745 dim.width += insets.left + insets.right;
746 dim.height += insets.top + insets.bottom;
747
748 return dim;
749 }
750 }
751
752 /**
753 * Returns the maximum dimensions for this layout given the components
754 * in the specified target container.
755 * @param target the component which needs to be laid out
756 * @see Container
757 * @see #minimumLayoutSize
758 * @see #preferredLayoutSize
759 */
760 public Dimension maximumLayoutSize(Container target) {
761 return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
762 }
763
764 /**
765 * Returns the alignment along the x 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 getLayoutAlignmentX(Container parent) {
772 return 0.5f;
773 }
774
775 /**
776 * Returns the alignment along the y axis. This specifies how
777 * the component would like to be aligned relative to other
778 * components. The value should be a number between 0 and 1
779 * where 0 represents alignment along the origin, 1 is aligned
780 * the furthest away from the origin, 0.5 is centered, etc.
781 */
782 public float getLayoutAlignmentY(Container parent) {
783 return 0.5f;
784 }
785
786 /**
787 * Invalidates the layout, indicating that if the layout manager
788 * has cached information it should be discarded.
789 */
790 public void invalidateLayout(Container target) {
791 }
792
793 /**
794 * Lays out the container argument using this border layout.
795 * <p>
796 * This method actually reshapes the components in the specified
797 * container in order to satisfy the constraints of this
798 * <code>BorderLayout</code> object. The <code>NORTH</code>
799 * and <code>SOUTH</code> components, if any, are placed at
800 * the top and bottom of the container, respectively. The
801 * <code>WEST</code> and <code>EAST</code> components are
802 * then placed on the left and right, respectively. Finally,
803 * the <code>CENTER</code> object is placed in any remaining
804 * space in the middle.
805 * <p>
806 * Most applications do not call this method directly. This method
807 * is called when a container calls its <code>doLayout</code> method.
808 * @param target the container in which to do the layout.
809 * @see java.awt.Container
810 * @see java.awt.Container#doLayout()
811 */
812 public void layoutContainer(Container target) {
813 synchronized (target.getTreeLock()) {
814 Insets insets = target.getInsets();
815 int top = insets.top;
816 int bottom = target.height - insets.bottom;
817 int left = insets.left;
818 int right = target.width - insets.right;
819
820 boolean ltr = target.getComponentOrientation()
821 .isLeftToRight();
822 Component c = null;
823
824 if ((c = getChild(NORTH, ltr)) != null) {
825 c.setSize(right - left, c.height);
826 Dimension d = c.getPreferredSize();
827 c.setBounds(left, top, right - left, d.height);
828 top += d.height + vgap;
829 }
830 if ((c = getChild(SOUTH, ltr)) != null) {
831 c.setSize(right - left, c.height);
832 Dimension d = c.getPreferredSize();
833 c.setBounds(left, bottom - d.height, right - left,
834 d.height);
835 bottom -= d.height + vgap;
836 }
837 if ((c = getChild(EAST, ltr)) != null) {
838 c.setSize(c.width, bottom - top);
839 Dimension d = c.getPreferredSize();
840 c
841 .setBounds(right - d.width, top, d.width,
842 bottom - top);
843 right -= d.width + hgap;
844 }
845 if ((c = getChild(WEST, ltr)) != null) {
846 c.setSize(c.width, bottom - top);
847 Dimension d = c.getPreferredSize();
848 c.setBounds(left, top, d.width, bottom - top);
849 left += d.width + hgap;
850 }
851 if ((c = getChild(CENTER, ltr)) != null) {
852 c.setBounds(left, top, right - left, bottom - top);
853 }
854 }
855 }
856
857 /**
858 * Get the component that corresponds to the given constraint location
859 *
860 * @param key The desired absolute position,
861 * either NORTH, SOUTH, EAST, or WEST.
862 * @param ltr Is the component line direction left-to-right?
863 */
864 private Component getChild(String key, boolean ltr) {
865 Component result = null;
866
867 if (key == NORTH) {
868 result = (firstLine != null) ? firstLine : north;
869 } else if (key == SOUTH) {
870 result = (lastLine != null) ? lastLine : south;
871 } else if (key == WEST) {
872 result = ltr ? firstItem : lastItem;
873 if (result == null) {
874 result = west;
875 }
876 } else if (key == EAST) {
877 result = ltr ? lastItem : firstItem;
878 if (result == null) {
879 result = east;
880 }
881 } else if (key == CENTER) {
882 result = center;
883 }
884 if (result != null && !result.visible) {
885 result = null;
886 }
887 return result;
888 }
889
890 /**
891 * Returns a string representation of the state of this border layout.
892 * @return a string representation of this border layout.
893 */
894 public String toString() {
895 return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap
896 + "]";
897 }
898 }
|