- 容器把对构件的布置,整形和定位,授权给一个布局管理器。一个容器的布局管理器是专用工具,用于定位和整形与它相关的容器中的构件。
- 每个容器保存一-个对一个布局管理器的引用,这个布局管理器对容器中的构件进行定位和整形。
- 容器只是可以含有其他构件的构件。AWT提供了一些扩展Container的类。
- 每个容器都访问一个布局管理器,该布局管理器有责任对容器中的构件进行定位和整形。
Container扩展的类框图:
1、布局管理器
LayoutManager
是一个接口,它定义了下面一些方法:
void addLayoutComponent(String name, Component comp) //如果布局管理器使用每个组件的字符串,则将组件 comp添加到布局,并将其与 name指定的字符串相关联。
void layoutContainer(Container parent) //布置指定的容器。
Dimension minimumLayoutSize(Container parent) //在给定组件包含的组件的情况下,计算指定容器的最小大小尺寸。
Dimension preferredLayoutSize(Container parent) //给定包含的组件的情况下,计算指定容器的首选大小尺寸。
void removeLayoutComponent(Component comp) //从布局中删除指定的组件。
布局管理器的责任有:
- 计算一个容器的首选尺寸和最小尺寸。
- 布置一个容器内的构件。
注意:
虽然每个容器只有一个布局管理器,但是一个布局管理器可以为不止一个容器工作。因此,当一个布局管理器完成一个容器的一些工作时,必须把需要布局管理器服务的容器的引用传递给布局管理器。实际上,如果查看一下 Panel.java,就会发现java.awt . Panel实例在默认情况下共用一个FlowLayout,并且比较频繁地使用它。
2、两种类型的布局管理器
所有的布局管理器都为一个或多个容器布置构件。一些布局管理器给构件加上约束条件以确定构件如何被布置。
例如,为了确定构件被摆放在边框内的位置,BorderLayout在它的构件上加上方向指示。约束条件被规定为字符串–“North”、“South”、“East”、“West”和“Cen-ter”。
其他的布局管理器不需要为单个构件加上约束条件,例如,FlowLayout仅仅从左到右、从上到下地摆放构件——当构件适合它们的容器时。
AWT为布局管理器提供了一个接口----LayoutManager2,以把约束条件和构件联系起来,它扩展了LayoutManager接口并增加了以下方法:
void addLayoutComponent(Component comp, Object constraints) //使用指定的约束对象将指定的组件添加到布局中。
float getLayoutAlignmentX(Container target) //返回沿x轴的对齐方式。
float getLayoutAlignmentY(Container target) //返回沿y轴的对齐方式。
void invalidateLayout(Container target) //使布局无效,表明如果布局管理器缓存了信息,则应将其丢弃。
Dimension maximumLayoutSize(Container target) //在给定组件包含的组件的情况下,计算指定容器的最大大小尺寸。
标准AWT布局管理器实现的接口:
布局管理器 | 实现的接口 | 构件的约束条件 |
---|---|---|
BorderLayout | LayoutManager2 | 字符串规定方位 |
CardLayout | LayoutManager2 | 字符串规定名字 |
FlowLayout | LayoutManager | 无 |
GridBagLayout | LayoutManager2 | GridBagConstraints规定网格约束条件 |
GridLayout | LayoutManager |
3、布局管理器和容器空白区
每个容器都有一组用像素定义的和它相关的空白区(inset),规定容器内上,下,左,右空白边缘区。
一个容器的空白区值很重要,因为布局管理器不能在容器的空白区内布置构件,但容器可以覆盖paint(),并在空白区绘制构件。
java.awt.container定义了getInsets方法,提供了对一个容器空白区的访问。
Insets container.getInsets()
4、同位体和空白区
如果一个容器没有覆盖getInsets(),那么由它的同位体提供空白区值。如果容器还没有一个同位体,那么返回一个四个边缘区都是零的Insets。
5、布局管理器和构件首选尺寸
getPreferredSize() //返回构件的首选尺寸
getMinimumSize() //返回构件可以接受的最小尺寸
通过实现LayoutManager接口中的方法,布局管理器计算一个容器的首选和最小尺寸
Dimension preferedLayoutSize(Container)
Dimension minimumLayoutSize(Container)
布局构件在layoutContainer()方法中布置构件:void layoutContainer(Container)
布局管理器默认:
布局管理器 | 保留构件首选尺寸的策略 |
---|---|
BorderLayout | 北和南:保留高,忽略宽 |
东和西:保留宽,忽略高 | |
中:忽略高和宽 | |
FlowLayout | 如果构件没有被显式地设置大小,则保留首选高度和宽度 |
CardLayout | 忽略高和宽 |
GridLayout | 忽略高和宽 |
GridBagLayout | 根据构件的GridBagConstraints变化 |
6、强制一个容器布置它的构件
- 要强制改变的时候,先使文本框无效,然后调用父容器的validate()。
- 要使构件无效,就用在最内层的构件调用,invalidate(),冒泡出来,外面的构件也就无效了。
- 另外,当调整窗口大小时窗口将变得无效,当设置框架里的菜单栏时框架将变得无效;当改变滚动条的方向时,滚动条将变得无效;当改变文本域的行数或列数时,文本域将变得无效;当改变文本框的列数时,文本框将变得无效。
使构件无效的Conponent和Container方法:
Component.addNotify()
.show()
.hide()
.reshape(int x, int y, int width, int height)
.setSize(int width, int height)
.setBounds(int x, int y, int width, int height)
.setLayout(LayoutManager)
Container.add(Component)
.remove(Component)
.removeAll()
.setLayout(LayoutManager)
ps:强制一个容器布置它的构件调用Container . validate ()强制容器布置它的构件,只有容器无效时布置才可能发生。
7、标准AWT布局管理器
布局管理器 | 描述 |
---|---|
BorderLayout | 按北、东、西、南和中心位置将构件布置在容器四周和中心。可以规定构件之间的间隙。BorderLayout是Window、Dialog 和 Frame容器的默认布局管理器 |
CardLayout | 从一组构件中每次显示一个构件。构件可以被换进换出 |
FlowLayout | 从左到右、从上到下地显示构件。FlowLayout是面板和applet的默认布局管理器 |
GridBaglLayout | 使用一组详细的网格约束条件在一个网格中安排构件 |
GridLayout | 在网格中布置构件,每个构件都扩展以填满它的网格单元。可以规定构件之间水平和垂直间隙 |
Container默认的布局管理器null
Panel默认的布局管理器FlowLayout
Window,Dialog,Frame的默认布局管理器BorderLayout
布局管理器决策表:
布局管理器 | 使用条件 |
---|---|
BorderLayout | 一个容器把它的构件分到几个区域:北和南,或东和西。一个单独的构件需要填满它所位于的容器的整个空间 |
CardLayout | 希望在不同环境下控制成组构件的可见性 |
FlowLayout | 容器的构件从左到右、从上到下填充容器 |
GridLayout | 容器把它的构件分到一个网格中 |
GridBagLayout | 一个容器具有复杂的布置需要 |