建立GUIs.docx
《建立GUIs.docx》由会员分享,可在线阅读,更多相关《建立GUIs.docx(25页珍藏版)》请在冰豆网上搜索。
建立GUIs
第八章建立GUIs
本模块讲述图形用户界面的建立及布局。
它介绍了抽象视窗工具包,一种建立GUIs的类包。
第一节相关问题
讨论—下述问题与本模块中出现的材料相关。
-Java编程语言是一个具有独立平台的编程语言。
GUI环境通常是从属平台。
那么,为了使GUI平台独立,Java技术是如何接近这个主题的呢?
第二节目的
完成本模块学习时,将能:
-描述AWT包及其组件
-定义Container、Component及LayoutManager等术语,以及它们是如何在一起来建立GUI的
-使用LayoutManager
-使用Flow、Border、Gird及Card布局管理器来获得期望的动态布局
-增加组件到Container
-正确运用Frame及Panel容器
-描述如何使用嵌套容器来完成复杂的布局
-在Java软件程序中,确认如下内容:
-容器
-相关布局管理器
-所有组件的布局层次
第三节AWT
AWT
-提供基本的GUI组件,用在所有的Javaapplets及应用程序中
-具有可以扩展的超类,它们的属性是继承的,类也可被抽象化
-确保显示在屏幕上的每个GUI组件都是抽象类组件的子类
-Contaner,它是一个Component的抽象子类,而且包括两个子类
-Panel
-window
AWT提供用于所有Javaapplets及应用程序中的基本GUI组件,还为应用程序提供与机器的界面。
这将保证一台计算机上出现的东西与另一台上的相一致。
在学AWT之前,简单回顾一下对象层次。
记住,超类是可以扩展的,它们的属性是可继承的。
而且,类可以被抽象化,这就是说,它们是可被分成子类的模板,子类用于类的具体实现。
显示在屏幕上的每个GUI组件都是抽象类组件的子类。
也就是说,每个从组件类扩展来的图形对象都与允许它们运行的大量方法和实例变量共享。
Container是Component的一个抽象子类,它允许其它的组件被嵌套在里面。
这些组件也可以是允许其它组件被嵌套在里面的容器,于是就创建了一个完整的层次结构。
在屏幕上布置GUI组件,容器是很有用的。
Panel是Container的最简单的类。
Container的另一个子类是Window。
第四节Java.awt包
Java.awt包包含生成WIDGETS和GUI组件的类。
该包的基本情况如下图所示。
黑体字的类表明该模块的要点。
第五节建立图形用户界面
8.5.1Container
Container
-Container的两个主要类型是Window和Panel
-Window是Java.awt.Window.的对象
-Panel是Java.awt.Panel的对象
Container有两个主要类型:
Window和Panel
Window是Java.awt.Window.的对象。
Window是显示屏上独立的本机窗口,它独立于其它容器。
Window有两种形式:
Frame(框架)和Dialog(对话框)。
Frame和Dialog是Window的子类。
Frame是一个带有标题和缩放角的窗口。
对话没有菜单条。
尽管它能移动,但它不能缩放。
Panel是Java.awt.Panel的对象。
Panel包含在另一个容器中,或是在Web浏览器的窗口中。
Panel确定一个四边形,其它组件可以放入其中。
Panel必须放在Window之中(或Window的子类中)以便能显示出来。
注—容器不但能容纳组件,还能容纳其它容器,这一事实对于建立复杂的布局是关键的,也是基本的。
滚动块也是Window的一个子类。
它在模块10“AWT组件集”里讨论。
8.5.2定位组件
定位组件
-容器里的组件的位置和大小是由布局管理器决定的。
-可以通过停用布局管理器来控制组件的大小或位置。
然后必须用组件上的setLocation(),setSize(),或setBounds()来定位它们在容器里的位置。
容器里的组件的位置和大小是由布局管理器决定的。
容器对布局管理器的特定实例保持一个引用。
当容器需要定位一个组件时,它将调用布局管理器来做。
当决定一个组件的大小时,同样如此。
布局管理器完全控制容器内的所有组件。
它负责计算并定义上下文中对象在实际屏幕中所需的大小。
8.5.3组件大小
因为布局管理器负责容器里的组件的位置和大小,因此不需要总是自己去设定组件的大小或位置。
如果想这样做(使用setLocation(),setSize()或setBounds()方法中的任何一种),布局管理器将覆盖你的决定。
如果必须控制组件的大小或位置,而使用标准布局管理器做不到,那就可能通过将下述方法调用发送到容器中来中止布局管理器:
setLayout(null);
做完这一步,必须对所有的组件使用setLocation(),setSize()或setBounds(),来将它们定位在容器中。
请注意,由于窗口系统和字体大小之间的不同,这种办法将导致从属于平台的布局。
更好的途径是创建布局管理器的新子类。
第六节Frames
Frames
-是Window的子类
-具有标题和缩放角
-从组件继承并以add方式添加组件
-能以字符串规定的标题来创建不可见框架对象
-能将BorderLayout当做缺省布局管理器
-用setLayout方式来改变缺省布局管理器
Frames是Window的一个子类。
它是带有标题和缩放角的窗口。
它继承于Java.awt.Container,因此,可以用add()方式来给框架添加组件。
框架的缺省布局管理器就是BorderLayout。
它可以用setLayout()方式来改变。
框架类中的构造程序Frame(String)用由String规定的标题来创建一个新的不可见的框架对象。
当它还处于不可见状态时,将所有组件添加到框架中。
1.importjava.awt.*;
2.publicclassMyFrameextendsFrame{
3.publicstaticvoidmain(Stringargs[]){
6.MyFramefr=newMyFrame("HelloOutThere!
");
7.fr.setSize(500,500);
4.fr.setBackground(Color.blue);
5.fr.setVisible(true);
6.}
7.publicMyFrame(Stringstr){
8.super(str);
9.}
10.}
上述程序创建了下述框架,它有一个具体的标题、大小及背景颜色。
注—在框架显示在屏幕上之前,必须做成可见的(通过调用程序setVisible(true)),而且其大小是确定的(通过调用程序setSize()或pack())。
第七节Panels
Panels
-为组件提供空间
-允许子面板拥有自己的布局管理器
-以add方法添加组件
象Frames一样,Panels提供空间来连接任何GUI组件,包括其它面板。
每个面板都可以有它自己的布管理程序。
一旦一个面板对象被创建,为了能看得见,它必须添加到窗口或框架对象上。
用Container类中的add()方式可以做到这一点。
下面的程序创建了一个小的黄色面板,并将它加到一个框架对象上:
1.importjava.awt.*;
2.publicclassFrameWithPanelextendsFrame{
3.
4.//Constructor
5.publicFrameWithPanel(Stringstr){
6.super(str);
7.}
8.
9.publicstaticvoidmain(Stringargs[]){
10.FrameWithPanelfr=
11.newFrameWithPanel("FramewithPanel");
12.Panelpan=newPanel();
13.
14.fr.setSize(200,200);
15.fr.setBackground(Color.blue);
16.fr.setLayout(null);//overridedefaultlayoutmgr
17.pan.setSize(100,100);
18.pan.setBackground(Color.yellow);
19.
20.fr.add(pan);
21.fr.setVisible(true);
22.}
23.....
24.
第八节容器布局(ContainerLayout)
容器布局(ContainerLayout)
-流程布局(FlowLayout)
-边框布局(BorderLayout)
-网格布局(GridLayout)
-卡布局(CardLayout)
-网格包布局(GridBagLayout)
容器中组件的布局通常由布局管理器控制。
每个Container(比如一个Panel或一个Frame)都有一个与它相关的缺省布局管理器,它可以通过调用setLayout()来改变。
布局管理器负责决定布局方针以及其容器的每一个子组件的大小。
第九节布局管理器
下面的布局管理器包含在Java编程语言中:
-FlowLayout—Panel和Applets的缺省布局管理器
-BorderLayout—Window、Dialog及Frame的缺省管理程序
-GridLayout
-CardLayout
-GridBagLayout
GridBag布局管理器在本模块中不深入讨论。
FlowLayout的一个简单例子
这个样板代码阐述了几个要点,将在下一节讨论。
1.importjava.awt.*;
2.
3.publicclassExGui{
4.privateFramef;
5.privateButtonb1;
6.privateButtonb2;
7.
8.publicstaticvoidmain(Stringargs[]){
9.ExGuiguiWindow=newExGui();
10.guiWindow.go();
11.}
12.
13.publicvoidgo(){
14.f=newFrame("GUIexample");
15.f.setLayout(newFlowLayout());
16.b1=newButton("PressMe");
17.b2=newButton("Don'tPressMe");
18.f.add(b1);
19.f.add(b2);
20.f.pack();
21.f.setVisible(true);
22.}
23.}
main()方法
本例中第8行main()方法有两个作用。
首先,它创建了ExGui对象的一个实例。
回想一下,直到一个实例存在,还没有被称做f,b1和b2的真实数据项可以使用。
第二,当数据空间被创建时,main()在该实例的上下文中调用实例方法go()。
在go()中,真正的运行才开始。
newFrame(“GUIExample”)
这个方法创建Java.awt.Frame类的一个实例。
根据本地协议,在Java编程语言中,Frame是顶级窗口,带有标题条—在这种情况下,标题条由构造程序参数“GUIExample”定义—缩放柄,以及其它修饰。
f.setLayout(newFlowLayout())
这个方法创建Flow布局管理器的一个实例,并将它安装在框架中。
对于每个Frame、Border布局来说,都有一个布局管理器,但本例中没有使用。
Flow布局管理器在AWT中是最简单的,它在某种程度上象一个页面中的单词被安排成一行一行的那样来定位组件。
请注意,Flow布局缺省地将每一行居中。
newButton(“PressMe”)
这个方法创建Java.awt.Button类的一个实例。
按钮是从本地窗口工具包中取出的一个标准按钮。
按钮标签是由构造程序的字符串参数定义的。
f.add(b1)
这个方法告诉框架f(它是一个容器),它将包容组件b1。
b1的大小和位置受从这一点向前的Frame布局管理器的控制。
f.pack()
这个方法告诉框架来设定大小,能恰好密封它所包含的组件。
为了确定框架要用多大,f.pack()询问布局管理器,在框架中哪个负责所有组件的大小和位置。
f.setVisible(true)
这个方法使框架以及其所有的内容变成用户看得见的东西。
第190页代码的最终结果是:
8.9.1Flow布局管理器
第190页例子中所用的Flow布局对组件逐行地定位。
每完成一行,一个新行便又开始。
与其它布局管理器不一样,Flow布局管理器不限制它所管理的组件的大小,而是允许它们有自己的最佳大小。
如果想将组件设定缺省居中的话,Flow布局构造程序参数允许将组件左对齐或右对齐。
如果想在组件之间创建一个更大的最小间隔,可以规定一个界限。
当用户对由Flow布局管理的区域进行缩放时,布局就发生变化。
如:
下面的例子就是如何用类容器的setLayout()方法来创建Flow布局对象并安装它们。
setLayout(newFlowLayout(intalign,inthgap,intvgap));
对齐的值必须是FlowLayout.LEFT,FlowLayout.RIGHT,或FlowLayout.CENTER。
例如:
setLayout(newFlowLayout(FlowLayout.RIGHT,20,40));
下述程序构造并安装一个新Flow布局,它带有规定好的对齐方式以及一个缺省的5单位的水平和垂直间隙。
对齐的值必须是FlowLayout.LEFT,FlowLayout.RIGHT,或FlowLayout.CENTER。
setLayout(newFlowLayout(intalign);
setLayout(newFlowLayout(FlowLayout.LEFT));
下述程序构造并安装一个新Flow布局,它带有规定好的居中对齐方式和一个缺省的5单位的水平和垂直间隙。
setLayout(newFlowLayout());
这个模块代码将几个按钮添加到框架中的一个Flow布局中:
1.importjava.awt.*;
2.
3.publicclassMyFlow{
4.privateFramef;
5.privateButtonbutton1,button2,button3;
6.
7.publicstaticvoidmain(Stringargs[]){
8.MyFlowmflow=newMyFlow();
9.mflow.go();
10.}
11.
12.publicvoidgo(){
13.f=newFrame("FlowLayout");
14.f.setLayout(newFlowLayout());
15.button1=newButton("Ok");
16.button2=newButton("Open");
17.button3=newButton("Close");
18.f.add(button1);
19.f.add(button2);
20.f.add(button3);
21.f.setSize(100,100);
22.f.setVisible(true);
23.}
24.}
8.9.2Border布局管理器
Border布局管理器为在一个Panel或Window中放置组件提供一个更复杂的方案。
Border布局管理器包括五个明显的区域:
东、南、西、北、中。
北占据面板的上方,东占据面板的右侧,等等。
中间区域是在东、南、西、北都填满后剩下的区域。
当窗口垂直延伸时,东、西、中区域也延伸;而当窗口水平延伸时,东、西、中区域也延伸。
Border布局管理器是用于Dialog和Frame的缺省布局管理器。
下例的代码是在第193页上:
注—当窗口缩放时,按钮相应的位置不变化,但其大小改变。
下面的代码对前例进行了修改,表示出了Border布局管理器的特性。
可以用从Container类继承的setLayout()方法来将布局设定为Border布局。
1.importjava.awt.*;
2.
3.publicclassExGui2{
4.privateFramef;
5.privateButtonbn,bs,bw,be,bc;
6.
7.publicstaticvoidmain(Stringargs[]){
8.ExGui2guiWindow2=newExGui2();
9.guiWindow2.go();
10.}
11.
12.publicvoidgo(){
13.f=newFrame("BorderLayout");
14.bn=newButton("B1");
15.bs=newButton("B2");
16.be=newButton("B3");
17.bw=newButton("B4");
18.bc=newButton("B5");
19.
20.f.add(bn,BorderLayout.NORTH);
21.f.add(bs,BorderLayout.SOUTH);
22.f.add(be,BorderLayout.EAST);
23.f.add(bw,BorderLayout.WEST);
24.f.add(bc,BorderLayout.CENTER);
25.
26.f.setSize(200,200);
27.f.setVisible(true);
28.}
29.}
下面这一行:
setLayout(newBorderLayout());
构造并安装一个新Border布局,在组件之间没有间隙。
这一行
setLayout(newBorderLayout(inthgap,intvgap);
构造并安装一个Border布局,在由hgap和vgap规定的组件之间有规定的间隙。
在布局管理器中组件必须被添加到指定的区域,而且还看不见。
区域名称拼写要正确,尤其是在选择不使用常量(如add(button,”Center”))而使用add(button,BorderLayout.CENTER)时。
拼写与大写很关键。
可以使用Border布局管理器来产生布局,且带有在缩放时在一个方向、另一方向或双方向上都延伸的元素。
注—如果窗口水平缩放,南、北、中区域变化;如果窗口垂直缩放,东、西、中区域变化;
如果离开一个Border布局未使用的区域,,好象它的大小为0。
中央区域即使在不含组件的情况下仍然呈现为背景。
可以仅将单个组件添加到Border布局管理器五个区域的每一个当中。
如果添加不止一个,只有最后一个看得见。
后面的模块将演示如何用中间容器来允许不止一个组件被放在单个Border布局管理器区域的空间里。
注—布局管理器给予南、北组件最佳高度,并强迫它们与容器一样宽。
但对于东、西组件,给予最佳宽度,而高度受到限制。
8.9.3Grid布局管理器
Grid布局管理器为放置组件提供了灵活性。
用许多行和栏来创建管理程序。
然后组件就填充到由管理程序规定的单元中。
比如,由语句newGridLayout(3,2)创建的有三行两栏的Grid布局能产生如下六个单元:
因为有Border布局管理器,组件相应的位置不随区域的缩放而改变。
只是组件的大小改变。
Grid布局管理器总是忽略组件的最佳大小。
所有单元的宽度是相同的,是根据单元数对可用宽度进行平分而定的。
同样地,所有单元的高度是相同的,是根据行数对可用高度进行平分而定的。
将组件添加到网格中的命令决定它们占有的单元。
单元的行数是从左到右填充,就象文本一样,而页是从上到下由行填充。
行
setLayout(newGridLayout());
创建并安装一个Grid布局,每行中的每个组件有一个栏缺省。
行
setLayout(newGridLayout(introws,intcols));
创建并安装一个带有规定好行数和栏数的Grid布局。
对布局中所有组件所给的大小一样。
下一行:
setLayout(newGridLayout(introws,intcols,inthgap,intvgap);
创建并安装一个带有规定好行数和栏数的网格布局。
布局中所有组件所给的大小一样。
hgap和vgap规定组件间各自的间隙。
水平间隙放在左右两边及栏与栏之间。
垂直间隙放在顶部、底部及每行之间。
注—行和栏中的一个,不是两个同时,可以为0。
这就是说,任何数量的对象都可以放在一个行或一个栏中。
第8—27页上所示的应用程序代码如下:
1.importjava.awt.*;
2.publicclassGridEx{
3.privateFramef;
4.privateButtonb1,b2,b3,b4,b5,b6;
5.
6.publicstaticvoidmain(Stringargs[]){
7.GridExgrid=newGridEx();
8.grid.go();
9.}
10.
11.publicvoidgo(){
12.f=newFrame("Gridexample");
13.
14.f.setLayout(newGridLayout(3,2));
15.b1=newButton("1");
16.b2=newButton("2");
17.b3=newButton("3");
18.b4=newButton("4");
19.b5=newButton("5");
20.b6=newButton("6");
21.
22.f.add(b1);
23.f.add(b2);
24.f.add(b3);
25.f.add(b4);
26.f.add(b5);
2