事件處理機制專門用于響應使用者的操作,比如,想要響應使用者的單擊滑鼠、按下鍵盤等操作,就需要使用AWT的事件處理機制
事件對象(Event):封裝了GUI元件上發生的特定事件(通常就是使用者的一次操作)。
事件源(元件):事件發生的場所,通常就是産生事件的元件。
監聽器(Listener):負責監聽事件源上發生的事件,并對各種事件做出相應處理的對象(對象中包含事件處理器)。
事件處理器:監聽器對象對接收的事件對象進行相應處理的方法。
事件對象、事件源、監聽器、事件處理器在整個事件處理機制中都起着非常重要的作用,它們彼此之間有着非常緊密的聯系。接下來用一個圖例來描述事件處理的工作流程,如圖所示。
在程式中,如果想實作事件的監聽機制,首先需要定義一個實作了事件監聽器接口的類,例如Window類型的視窗需要實作WindowListener。接着通過addWindowListener()方法為事件源注冊事件監聽器對象,當事件源上發生事件時,便會觸發事件監聽器對象,由事件監聽器調用相應的方法來處理相應的事件。
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class AnonyEvent {
public static void main(String[] args) {
Frame frame=new Frame("我的視窗");
frame.setVisible(true);
frame.setSize(300,300);
frame.setLocation(300,300);
Button btn=new Button("EXIT");
frame.add(btn);
btn.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
System.exit(0);
}
});
}
}
MyWindowListener類實作WindowListener接口後,需要實作接口中定義的7個方法,然而在程式中需要用到的隻有windowClosing()一個方法,其他六個方法都是空實作,沒有發揮任何作用,這樣代碼的編寫明顯是一種多餘但又必
需的工作。針對這樣的問題,JDK提供了一些擴充卡類,它們是監聽器接口的預設實作類,這些實作類中實作了接口的所有方法,但方法中沒有任何代碼,程式可以通過繼承擴充卡類來達到實作監聽器接口的目的。
import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
public class WinEventEx {
public static void main(String[] args) {
Frame frame=new Frame("我的視窗");
frame.setSize(300,300);
frame.setVisible(true);
MyWindowListener listener=new MyWindowListener();
frame.addWindowListener(listener);
}
}
class MyWindowListener implements WindowListener {
@Override
public void windowClosing(WindowEvent e) {
Window window=e.getWindow();
window.setVisible(false);
window.dispose();
}
@Override
public void windowActivated(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowClosed(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowOpened(WindowEvent e) {
}
}
可以通過繼承擴充卡類對事件源對象實作了監聽,但在實際開發中,為了代碼的簡潔,經常通過匿名内部類來建立事件的監聽器對象,針對所發生的事件進行處理。
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class WinEventEx2 {
public static void main(String[] args) {
Frame frame=new Frame("我的窗體");
frame.setSize(300,300);
frame.setLocation(300,300);
frame.setVisible(true);
frame.addWindowListener(new MyWindowListener2());
}
}
class MyWindowListener2 extends WindowAdapter {
@Override
public void windowClosing(WindowEvent e) {
Window window=(Window) e.getComponent();
window.setVisible(false);
window.dispose();
}
}
大部分GUI應用程式都需要使用Window窗體對象作為最外層的容器,可以說窗體對象是所有GUI應用程式的基礎,應用程式中通常都是将其他元件直接或者間接地置于窗體中。
當對窗體進行操作時,比如窗體的打開、關閉、激活、停用等,這些動作都屬于窗體事件,JDK中提供了一個類WindowEvent用于表示這些窗體事件。在應用程式中,當對窗體事件進行處理時,首先需要定義一個實作了WindowListener接口的類作為窗體監聽器,然後通過addWindowListener()方法将窗體對象與窗體監聽器綁定。
import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
public class WinEvent {
public static void main(String[] args) {
Frame frame=new Frame("我的視窗");
frame.setSize(300,300);
frame.setLocation(300,300);
frame.setVisible(true);
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)e.getComponent()).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()方法将監聽器綁定到事件源對象。
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.sql.SQLOutput;
public class MouseEvent {
public static void main(String[] args) {
final Frame frame=new Frame("window event");
frame.setLayout(new FlowLayout());
frame.setSize(300,300);
frame.setLocation(300,300);
frame.setVisible(true);
Button btn=new Button("button");
frame.add(btn);
btn.addMouseListener(
new MouseAdapter() {
@Override
public void mouseReleased(java.awt.event.MouseEvent e) {
System.out.println("mouseReleased 滑鼠放開事件");
}
@Override
public void mousePressed(java.awt.event.MouseEvent e) {
System.out.println("mousePressed 滑鼠按下事件");
}
@Override
public void mouseExited(java.awt.event.MouseEvent e) {
System.out.println("mouseExited 滑鼠移出按鈕區域事件");
}
@Override
public void mouseEntered(java.awt.event.MouseEvent e) {
System.out.println("mouseEntered 滑鼠進入按鈕區事件");
}
@Override
public void mouseClicked(java.awt.event.MouseEvent e) {
System.out.println("mouseClicked 滑鼠單擊事件完成");
if(e.getButton()==e.BUTTON1){
System.out.println("滑鼠左擊事件");
}
if(e.getButton()==e.BUTTON2){
System.out.println("滑鼠中鍵單擊事件");
}
if(e.getButton()==e.BUTTON3){
System.out.println("滑鼠右擊事件");
}
}
}
);
}
}
滑鼠的操作分為左鍵單擊輕按兩下和右鍵單擊輕按兩下,而且還有滾輪。上面隻給出這些事件的處理,能滿足實際需求嗎?答案是肯定的,MouseEvent類中定義了很多常量來辨別滑鼠動作。如下面的代碼所示:
從上面的代碼可以看出,MouseEvent類中針對滑鼠的按鍵都定義了對應的常量,可以通過MouseEvent對象的getButton()方法擷取被操作按鍵的常量鍵值,進而判斷是哪個按鍵的操作。另外,滑鼠的單擊次數也可以通過MouseEvent對象的getClickCount()方法擷取到。是以,在滑鼠事件中,可以根據不同的操作,做出相應的處理。
鍵盤操作也是最常用的使用者互動方式,例如鍵盤按下、釋放等,這些操作被定義為鍵盤事件。JDK中提供了一個KeyEvent類表示鍵盤事件,處理KeyEvent事件的監聽器對象需要實作KeyListener接口或者繼承KeyAdapter類。
import java.awt.*;
import java.awt.event.KeyAdapter;
public class KeyEvent {
public static void main(String[] args) {
Frame frame=new Frame("key event");
frame.setLayout(new FlowLayout());
frame.setSize(300,300);
frame.setLocation(300,300);
TextField tf=new TextField(30);
frame.add(tf);
frame.setVisible(true);
tf.addKeyListener(
new KeyAdapter() {
@Override
public void keyPressed(java.awt.event.KeyEvent e) {
int keyCode=e.getKeyCode();
String s=java.awt.event.KeyEvent.getKeyText(keyCode);
System.out.print("輸入的内容為:"+s+",");
System.out.println("對應的keycode為:"+keyCode);
}
}
);
}
}
動作事件與前面三種事件有所不同,它不代表某個具體的動作,隻是表示一個動作發生了。例如,在關閉一個檔案時,可以通過鍵盤關閉,也可以通過滑鼠關閉。在這裡讀者不需要關心使用哪種方式對檔案進行關閉,隻要是對關閉按鈕進行操作,即觸發了動作事件。
在Java中,動作事件用ActionEvent類表示,處理ActionEvent事件的監聽器對象需要實作ActionListener接口。監聽器對象在監聽動作時,不會像滑鼠事件一樣處理滑鼠的移動和單擊的細節,而是去處理類似于“按鈕按下”這樣“有意義”的事件。
通過動作事件實作的情況。如圖所示。