图形用户界面(Graphical User Interface,简称 GUI,又称图形用户接口)
AWT是Abstract Window ToolKit (抽象窗口工具包)的缩写,这个工具包提供了一套与本地图形界面进行交互的接口。AWT中的图形函数与操作系统所提供的图形函数之间有着一一对应的关系,我们把它称为peers。 也就是说,当我们利用 AWT 来构件图形用户界面的时候,我们实际上是在利用操作系统所提供的图形库。由于不同操作系统的图形库所提供的功能是不一样的,在一个平台上存在的功能在另外一个平台上则可能不存在。为了实现Java语言所宣称的"一次编译,到处运行"的概念,AWT 不得不通过牺牲功能来实现其平台无关性,也就是说,AWT 所提供的图形功能是各种通用型操作系统所提供的图形功能的交集。由于AWT是依靠本地方法来实现其功能的,我们通常把AWT控件称为重量级控件。
Swing是在AWT的基础上构建的一套新的图形界面系统,它提供了AWT 所能够提供的所有功能,并且用纯粹的Java代码对AWT 的功能进行了大幅度的扩充。例如说并不是所有的操作系统都提供了对树形控件的支持, Swing 利用了AWT 中所提供的基本作图方法对树形控件进行模拟。由于 Swing 控件是用100%的Java代码来实现的,因此在一个平台上设计的树形控件可以在其他平台上使用。由于在Swing 中没有使用本地方法来实现图形功能,我们通常把Swing控件称为轻量级控件。
AWT和Swing之间的基本区别:AWT 是基于本地方法的C/C++程序,其运行速度比较快;Swing是基于AWT 的Java程序,其运行速度比较慢。对于一个嵌入式应用来说,目标平台的硬件资源往往非常有限,而应用程序的运行速度又是项目中至关重要的因素。在这种矛盾的情况下,简单而高效的AWT 当然成了嵌入式Java的第一选择。而在普通的基于PC或者是工作站的标准Java应用中,硬件资源对应用程序所造成的限制往往不是项目中的关键因素,所以在标准版的Java中则提倡使用Swing, 也就是通过牺牲速度来实现应用程序的功能。
AWT 是抽象窗口组件工具包,是 java 最早的用于编写图形节目应用程序的开发包。
Swing 是为了解决 AWT 存在的问题而新开发的包,它以 AWT 为基础的。
1、布局
(1)FlowLayout(流式布局管理器),从左到右的顺序排列;是Panel的默认布局管理器。
(2)BorderLayout(边界布局管理器),东南西北中,在边界上布局,默认是居中填充;是Frame的默认布局管理。
(3)GridLayout(网格布局管理器),跪着的矩阵。
(4)CardLayout(卡片布局管理器),即选项卡。
(5)GridBagLayout(网格包布局管理器),非规则的矩阵。
2、Frame
(1)new Frame(String title),建立窗口对象。
(2)setSize(int w,int h),设置窗口大小;setLocation(int x,int y),设置屏幕上显示的位置;setLayout(new 某种Layout类型),即传递一个布局管理器对象,控制Frame的布局。setBounds(int x,int y,int w,int h),设置窗口的大小和屏幕初始位置。
(3)add(组件对象),向窗口里添加组件。
(4)setVisible(boolean b),设置窗口可见性。
3、窗体事件
(1)addWindowListener(WindowListener wl),添加一个窗口监听器对象给窗口,用于监控窗口事件。
(2)WindowListener接口规定的方法:windowActivated(WindowEvente),将窗口看设置为活动窗口时调用;windowClosed(WindowEvent e)对窗口调用dispose而将其关闭时调用;windowClosing(WindowEvente)用户试图从窗口的系统菜单中关闭窗口时调用;windowDeactivated(windowEvent e)当窗口不再是活动窗口时调用;windowDeiconified(WindowEvent e)窗口从最小化状态变为正常状态时调用;windowIconified(WindowEvent e)窗口从正常状态变为最小化状态时调用;windowOpened(WindowEvent e)窗口首次变为可见时调用。
(3)WindowAdapter类是WindowListener接口的实现类,用于快速建立事件监听器,在实际使用中,只要建立一个继承WindowAdapter类并根据需要覆写了对应窗口事件的方法的类,然后在addWindowListener的参数里传递这个类的对象即可。
(4)除了WindowListener规定的方法,WindowAdapter还建立一些自己的方法,具体使用中可以查看API文档。
4、Action事件
(1)为Button(按钮)添加按钮事件监听器:but.addActionListener(ActionListener e);语句为but按钮添加一个监听器。
(2)ActionListener和WindowListener一样,也是一个接口,在建立作为参数的对象前,需要建立一个类继承它并覆写actionPerformed(ActionEvent e)方法。
5、鼠标事件
(1)为Button(按钮)添加鼠标事件监听器:but.addMouseListener(MouseListener e),同样MouseListener也是一个接口,它有一个实现子类MouseAdapter,具体使用时一般参数都是传递一个继承并覆写MouseAdapter的类对象
(2)MouseAdapter具有的方法:
a、mouseClicked(MouseEvent e),响应单击事件;
b、mouseEntered(MouseEvent e),鼠标进入到组件时调用;
c、mouseExited(MouseEvent e),鼠标离开组件时调用;
d、mousePressed(MouseEvent e),鼠标按键在组件上按下时调用;
e、mouseReleased(MouseEvent e),鼠标在组件上释放时调用;
f、mouseDragged(MouseEvent e),鼠标按键在组件上按下并拖动时调用;
g、mouseMoved(MouseEvent e),鼠标光标移动到组件上但无按键按下时调用;
h、mouseWheelMoved(MouseEvent e),鼠标滚轮旋转时调用;
(3)判断双击事件:MouseEvent类具有点击次数判断方法getClickCount(),所以只要判断e.getClickCount()==2,就可以了。以及左右键等等的数据判断方法都存在于MouseEvent类中。
6、键盘事件
(1)为Button(按钮)添加键盘事件监听器:but.addKeyListener(KeyListener e),同样KeyListener也是一个接口,它有一个实现子类KeyAdapter,具体使用时一般参数都是传递一个继承并覆写KeyAdapter的类对象。
(2)KeyAdapter具有的方法:
a、keyPressed(KeyEvent e),按下某个按键时调用此方法;
b、keyRelease(KeyEvent e),释放某个按键时调用次方法;
c、keyTyped(KeyEvent e),键入某个键时调用此方法;
(3)KeyEvent类的常用方法:
a、getKeyChar();返回与事件中的键相关联的字符;
b、getKeyCode();返回事件中的键关联的整数KeyCode;
c、static String getKeyText(int keycode),这是一个静态方法,返回描述 keyCode 的 String,如"HOME"、"F1" 或 "A"。一般使用为KeyEvent.getKeyCode(e.getKeyCode())。
7、其他窗口组件类
TextFiled 文本行;TextArea 文本区;Dialog 对话框;MenuBar 菜单条;Menu 目录项;MenuItem 子条目;FileDialog 文件选择对话框;
AWT事件处理基本概念
若使图形界面能够接收用户的操作,我们就必须给各个组件加上事件处理机制。在事件处理的过程中,主要涉及3类对象。
— Event(事件):用户对组件的一个操作,称之为一个事件,以类的形式出现,例如,键盘操作对应的事件类是KeyEvent。
— EventSource(事件源):事件发生的场所,通常就是各个组件,例如按钮Button。
— EventHandler(事件处理者):接收事件对象并对其进行处理的对象事件处理器,通常就是某个Java类中负责处理事件的成员方法。
例如,如果用户用鼠标单击了按钮对象button,则该按钮button就是事件源,而Java运行时系统会生成ActionEvent类的对象actionEvent,该对象中描述了单击事件发生时的一些信息。然后,事件处理者对象将接收由Java运行时系统传递过来的事件对象actionEvent,并进行相应的处理。事件处理模型如下图所示。
由于同一个事件源上可能发生多种事件,因此,Java采取了授权模型(Delegation Model),事件源可以把在其自身所有可能发生的事件分别授权给不同的事件处理者来处理。比如,在Canvas对象上既可能发生鼠标事件,也可能发生键盘事件,该Canvas对象就可以授权给事件处理者1来处理鼠标事件,同时授权给事件处理者2来处理键盘事件。有时也将事件处理者称为监听器,主要原因也在于监听器时刻监听着事件源上所有发生的事件类型,一旦该事件类型与自己所负责处理的事件类型一致,就马上进行处理。授权模型把事件的处理委托给外部的处理实体进行处理,实现了将事件源和监听器分开的机制。事件处理者(监听器)通常是一个类,该类如果能够处理某种类型的事件,就必须实现与该事件类型相对的接口。例如,一个ButtonHandler类之所以能够处理ActionEvent事件,原因在于它实现了与ActionEvent事件对应的接口 ActionListener。每个事件类都有一个与之相对应的接口。
事件分类:
按事件的性质分类
java.util.EventObject类是所有事件对象的基础父类,所有事件都是由它派生出来的。AWT的相关事件继承于java.awt.AWTEvent类,这些AWT事件分为两大类:低级事件和高级事件。
(1)低级事件
低级事件是指基于组件和容器的事件,当一个组件上发生事件,如鼠标的进入、点击、拖放等,或组件的窗口开关等时,触发了组件事件。
— ComponentEvent(组件事件:组件尺寸的变化、移动);
— ContainerEvent(容器事件:组件增加、移动);
— WindowEvent(窗口事件:关闭窗口、窗口闭合、图标化);
— FocusEvent(焦点事件:焦点的获得和丢失);
— KeyEvent(键盘事件:键按下、释放);
— MouseEvent(鼠标事件:鼠标单击、移动)。
(2)高级事件(语义事件)
高级事件是基于语义的事件,它可以不和特定的动作相关联,而依赖于触发此事件的类。比如,在TextField中按Enter键会触发ActionEvent事件,滑动滚动条会触发 AdjustmentEvent事件,选中项目列表的某一条就会触发ItemEvent事件。
— ActionEvent(动作事件:按钮按下,TextField中按Enter键);
— AdjustmentEvent(调节事件:在滚动条上移动滑块以调节数值);
— ItemEvent(项目事件:选择项目,不选择“项目改变”);
— TextEvent(文本事件:文本对象改变)。
用内部类示例常用监听事件:
f.addWindowListener(new WindowAdapter()
//只要java.awt.event包中的一个接口有3个及以上方法都有自己的适配器
{
Public voidwindowClosing(WindowEvent e)
{
System.exit(0);程序退出
}
}
);
//小例子:简单的记事本儿程序。实现打开,保存功能
package GUI;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
publicclass GuiTest1 {
private Framef;
private MenuBarbar;
private TextAreata;
private MenufileMenu;
private MenuItemopenItem,saveItem,closeItem;
private FileDialogopenDia,saveDia;
private Filefile;
//构造一个方法初始窗体用
GuiTest1()
{
init();
}
//初始化窗体方法
publicvoid init()
{
//创建一个窗体
f =new Frame("我的第一个窗体");
//给窗体设置位置及宽高
f.setBounds(300, 100, 650, 600);
//创建一个工具栏
bar =new MenuBar();
//创建一个文本域
ta =new TextArea();
//工具栏上创建父节点
fileMenu =new Menu("文件");
//创建文件下面子节点
openItem =new MenuItem("打开");
saveItem =new MenuItem("保存");
closeItem =new MenuItem("退出");
//把子节点加到文件父节点上
fileMenu.add(openItem);
fileMenu.add(saveItem);
fileMenu.add(closeItem);
bar.add(fileMenu);
//再把工具栏加到窗体上
f.setMenuBar(bar);
//创建打开和保存的对话框
openDia =new FileDialog(f,"打开", FileDialog.LOAD);
saveDia =new FileDialog(f,"保存", FileDialog.SAVE);
//把文件域添加到窗体上
f.add(ta);
//调用事件方法
MyEvent();
//把框架显示
f.setVisible(true);
}
//利用内部类处理 事件监听和处理方法
publicvoid MyEvent()
{
//打开按钮并写入到文本截域
openItem.addActionListener(new ActionListener() {
publicvoid actionPerformed(ActionEvent e) {
//打开对话框显示
openDia.setVisible(true);
//获取目录名
String dirPath = openDia.getDirectory();
//获取文件名
String fileName = openDia.getFile();
if(dirPath ==null || fileName ==null)
return;
//清空动作
ta.setText("");
//创建效率写入流
file = new File(dirPath,fileName);
try
{
BufferedReader bufr =new BufferedReader(new FileReader(file));
String line = null;
while((line = bufr.readLine())!=null)
{
ta.append(line+"\r\n");
}
bufr.close();
}
catch (IOException ex)
{
thrownew RuntimeException("读取失败");
}
}
});
//保存按钮修改并保存
saveItem.addActionListener(new ActionListener() {
publicvoid actionPerformed(ActionEvent e) {
//判断文件数据是否存在,不存在的话,打开保存框
if(file==null)
{
saveDia.setVisible(true);
String dirPath= saveDia.getDirectory();
String fileName = saveDia.getFile();
if(dirPath==null || fileName==null)
return ;
file = new File(dirPath,fileName);
}
try
{
BufferedWriter bufw =new BufferedWriter(new FileWriter(file));
String text = ta.getText();
bufw.write(text);
bufw.flush();
bufw.close();
}
catch (IOException ex)
{
thrownew RuntimeException();
}
}
});
//退出按钮关闭程序
closeItem.addActionListener(new ActionListener() {
publicvoid actionPerformed(ActionEvent e) {
//程序退出
System.exit(0);
}
});
//窗口关闭按钮关闭程序
f.addWindowListener(new WindowAdapter(){
publicvoid windowClosing(WindowEvent e)
{
//程序退出
System.exit(0);
}
});
}
publicstaticvoid main(String[] args) {
//创建加载
new GuiTest1();
}
}
拓展:
如何制作可以双击执行的jar包呢?
1,将多个类封装到了一个包(package)中。
javac –d 盘符:\目录名 需编译的java文件.java
2,定义一个jar包的配置信息。
定义一个文件a.txt 。文件内容内容为:
Main-Class:(空格)包名.类名(回车)
3,打jar包。
jar -cvfm my.jar a.txt 包名
4,通过winrar程序进行验证,查看该jar的配置文件中是否有自定义的配置信息。
5,通过工具--文件夹选项--文件类型--jar类型文件,通过高级,定义该jar类型文件的打开动作的关联程序。
jdk\bin\javaw.exe -jar
6,双击试试!哦了。