Swing布局管理器文档.docx
- 文档编号:28125484
- 上传时间:2023-07-08
- 格式:DOCX
- 页数:26
- 大小:28.91KB
Swing布局管理器文档.docx
《Swing布局管理器文档.docx》由会员分享,可在线阅读,更多相关《Swing布局管理器文档.docx(26页珍藏版)》请在冰豆网上搜索。
Swing布局管理器文档
一,概述
实际上,在Swing使用的布局管理器是在Awt中的,这也不是什么奇怪的事,因为Swing本身也在AWT的基础上开发的。
容器仅仅记录其包含的组件,而布局管理器则指明了容器中组件的位置和尺寸大小。
通过布局管理器,您只需要告知您想放置的组件同其他组件的相对位置即可,这有助于用户实现软件的平台无关性。
AWT提供了五种类型的布局管理器。
·BorderLayout布局管理器:
该管理器将容器分到北、南、东、西、中五个区域,当您向容器中添加组件时,您要告诉BorderLayout将组件放置到五个域中的某个域。
·CardLayout布局管理器:
该布局管理器将加入到容顺中的组件视为卡片栈,把每个组件放置在一个单独的卡片上,而每次只能看见一张卡片。
·FlowLayout布局管理器:
该布局管理器将组件从左到右、从上到下放置。
·GridLayout布局管理器:
该布局管理器将容器分成相同尺寸的网格,将组件按从左到右、从上到下的顺序放置在网格中
·GridBagLayout布局管理器:
和上面的GridLayout布局管理器不一样的是,一个组件不只是占一个网格位置,加入组件时,必须指明一个对应的参数。
二,布局管理器的工作过程
每个容器保存一个对一个布局管理器的引用,这个布局管理器对容器中的组件进行定位和整形。
容器只是可以含有其他组件的组件。
如图10-2所描述的,AWT提供了一些扩展Container的类。
每个容器都访问一个布局管理器,该布局管理器有责任对容器中的组件进行定位和整形。
当发生一个可以引起容器布置它的组件(例如调整一个K窗口的大小)的事件时,调用容器的布局管理器布置容器内的组件。
从原则上讲,容器把布置它的组件的工作授权给一个布局管理器。
不同的布局管理器使用不同的算法布置组件,容器可以通过使用适当的布局管理器自由选择布置算法。
这种定义一个算法集并把这个算法封装在一个类里的技术通称为策略模式(strategypattern)。
我们来看一下:
Container类的部分实现,
/**
*我们可以看到Container扩展了Compoent类
*/
publicclassContainerextendsComponent{
/**
*容器内组件的数量,此值可为null
*/
intncomponents;
/**
*容器内的组件集,它把它们保存一个数组中
*/
Componentcomponent[]=newComponent[0];
/**
*容器的布局管理器
*/
LayoutManagerlayoutMgr;
/**
*当我们向容器中add组件时,实际上调用的就是这方法,这里只给出了和布局管理有关的部分
*/
protectedvoidaddImpl(Componentcomp,Objectconstraints,intindex){
synchronized(getTreeLock()){
/*通知布局管理器已经add了组件*/
if(layoutMgr!
=null){
if(layoutMgrinstanceofLayoutManager2){
((LayoutManager2)layoutMgr).addLayoutComponent(comp,constraints);
}elseif(constraintsinstanceofString){
layoutMgr.addLayoutComponent((String)constraints,comp);
}
}
}
}
/**
*当我们删除组件时,要调用这个方法,而它要遍布容器内的所有组件,然后根据索引值调用remove(int*index)方法。
*/
publicvoidremove(Componentcomp){
synchronized(getTreeLock()){
if(comp.parent==this){
Componentcomponent[]=ponent;
for(inti=ncomponents;--i>=0;){
if(component[i]==comp){
remove(i);
}
}
}
}
}
/**
*根据索引值删除容器的组件,可以看到该方法调用了布局管理器的removeLayoutComponent()
*/
publicvoidremove(intindex){
synchronized(getTreeLock()){
if(index<0||index>=ncomponents){
thrownewArrayIndexOutOfBoundsException(index);
}
Componentcomp=component[index];
if(layoutMgr!
=null){
layoutMgr.removeLayoutComponent(comp);
}
if(valid){
invalidate();
}
}
}
/**
*返回容器当前的布局管理器
*/
publicLayoutManagergetLayout(){
returnlayoutMgr;
}
/**
*这个是我们经常调用的方法,设置容器的布局管理器
*/
publicvoidsetLayout(LayoutManagermgr){
layoutMgr=mgr;
if(valid){
invalidate();
}
}
publicvoiddoLayout(){
//让布局管理器进行布局组件
layout();
}
@Deprecated
publicvoidlayout(){
LayoutManagerlayoutMgr=this.layoutMgr;
if(layoutMgr!
=null){
layoutMgr.layoutContainer(this);
}
}
/**
*Invalidatesthecontainer.Thecontainerandallparentsaboveitaremarkedasneeding*tobelaidout.Thismethodcanbecalledoften,soitneedstoexecutequickly.
*/
publicvoidinvalidate(){
LayoutManagerlayoutMgr=this.layoutMgr;
if(layoutMgrinstanceofLayoutManager2){
LayoutManager2lm=(LayoutManager2)layoutMgr;
lm.invalidateLayout(this);
}
super.invalidate();
}
/**
*取得容器的首选大小
*/
publicDimensiongetPreferredSize(){
returnpreferredSize();
}
@Deprecated
publicDimensionpreferredSize(){
Dimensiondim=prefSize;
if(dim==null||!
(isPreferredSizeSet()||isValid())){
synchronized(getTreeLock()){
prefSize=(layoutMgr!
=null)?
layoutMgr.preferredLayoutSize(this):
super.preferredSize();
dim=prefSize;
}
}
if(dim!
=null){
returnnewDimension(dim);
}else{
returndim;
}
}
/**
*取得容器的最小大小
*/
publicDimensiongetMinimumSize(){
returnminimumSize();
}
@Deprecated
publicDimensionminimumSize(){
Dimensiondim=minSize;
if(dim==null||!
(isMinimumSizeSet()||isValid())){
synchronized(getTreeLock()){
minSize=(layoutMgr!
=null)?
layoutMgr.minimumLayoutSize(this):
super.minimumSize();
dim=minSize;
}
}
if(dim!
=null){
returnnewDimension(dim);
}else{
returndim;
}
}
/**
*取得容器的最大大小
*/
publicDimensiongetMaximumSize(){
Dimensiondim=maxSize;
if(dim==null||!
(isMaximumSizeSet()||isValid())){
synchronized(getTreeLock()){
if(layoutMgrinstanceofLayoutManager2){
LayoutManager2lm=(LayoutManager2)layoutMgr;
maxSize=lm.maximumLayoutSize(this);
}else{
maxSize=super.getMaximumSize();
}
dim=maxSize;
}
}
if(dim!
=null){
returnnewDimension(dim);
}else{
returndim;
}
}
}
三,布局管理器的实现
1,布局管理器是一个实现了接口LayoutManager或LayoutManger2的一个类;
2,布局管理器的责任有:
·计算一个容器的首选尺寸、最小尺寸及最大尺寸。
·布置一个容器内的组件。
3,LayoutManager是一个接口,它定义了以下几个方法:
voidaddLayoutComponent(Stringname,Componentcomp)
voidremoveLayoutCompoenet(Stringname,Componentcomp)
DimensionpreferredLayoutSize(Containerparent)
DimensionminimumLayoutSize(Containerparent)
voidLayoutContainer(Containerparent)
4,LayoutManger2也是一个接口,它扩展了LayoutManger接口,包含方法如下:
voidaddLayoutComponent(Componentc,Objectconstraints)
DimensionmaximumLayoutSize(Container)
floatgetLayoutAlignmentx(Containerparent)
floatgetLayoutAlignmenty(Containerparent)
voidinvalidateLayout(Containerparent)
5,对LayoutManager2接口方法的说明
addLayoutComponent()允许向一个带有约束条件的布局管理器添加组件。
组成一个约束条件的对象的类型应符合LayoutManager2接口的需求。
例如,GridBagLayout的约束条件必须是一个GridBagConstraints引用,然而BorderLayout需要的约束条件是一个字符串。
maximumLayoutSize()返回容器的最大尺寸,而该容器已经给出了组件的当前约束条件。
getLayoutAlignment...方法被一些布局管理器用来沿着x和y轴定位组件。
invalidateLayout()表示布局管理器应该抛弃任何它隐藏的涉及约束条件的信息。
6标准AWT布局管理器实现的接口
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
布局管理器 实现的接口 字符串规定方位
─────────────────────────────────
BorderLayout LayoutManager2 字符串规定方位
CardLayout LayoutManager2 字符串规定名字
FlowLayout LayoutManager 无
GridBagLayout LayoutManager2 GridBagConstaints规定网格约束条件
GridLayout LayoutManager 无
─────────────────────────────────
7,布局管理器和组件首选尺寸
组件实现下面两个影响组件和布局管理器之间相互作用的方法:
//Componentmethods
publicDimensiongetPreferredSize();
publicDimensiongetMinimumSize();
从它们的名字可以猜到,getPreferredSize()返回组件的首选尺寸,getMinimumSize()返回组件可以接受的最小尺寸。
通过实现LayoutManager接口中的下列方法,布局管理器计算一个容器的首选和最小尺寸:
//LayoutMangermethods
DimensionpreferredLayoutSize(Container);
DimensionminimumLayoutSize(Container);
通常,这些方法循环容器中的所有组件,并利用每个组件的首选和最小尺寸计算容器的首选和最小尺寸。
布局管理器在layoutContainer()方法中布置组件:
voidlayoutContainer(Container);
一些布局管理器完全忽略它们所布置组件的首选尺寸,而另一些则很容易接受组件的请求,即根据它们的首选尺寸进行整形。
尽管如此仍有一些布局管理器将只注意组件首选尺寸的一部分,BorderLayout将保留北边组件的首选高度,忽略组件的首选宽度,因此在水平方向扩展组件直到填满它的容器,下面是标准AWT布局管理器和它们对一个组件的首选及最小尺寸的“态度”:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
布局管理器 保留组件首选尺寸的策略
─────────────────────────────────
BorderLayout 北面和南面组件:
保留高度,忽略宽度
东面和西面组件:
保留宽度,忽略高度
中心组件:
忽略首选高度和宽度
FlowLayout 如果组件没有被显式地设置大小,则保留首选高度和宽度
CardLayout 忽略首选高度和宽度
GridLayout 忽略首选高度和宽度
GridBagLayout 根据组件的GridBagConstraints变化
─────────────────────────────────
四:
AWT标准布局管理器
1,BorderLayout布局管理器
Borderlayout实现LayoutManager2接口,即在它布置的组件上加上约束条件。
约束条件是字符串,可以传递给容器的add(Container,Object)方法。
这个字符串指定了组件的位置——“北”、“南”、“东”、“西”或“中心”。
构造函数如下:
BorderLayout()
构造一个组件之间没有间距的新边框布局。
BorderLayout(int hgap,int vgap)
构造一个具有指定组件间距的边框布局。
这也是我们经常用到一个布局管理器,我一般用它作界面的一个整体性的布局。
它根据其首选大小和容器大小的约束(constraints)对组件进行布局。
NORTH和SOUTH组件可以在水平方向上拉伸;而EAST和WEST组件可以在垂直方向上拉伸;CENTER组件可同时在水平和垂直方向上拉伸,从而填充所有剩余空间。
这是一个布置容器的边框布局,它可以对容器组件进行安排,并调整其大小,使其符合下列五个区域:
北、南、东、西、中。
每个区域最多只能包含一个组件,并通过相应的常量进行标识:
NORTH、SOUTH、EAST、WEST、CENTER。
当使用边框布局将一个组件添加到容器中时,要使用这五个常量之一,例如:
Panelp=newPanel();
p.setLayout(newBorderLayout());
p.add(newButton("Okay"),BorderLayout.SOUTH);
为了方便起见,BorderLayout将缺少字符串说明的情况解释为常量CENTER:
Panelp2=newPanel();
p2.setLayout(newBorderLayout());
p2.add(newTextArea());//Sameasp.add(newTextArea(),BorderLayout.CENTER);
此外,BorderLayout支持相对定位常量PAGE_START、PAGE_END、LINE_START和LINE_END。
在ComponentOrientation设置为ComponentOrientation.LEFT_TO_RIGHT的容器中,这些常量分别映射到NORTH、SOUTH、WEST和EAST。
最后来看一个例子:
packagecom.tianyistar.swing.layout;
importjava.awt.BorderLayout;
importjava.awt.Container;
importjava.awt.event.WindowAdapter;
importjava.awt.event.WindowEvent;
importjavax.swing.JButton;
importjavax.swing.JFrame;
importjavax.swing.JLabel;
publicclassBorderLayoutTest{
publicBorderLayoutTest(){
JFramef=newJFrame();
ContainercontentPane=f.getContentPane();
contentPane.setLayout(newBorderLayout());
contentPane.add(newJButton("EAST"),BorderLayout.EAST);
contentPane.add(newJButton("WEST"),BorderLayout.WEST);
contentPane.add(newJButton("SOUTH"),BorderLayout.SOUTH);
contentPane.add(newJButton("NORTH"),BorderLayout.NORTH);
contentPane.add(newJLabel("CENTER",JLabel.CENTER),BorderLayout.CENTER);
f.setTitle("BorderLayout");
f.pack();
f.setVisible(true);
/*处理关闭窗口的操作,若你没写这一段,就算你已经关闭窗口了,但程序并不会终止。
*/
f.addWindowListener(newWindowAdapter(){
@Override
publicvoidwindowClosing(WindowEvente){
System.exit(0);
}
});
}
publicstaticvoidmain(String[]args){
BorderLayoutTestb=newBorderLayoutTest();
}
}
2,CardLayout布局管理器
CardLayout对象是容器的布局管理器。
它将容器中的每个组件看作一张卡片。
一次只能看到一张卡片,容器则充当卡片的堆栈。
当容器第一次显示时,第一个添加到CardLayout对象的组件为可见组件。
卡片的顺序由组件对象本身在容器内部的顺序决定。
CardLayout定义了一组方法,这些方法允许应用程序按顺序地浏览这些卡片,或者显示指定的卡片。
addLayoutComponent(java.awt.Component,java.lang.Object)方法可用于将一个字符串标识符与给定卡片关联,以便进行快速随机访问。
CardLayout()
创建一个间距大小为0的新卡片布局。
CardLayout(int hgap,int vgap)
创建一个具有指定水平间距和垂直间距的新卡片布局。
方法如下:
voidfirst(Container)显示第一个添加到容器中的组件
voidlast(Container) 显示最后一个添加到容器的组件
voidnext(Containerparent)显示在当前显示组件后加入到容器中的一个组件。
如果当前组件是最后一个,那么显示第一个组件
voidprevious(Containerparent)显示在当前显示组件前加入到容器中的一个组件。
如果当前组件是第一个,那么显示后后一个组件
voidshow(Containerparent,Stringname)显示名称和传递的字符串相匹配的组件。
如果没有组件匹配,则为空操作
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Swing 布局 管理器 文档