blob: 6597916c43bc92da852cc09875073122e2f75356 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1995-2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any 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>, <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 * unpredicable 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 * 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 * @author Arthur van Hoff
120 * @see java.awt.Container#add(String, Component)
121 * @see java.awt.ComponentOrientation
122 * @since JDK1.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</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 unpredicable 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
418 * constants.
419 * @since JDK1.1
420 */
421 public void addLayoutComponent(Component comp, Object constraints) {
422 synchronized (comp.getTreeLock()) {
423 if ((constraints == null) || (constraints instanceof String)) {
424 addLayoutComponent((String)constraints, comp);
425 } else {
426 throw new IllegalArgumentException("cannot add to layout: constraint must be a string (or null)");
427 }
428 }
429 }
430
431 /**
432 * @deprecated replaced by <code>addLayoutComponent(Component, Object)</code>.
433 */
434 @Deprecated
435 public void addLayoutComponent(String name, Component comp) {
436 synchronized (comp.getTreeLock()) {
437 /* Special case: treat null the same as "Center". */
438 if (name == null) {
439 name = "Center";
440 }
441
442 /* Assign the component to one of the known regions of the layout.
443 */
444 if ("Center".equals(name)) {
445 center = comp;
446 } else if ("North".equals(name)) {
447 north = comp;
448 } else if ("South".equals(name)) {
449 south = comp;
450 } else if ("East".equals(name)) {
451 east = comp;
452 } else if ("West".equals(name)) {
453 west = comp;
454 } else if (BEFORE_FIRST_LINE.equals(name)) {
455 firstLine = comp;
456 } else if (AFTER_LAST_LINE.equals(name)) {
457 lastLine = comp;
458 } else if (BEFORE_LINE_BEGINS.equals(name)) {
459 firstItem = comp;
460 } else if (AFTER_LINE_ENDS.equals(name)) {
461 lastItem = comp;
462 } else {
463 throw new IllegalArgumentException("cannot add to layout: unknown constraint: " + name);
464 }
465 }
466 }
467
468 /**
469 * Removes the specified component from this border layout. This
470 * method is called when a container calls its <code>remove</code> or
471 * <code>removeAll</code> methods. Most applications do not call this
472 * method directly.
473 * @param comp the component to be removed.
474 * @see java.awt.Container#remove(java.awt.Component)
475 * @see java.awt.Container#removeAll()
476 */
477 public void removeLayoutComponent(Component comp) {
478 synchronized (comp.getTreeLock()) {
479 if (comp == center) {
480 center = null;
481 } else if (comp == north) {
482 north = null;
483 } else if (comp == south) {
484 south = null;
485 } else if (comp == east) {
486 east = null;
487 } else if (comp == west) {
488 west = null;
489 }
490 if (comp == firstLine) {
491 firstLine = null;
492 } else if (comp == lastLine) {
493 lastLine = null;
494 } else if (comp == firstItem) {
495 firstItem = null;
496 } else if (comp == lastItem) {
497 lastItem = null;
498 }
499 }
500 }
501
502 /**
503 * Gets the component that was added using the given constraint
504 *
505 * @param constraints the desired constraint, one of <code>CENTER</code>,
506 * <code>NORTH</code>, <code>SOUTH</code>,
507 * <code>WEST</code>, <code>EAST</code>,
508 * <code>PAGE_START</code>, <code>PAGE_END</code>,
509 * <code>LINE_START</code>, <code>LINE_END</code>
510 * @return the component at the given location, or <code>null</code> if
511 * the location is empty
512 * @exception IllegalArgumentException if the constraint object is
513 * not one of the nine specified constants
514 * @see #addLayoutComponent(java.awt.Component, java.lang.Object)
515 * @since 1.5
516 */
517 public Component getLayoutComponent(Object constraints) {
518 if (CENTER.equals(constraints)) {
519 return center;
520 } else if (NORTH.equals(constraints)) {
521 return north;
522 } else if (SOUTH.equals(constraints)) {
523 return south;
524 } else if (WEST.equals(constraints)) {
525 return west;
526 } else if (EAST.equals(constraints)) {
527 return east;
528 } else if (PAGE_START.equals(constraints)) {
529 return firstLine;
530 } else if (PAGE_END.equals(constraints)) {
531 return lastLine;
532 } else if (LINE_START.equals(constraints)) {
533 return firstItem;
534 } else if (LINE_END.equals(constraints)) {
535 return lastItem;
536 } else {
537 throw new IllegalArgumentException("cannot get component: unknown constraint: " + constraints);
538 }
539 }
540
541
542 /**
543 * Returns the component that corresponds to the given constraint location
544 * based on the target <code>Container</code>'s component orientation.
545 * Components added with the relative constraints <code>PAGE_START</code>,
546 * <code>PAGE_END</code>, <code>LINE_START</code>, and <code>LINE_END</code>
547 * take precedence over components added with the explicit constraints
548 * <code>NORTH</code>, <code>SOUTH</code>, <code>WEST</code>, and <code>EAST</code>.
549 * The <code>Container</code>'s component orientation is used to determine the location of components
550 * added with <code>LINE_START</code> and <code>LINE_END</code>.
551 *
552 * @param constraints the desired absolute position, one of <code>CENTER</code>,
553 * <code>NORTH</code>, <code>SOUTH</code>,
554 * <code>EAST</code>, <code>WEST</code>
555 * @param target the {@code Container} used to obtain
556 * the constraint location based on the target
557 * {@code Container}'s component orientation.
558 * @return the component at the given location, or <code>null</code> if
559 * the location is empty
560 * @exception IllegalArgumentException if the constraint object is
561 * not one of the five specified constants
562 * @exception NullPointerException if the target parameter is null
563 * @see #addLayoutComponent(java.awt.Component, java.lang.Object)
564 * @since 1.5
565 */
566 public Component getLayoutComponent(Container target, Object constraints) {
567 boolean ltr = target.getComponentOrientation().isLeftToRight();
568 Component result = null;
569
570 if (NORTH.equals(constraints)) {
571 result = (firstLine != null) ? firstLine : north;
572 } else if (SOUTH.equals(constraints)) {
573 result = (lastLine != null) ? lastLine : south;
574 } else if (WEST.equals(constraints)) {
575 result = ltr ? firstItem : lastItem;
576 if (result == null) {
577 result = west;
578 }
579 } else if (EAST.equals(constraints)) {
580 result = ltr ? lastItem : firstItem;
581 if (result == null) {
582 result = east;
583 }
584 } else if (CENTER.equals(constraints)) {
585 result = center;
586 } else {
587 throw new IllegalArgumentException("cannot get component: invalid constraint: " + constraints);
588 }
589
590 return result;
591 }
592
593
594 /**
595 * Gets the constraints for the specified component
596 *
597 * @param comp the component to be queried
598 * @return the constraint for the specified component,
599 * or null if component is null or is not present
600 * in this layout
601 * @see #addLayoutComponent(java.awt.Component, java.lang.Object)
602 * @since 1.5
603 */
604 public Object getConstraints(Component comp) {
605 //fix for 6242148 : API method java.awt.BorderLayout.getConstraints(null) should return null
606 if (comp == null){
607 return null;
608 }
609 if (comp == center) {
610 return CENTER;
611 } else if (comp == north) {
612 return NORTH;
613 } else if (comp == south) {
614 return SOUTH;
615 } else if (comp == west) {
616 return WEST;
617 } else if (comp == east) {
618 return EAST;
619 } else if (comp == firstLine) {
620 return PAGE_START;
621 } else if (comp == lastLine) {
622 return PAGE_END;
623 } else if (comp == firstItem) {
624 return LINE_START;
625 } else if (comp == lastItem) {
626 return LINE_END;
627 }
628 return null;
629 }
630
631 /**
632 * Determines the minimum size of the <code>target</code> container
633 * using this layout manager.
634 * <p>
635 * This method is called when a container calls its
636 * <code>getMinimumSize</code> method. Most applications do not call
637 * this method directly.
638 * @param target the container in which to do the layout.
639 * @return the minimum dimensions needed to lay out the subcomponents
640 * of the specified container.
641 * @see java.awt.Container
642 * @see java.awt.BorderLayout#preferredLayoutSize
643 * @see java.awt.Container#getMinimumSize()
644 */
645 public Dimension minimumLayoutSize(Container target) {
646 synchronized (target.getTreeLock()) {
647 Dimension dim = new Dimension(0, 0);
648
649 boolean ltr = target.getComponentOrientation().isLeftToRight();
650 Component c = null;
651
652 if ((c=getChild(EAST,ltr)) != null) {
653 Dimension d = c.getMinimumSize();
654 dim.width += d.width + hgap;
655 dim.height = Math.max(d.height, dim.height);
656 }
657 if ((c=getChild(WEST,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(CENTER,ltr)) != null) {
663 Dimension d = c.getMinimumSize();
664 dim.width += d.width;
665 dim.height = Math.max(d.height, dim.height);
666 }
667 if ((c=getChild(NORTH,ltr)) != null) {
668 Dimension d = c.getMinimumSize();
669 dim.width = Math.max(d.width, dim.width);
670 dim.height += d.height + vgap;
671 }
672 if ((c=getChild(SOUTH,ltr)) != null) {
673 Dimension d = c.getMinimumSize();
674 dim.width = Math.max(d.width, dim.width);
675 dim.height += d.height + vgap;
676 }
677
678 Insets insets = target.getInsets();
679 dim.width += insets.left + insets.right;
680 dim.height += insets.top + insets.bottom;
681
682 return dim;
683 }
684 }
685
686 /**
687 * Determines the preferred size of the <code>target</code>
688 * container using this layout manager, based on the components
689 * in the container.
690 * <p>
691 * Most applications do not call this method directly. This method
692 * is called when a container calls its <code>getPreferredSize</code>
693 * method.
694 * @param target the container in which to do the layout.
695 * @return the preferred dimensions to lay out the subcomponents
696 * of the specified container.
697 * @see java.awt.Container
698 * @see java.awt.BorderLayout#minimumLayoutSize
699 * @see java.awt.Container#getPreferredSize()
700 */
701 public Dimension preferredLayoutSize(Container target) {
702 synchronized (target.getTreeLock()) {
703 Dimension dim = new Dimension(0, 0);
704
705 boolean ltr = target.getComponentOrientation().isLeftToRight();
706 Component c = null;
707
708 if ((c=getChild(EAST,ltr)) != null) {
709 Dimension d = c.getPreferredSize();
710 dim.width += d.width + hgap;
711 dim.height = Math.max(d.height, dim.height);
712 }
713 if ((c=getChild(WEST,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(CENTER,ltr)) != null) {
719 Dimension d = c.getPreferredSize();
720 dim.width += d.width;
721 dim.height = Math.max(d.height, dim.height);
722 }
723 if ((c=getChild(NORTH,ltr)) != null) {
724 Dimension d = c.getPreferredSize();
725 dim.width = Math.max(d.width, dim.width);
726 dim.height += d.height + vgap;
727 }
728 if ((c=getChild(SOUTH,ltr)) != null) {
729 Dimension d = c.getPreferredSize();
730 dim.width = Math.max(d.width, dim.width);
731 dim.height += d.height + vgap;
732 }
733
734 Insets insets = target.getInsets();
735 dim.width += insets.left + insets.right;
736 dim.height += insets.top + insets.bottom;
737
738 return dim;
739 }
740 }
741
742 /**
743 * Returns the maximum dimensions for this layout given the components
744 * in the specified target container.
745 * @param target the component which needs to be laid out
746 * @see Container
747 * @see #minimumLayoutSize
748 * @see #preferredLayoutSize
749 */
750 public Dimension maximumLayoutSize(Container target) {
751 return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
752 }
753
754 /**
755 * Returns the alignment along the x axis. This specifies how
756 * the component would like to be aligned relative to other
757 * components. The value should be a number between 0 and 1
758 * where 0 represents alignment along the origin, 1 is aligned
759 * the furthest away from the origin, 0.5 is centered, etc.
760 */
761 public float getLayoutAlignmentX(Container parent) {
762 return 0.5f;
763 }
764
765 /**
766 * Returns the alignment along the y axis. This specifies how
767 * the component would like to be aligned relative to other
768 * components. The value should be a number between 0 and 1
769 * where 0 represents alignment along the origin, 1 is aligned
770 * the furthest away from the origin, 0.5 is centered, etc.
771 */
772 public float getLayoutAlignmentY(Container parent) {
773 return 0.5f;
774 }
775
776 /**
777 * Invalidates the layout, indicating that if the layout manager
778 * has cached information it should be discarded.
779 */
780 public void invalidateLayout(Container target) {
781 }
782
783 /**
784 * Lays out the container argument using this border layout.
785 * <p>
786 * This method actually reshapes the components in the specified
787 * container in order to satisfy the constraints of this
788 * <code>BorderLayout</code> object. The <code>NORTH</code>
789 * and <code>SOUTH</code> components, if any, are placed at
790 * the top and bottom of the container, respectively. The
791 * <code>WEST</code> and <code>EAST</code> components are
792 * then placed on the left and right, respectively. Finally,
793 * the <code>CENTER</code> object is placed in any remaining
794 * space in the middle.
795 * <p>
796 * Most applications do not call this method directly. This method
797 * is called when a container calls its <code>doLayout</code> method.
798 * @param target the container in which to do the layout.
799 * @see java.awt.Container
800 * @see java.awt.Container#doLayout()
801 */
802 public void layoutContainer(Container target) {
803 synchronized (target.getTreeLock()) {
804 Insets insets = target.getInsets();
805 int top = insets.top;
806 int bottom = target.height - insets.bottom;
807 int left = insets.left;
808 int right = target.width - insets.right;
809
810 boolean ltr = target.getComponentOrientation().isLeftToRight();
811 Component c = null;
812
813 if ((c=getChild(NORTH,ltr)) != null) {
814 c.setSize(right - left, c.height);
815 Dimension d = c.getPreferredSize();
816 c.setBounds(left, top, right - left, d.height);
817 top += d.height + vgap;
818 }
819 if ((c=getChild(SOUTH,ltr)) != null) {
820 c.setSize(right - left, c.height);
821 Dimension d = c.getPreferredSize();
822 c.setBounds(left, bottom - d.height, right - left, d.height);
823 bottom -= d.height + vgap;
824 }
825 if ((c=getChild(EAST,ltr)) != null) {
826 c.setSize(c.width, bottom - top);
827 Dimension d = c.getPreferredSize();
828 c.setBounds(right - d.width, top, d.width, bottom - top);
829 right -= d.width + hgap;
830 }
831 if ((c=getChild(WEST,ltr)) != null) {
832 c.setSize(c.width, bottom - top);
833 Dimension d = c.getPreferredSize();
834 c.setBounds(left, top, d.width, bottom - top);
835 left += d.width + hgap;
836 }
837 if ((c=getChild(CENTER,ltr)) != null) {
838 c.setBounds(left, top, right - left, bottom - top);
839 }
840 }
841 }
842
843 /**
844 * Get the component that corresponds to the given constraint location
845 *
846 * @param key The desired absolute position,
847 * either NORTH, SOUTH, EAST, or WEST.
848 * @param ltr Is the component line direction left-to-right?
849 */
850 private Component getChild(String key, boolean ltr) {
851 Component result = null;
852
853 if (key == NORTH) {
854 result = (firstLine != null) ? firstLine : north;
855 }
856 else if (key == SOUTH) {
857 result = (lastLine != null) ? lastLine : south;
858 }
859 else if (key == WEST) {
860 result = ltr ? firstItem : lastItem;
861 if (result == null) {
862 result = west;
863 }
864 }
865 else if (key == EAST) {
866 result = ltr ? lastItem : firstItem;
867 if (result == null) {
868 result = east;
869 }
870 }
871 else if (key == CENTER) {
872 result = center;
873 }
874 if (result != null && !result.visible) {
875 result = null;
876 }
877 return result;
878 }
879
880 /**
881 * Returns a string representation of the state of this border layout.
882 * @return a string representation of this border layout.
883 */
884 public String toString() {
885 return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + "]";
886 }
887}