第6章图形用户界面
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第6章图形用户界面
第6章图形用户界面
本章内容是JA V A API中与GUI(图形用户界面设计)有关的2组类:AWT和SWING,编写Windows风格的程序。
本章涉及AWT和SWING许多的类,及其属性、方法,这不是学习的重点,只需对其有大致的了解,需要的时候查阅JDK DOC即可。
本章学习的重点是:
●掌握GUI编程的一般步骤,主要包括GUI界面的构造顺序和
事件处理;
●结合样例程序强化以前学过的类的继承、组成的概念及实际
使用;
●最后,学习编写符合MVC模式要求的GUI程序。
6.1 AWT组件及其属性类
本小节的要点是:
(1)基本概念【这些概念教材都给出了答案】
什么是AWT?
什么是组件?
什么是容器?
(2)组件类和容器类的继承关系
见P143【图6.1】,这个图很重要,要反复看。
在GUI界面设计中,要反复用到面向对象的两种最常见的类之间的关系:继承关系和组成(组合)关系,该图说明了常用组件类的继承关系(所有组件类的继承关系可以查阅JDK DOC或上网搜索)。
阅读教材“6.1.1AWT组件”。
阅读教材P145【例6.1】,从本例中学习到:
使用AWT创建一个GUI程序一般需要以下几步:
1)首先继承Frame类,创建一个窗体(窗体相当于Windows的
窗口)。
2)窗体是一个容器,如果将要设计的GUI界面比较复杂,可以
再窗体创建几个容器(比如Panel类)的对象,将窗体分割成几个部分。
3)向窗体添加菜单、文本框、按钮、树等等组件,这些组件是
窗体的“组成部分”,是类的组成关系的使用。
这些初始化窗体及组件的工作,一般是在构造方法中完成的。
4)在main()或其它方法中实例化窗体。
5)大致上,经过以上几步后,一个GUI程序界面就构造好了。
6)需要注意的是:本例是需要一行行输入源代码的,这比较麻
烦。
如果使用MyEclipse或NetBeans等开发环境,提供GUI 组件的“所见即所得”拖放操作,有为GUI界面自动写代码的功能,已经掌握了GUI设计原理的专业程序员当然可以依赖这些自动化的工具,但同学们不要这样做,还是要一行行的看代码、输入代码。
7)经过上述步骤后,一个GUI界面就完成了,但这个界面是“死”
的,还需要添加事件处理,以响应用户的鼠标或键盘等输入,事件处理是本章下一小节涉及的内容。
阅读教材“6.1.2布局管理”,本小节讲述了AWT组件几种常见的布局,合理的布局会使组件的安排有条理,并能自动适应窗口大小和位置的变化。
本小节内容一般性了解即可。
阅读教材“6.1.3颜色和字体”,本小节内容一般性了解即可。
6.2 事件处理
1 什么是事件?
与一般的控制台程序不同,GUI程序是事件驱动的。
当一个GUI 程序完成了初始化工作,创建成功后,就开始“等待”----等待键盘鼠标等操作,然后做出相应的反应。
一个GUI窗体有很多组件,这些组件都可以响应键盘鼠标的操作,当操作发生时(比如鼠标点击了一个按钮组件,或文本框组件输入了文字,或点击了窗口的关闭图标),就发生了一个“事件”。
事件,就是由于外界操作而引发的(某个或某些)组件的状态的改变,外界操作常见的是鼠标键盘,但不仅限于鼠标键盘。
当事件发生时,往往需要程序员写一段程序去响应事件,这种程序叫“事件处
理程序”,它一般首先判断哪个组件发生了事件,发生了何种事件,然后按程序设计的要求做出合适的反应。
2 事件处理程序
本章6.1讲解了GUI界面构造的要点,这一部分将介绍编写事件处理程序的要点。
两部分合起来就是一个相对完整的GUI程序。
事件处理程序的编写有一些特殊的地方,首先看一个简单的事件处理程序。
示例1:该程序的界面如下, 其功能是:(1)点击“清除”按钮,清除文本框中的数据,(2)点击窗口“关闭”按钮关闭窗口。
下面是源程序,重点关注紫色字的部分:
import java.awt.*;
import java.awt.event.*; //导入事件处理包
public class QueryFrame extends Frame implements ActionListener //QueryFrame窗口响应单击事件
{
private TextField text; //文本行
private Button button; //按钮
public QueryFrame() //构造方法
{super("清除文本框"); //窗口标题
setBounds(300,240,300,100); //窗口位置和尺寸
setBackground(Color.lightGray); //窗口背景色
setLayout(new FlowLayout(FlowLayout.LEFT));
text = new TextField(10); //实例化文本框
add(text); //添加文本框到窗体
button = new Button("清除"); //实例化按钮
add(button); //添加按钮到窗体
button.addActionListener(this);
//为按钮注册单击事件监听器
addWindowListener(new WinClose());
//注册窗口事件监听器,委托WinClose类的对象处理事件
setVisible(true); //显示窗体
}
public void actionPerformed (ActionEvent e)
//单击事件处理方法,实现ActionListener接口
{if (e.getSource()==button)
//获得当前事件源
text.setText("");//清除文本框
}
public static void main(String arg[])
{ new QueryFrame(); }
}
class WinClose extends WindowAdapter { public void windowClosing(WindowEvent e) //单击窗口关闭按钮时触发并执行{System.exit(0); //程序结束}
}
本程序的设计意图是响应两种事件:
A.按钮组件button可以响应鼠标单击事件,事件发生后清除文本框。
B.窗体组件QueryFrame响应窗体关闭事件,事件发生后关闭窗口退出程序。
这两种事件都采用了JA V A的“委托事件处理模型”,所谓委托,是指发生事件的组件(本程序发生事件的组件是按钮和窗体)自已不去处理事件,而是委托给别的对象处理。
本例中按钮单击事件委托给本类的事件处理方法actionPerformed()处理,而窗体事件则委托
给另一个类WinClose处理。
下面分别讨论其操作步骤:
A.按钮组件button可以响应鼠标单击事件,事件发生后清除文本框。
操作步骤是:
●声明QueryFrame类实现ActionListener接口,该接口
专门用于响应组件的单击事件,包括按钮组件或其它组件。
●button.addActionListener(this)为按钮注册单击事
件监听器,JAVA运行时环境将“后台监听”单击事件的发生。
形参this表示该事件将交给本类的单事件处理方法处理。
●实现ActionListener接口的抽象方法
ActionPerformed(ActionEvent e),该方法也叫“(单击)事件处理方法,实现该方法是程序员要完成的最主要的工作。
●当按钮单击事件发生后,后台运行的JAVA“单击事件监视器”
(该监视器对程序员不可见)捕获到了该单击事件,自动调用方法ActionPerformed(ActionEvent e),形参e的类型是ActionEvent,这是JAVA预定义的一个单击事件类,“单击事件监视器”将自动创建一个该类的对象e作为实参传给该方法。
在单击事件处理方法ActionPerformed(ActionEvent e)体内,程序员一般首先要写一行
if (e.getSource()==button)
获得事件源,即那个组件发生了单击事件(可能有多个事件注册了单击事件),然后根据程序的设计要求作相应处理。
上面讲解了使用事件处理方法处理按钮组件单击事件的一般步骤,这些步骤实际上是通用的,也就是说,任何一个组件(按钮、文本框…)要使用事件处理方法响应任何事件(鼠标单击、双击、移动,键盘按键…),一般都要进行以下步骤:
1)在类的声明中implements要响应的事件接口,JAVA API 有很多事件接口,每种接口对应一种事件,常见的有:ActionListener 单击事件接口
MouseListener鼠标事件接口
KeyListener键盘事件接口
WindowListener窗口事件接口
2)为组件注册事件,JAVA运行时环境将“后台监听”注册事件的发生。
注册是通过调用组件的add***listener()方法完成的,比如示例1中的:
button.addActionListener(this);
对于Component组件及其子类组件,常见的事件监听器有:
addActionListener()注册单击事件
addMouseListener()注册鼠标事件
addKeyListener()注册键盘事件
对于Window组件及其子类组件,常见的事件监听器有:
addWindowListener();
3)编写事件处理方法,这是程序员最主要的工作,实际上是实
现第1)步所述的事件接口的抽象方法。
比如对于“示例1”的ActionListener接口,其抽象方法只有一个:
public void actionPerformed (ActionEvent e)
其它常用的事件接口的抽象方法是:
MouseListener鼠标事件接口
mouseDragged(MouseEvent e)
mouseMoved(MouseEvent e)
KeyListener键盘事件接口
keyPressed(KeyEvent e)
keyReleased(KeyEvent e)
keyTyped(KeyEvent e)
WindowListener窗口事件接口一共有9个抽象方法
按JAVA语法要求,一旦类声明implement了某个接口,就要实现该接口的所有抽象方法。
4)事件处理方法一旦写好,是不需要程序员调用的,而是由“后台运行”的事件监听器在事件发生后自动调用。
事件监听器对程序员是不可见的。
如果需要的话,程序员也可以自行调用事件处理方法。
B.窗体组件QueryFrame响应窗体关闭事件,事件发生后退出程序。
其关键的代码是:
addWindowListener(new WinClose());
注意在窗体事件注册时,方法的参数不是this(this表示本类的事件处理方法),而是new WinClose(),说明窗体事件被委托给另一个类WinClose去处理,在该类中实现事件接口的抽象方法。
按JAVA语法要求,一旦类声明implement了某个接口,就要实现该接口的所有抽象方法。
WindowListener窗口事件接口有9个抽象方法,一一实现太麻烦,所以JAVA为WindowListener设计了一个适配器类WindowAdapter,只
要继承了这个类,只需写程序员需要实现的抽象方法即可,其它
抽象方法由WindowAdapter自动实现,如下所示,程序员只
需实现windowClosing():
class WinClose extends WindowAdapter
{ public void windowClosing(WindowEvent e) {System.exit(0);} }
从上述A和B两部分的讨论可知,将事件委托给本类的事件处理
方法处理和委托给其它类的事件处理方法处理,其步骤基本雷
同,主要差别在于事件注册调用
add***Listener(参数)
方法时,前者用了this作实参,意指“本类对象的事件处理方
法”,而后者new了一个其它类的对象。
阅读教材“6.2.1委托事件模型”和【例6.2】,它们以单击事件
和窗口事件为例,说明了JA V A GUI事件处理的原理和编程步骤。
阅读教材“6.2.2 AWT事件类和事件监听器接口”,这一小节可以
作为AWT事件编程的参考资料使用。
1 AWT事件类
图6.8列出了AWT常见的事件类,这些类可以作为事件处理
方法的参数。
2 AWT事件监听器接口
表6-1列出了常见的AWT事件监听器接口及接口的抽象方法,这些抽象方法实现后就是事件处理方法。
3 事件适配器类
说明了窗口事件适配器类的使用。
4 AWT组件中注册事件监听器的方法
说明了AWT组件类(及其子类!参考P143图6.1)注册事件
监听器的方法。
思考题:
根据6.2小节提供的编程样例及资料,写一个小程序:窗口内有一个文本框和按钮,当鼠标进入按钮区域后,文本框显示“HELLO”,当鼠标离开按钮区域后,文本框为空。