AWT图形用户界面设计(一)
5.1 用AWT生成图形化用户界面
抽象窗口工具包AWT (Abstract Window Toolkit) 是 API为Java 程序提供的建立图形用户界面GUI (Graphics User Interface)工具集,AWT可用于Java的applet和applications中。它支持图形用户界面编程的功能包括: 用户界面组件;事件处理模型;图形和图像工具,包括形状、颜色和字体类;布局管理器,可以进行灵活的窗口布局而与特定窗口的尺寸和屏幕分辨率无关;数据传送类,可以通过本地平台的剪贴板来进行剪切和粘贴。
5.1.1 java.awt包
java.awt包中提供了GUI设计所使用的类和接口,可从图5.1中看到主要类之间的关系。
java.awt包提供了基本的java程序的GUI设计工具。主要包括下述三个概念:
组件--Component
容器--Container
布局管理器--LayoutManager
5.1.2 组件和容器
Java的图形用户界面的最基本组成部分是组件(Component),组件是一个可以以图形化的方式显示在屏幕上并能与用户进行交互的对象,例如一个按钮,一个标签等。组件不能独立地显示出来,必须将组件放在一定的容器中才可以显示出来。
类java.awt.Component是许多组件类的父类,Component类中封装了组件通用的方法和属性,如图形的组件对象、大小、显示位置、前景色和背景色、边界、可见性等,因此许多组件类也就继承了Component类的成员方法和成员变量,相应的成员方法包括:
getComponentAt(int x, int y)
getFont()
getForeground()
getName()
getSize()
paint(Graphics g)
repaint()
update()
setVisible(boolean b)
setSize(Dimension d)
setName(String name)等
容器(Container)也是一个类,实际上是Component的子类,因此容器本身也是一个组件,具有组件的所有性质,但是它的主要功能是容纳其它组件和容器。
布局管理器(LayoutManager):每个容器都有一个布局管理器,当容器需要对某个组件进行定位或判断其大小尺寸时,就会调用其对应的布局管理器。
为了使我们生成的图形用户界面具有良好的平台无关性,Java语言中,提供了布局管理器这个工具来管理组件在容器中的布局,而不使用直接设置组件位置和大小的方式。
在程序中安排组件的位置和大小时,应该注意以下两点:
1.容器中的布局管理器负责各个组件的大小和位置,因此用户无法在这种情况下设置组件的这些属性。如果试图使用Java 语言提供的setLocation(),setSize(),setBounds() 等方法,则都会被布局管理器覆盖。
2.如果用户确实需要亲自设置组件大小或位置,则应取消该容器的布局管理器,方法为:
setLayout(null);
5.1.3 常用容器
容器java.awt.Container是Component的子类,一个容器可以容纳多个组件,并使它们成为一个整体。容器可以简化图形化界面的设计,以整体结构来布置界面。所有的容器都可以通过add()方法向容器中添加组件。
有三种类型的容器:Window、Panel、ScrollPane,常用的有Panel, Frame, Applet。
1.Frame
以下是容器的例子:
例5.1
import java.awt.*;
public class MyFrame extends Frame{
public static void main(String args[ ]){
MyFrame fr = new MyFrame("Hello Out There!");
//构造方法
fr.setSize(200,200);
//设置Frame的大小,缺省为(0,0)
fr.setBackground(Color.red);
//设置Frame的背景,缺省为红色
fr.setVisible(true);
//设置Frame为可见,缺省为不可见
}
public MyFrame (String str){
super(str); //调用父类的构造方法
}
}
一般我们要生成一个窗口,通常是用Window的子类Frame来进行实例化,而不是直接用到Window类。Frame的外观就像我们平常在windows系统下见到的窗口,有标题、边框、菜单、大小等等。每个Frame的对象实例化以后,都是没有大小和不可见的,因此必须调用setSize( )来设置大小,调用setVisible(true)来设置该窗口为可见的。
另外,AWT在实际的运行过程中是调用所在平台的图形系统,因此同样一段AWT程序在不同的操作系统平台下运行所看到的图形系统是不一样的。例如在windows下运行,则显示的窗口是windows风格的窗口;而在UNIX下运行时,则显示的是UNIX风格的窗口。
2. Panel
例5.2
import java.awt.*;
public class FrameWithPanel extends Frame{
public FrameWithPanel(String str){
super(str);
}
public static void main(String args[]){
FrameWithPanel fr = new FrameWithPanel("Frame with Panel");
Panel pan=new Panel();
fr.setSize(200,200);
fr.setBackground(Color.red);
//框架fr的背景颜色设置为红色
fr.setLayout(null);
//取消布局管理器
pan.setSize(100,100);
pan.setBackground(Color.yellow);
//设置面板pan的背景颜色为黄色
fr.add(pan); //用add方法把面板pan添加到框架fr中
fr.setVisible(true);
}
}
一般我们要生成一个窗口,通常是用Window的子类Frame来进行实例化,而不是直接用到Window类。Frame的外观就像我们平常在windows系统下见到的窗口,有标题、边框、菜单、大小等等。每个Frame的对象实例化以后,都是没有大小和不可见的,因此必须调用setSize( )来设置大小,调用setVisible(true)来设置该窗口为可见的。
另外,AWT在实际的运行过程中是调用所在平台的图形系统,因此同样一段AWT程序在不同的操作系统平台下运行所看到的图形系统是不一样的。例如在windows下运行,则显示的窗口是windows风格的窗口;而在UNIX下运行时,则显示的是UNIX风格的窗口。
5.1.4 layoutmanager 布局管理器(1)
java为了实现跨平台的特性并且获得动态的布局效果,java将容器内的所有组件安排给一个"布局管理器"负责管理,如:排列顺序,组件的大小、位置,当窗口移动或调整大小后组件如何变化等功能授权给对应的容器布局管理器来管理,不同的布局管理器使用不同算法和策略,容器可以通过选择不同的布局管理器来决定布局。
布局管理器主要包括:flowlayout,borderlayout,gridlayout,cardlayout,gridbaglayout
例5.3
import java.awt.*;
public class exgui<
private frame f;
private button b1;
private button b2;
public static void main(string args[])<
exgui that = new exgui();
that.go();
>
public void go()<
f = new frame("gui example");
f.setlayout(new flowlayout());
//设置布局管理器为flowlayout
b1 = new button("press me");
//按钮上显示字符"press me"
b2 = new button("dont press me");
f.add(b1);
f.add(b2);
f.pack();
//紧凑排列,其作用相当于setsize(),即让窗口
尽量小,小到刚刚能够包容住b1、b2两个按钮
f.setvisible(true);
>
>
1. flowlayout
flowlayout 是panel,applet的缺省布局管理器。其组件的放置规律是从上到下、从左到右进行放置,如果容器足够宽,第一个组件先添加到容器中第一行的最左边,后续的组件依次添加到上一个组件的右边,如果当前行已放置不下该组件,则放置到下一行的最左边。
构造方法主要下面几种:
flowlayout(flowlayout.right,20,40);
/*第一个参数表示组件的对齐方式,指组件在这一行中的位置是居中对齐、居右对齐还是居左对齐,第二个参数是组件之间的横向间隔,第三个参数是组件之间的纵向间隔,单位是象素。*/
flowlayout(flowlayout.left);
//居左对齐,横向间隔和纵向间隔都是缺省值5个象素
flowlayout();
//缺省的对齐方式居中对齐,横向间隔和纵向间隔都是缺省值5个象素
例5.4
import java.awt.*;
public class mybuttons<
public static void main(string args[])
<
frame f = new frame();
f.setlayout(new flowlayout());
button button1 = new button("ok");
button button2 = new button("open");
button button3 = new button("close");
f.add(button1);
f.add(button2);
f.add(button3);
f.setsize(300,100);
f.setvisible(true);
>
>
当容器的大小发生变化时,用flowlayout管理的组件会发生变化,其变化规律是:组件的大小不变,但是相对位置会发生变化。例如上图中有三个按钮都处于同一行,但是如果把该窗口变窄,窄到刚好能够放下一个按钮,则第二个按钮将折到第二行,第三个按钮将折到第三行。按钮"open"本来在按钮"ok"的右边,但是现在跑到了下面,所以说"组件的大小不变,但是相对位置会发生变化"。
2. borderlayout
borderlayout 是window,frame和dialog的缺省布局管理器。borderlayout布局管理器把容器分成5个区域:north,south,east,west和center,每个区域只能放置一个组件。
例5.5
import java.awt.*;
public class buttondir<
public static void main(string args[])<
frame f = new frame("borderlayout");
f.setlayout(new borderlayout());
f.add("north", new button("north"));
//第一个参数表示把按钮添加到容器的north区域
f.add("south", new button("south"));
//第一个参数表示把按钮添加到容器的south区域
f.add("east", new button("east"));
//第一个参数表示把按钮添加到容器的east区域
f.add("west", new button("west"));
//第一个参数表示把按钮添加到容器的west区域
f.add("center", new button("center"));
//第一个参数表示把按钮添加到容器的center区域
f.setsize(200,200);
f.setvisible(true);
>
>
在使用borderlayout的时候,如果容器的大小发生变化,其变化规律为:组件的相对位置不变,大小发生变化。例如容器变高了,则north、south区域不变,west、center、east区域变高;如果容器变宽了,west、east区域不变,north、center、south区域变宽。不一定所有的区域都有组件,如果四周的区域(west、east、north、south区域)没有组件,则由center区域去补充,但是如果center区域没有组件,则保持空白。
3. gridlayout
使容器中各个组件呈网格状布局,平均占据容器的空间。
例5.6
import java.awt.*;
public class buttongrid <
public static void main(string args[]) <
frame f = new frame("gridlayout");
f.setlayout(new gridlayout(3,2));
//容器平均分成3行2列共6格
f.add(new button("1")); //添加到第一行的第一格
f.add(new button("2")); //添加到第一行的下一格
f.add(new button("3")); //添加到第二行的第一格
f.add(new button("4")); //添加到第二行的下一格
f.add(new button("5")); //添加到第三行的第一格
f.add(new button("6")); //添加到第三行的下一格
f.setsize(200,200);
f.setvisible(true);
>
>
5.1.4 layoutmanager 布局管理器(2)
4. cardlayout
cardlayout布局管理器能够帮助用户处理两个以至更多的成员共享同一显示空间,它把容器分成许多层,每层的显示空间占据整个容器的大小,但是每层只允许放置一个组件,当然每层都可以利用panel来实现复杂的用户界面。牌布局管理器(cardlayout)就象一副叠得整整齐齐的扑克牌一样,有54张牌,但是你只能看见最上面的一张牌,每一张牌就相当于牌布局管理器中的每一层。
例5.7
import java.awt.*;
import java.awt.event.*; //事件处理机制,下一节的内容
public class threepages implements mouslistener <
cardlayout layout=new cardlayout(); //实例化一个牌布局管理器对象
frame f=new frame("cardlayout");
button page1button;
label page2label; //label是标签,实际上是一行字符串
textarea page3text; //多行多列的文本区域
button page3top;
button page3bottom;
public static void main(string args[])
< new threepages().go(); >
public void go()
< f.setlayout(layout); //设置为牌布局管理器layout
f.add(page1button=new button("button page"),"page1button"); /*第二个参数"page1button"表示的是你对这层牌所取的名字*/
page1button.addmouselistener(this); //注册监听器
f.add(page2label=new label("label page"),"page2label");
page2label.addmouselisener(this); //注册监听器
panel panel=new panel();
panel.setlayout(new borderlayout());
panel.add(page3text=new textarea("composite page"),"center");
page3text.addmouselistener(this);
panel.add(page3top=new button("top button") , "north");
page3top.addmouselistener(this);
panel.add(page3bottom=new button("bottom button") ,"south");
page3bottom.addmouselistener(this);
f.add(panel,"panel");
f.setsize(200,200);
f.setvisible(true);
>
……
>
5.容器的嵌套
在复杂的图形用户界面设计中,为了使布局更加易于管理,具有简洁的整体风格,一个包含了多个组件的容器本身也可以作为一个组件加到另一个容器中去,容器中再添加容器,这样就形成了容器的嵌套。下面是一个容器嵌套的例子。
例5.8
import java.awt.*;
public class exgui3<
private frame f;
private panel p;