Java 事件模型基礎:監聽器、事件、事件源、事件注冊


 

事件模型相關概念

  事件:描述發生了什么的對象

  存在各種不同類型的事件類用來描述各種類型的用戶交互。

  事件源:事件的產生器。

  事件處理器:接收事件、解釋事件並處理用戶交互的方法

 

  比如在Button組件上點擊鼠標會產生以這個Button為源的一個ActionEvent,這個ActionEvent實例是一個對象,它包含關於剛才發生的那個事件的信息,這些信息包括:

  getActionCommand():返回與動作相關聯的命令名稱。

  getWhen():返回事件發生的時間。

  如果用戶在用戶界面層執行了一個動作(鼠標點擊和按鍵),這將導致一個事件的發生。

 

AWT事件模型

  JDK1.0的事件模型:層次模型。(已廢棄)

  JDK1.1或更高的事件模型:委托模型

  事件監聽器:實現了監聽器接口的類。一個監聽器對象是一個實現了專門的監聽器接口的類的實例。

  下面是一個簡單的代碼例子,說明按鈕事件的監聽處理。

按鈕事件監聽
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class TestButton
{
    public static void main(String[] args)
    {
        Frame frame = new Frame("Test Button");
        Button button = new Button("Press Me!");

        // 增加事件處理器
        button.addActionListener(new ButtonHandler());

        // 將按鈕加入frame
        frame.add(button, BorderLayout.CENTER);

        frame.pack();

        frame.setVisible(true);
    }

}

class ButtonHandler implements ActionListener
{

    @Override
    public void actionPerformed(ActionEvent e)
    {
        //事件處理器

        System.out.println("Button is pressed!");
        
        String label = e.getActionCommand();
        System.out.println(label);
    }
}

 

  當單擊一個按鈕時,就會產生一個事件(ActionEvent),然后檢查是否有與該按鈕關聯的事件處理器(實際上是一個方法),

  如果沒有,那么什么都不執行;

  如果有的話,就會將該事件傳遞給與該按鈕關聯的事件處理器方法,作為該方法的參數,之后該事件處理方法就會自動得到調用,並且該方法可以使用傳遞過來的ActionEvent對象,進而獲得事件發生時與該事件及事件源相關聯的那些信息。

  Java中的組件若想添加事件處理器,都會使用形如addXxxListener()的方法來添加。一個事件源可以添加多個監聽器。

 

委托模型的優點

  事件不會被意外地處理。

  有可能創建並使用適配器(adapter)類對事件動作進行分類。

  委托模型有利於把工作分布到各個類中。

 

幾類具有典型代表意義的事件

  MouseEvent,鼠標事件,鼠標按下、釋放、點擊等。

  WindowEvent,窗口事件,點擊關閉按鈕,窗口得到與失去焦點,窗口最小化等。

  ActionEvent,動作事件,不代表具體的動作,是一種語義。如按鈕或菜單被鼠標單擊,單行文本框中按下回車鍵等都可以看做是ActionEvent事件。

  如果用戶的一個動作導致了某個組件最基本的動作發生了,這就是ActionEvent事件。

  對於每類事件,都會有一個接口(接口一般叫XxxListener),這個接口要求定義一個或多個方法。想接收這個事件的類必須實現這個接口,當發生這些事件時,就會調用這些方法。

  關於事件處理的另一個例子:  

圖形界面事件處理例子
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
import java.awt.Label;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.sql.Date;

public class MyWindow implements MouseListener, MouseMotionListener
{
    private Frame frame;
    private Label label;
    private Button button;
    private TextField textField;

    public void go()
    {
        frame = new Frame("My Frame");
        // 加上窗口監聽器,其中主要實現了退出功能
        frame.addWindowListener(new MyWindowListener());

        // 加一個標簽
        label = new Label("This is my Window");
        frame.add(label, BorderLayout.NORTH);

        // 加一個按鈕
        button = new Button("MyButton");
        frame.add(button, BorderLayout.WEST);

        // 設置按鈕事件監聽器,按鈕按下時會向控制台輸出信息
        button.addActionListener(new MyButtonListener());

        // 加一個文本編輯框
        textField = new TextField(40);
        frame.add(textField, BorderLayout.SOUTH);

        // 加上鼠標動作監聽器,因為類本身實現了這兩個接口,所以參數是this
        frame.addMouseListener(this);
        frame.addMouseMotionListener(this);
        // 可以添加多個監聽器,所以還可以定義其他的,如MyMouseListener類,然后加上

        // 設置剛好能容納這些控件的尺寸
        frame.pack();
        // 設置為可見
        frame.setVisible(true);
    }

    public static void main(String[] args)
    {
        MyWindow window = new MyWindow();

        window.go();
    }

    @Override
    public void mouseDragged(MouseEvent e)
    {

    }

    @Override
    public void mouseMoved(MouseEvent e)
    {
        String str = "x = " + e.getX() + ", y = " + e.getY();
        this.textField.setText(str);
        System.out.println(str);
    }

    @Override
    public void mouseClicked(MouseEvent e)
    {

    }

    @Override
    public void mouseEntered(MouseEvent e)
    {

    }

    @Override
    public void mouseExited(MouseEvent e)
    {
        this.textField.setText("the mouse has exited.");
    }

    @Override
    public void mousePressed(MouseEvent e)
    {

    }

    @Override
    public void mouseReleased(MouseEvent e)
    {

    }

}

class MyButtonListener implements ActionListener
{

    @SuppressWarnings("deprecation")
    @Override
    public void actionPerformed(ActionEvent e)
    {
        // 輸出信息
        System.out.println("The Button is pressed!");

        // 輸出時間戳
        Long time = e.getWhen();
        System.out.println("timestamp: " + time);

        // 日期時間
        Date date = new Date(time);
        System.out.println(date.toLocaleString());

    }

}

class MyWindowListener implements WindowListener
{

    @Override
    public void windowActivated(WindowEvent e)
    {

    }

    @Override
    public void windowClosed(WindowEvent e)
    {

    }

    @Override
    public void windowClosing(WindowEvent e)
    {
        System.out.println("windowClosing");
        // 退出
        System.exit(0);
    }

    @Override
    public void windowDeactivated(WindowEvent e)
    {

    }

    @Override
    public void windowDeiconified(WindowEvent e)
    {

    }

    @Override
    public void windowIconified(WindowEvent e)
    {

    }

    @Override
    public void windowOpened(WindowEvent e)
    {

    }
}

 

 

參考資料

  張龍老師Java SE視頻教程。

  本博客相關文章:

  http://www.cnblogs.com/mengdd/archive/2012/09/08/2676587.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM