窗口环境与事件处理
图形用户界面(Graphics User Interface,GUI)是一种以图形化为基础的用户界面,用户在操作时自需要移动鼠标,单机另一个赋予功能的图形,即可执行对应的已设计好的程序。
在Java中,抽象窗口工具包(Abstract Window Toolkit,AWT)提供了窗口与绘图的基本工具。AWT是Java较早的技术,缺点是会浪费许多系统资源,SUN公司后来又推出了Swing类库以取代AWT类库。
在Swing类库中提供了比AWT更多的对象,也是Java窗口应用程序更新一代的架构。Swing的对象是基于AWT的Container类发展而来的。由于用AWT开发窗应用程序的普及率不低,即使SUN不再扩充AWT类库,我们仍需要了解。
AWT程序包
AWT在Java中提供了有关可视化功能的工具程序包。AWT程序包主要用于Applet窗口的用户图形界面或直接产生GUI窗口应用程序。
AWT程序包中拥有相当多的派生类,这些派生类根据功能的不同可以归纳为以下4种类型。
- 图形界面:这些类提供了各种管理、创建及设置图形见面的方法,如Button(按钮)、List(列表框)、Labek(标签)等。
- 版面布局:这些类提供了各种版面布局的相关方法,如BorderLayout(边框布局)、FlowLayout(流式布局)、GridLayout(网络布局)等。
- 图形绘制:这些类提供了各种图形的绘制方法,如Rectangle(矩形)、Polygon(多边形)等。
- 事件处理:这些类负责相关事件的触发以及事件处理工作,如MouseEvent(鼠标相关事件的处理)、InputEvent(输入相关事件的处理)等。
AWT(抽象窗口工具包)的用户界面控制(User Interface Control)多数派生自java.awt.Component类。java.awt.Container类派生自java.awt.Component类,所以它是一个组件,其主要功能是装进其他的组件。容器(Container)组件与其他组件最大的不同在于:一般组件必须加入容器后才能操作和显示,而使用这些窗口容器组件就可以让我们创建出基本的窗口样式。
窗口程序
窗口程序的编写与文本模式程序的编写有很大差异,除了程序代码明显增加外,在基本设计原理上也大不相同。对于Java的窗口应用程序而言,主要的构成元素为各种窗口组件,至于窗口本身则被视为一种转载这些组件的容器。
与基本窗口创建有关的语法:
import java.awt.* //导入AWT程序包
import java.awt.event.* //导入事件处理机制
public class 类名称 extends Frame { //以继承Frame类的方式创建窗口
}
AWT 中与窗口相关的基本方法 | 说明 |
---|---|
void setSize(int X, int Y) | 设置窗口规格的大小,X 与 Y坐标值的单位为像素 |
void setTitle(String 名称) | 设置此窗口的名称,会显示在窗口的上方 |
void setBackground(int 颜色代码或RGB值) | 设置此窗口的背景颜色,颜色代码为 Java 内部定义的基本颜色标识符,如 Color.CYAN 代表浅蓝 |
void setFont(int 字体名称, int 类型, int 大小) | 设置此窗口的字体、字体类型与大小,常用的类型值有三种:Font.PLAIN(平常字)、Font.BOLD(粗体字)、Font.ITALIC(斜体字) |
void setResizable(boolean 布尔值) | 设置此窗口是否可以重新调整大小,当布尔值为 false 时,窗口无法重新调整大小,此方法的默认值为 true |
void add(String 组件名称) | 在窗口中加入指定的组件 |
void remove(String 组件名称) | 在窗口中删除指定的组件 |
show() | 显示窗口 |
完成窗口创建的操作后,接着要将各个组件摆放到窗口中,这些组件主要包含三大类,分别是图形界面组件、版面布局组件与绘图组件。在Java窗口环境中,组件的操作必须依靠触发各种事件才会起作用。
Frame 类的构造函数 | 意义 |
---|---|
Frame() | 创建一个窗口 |
Frame(String 窗口标题) | 创建窗口并指定窗口的标题 |
void setIconImage(Image 图形) | 设置窗口左上角所显示的图标(Icon) |
Image getIconImage() | 将窗口左上角所显示的图标作为图像对象返回 |
void setTitle(String 字符串) | 设置窗口标题栏所显示的文字(字符串) |
String getTitle() | 返回一个字符串 |
void setState(int 状态) | 设置窗口的外观状态。NORMAL:正常,ICONIFIED:最小化 |
int getState() | 返回获取窗口的外观形态。NORMAL:正常,ICONIFIED:最小化 |
void setResizable(Boolean 是否可缩放) | 设置窗口是否可以调整大小 |
boolean isResizable() | 返回窗口是否可以调整大小,boolean 值 |
static Frame[ ] getFrames() | 获取此应用程序所打开的所有窗口,以窗口对象数组的方式返回 |
void setMaximizedBounds(Rectangle 范围) | 设置窗口可显示的最大范围 |
Rectangle getMaximizedBounds() | 返回窗口的最大范围 |
void setMenuBar(MenuBar 菜单栏) | 设置窗口的菜单栏 |
MenuBar getMenuBar() | 返回窗口的菜单栏对象(MenuBar) |
Fram类的继承关系:
Window 类的方法 | 说明 |
---|---|
void toBack() | 设置指定窗口在所有窗口的下面 |
void toFront() | 设置指定窗口在所有窗口的上面 |
void pack() | 调整窗口到最适合的大小· |
boolean isShowing() | 返回一个 boolean 值,表示窗口是否显示在屏幕上 |
Container 类的方法 | 说明 |
---|---|
void remove(Componet 组件名称) | 删除容器中指定的组件 |
void remove(int 组件编号) | 删除容器中指定的组件编号。编号是按照组件加入容器的顺序,第一个为0 |
void removeAll() | 删除容器中所有的组件 |
Component 类的方法 | 说明 |
---|---|
void setForeground(Color 颜色) | 设置组件的前景色 |
void setBackground(Color 颜色) | 设置组件的背景色 |
void setFont(Font 字体) | 设置组件显示的字体 |
void setSize(int 宽, int 高) | 设置组件显示的宽与高 |
void setLocation(int X, int Y) | 设置组件显示时的坐标 |
Pack方法
在Java中,Window组件提供了一个自动调整窗口大小的方法Pack()。Pack()方法主要用于当窗口内的组件需要根据显示的大小自动调整时。当窗口调用Pack()设置为自动调整大小与未设置时,呈现的窗口有所不同。
版面布局
常用的版面布局3种:
- 流式版面布局(FlowLayout)
- 边框版面布局(BorderLayout)
- 网络版面布局(GridLayout)
流式版面布局
对程序窗口中的多有组件做一定流向式的排列。当窗口设置为流式版面布局方式时,组件会按照加入窗口的顺序排列,当显示器区域的大小改变时,组件的布局方式会自动地按照从左到右、自上而下地方式将组件调整到适当地位置。
是默认的版面布局方式。当组件加入窗口容器时,假如未指定组件所要显示地位置或大小,Java会自动按照流式版面布局地方式将组件布置在窗口适当的位置。
使用流式版面布局方式必须通过FlowLayout类来建立,布局时可以调用窗口容器所提供的setLayout()方法来完成。
假设一个Frame类的对象名为frmMyFrame,要完成流式版面布局,设置的语法:
frmMyFrame.setLayout(new FlowLayout());
流式版面布局类的构造函数 | 说明 |
---|---|
FlowLayout() | 默认的构造函数 |
FlowLayout(int 组建排列方向) | 设置组件在窗口中排列的方向 |
FlowLayout(int 组建排列方向, int 组件横向间隔, int 组件纵向间隔) | 设置组件在窗口中排列的方向以及组件间横向与纵向的间隔 |
流式版面布局类的方法 | 说明 |
---|---|
void setAlignment(int 方向) | 设置组件排列的方向 |
int getAlignment() | 获取组件排列的方向 |
int getRows() | 获取版面布局纵向的网格数 |
int getVgap() | 获取版面布局纵向组件的间隔大小 |
void setHgap(int 横向组件间隔) | 设置横向组件间隔 |
void setVgap(int 纵向组件间隔) | 设置纵向组件间隔 |
边框版面布局
窗口版面会被分割为东、西、南、北、中 5部分,组件会按照指定的方向布置在窗口内。当窗口的中心位置用于信息的显示时,或者希望把组件布置在窗口的周边时使用。
选择边框版面布局方式必须通过BorderLayout类来建立,布局时可以调用窗口容器所提供的setLayout()方法来完成。
假设一个Frame类的对象名为frmMyFrame,要完成边框版面布局,设置的语法:
frmMyFrame.setLayout(new BorderLayout());
//当组件加入窗口容器时必须指定布局的位置,指定语法:
Add(new Button("北"), BorderLayout.NORTH);
BorderLayout 类的构造函数 | 说明 |
---|---|
BorderLayout() | 默认的构造函数 |
BorderLayout(int 组件横向间隔, int 组件纵向间隔) | 设置横向与纵向组件间隔的大小 |
BorderLayout 类的方法 | 说明 |
---|---|
int getRows() | 获取版面布局纵向的间隔大小 |
int getVgap() | 获取版面布局纵向组件的间隔大小 |
void setHgap(int 横向组件间隔) | 设置横向组件间隔 |
void setVgap(int 纵向组件间隔) | 设置纵向组件间隔 |
网络版面布局
网络版面布局(GridLayout)方式要求窗口版面均分,当窗口设置为这种版面布局方式时,窗口版面将根据所设置的长与宽的网格数把窗口等分为长乘以宽的数量。例如版面时长为3、宽为4,则版面布局后的结果窗口将呈现“3×4=12”等份。
采用网格面板布局方式必须通过GridLayout类来建立,布局时可以调用窗口容器所提供的setLayout()方法来完成。
假设一个Frame类的对象名为frmMyFrame,要完成网格版面布局,设置的语法:
frmMyFrame.setLayout(new GridLayout(宽, 高));
//当组件加入窗口容器时必须指定布局的位置,指定的语法:
add(new Button("Button")); //加入了一个按钮,并指定布局的位置在窗口的上方。
GridLayout 类的构造函数 | 说明 |
---|---|
GridLayout() | 默认的构造函数 |
GridLayout(int 宽, int 长) | 设置横向与纵向所要划分的网格数 |
GridLayout(int 宽, int 长, int 横向间距, int 纵向间距) | 设置横向和纵向所要划分的网格数,且设置横向和纵向组件之间的间隔大小 |
GridLayout 类的方法 | 说明 |
---|---|
void addLayoutComponent(String 组件名称, Component 组件) | 给指定的组件设置名称并加入版面布局中 |
int getColumns() | 获取版面布局横向的网格数 |
int getHgap() | 获取版面布局中横向组件的间隔大小 |
int getRows() | 获取版面布局纵向的网格数 |
int getVgap() | 获取版面布局中纵向组件的间隔大小 |
void layoutContainer(Container 容器) | 指定容器的版面布局方式为网格版面布局方式 |
void setColumns(int 横向方格数) | 设置横向网格数 |
void setRows(int 纵向方格数) | 设置纵向网格数 |
void setHgap(int 横向组件间隔) | 设置横向组件的间隔 |
void setVgap(int 纵向组件间隔) | 设置纵向组件的间隔 |
事件处理的实现
窗口模式和文本模式最大的不同在于用户与程序之间的操作模式。在文本模式下,用户必须按照程序规划的流程来操作;在窗口模式下,用户的操作则是通过事件的触发来与程序进行沟通。事件的定义:用户执行窗口程序时,对窗口组件所进行的操作。
在传统模式下,程序与用户是通过固定的流程来互动的,用户必须按照程序所规划的流程进行相应的操作,只有这样程序才能获取用户所输入的信息,再进行适当的处理;在窗口模式下,程序与用户互动的流程不再是固定的,当程序需要获得用户所输入的信息时,必须在特定组件上加入事件处理部分的程序代码,当用户通过操作界面和设备输入信息时,这时特定的事件将会被触发,随后调用事件处理程序来处理用户的需求。
在Java窗口模式 下,Java提供了许多事件监听器(EventListener)。事件的种类包含窗口事件(WindowsEvent)、鼠标事件(MouseEvent)及键盘事件(KeyEvent)等。事件监听器以接口的方式来定义,加入要加入某一种监听器接口,则必须实现该监听器接口。
事件类
事件类(Event Class)是Java事件处理机制的核心。事件类是分层派生而来的,是从EventObject类中派生出AWTEvent类,再从AWTEvent类派生出不同类的事件类,以用于不同的需求。事件类分成“高级事件类”和“低级事件类”。
高级事件类是从AWTEvent类派生的子类,而低级事件类是从ComponentEvent类派生的子类以及从InputEvent类派生的子类。
高级事件类 | 使用说明 |
---|---|
ActionEvent | 当单击按钮(Button)、菜单(Menu)、列表框(List)或者输入文字或数字的文本框(TextField)触发的事件类 |
HierarchyEvent | 当容器(Container)中的组件(Component)发生结构改变时触发的事件 |
AdjustmentEvent | 滚动窗口中的滚动条(Scroll Bar)时触发的事件 |
ComponentEvent | 当组件(Component)被移动、隐藏、重新设置大小或者显现时触发的事件 |
ItemEvent | 下拉式菜单(Choice)、列表框(List)或者复选框(Check Box)、可选择的菜单项(Checkable Menu Item)被选择或取消选择时触发的事件 |
InvocationEvent | 当调用具有可运行(Runnable)接口对象的 run() 方法时触发的事件 |
TextEvent | 改变文本字段(TextField)或文本框(TextArea)中的文字时触发的事件 |
TextSelectionEvent | 选择文本字段(TextField)或文本框(TextArea)中的文字时触发的事件 |
低级事件类 | 使用说明 |
---|---|
ContainerEvent | 在容器(Container)中添加组件或删除组件触发的事件 |
WindowEvent | 当执行打开(open)、关闭(close)、闲置、图标化(iconified,即缩小)、取消图标化(deiconified,即还原)、获得主控权(activated)和失去主控权(deactivated)等操作时触发的事件 |
InputEvent | 组件(Component)输入事件的父类,属于抽象类 |
FocusEvent | 组件(Component)获得主控权(activated)和失去主控权(deactivated)触发的事件 |
MouseEvent | 当鼠标被拖拽(draged)、单机(clicked)、移动(moved)和鼠标按钮被松开时触发的事件 |
MouseWheelEvent | 当滚动鼠标滚轮时触发的事件 |
KeyEvent | 从键盘(keyboard)输入时,按下按键和松开按键时触发的事件 |
EventObject类WTEvent是类的父类:
- EventObject类:所有事件类的基类(或父类),包含在java.util程序包中,EventObject类内含:
- getSource():将返回“源”事件。
- toString():返回事件字符串。
- AWTEvent类:所有AWT的基类(或父类),包含在java.util程序包中。其中的方法getID()是用来获取事件类型的。
事件来源与监听器接口
事件(Event)的触发一定会有来源,譬如单击“确定”按钮,单机的动作是事件产生的来源,因为改变了内部的状态,有可能是发出“OK”的消息。因此,事件来源(Evemt Source)是指“触发事件的对象是因其内部状态改变所致的”,事件来源可能产生于一个或多个对象。
既然有事件触发,相对应的就有事件的处理。事件监听器(Event Listener)提供了接收和处理事件的方法,是事件触发会通知的对象。事件监听器接口(Event Listener Interface)能够提供一个或多个方法来接收和处理事件。
事件来源 | 使用说明 |
---|---|
Button(按钮) | 单机按钮时,触发 action 事件 |
Checkbox(复选框) | 勾选或取消勾选时,触发 item 事件 |
Choice(选项) | Choice 被选取时,触发 item 事件 |
List(列表选项) | 双击列表中的选项时,触发 action 事件;当列表中的选项被选取或取消选取时,触发 item 事件 |
Menu Item(菜单项) | 菜单项被选取时,触发 action 事件。当可复选菜单项(Checkable Menu Item)被选取时,触发 item 事件 |
Scrollbar(滚动条) | 鼠标的滚轮滚动时,触发 text 事件 |
Text Component(文字组件) | 输入文字时,触发 item 事件 |
Window(窗口) | 当执行打开(open)、关闭(close)、闲置、图标化(iconified,即缩小)、取消图标化(deiconified,即还原)、获得主控权(activated)和失去主控权(deactivated)等操作时所触发的Window事件 |
事件监听器接口 | 使用说明 |
---|---|
ActionListener | 定义一个接收 action 事件的方法 |
AdjustmentListener | 定义一个接收 adjustment 事件的方法 |
ComponentListener | 4 个方法,用于辨别组件被移动、隐藏、重新调整大小或者显现 |
ComponentListener | 2 个方法,用于辨别容器中添加组件或删除组件 |
FocusListerner | 2 个方法,用于辨别组件获得主控权(activated)和失去主控权(deactivated) |
ItemListerner | 定义一个接收组件选项内部状态改变的 item 事件的方法 |
KeyListener | 3 个方法,用于辨别在键盘(keyboard)输入时,是按下按键还是放开按键 |
//记录事件来源的监听器
public void addTypeListener(TypeListener 事件对象)
//取消事件来源的监听器
public void removeTypeListener(TypeListener 事件对象)
低级事件类
ComponentEvent类
ComponentEvent 类的常数 | 说明 |
---|---|
COMPONENT_HIDDEN | 隐藏组件 |
COMPONENT_MOVED | 移动组件 |
COMPONENT_RESIZED | 重新调整组件的大小 |
COMPONENT_SHOWN | 显示组件 |
//ComponentEvent构造函数
ComponentEvent(Component ref, int type)
//返回触发事件的组件
Component getComponentEvent();
ComponentEvent 事件触发时,会调用 ComponentListener 来接收 ComponentEvent 事件。
WindowEvent类
WindowEvent类 的常数 | 说明 |
---|---|
WINDOW_ICONIFIED | 缩小窗口,即图标化窗口 |
WINDOW_DEICONIFIED | 将缩小的窗口还原,即取消图标化 |
WINDOW_OPENE | 打开窗口 |
WINDOW_CLOSING | 关闭窗口 |
WINDOW_ACTIVATED | 取得窗口主控权 |
WINDOW_DEACTIVATED | 失去窗口主控权 |
//WindowEvent 构造函数
WindowEvent(Object obj, int ID)
//获取 WindowEvent 事件窗口对象
Window getWindow()
//事件的字符串参数
String paramString()
WindowListener 类的方法 | 说明 |
---|---|
void windowActioned(WindowEvent 对象) | 被监听的窗口获得主控权 |
void windowDeactivated(WindowEvent 对象) | 被监听的窗口失去主控权 |
void windowClosed(WindowEvent 对象) | 被监听的窗口被关闭了 |
void windowClosing(WindowEvent 对象) | 被监听的窗口正在关闭 |
void windowDeiconified(WindowEvent 对象) | 被监听的窗口被缩小了,即图标化 |
void windowIconified(WindowEvent 对象) | 被监听的窗口被还原了,即取消图标化 |
void windowOPened(WindowEvent 对象) | 被监听的窗口获被打开了 |
//WindowListener的语法
public void addWindowListener(WindowListener 对象)
InputEvent类
- InputEvent事件的触发:InputEvent 事件类不仅仅是 ComponentEvent 事件类的子类,也是MouseEvent事件类与KeyEvent事件类的父类。
- 监听器部分:关于监听器的部分,调用 KeyListener、MouseListeter 和 MouseMotionListeter 来接收 KeyEvent 事件类或 MouseEvent 事件类。