一、GUI概述
GUI全称是Graphic User Interface,即图形用户界面。顾名思义,就是应用程序提供给用户操作的图形界面,包括窗口、菜单、按钮、工具栏和其他各种图形界面元素。几乎所有的程序设计语言都提供了GUI设计功能。Java中针对GUI设计提供了丰富的类库,这些类分别位于java.awt和javax.swing包中,简称为AWT和Swing。其中,AWT是SUN公司最早推出的一套API,它的组件种类有限,可以提供基本得GUI设计工具,却无法实现目前GUI设计所需的所有功能。随后,SUN公司对AWT进行改进,提供了Swing组件,Swing不仅实现了AWT中的所有功能,而且提供了更加丰富的组件和功能,足以满足GUI设计的一切需求。Swing会用到AWT中的许多知识,掌握了AWT,学习了Swing就变成了一件很容易的事情,因此本章将从AWT开始学习图形用户界面。
二、AWT概述
AWT是用于创建图形用户界面的一个工具包,它提供了一系列用于实现图形界面的组件,如窗口、按钮、文本框、对话框等。在JDK中针对每个组件都提供了对应的Java类,这些类都位于java.awt包中,接下来通过一个图例来描述这些类的继承关系,如下图所示。
从下图的继承关系可以看出,在AWT中组件分为两个大类,这两类的基类分别是Component和MenuComponent。其中,MenuComponent是所有与菜单相关组件的父类,Component则是除菜单外其他AWT组件的父类,它表示一个能以图形化方式显示出来,并可与用户交互的对象。
Component类通常被称为组件,根据Component的不同作用,可将其分为基本组件类和容器类。基本组件类是诸如按钮、文本框之类的图形界面元素,而容器类则是通过Component的子类Container实例化的对象。Container类表示容器,它是一种特殊的组件,可以用来容纳其他组件。Container容器又分为两种类型,分别是Window和Panel,接下来对这两种类型进行详细讲解。
1.Window
Window类是不依赖其他容器而独立存在的容器,它有两个子类,分别是Frame类Dialog类。Frame类用于创建一个具有标题栏的框架窗口,作为程序的主界面,如下图所示。
Dialog类用于创建一个对话框,实现与用户的信息交互,如下图所示。
2.Panel
Panel也是一个容器,但是它不能单独存在,只能存在其他容器(Window或其子类)中,一个Panel对象代表了一个长方形的区域,在这个区域中可以容纳其他组件,在程序中通常会使用Panel来实现一些特殊的布局。
了解了AWT组件的相关类后,为了使初学者对GUI有一个更直观的认识,接下来通过一个案例来创建一个简单的图形界面,如下例所示。
package _1AWT事件处理;
import java.awt.*;
public class Demo01 {
public static void main(String[] args) {
//建立新窗体对象
Frame f = new Frame("我的窗体");
//设置窗体的宽和高
f.setSize(400,300);
//设置窗体可见
f.setVisible(true);
//设置窗体在屏幕中所处的位置(参数是左上角坐标)
f.setLocation(300,200);
}
}
程序运行后会在桌面上弹出一个名为“我的窗体”的图形化窗口
三、AWT事件处理
1、事件处理机制
事件处理机制专门用于响应用户的操作,比如点击鼠标、按下键盘等操作,就需要使用AWT的事件处理机制。
事件对象(Event):封装了GUI组件上发生的特定事件。(通常就是用户的一次操作)
事件源(组件):事件发生的场所,通常就是产生事件的组件。
监听器(Listener):负责监听事件源上发生的事件,并对各种事件做出相应处理的对象(对象中包含时间处理器)。
事件处理器:监听器对象对接收的事件对象进行相应处理的方法。
import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
public class Demo01 {
public static void main(String[] args){
//创建窗体
Frame f = new Frame("我的电脑");
//设置窗体大小
f.setSize(500,300);
//设置窗体出现的位置
f.setLocation(300,300);
//设置窗体可见
f.setVisible(true);
//为窗体组件添加监听器
f.addWindowListener(new WindowListener(){
//对事件做出处理
public void windowClosing(WindowEvent e){
Window window = e.getWindow();
//释放窗口
window.dispose();
}
public void windowActivated(WindowEvent e){}
public void windowClosed(WindowEvent e){}
public void windowDeactivated(WindowEvent e){}
public void windowDeiconified(WindowEvent e){}
public void windowIconified(WindowEvent e){}
public void windowOpened(WindowEvent e){}
});
}
}
事件适配器
为了实现WindowListener接口,需要实现接口中定义的7个方法,然而只需要用到windowClosing()方法,其他6个方法都是空实现。针对这样的问题,JDK提供了一些适配类,他们是监听器接口的默认实现类,这些实现类中实现了接口的所有方法,但方法中没有任何代码。
public class Demo02 {
public static void main(String[] args) {
//创建窗体对象
Frame frame = new Frame("我的窗体");
//给窗体设置宽高
frame.setSize(400,300);
frame.setVisible(true);
frame.setLocation(300,200);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
Window window = e.getWindow();
window.dispose();
}
});
}
}
常用事件分类
在AWT中提供了丰富的事件,大致可以分为窗体事件(WindowEvent)、鼠标事件(MouseEvent)、键盘事件(KeyEvent)、动作事件(ActionEvent)等。
1、窗体事件
大部分GUI应用程序都需要使用Window窗体事件对象作为外层的容器,可以说窗体对象是所有GUI应用程序的基础,应用程序中通常都是讲其他组件直接或间接地置于窗体中。在应用程序中,当对窗体时间进行处理时,首先需要定义一个类实现WindowListener接口作为窗体监听器,然后通过addWindowListener()方法将窗体对象与监听器绑定。
public class Demo02 {
public static void main(String[] args) {
//创建窗体对象
Frame frame = new Frame("我的窗体");
//给窗体设置宽高
frame.setSize(400,300);
frame.setVisible(true);
frame.setLocation(300,200);
frame.addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {
System.out.println("WindowOpened-->窗口正在打开");
}
@Override
public void windowClosing(WindowEvent e) {
System.out.println("windowClosing-->窗体正在关闭事件");
Window window = e.getWindow();
window.dispose();
}
@Override
public void windowClosed(WindowEvent e) {
System.out.println("windowClosed-->窗体关闭事件");
}
@Override
public void windowIconified(WindowEvent e) {
System.out.println("WindowIconified-->窗体图标化事件");
}
@Override
public void windowDeiconified(WindowEvent e) {
System.out.println("WindowDeiconified-->窗体取消图标化事件");
}
@Override
public void windowActivated(WindowEvent e) {
System.out.println("windowActivated-->窗体激活事件");
}
@Override
public void windowDeactivated(WindowEvent e) {
System.out.println("windowDeactivated-->窗体停用事件");
}
});
}
}
鼠标事件
在图形用户界面中,用户会经常通过鼠标来进行选择、切换界面等操作,这些操作被定义为鼠标事件,其中包括鼠标按下、鼠标松开、鼠标单击等。JDK中提供了一个MouseEvent类用于表示鼠标事件,几乎所有的组件都可以产生鼠标事件,处理鼠标事件需要先实现MouseListener接口定义监听器,也可以通过继承适配器MouseAdapter类来实现,然后调用addMouseListener()方法将监听器绑定到事件源对象。
public class Demo02 {
public static void main(String[] args) {
//创建窗体对象
Frame frame = new Frame("我的窗体");
//给窗体设置宽高
frame.setSize(400,300);
frame.setVisible(true);
frame.setLocation(300,200);
frame.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("mouseClicked-->鼠标完成点击");
}
@Override
public void mousePressed(MouseEvent e){
System.out.println("mousePressed-->鼠标按下");
}
@Override
public void mouseReleased(MouseEvent e){
System.out.println("mouseReleased-->鼠标放开");
}
@Override
public void mouseEntered(MouseEvent e) {
System.out.println("mouseEntered-->鼠标进入区域");
}
@Override
public void mouseExited(MouseEvent e) {
System.out.println("mouseExited-->鼠标移出区域");
}
});
}
}
MouseEvent类中针对鼠标的按键都定义了对应的常量,可以通过MouseEvent对象的getButton()方法获取被操作按键的常量键值,从而判断时哪个按键的操作。另外,鼠标的点击次数也可以通过MouseEvent对象的getClickCount()方法获取到。
@Override
public void mouseClicked(MouseEvent e) {
if(e.getButton()==e.BUTTON1){
System.out.println("鼠标左键");
}
if(e.getButton()==e.BUTTON2){
System.out.println("鼠标滚轮键");
}
if(e.getButton()==e.BUTTON3){
System.out.println("鼠标右键");
}
int c = e.getClickCount();
System.out.println(c);
}
键盘事件
键盘操作也是最常用的用户交互方式,例如键盘按下、释放等,这些操作被定义为键盘事件,在JDK中定义了一个KeyEvent类表示键盘事件,处理KeyEvent事件的监听器对象需要实现KeyListener接口或继承KeyAdapter类。
public class Demo02 {
public static void main(String[] args) {
//创建窗体对象
Frame frame = new Frame("我的窗体");
//给窗体设置宽高
frame.setSize(400,300);
frame.setVisible(true);
frame.setLocation(300,200);
TextField tf = new TextField(30);
frame.add(tf);
frame.setVisible(true);
tf.addKeyListener(new KeyListener(){
public void keyPressed(KeyEvent e){
int keyCode = e.getKeyCode();
String s = KeyEvent.getKeyText(keyCode);
System.out.print("输入的内容为:"+s+",");
System.out.println("对应的keyCode为:"+keyCode);
}
public void keyReleased(KeyEvent e){
System.out.println("keyReleased-->键盘放开时");
System.out.println("-----------------------");
}
public void keyTyped(KeyEvent e){
System.out.println("keyTyped-->键入某个键时调用");
}
});
}
}