第8讲GUI/图形用户界面
8.1AWT的基础知识
GUI的全称是Graphical User Interface,即图形用户界面。
JDK中提供AWT和Swing两个包,用于GUI程序的设计和开发。Swing是改进版,功能全
GUI组件可以分为两个大类:基本组件和容器,分别是java.awt.Component和java.awt.Container的直接或间接子类。
程序的GUI部分由AWT线程管理
编程举例,打开一个窗口5秒钟后自动关闭,并查看AWT线程状态。
import java.awt.*;
public class TestFrame {
public static void main(String[] args) {
// TODO: 在这添加你的代码
Frame f = new Frame("www.it315.org");
f.add(new Button("ok"));
f.setSize(300,300);
f.setVisible(true);
//f.addWindowListener(new MyWindowListener())
try
{
Thread.sleep(5000);
}
catch(Exception e){}
//f.setVisible(true);隐藏而非结束窗口;
f.dispose();//从内存中清除窗口;
}
}
8.2AWT事件处理机制
三个重要概念:
事件:用户对组件的一个操作
事件源:发生事件的组件就是事件源
事件处理器:某个java类中的负责处理事件的成员方法
事件源、事件、事件处理器之间的工作关系:
1、事件处理器(必须是属于java某个类的成员方法)必须先关联到事件源上(即是注册)
2、组件(事件源) 用于接收外部作用,并产生事件对象,把事件对象传入事件处理器
事件分类
按产生事件的物理操作和GUI组件的表现效果进行分类:
MouseEvent
WindowEvent
ActionEvent
按事件的性质分类:
低级事件
语义事件(高级事件)对应的事件监听器中只有一个成员处理方法
8.3事件监听器
1、一个事件监听器对象负责处理一类事件
2、一类事件的每一种发生情况,分别由事件监听器对象中的一个方法来具体处理。
3、在事件源和事件监听器对象中进行约定的接口类,被称为事件监听器接口。
4、事件监听器接口类的名称与事件类的名称是相对应的,例如,MouseEvent事件类的监听器接口名为MouseListener。
编程举例:实现关闭窗口的事件处理,讲解用不同层次的事件类型来表示同一个事件源对象
新建类MyWindowListener,实现事件类型接口,处理代码如下:
public void windowClosing(WindowEvent parm1) {
parm1.getWindow().setVisible(false);
//parm1.getSource();//产生发生这种事件的来源;返回object类型
//parm1.getComponent();//产生发生事件的组件,返回java.awt.Component类型;
((Window)parm1.getComponent()).dispose();
System.exit(0);
//getEngine方法的返回类型只能是发动机Engine,没法是具体的东风发动机,东风汽车继承getEngine方法获得东风上面的发动机;
//要想直接使用东风牌发动机还得进行强制转换;
最后将该类注册到启动运行类TestFrame中:addWindowListener(new MyWindowListener());
总结:处理发生在某个GUI组件上的XxxEvent事件的某种情况,其事件处理的通用编写流程:
编写一个实现了XxxListener接口的事件监听器类;
XxxListener类中的用于处理该事件情况的方法中,编写处理代码;
调用组件中addXxxListener方法,将XxxListener创建的实例对象注册到GUI组件上。
8.4事件适配器
1、JDK中也提供了大多数事件监听器接口的最简单的实现类,称之为事件适配器(Adapter)类。
2、用事件适配器来处理事件,可以简化事件监听器编写。
编程实例:使用事件适配器类来关闭窗口。
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class YourWindowListener extends WindowAdapter {
public void windowClosing(WindowEvent e)//覆盖WindowAdapter中的方法;
{
System.out.print("haha");
e.getWindow().dispose();
System.exit(0);
}
然后注册到启动运行类TestFrame中:addWindowListener(new YourWindowListener());
总结:初学者使用事件适配器时的常见问题,解决问题的思路:
是方法没被调用,还是方法中的程序代码的执行问题?
是方法名写错了,还是没有注册事件监听器?
3、事件适配器类的不足之处:
遇到需要设计事件类和监听器类方法的时候就没有必要提供适配器类了;
8.5灵活设计事件监听器类——复杂监听器类设计
如果要在事件监听器类中访问非事件源的其他GUI组件,程序该如何编写?
import java.awt.*;
import java.awt.event.*;
import java.util.EventListener;
public class TestFrame implements ActionListener {
Frame f = new Frame("www.it315.org");
public static void main(String[] args) {
TestFrame tf = new TestFrame();
/*
*Button btn = new Button("quit");
btn.addActionListener(new TestFrame());
tf.f.add(btn);
tf.f.setSize(300,300);
tf.f.setVisible(true);
*程序的规范性太差,改为如下init中的代码
*/
tf.init();
}
public void init()
{
Button btn = new Button("quit");
btn.addActionListener(new TestFrame());
f.add(btn);
f.setSize(300,300);
f.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
f.setVisible(false);
f.dispose();
System.exit(0);
}
}
8.6用匿名内置类实现事件监听器
import java.awt.*;
import java.awt.event.*;
import java.util.EventListener;
class TestFrame implements ActionListener {
Frame f = new Frame("www.it315.org");
public static void main(String[] args) {
new TestFrame().init();
}
public void init()
{
Button btn = new Button("quit");
btn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
f.setVisible(false);
f.dispose();
System.exit(0);
}
});
f.add(btn);
f.setSize(300,300);
f.setVisible(true);
}
}