




已阅读5页,还剩12页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
天一Star整体编著一, 概述实际上,在Swing使用的布局管理器是在Awt中的,这也不是什么奇怪的事,因为Swing本身也在AWT的基础上开发的。容器仅仅记录其包含的组件,而布局管理器则指明了容器中组件的位置和尺寸大小。通过布局管理器,您只需要告知您想放置的组件同其他组件的相对位置即可,这有助于用户实现软件的平台无关性。AWT提供了五种类型的布局管理器。BorderLayout布局管理器:该管理器将容器分到北、南、东、西、中五个区域,当您向容器中添加组件时,您要告诉BorderLayout将组件放置到五个域中的某个域。CardLayout布局管理器:该布局管理器将加入到容顺中的组件视为卡片栈,把每个组件放置在一个单独的卡片上,而每次只能看见一张卡片。FlowLayout布局管理器:该布局管理器将组件从左到右、从上到下放置。GridLayout布局管理器:该布局管理器将容器分成相同尺寸的网格,将组件按从左到右、从上到下的顺序放置在网格中GridBagLayout布局管理器:和上面的GridLayout布局管理器不一样的是,一个组件不只是占一个网格位置,加入组件时,必须指明一个对应的参数。二, 布局管理器的工作过程每个容器保存一个对一个布局管理器的引用,这个布局管理器对容器中的组件进行定位和整形。容器只是可以含有其他组件的组件。如图10-2所描述的,AWT提供了一些扩展Container的类。每个容器都访问一个布局管理器,该布局管理器有责任对容器中的组件进行定位和整形。当发生一个可以引起容器布置它的组件(例如调整一个K窗口的大小)的事件时,调用容器的布局管理器布置容器内的组件。从原则上讲,容器把布置它的组件的工作授权给一个布局管理器。不同的布局管理器使用不同的算法布置组件,容器可以通过使用适当的布局管理器自由选择布置算法。这种定义一个算法集并把这个算法封装在一个类里的技术通称为策略模式(strategy pattern)。我们来看一下:Container类的部分实现,/* * 我们可以看到Container扩展了Compoent类*/public class Container extends Component /* * 容器内组件的数量,此值可为null */ int ncomponents; /* * 容器内的组件集,它把它们保存一个数组中 */ Component component = new Component0; /* *容器的布局管理器 */ LayoutManager layoutMgr;/*当我们向容器中add组件时,实际上调用的就是这方法,这里只给出了和布局管理有关的部分*/ protected void addImpl(Component comp, Object constraints, int index) synchronized (getTreeLock() /*通知布局管理器已经add了组件 */ if (layoutMgr != null) if (layoutMgr instanceof LayoutManager2) (LayoutManager2)layoutMgr).addLayoutComponent(comp, constraints); else if (constraints instanceof String) layoutMgr.addLayoutComponent(String)constraints, comp); /*当我们删除组件时,要调用这个方法,而它要遍布容器内的所有组件,然后根据索引值调用remove(int *index)方法。*/public void remove(Component comp) synchronized (getTreeLock() if (comp.parent = this) Component component = ponent; for (int i = ncomponents; -i = 0; ) if (componenti = comp) remove(i); /*根据索引值删除容器的组件,可以看到该方法调用了布局管理器的removeLayoutComponent()*/public void remove(int index) synchronized (getTreeLock() if (index 0 | index = ncomponents) throw new ArrayIndexOutOfBoundsException(index); Component comp = componentindex; if (layoutMgr != null) layoutMgr.removeLayoutComponent(comp); if (valid) invalidate(); /*返回容器当前的布局管理器*/ public LayoutManager getLayout() return layoutMgr; /*这个是我们经常调用的方法,设置容器的布局管理器*/ public void setLayout(LayoutManager mgr) layoutMgr = mgr;if (valid) invalidate();public void doLayout() /让布局管理器进行布局组件layout(); Deprecated public void layout() LayoutManager layoutMgr = this.layoutMgr;if (layoutMgr != null) layoutMgr.layoutContainer(this); /* * Invalidates the container. The container and all parents above it are marked as needing * to be laid out. This method can be called often, so it needs to execute quickly. */ public void invalidate() LayoutManager layoutMgr = this.layoutMgr; if (layoutMgr instanceof LayoutManager2) LayoutManager2 lm = (LayoutManager2) layoutMgr; lm.invalidateLayout(this); super.invalidate(); /*取得容器的首选大小*/public Dimension getPreferredSize() return preferredSize();Deprecatedpublic Dimension preferredSize() Dimension dim = prefSize; if (dim = null | !(isPreferredSizeSet() | isValid() synchronized (getTreeLock() prefSize = (layoutMgr != null) ? layoutMgr.preferredLayoutSize(this) : super.preferredSize(); dim = prefSize; if (dim != null) return new Dimension(dim); else return dim; /*取得容器的最小大小*/public Dimension getMinimumSize() return minimumSize();Deprecatedpublic Dimension minimumSize() Dimension dim = minSize; if (dim = null | !(isMinimumSizeSet() | isValid() synchronized (getTreeLock() minSize = (layoutMgr != null) ? layoutMgr.minimumLayoutSize(this) : super.minimumSize(); dim = minSize; if (dim != null) return new Dimension(dim); else return dim; /*取得容器的最大大小*/public Dimension getMaximumSize() Dimension dim = maxSize; if (dim = null | !(isMaximumSizeSet() | isValid() synchronized (getTreeLock() if (layoutMgr instanceof LayoutManager2) LayoutManager2 lm = (LayoutManager2) layoutMgr; maxSize = lm.maximumLayoutSize(this); else maxSize = super.getMaximumSize(); dim = maxSize; if (dim != null) return new Dimension(dim); else return dim; 三, 布局管理器的实现1, 布局管理器是一个实现了接口LayoutManager或LayoutManger2的一个类;2, 布局管理器的责任有:计算一个容器的首选尺寸、最小尺寸及最大尺寸。布置一个容器内的组件。3, LayoutManager是一个接口,它定义了以下几个方法: void addLayoutComponent (String name,Component comp)void removeLayoutCompoenet(String name,Component comp)Dimension preferredLayoutSize(Container parent)Dimension minimumLayoutSize(Container parent)void LayoutContainer(Container parent)4, LayoutManger2也是一个接口,它扩展了LayoutManger接口,包含方法如下: void addLayoutComponent(Component c,Object constraints)Dimension maximumLayoutSize(Container)float getLayoutAlignmentx(Container parent)float getLayoutAlignmenty(Container parent)void invalidateLayout(Container parent)5,对LayoutManager2接口方法的说明addLayoutComponent()允许向一个带有约束条件的布局管理器添加组件。组成一个约束条件的对象的类型应符合LayoutManager2接口的需求。例如,GridBagLayout的约束条件必须是一个GridBagConstraints引用,然而BorderLayout需要的约束条件是一个字符串。maximumLayoutSize()返回容器的最大尺寸,而该容器已经给出了组件的当前约束条件。getLayoutAlignment.方法被一些布局管理器用来沿着x和y轴定位组件。invalidateLayout()表示布局管理器应该抛弃任何它隐藏的涉及约束条件的信息。6标准AWT布局管理器实现的接口布局管理器 实现的接口 字符串规定方位BorderLayout LayoutManager2 字符串规定方位CardLayout LayoutManager2 字符串规定名字FlowLayout LayoutManager无GridBagLayoutLayoutManager2 GridBagConstaints规定网格约束条件GridLayout LayoutManager 无7, 布局管理器和组件首选尺寸组件实现下面两个影响组件和布局管理器之间相互作用的方法:/Component methodspublic Dimension getPreferredSize();public Dimension getMinimumSize();从它们的名字可以猜到,getPreferredSize()返回组件的首选尺寸,getMinimumSize()返回组件可以接受的最小尺寸。通过实现LayoutManager接口中的下列方法,布局管理器计算一个容器的首选和最小尺寸:/LayoutManger methodsDimension preferredLayoutSize(Container);Dimension minimumLayoutSize(Container);通常,这些方法循环容器中的所有组件,并利用每个组件的首选和最小尺寸计算容器的首选和最小尺寸。布局管理器在layoutContainer()方法中布置组件:void layoutContainer(Container);一些布局管理器完全忽略它们所布置组件的首选尺寸,而另一些则很容易接受组件的请求,即根据它们的首选尺寸进行整形。尽管如此仍有一些布局管理器将只注意组件首选尺寸的一部分,BorderLayout将保留北边组件的首选高度,忽略组件的首选宽度,因此在水平方向扩展组件直到填满它的容器,下面是标准AWT布局管理器和它们对一个组件的首选及最小尺寸的“态度”:布局管理器保留组件首选尺寸的策略 BorderLayout 北面和南面组件:保留高度,忽略宽度东面和西面组件:保留宽度,忽略高度 中心组件:忽略首选高度和宽度FlowLayout 如果组件没有被显式地设置大小,则保留首选高度和宽度CardLayout 忽略首选高度和宽度GridLayout 忽略首选高度和宽度GridBagLayout 根据组件的GridBagConstraints变化四:AWT标准布局管理器1, BorderLayout布局管理器 Borderlayout实现LayoutManager2接口,即在它布置的组件上加上约束条件。约束条件是字符串,可以传递给容器的add(Container,Object)方法。这个字符串指定了组件的位置“北”、“南”、“东”、“西”或“中心”。构造函数如下:BorderLayout() 构造一个组件之间没有间距的新边框布局。BorderLayout(inthgap, intvgap) 构造一个具有指定组件间距的边框布局。这也是我们经常用到一个布局管理器,我一般用它作界面的一个整体性的布局。它根据其首选大小和容器大小的约束 (constraints) 对组件进行布局。NORTH 和 SOUTH 组件可以在水平方向上拉伸;而 EAST 和 WEST 组件可以在垂直方向上拉伸;CENTER 组件可同时在水平和垂直方向上拉伸,从而填充所有剩余空间。 这是一个布置容器的边框布局,它可以对容器组件进行安排,并调整其大小,使其符合下列五个区域:北、南、东、西、中。每个区域最多只能包含一个组件,并通过相应的常量进行标识:NORTH、SOUTH、EAST、WEST、CENTER。当使用边框布局将一个组件添加到容器中时,要使用这五个常量之一,例如: Panel p = new Panel(); p.setLayout(new BorderLayout(); p.add(new Button(Okay), BorderLayout.SOUTH);为了方便起见,BorderLayout 将缺少字符串说明的情况解释为常量 CENTER: Panel p2 = new Panel(); p2.setLayout(new BorderLayout(); p2.add(new TextArea(); / Same as p.add(new TextArea(), BorderLayout.CENTER);此外,BorderLayout 支持相对定位常量 PAGE_START、PAGE_END、LINE_START 和 LINE_END。在 ComponentOrientation 设置为 ComponentOrientation.LEFT_TO_RIGHT 的容器中,这些常量分别映射到 NORTH、SOUTH、WEST 和 EAST。最后来看一个例子:package com.tianyistar.swing.layout;import java.awt.BorderLayout;import java.awt.Container;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;public class BorderLayoutTest public BorderLayoutTest() JFrame f = new JFrame(); Container contentPane = f.getContentPane(); contentPane.setLayout(new BorderLayout(); contentPane.add(new JButton(EAST), BorderLayout.EAST); contentPane.add(new JButton(WEST), BorderLayout.WEST); contentPane.add(new JButton(SOUTH), BorderLayout.SOUTH); contentPane.add(new JButton(NORTH), BorderLayout.NORTH); contentPane.add(new JLabel(CENTER, JLabel.CENTER), BorderLayout.CENTER); f.setTitle(BorderLayout); f.pack(); f.setVisible(true); /*处理关闭窗口的操作,若你没写这一段,就算你已经关闭窗口了,但程序并不会终止。 */ f.addWindowListener(new WindowAdapter() Override public void windowClosing(WindowEvent e) System.exit(0); ); public static void main(String args) BorderLayoutTest b = new BorderLayoutTest(); 2, CardLayout布局管理器CardLayout 对象是容器的布局管理器。它将容器中的每个组件看作一张卡片。一次只能看到一张卡片,容器则充当卡片的堆栈。当容器第一次显示时,第一个添加到 CardLayout 对象的组件为可见组件。 卡片的顺序由组件对象本身在容器内部的顺序决定。CardLayout 定义了一组方法,这些方法允许应用程序按顺序地浏览这些卡片,或者显示指定的卡片。addLayoutComponent(java.awt.Component, java.lang.Object)方法可用于将一个字符串标识符与给定卡片关联,以便进行快速随机访问。 CardLayout() 创建一个间距大小为 0 的新卡片布局。CardLayout(inthgap, intvgap) 创建一个具有指定水平间距和垂直间距的新卡片布局。方法如下:void first(Container)显示第一个添加到容器中的组件void last(Container)显示最后一个添加到容器的组件void next(Container parent)显示在当前显示组件后加入到容器中的一个组件。如果当前组件是最后一个,那么显示第一个组件void previous(Container parent)显示在当前显示组件前加入到容器中的一个组件。 如果当前组件是第一个,那么显示后后一个组件void show(Container parent,String name)显示名称和传递的字符串相匹配的组件。如果没有组件匹配,则为空操作这个布局管理器,作用于和SWT的StackLayout相似。看一个例子:package com.tianyistar.swing.layout;import java.awt.BorderLayout;import java.awt.CardLayout;import java.awt.Container;import java.awt.FlowLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import javax.swing.BorderFactory;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.WindowConstants;/* * author tianyistar */public class CardLayoutTest extends JFrame private JButton labelButton,buttonButton; private JPanel labelPane,buttonPane,cardPane,controlPane; private Container contentPane; public CardLayoutTest() this.setTitle(CardLayout的使用); init(); private void init() contentPane=getContentPane(); contentPane.setLayout(new BorderLayout(); labelButton=new JButton(标签面板); labelButton.addActionListener(new ActionListener() Override public void actionPerformed(ActionEvent e) (CardLayout)cardPane.getLayout().show(cardPane, labelPane); ); buttonButton=new JButton(按钮面板); buttonButton.addActionListener(new ActionListener() Override public void actionPerformed(ActionEvent e) (CardLayout)cardPane.getLayout().show(cardPane, buttonPane); ); controlPane=new JPanel(); controlPane.setBorder(BorderFactory.createTitledBorder(选择要显示的面板); controlPane.setLayout(new FlowLayout(); controlPane.add(labelButton); controlPane.add(buttonButton); contentPane.add(controlPane,BorderLayout.NORTH); /标签面板 labelPane=new JPanel(); labelPane.setBorder(BorderFactory.createTitledBorder(标签面板); labelPane.add(new JLabel(我是标签面板); /按钮面板 buttonPane=new JPanel(); buttonPane.setBorder(BorderFactory.createTitledBorder(按钮面板); buttonPane.add(new JLabel(我是按钮面板); cardPane=new JPanel(); cardPane.setLayout(new CardLayout(); cardPane.add(labelPane,labelPane); cardPane.add(buttonPane,buttonPane); contentPane.add(cardPane,BorderLayout.CENTER); public static void main(String args) CardLayoutTest cl=new CardLayoutTest(); cl.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); cl.addWindowListener(new WindowAdapter() Override public void windowClosing(WindowEvent e) System.exit(0); ); cl.setSize(500,400); cl.setVisible(true); 3, FlowLayout布局管理器FlowLayout仅仅是从左到右、从上到下地布置构件。FlowLayout的类层次结构图: java.lang.Object -java.awt.FlowLayout 构造函数:FlowLayout()建立一个新的Flow Layout,此FlowLayout默认值是居中对齐,组件彼此有5单位的水平与垂直间距。 FlowLayout(int align)建立一个新的Flow Layout,此FlowLayout可设置排列方式,组件彼此有5单位的水平与垂直间距。 FlowLayout(int align,int hgap,int vgap)建立一个新的Flow Layout,此FlowLayout可设置排列方式与组件间距。4, GridLayout布局管理器GridLayout 类是一个布局处理器,它以矩形网格形式对容器的组件进行布置。容器被分成大小相等的矩形,一个矩形中放置一个组件。 GridLayout的类层次结构图: java.lang.Object -java.awt.GridLayout GridLayout比FlowLayout多了行和列的设置,也就是说你要先设置GridLayout共有几行几列,就如同二维平面一般,然后你加进去的组件会先填第一行的格子,然后再从第二行开始填,依此类扒,就像是一个个的格子一般。而且GridLayout会将所填进去组件的大小设为一样。构造函数:GridLayout()建立一个新的GridLayout,默认值是1行1列。 GridLayout(int rows,int cols)建立一个几行几列的GridLayout. GridLayout(int rows,int cols, int hgap,int vgap)建立一个几行几列的GridLayout,并设置组件的间距。GridLayout布置的构件将完全填满它所占据的网格单元。另外,不能控制一个构件的任何涉及网格单元属性的约束条件。例如,不能规定一个构件占据多少个网格单元,因为每个构件总是正好占据一个网格单元。5, GridBagLayout布局管理器GridBagLayout 类是一个灵活的布局管理器,它不要求组件的大小相同便可以将组件垂直、水平或沿它们的基线对齐。每个 GridBagLayout 对象维持一个动态的矩形单元网格,每个组件占用一个或多个这样的单元,该单元被称为显示区域。 每个由 GridBagLayout 管理的组件都与 GridBagConstraints的实例相关联。Constraints 对象指定组件的显示区域在网格中的具体放置位置,以及组件在其显示区域中的放置方式。除了 Constraints 对象之外,GridBagLayout 还考虑每个组件的最小大小和首选大小,以确定组件的大小。网格的总体方向取决于容器的 ComponentOrientation 属性。对于水平的从左到右的方向,网格坐标 (0,0) 位于容器的左上角,其中 X 向右递增,Y 向下递增。对于水平的从右到左的方向,网格坐标 (0,0) 位于容器的右上角,其中 X 向左递增,Y 向下递增。 为了有效使用网格包布局,必须自定义与组件关联的一个或多个 GridBagConstraints 对象。可以通过设置一个或多个实例变量来自定义 GridBagConstraints 对象: GridBagConstraints.gridx、GridBagConstraints.gridy 指定包含组件显示区域的前导角的单元,在此显示区域中,位于网格原点的单元地址是 gridx=0, gridy=0。对于水平的从左到右的布局,组件的前导角是其左上角。对于水平的从右到左的布局,组件的前导角是其右上角。使用 GridBagConstraints.RELATIVE(默认值),指定会将组件直接放置在之前刚添加到容器中的组件的后面(沿 X 轴向为 gridx 或 Y 轴向为 gridy)。 GridBagConstraints.gridwidth、GridBagConstraints.gridheight 指定组件的显示区域中行(针对 gridwidth)或列(针对 gridheight)中的单元数。默认值为 1。使用 GridBagConstraints.REMAINDER 指定组件的显示区域,该区域的范围是从 gridx 到该行(针对 gridwidth)中的最后一个单元,或者从 gridy 到该列(针对 gridheight)中的最后一个单元。 使用 GridBagConstraints.RELATIVE 指定组件的显示区域,该区域的范围是从 gridx 到其所在行(针对 gridwidth)的倒数第二个单元,或者从 gridy 到其所在列(针对 gridheight)的倒数第二个单元。 GridBagConstraints.fill 当组件的显示区域大于组件的所需大小时,用于确定是否(以及如何)调整组件。可能的值为 GridBagConstraints.NONE(默认值)、GridBagConstraints.HORIZONTAL(加宽组件直到它足以在水平方向上填满其显示区域,但不更改其高度)、GridBagConstraints.VERTICAL(加高组件直到它足以在垂直方向上填满其显示区域,但不更改其宽度)和 GridBagConstraints.BOTH(使组件完全填满其显示区域)。 GridBagConstraints.ipadx、GridBagConstraints.ipady指定布局中组件的内部填充,即对组件最小大小的添加量。组件的宽度至少为其最小宽度加上 ipadx 像素。类似地,组件的高度至少为其最小高度加上 ipady 像素。 GridBagConstraints.insets 指定组件的外部填充,即组件与其显示区域边缘之间间距的最小量。 GridBagConstraints.anchor 指定组件应置于其显示区域中何处。可能的值有三种:绝对值、相对于方向的值和相对于基线的值。相对于方向的值是相对于容器的 ComponentOrientation 属性进行解释的,而绝对值则不然。相关于基线的值是相对于基线进行计算的。GridBagConstraints.weightx、GridBagConstraints.weighty 用于确定分布空间的方式,这对于指定调整行为至关重要。除非在行 (weightx) 和列 (weighty) 中至少指定一个组件的权重,否则所有组件都会聚集在其容器的中央。这是因为,当权重为零(默认值)时,GridBagLayout 对象会将所有额外空间置于其单元网格和容器边缘之间。 一个例子:package com.tianyistar.swing.layout;import com.tianyistar.swing.JTextFieldFixedLengthDocument;import java.awt.BorderLayout;import java.awt.Container;import java.awt.GridBagConstraints;import java.awt.GridBagLayout;import java.awt.Insets;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import javax.swing.BorderFactory;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JPasswordField;import javax.swing.JScrollPane;import javax.swing.JTextArea;import javax.swing.JTextField;/* * author tianyistar */public class GridBagLayoutTest public static void main(String args) JFrame f = new JFrame(JTextField); Container contentPane = f.getContentPane(); /contentPane.setLayout(new FlowLayout(); contentPane.setLayout(new BorderLayout(); JPanel p1 = new JPanel(); p1.setL
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 做防水协议书范本
- 立春宣传课件图片
- 2025年磁盘用微晶玻璃基板项目合作计划书
- 2025年循环流化床锅炉合作协议书
- 2025年高收缩腈纶项目合作计划书
- 2025版酒店餐厅场地租赁及美食合作合同
- 二零二五年度贷款购买别墅买卖合同细则
- 二零二五版山林资源开发合作协议范本
- 2025版06289工程招标与合同法适用及合规性审查合同
- 2025版个人教育贷款补充协议示范书
- 第五届应急管理普法知识竞赛考试题库500题(含答案)
- 2024年计算机软件水平考试-初级信息处理技术员考试近5年真题附答案
- 尼康-D300S-相机说明书
- 酒水饮料运输协议模板
- DB3401T 218-2021 芡实米加工技术规程
- TSDDP 8-2024 新型无机磨石施工质量与验收规范
- 钢结构雨棚施工承包合同
- 劳动合同模板纸打印
- (高清版)JTGT 3365-02-2020 公路涵洞设计规范
- 【丽声北极星-江苏版】The Vullage Show绘本课件
- 安徽省水利“安全生产月”知识竞赛考试题库(附答案)
评论
0/150
提交评论