[备注]:我们之前所学基本都是基于命令行模式下的代码程序设计,而AWT开始就是开始图形用户界面的设计,但是建议学习过程不要花太多精力放在学习这一块的内容上,原因是我们将来比较少用到这边的知识,应该把侧重点放在这里面涉及的思想和设计模式,这些东西是我们学习的本源和重点。
1. 构建图形用户界面:GUI(Graphical User Interface),图形用户界面。
课程目标
1) 描述AWT包及其组件
2) 定义Container、Component及Layout Manager等术语,以及它们是如何在一起来建立GUI的
3) 使用Layout Manager
4) 使用Flow、Border、Gird及Card布局管理器来获得期望的动态布局
5) 增加组件到Container
6) 正确运用Frame及Panel容器
7) 描述如何使用嵌套容器来完成复杂的布局
2. 在学习这部分内容之前我们先学习一下Eclipse中的jar包的打包方法,jar包在前面几讲内容已经说明过了,打包方法:
1). 在需要打包的项目上右击 --> Export --> Java--JAR file --> 指定好生成路径并点击next到完成为止 [注意在选项中有一个 Main class,在这个选项中由于我们是命令行模式下打包,所以这项为空,如果是图形界面的,这边指定好程序入口点后,打包成的jar文件可以直接双击运行,与.exe文件类似。]
2). 将jar文件解压缩可以发现生成两个目录,其中有一个目录 "META-INF" 打开文件MANIFFST.MF文件如下图所示:
[这个文件表示原文件的信息,因为我们这个JAR包是命令行界面的程序打包的,如果这个程序是图形用户界面的程序,它还会有一条信息表示程序的入口点main方法:Main-Class:** 类似的信息]
3). 查看JDK 安装目录 Java/jdk1.6.0_26/demo/jfc/ 下的用例就是Java给我们提供的一些GUI程序的demo和源代码,可以参考一下
3. 基本概念
1) AWT(Abstract Window Toolkit),抽象窗口工具集,第一代的Java GUI组件,是重量级的。
2). Swing,不依赖于底层细节,轻量级的组件。
GUI全称是Graphical User Interface,即图形用户界面。根据作用GUI组件可分为基本组件和容器。组件又称构件,诸如按钮、文本框之类的图形界面元素,容器其实是一种比较特殊的组件,可以容纳其它组件,如窗口、对话框等,所有的容器类都是java.awt.Container的直接或间接子类。
AWT 提供基本的GUI组件,用在所有的Java applets[applets已经很少用了]及应用程序中
- 具有可以扩展的超类,它们的属性是继承的
- 确保显示在屏幕上的每个GUI组件都是抽象类组件的子类
- Container[容器,容器本身也可以看做是一个组件],它是Component的一个子类,而且包括两个主要子类
- Panel [面板]
- window [窗口]
4. AWT(Abstract Window Toolkit),抽象窗口工具包,SUN公司提供的用于图形界面编程(GUI)的类库。基本的AWT库处理用户界面元素的方法是把这些元素的创建和行为委托给每个目标平台上(Windows、Unix、Macintosh等)的本地GUI工具进行处理。例如:如果我们使用AWT在一个Java窗口中放置一个按钮,那么实际上使用的是一个具有本地外观和感觉的按钮。这样,从理论上来说,我们所编写的图形界面程序能运行在任何平台上,做到了图形界面程序的跨平台运行。
5. Java.awt包如下图所示:
图76-2:Java.awt包
6. 建立图形用户界面
Container:Container的两个主要类型是Window和Panel
1) Window是Java.awt.Window的对象
(1) Window是java.awt.Window的对象。Window是显示屏上独立的本机窗口,它独立于其它容器
2) Panel是Java.awt.Panel的对象(2) Window有两种形式:Frame(框架)和Dialog(对话框)。Frame和Dialog是Window的子类。Frame是一个带有标题和缩放角的窗口。对话框没有菜单条。尽管它能移动,但它不能缩放。
[查看JDK Doc文档中的Window类]
(1) Panel是Java.awt.Panel的对象。Panel包含在另一个容器中,或是在Web浏览器的窗口中。Panel确定一个四边形,其它组件可以放入其中。Panel必须放在Window之中(或Window的子类中)以便能显示出来
(2) 注:容器不但能容纳组件,还能容纳其它容器,这一事实对于建立复杂的布局是关键的,也是基本的。
7. 定位组件
1) 容器里的组件的位置和大小是由布局管理器决定的。
2) 可以通过停用布局管理器来控制组件的大小或位置。
3) 然后必须用组件上的setLocation()[设置位置],setSize()[设置大小],或setBounds()[设置边框]来定位它们在容器里的位置
4) 容器里的组件的位置和大小是由布局管理器决定的。容器对布局管理器的特定实例保持一个引用。当容器需要定位一个组件时,它将调用布局管理器来做。当决定一个组件的大小时,同样如此。布局管理器完全控制容器内的所有组件。它负责计算并定义上下文中对象在实际屏幕中所需的大小。
8. 组件大小
1)因为布局管理器负责容器里的组件的位置和大小,因此不需要总是自己去设定组件的大小或位置。
2)如果必须控制组件的大小或位置,而使用标准布局管理器做不到,那就可能通过将下述方法调用发送到容器中来中止布局管理器:
setLayout(null);
3) 做完这一步,必须对所有的组件使用setLocation(),setSize()或setBounds(),来将它们定位在容器中。请注意,由于窗口系统和字体大小之间的不同,这种办法将导致从属于平台的布局。更好的途径是创建布局管理器的新子类
9. Frames
1) 是Window的子类
2) 具有标题和缩放角
3) 从容器继承并以add方式添加组件
4) 能以字符串规定的标题来创建不可见框架对象
5) 能将BorderLayout当做缺省布局管理器
6) 用setLayout方式来改变缺省布局管理器
7) Frame是Window的一个子类。它是带有标题和缩放角的窗口。它继承于Java.awt.Container,因此,可以用add()方式来给框架添加组件。框架的缺省布局管理器就是Border Layout。它可以用setLayout()方式来改变
8) 框架类中的构造程序 Frame(String)用由String规定的标题来创建一个新的不可见的框架对象。当它还处于不可见状态时,将所有组件添加到框架中。
查看JDk Doc文档中的Frame类的构造方法
public Frame(String title)
throws HeadlessException这个方法中title就是显示的标题
程序如下所示:
package com.ahuier.awt; import java.awt.Color; import java.awt.Frame; public class MyFrame extends Frame{ public MyFrame(String title){ super(title); } public static void main(String[] args){ MyFrame frame = new MyFrame("我的第一个GUI程序"); frame.setSize(500, 500); //设置宽度和高度 frame.setBackground(Color.BLUE); //设置背景色 frame.setVisible(true); //设置可见 } }编译执行结果:
10. Frame类继承层次如下图所示:
图76-3:Frame类继承层次
11. Panels
1) 为组件提供空间
2) 允许子面板拥有自己的布局管理器
3) 以add方法添加组件
(1) 象Frames一样,Panels提供空间来连接任何GUI组件,包括其它面板。每个面板都可以有它自己的布管理程序。
(2) 一旦一个面板对象被创建,为了能看得见,它必须添加到窗口或框架对象上。用Container类中的add()方式可以做到这一点
Panel类
图76-5:Panel类的继承层次
程序如下:
package com.ahuier.awt; import java.awt.Color; import java.awt.Frame; import java.awt.Panel; public class FrameWithPanel extends Frame{ public FrameWithPanel(String title){ super(title); } public static void main(String[] args) { FrameWithPanel frame = new FrameWithPanel("frame with panel"); Panel panel = new Panel(); frame.setSize(200,200); frame.setBackground(Color.BLACK); frame.setLayout(null); //制定布局管理器,我们设置为空,也就是不使用它自带的布局管理器 panel.setSize(100, 100); panel.setBackground(Color.YELLOW); frame.add(panel); //将panel设置到frame上 frame.setVisible(true); } }编译执行结果:
12. 布局管理器,现在我们使用的布局管理器一般是使用默认的,或者屏蔽掉自己定义一个布局管理器。
1) 容器里组件的位置和大小是由布局管理器来决定的。容器对布局管理器的特定实例保持一个引用。当容器需要定位一个组件时,它将调用布局管理器来完成。当决定一个组件的大小时,也是如此。
2) 在AWT中,给我们提供了五种布局管理器[了解一下]:
BorderLayout
FlowLayout
GridLayout
CardLayout
GridBagLayout
3) 容器中组件的布局通常由布局管理器控制。每个Container(比如一个Panel或一个Frame)都有一个与它相关的缺省布局管理器,它可以通过调用setLayout()来改变
4) 布局管理器负责决定布局方针以及其容器的每一个子组件的大小。5) 我们可以通过设置空布局管理器,来控制组件的大小和位置。调用setLayout(null)。
6) 在设置空布局管理器后,必须对所有的组件调用setLocation(),setSize()或setBounds(),将它们定位在容器中。
图76-8:默认的布局管理器
13. FlowLayout布局管理器
1) 与其它布局管理器不一样,Flow布局管理器不限制它所管理的组件的大小,而是允许它们有自己的最佳大小。
2) 默认是居中放置组件
3) 如果想在组件之间创建一个更大的最小间隔,可以规定一个界限。4) 当用户对由Flow布局管理的区域进行缩放时,布局就发生变化
14. Border布局管理器
1) Border布局管理器为在一个Panel或Window中放置组件提供一个更复杂的方案。Border布局管理器包括五个明显的区域:东、南、西、北、中。
2) 北占据面板的上方,东占据面板的右侧,等等。中间区域是在东、南、西、北都填满后剩下的区域。当窗口垂直延伸时,东、西、中区域也延伸;而当窗口水平延伸时,东、西、中区域也延伸
3) 当窗口缩放时,按钮相应的位置不变化,但其大小改变
4) BorderLayout是Frame类的默认布局管理器
程序如下:
package com.ahuier.awt; import java.awt.Button; import java.awt.FlowLayout; import java.awt.Frame; public class ExGui { private Frame frame; private Button button1; private Button button2; public void go(){ frame = new Frame("gui example"); frame.setLayout(new FlowLayout()); button1 = new Button("Press me"); button2 = new Button("Don't press me"); frame.add(button1); frame.add(button2); frame.pack(); //这个方法表示这个容器刚刚能够包含到里面的组件的最小的大小 frame.setVisible(true); } public static void main(String[] args) { ExGui window = new ExGui(); window.go(); } }编译执行结果:
这边如果讲go()方法中的:frame.setLayout(new FlowLayout());屏蔽掉的话,则编译运行如下图所示:
【说明】:此时第一个按钮就消失了,这边产生这种现象的原因是由FlowLayout布局管理器本身特点来决定的,它是一种流式的布局管理器,第一行放控件,放不下的放在第二行,而如果我们自定义的布局屏蔽掉之后,则默认是使用Broader布局管理器,这个布局管理器是根据方位布局,而且控件本身位置不变,大小改变导致第一个按钮被第二个按钮遮挡在后面,而且都是填充整个容器。