Java-GUI程式設計之事件處理

愚生淺末發表於2022-04-06

事件處理

前面介紹瞭如何放置各種元件,從而得到了豐富多彩的圖形介面,但這些介面還不能響應使用者的任何操作。比如單擊前面所有視窗右上角的“X”按鈕,但視窗依然不會關閉。因為在 AWT 程式設計中 ,所有使用者的操作,都必須都需要經過一套事件處理機制來完成,而 Frame 和元件本身並沒有事件處理能力 。

GUI事件處理機制

定義:

​ 當在某個元件上發生某些操作的時候,會自動的觸發一段程式碼的執行。

在GUI事件處理機制中涉及到4個重要的概念需要理解:

事件源(Event Source) :操作發生的場所,通常指某個元件,例如按鈕、視窗等;
事件(Event):在事件源上發生的操作可以叫做事件,GUI會把事件都封裝到一個Event物件中,如果需要知道該事件的詳細資訊,就可以通過Event物件來獲取。
事件監聽器(Event Listener):當在某個事件源上發生了某個事件,事件監聽器就可以對這個事件進行處理。

註冊監聽:把某個事件監聽器(A)通過某個事件(B)繫結到某個事件源(C)上,當在事件源C上發生了事件B之後,那麼事件監聽器A的程式碼就會自動執行。

Java-GUI程式設計之事件處理

使用步驟:

1.建立事件源元件物件;

2.自定義類,實現XxxListener介面,重寫方法;

3.建立事件監聽器物件(自定義類物件)

4.呼叫事件源元件物件的addXxxListener方法完成註冊監聽

案例:

​ 完成下圖效果,點選確定按鈕,在單行文字域內顯示 hello world:

Java-GUI程式設計之事件處理
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class EventDemo1 {
    Frame  frame = new Frame("這裡測試事件處理");

    //事件源
    Button button = new Button("確定");

    TextField tf = new TextField(30);
    public void init(){
        //註冊監聽
        button.addActionListener(new MyActionListener());

        //新增元件到frame中
        frame.add(tf);
        frame.add(button,BorderLayout.SOUTH);

        //設定frame最佳大小並可見
        frame.pack();
        frame.setVisible(true);
    }

    //自定義事件監聽器類
    private  class MyActionListener implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent e) {

            System.out.println("使用者點選了確定按鈕");
            tf.setText("hello world");
        }
    }
    
    public static void main(String[] args) {
        new EventDemo1().init();
    }
}

GUI中常見事件和事件監聽器

事件監聽器必須實現事件監聽器介面, AWT 提供了大量的事件監聽器介面用於實現不同型別的事件監聽器,用於監聽不同型別的事件 。 AWT 中提供了豐富的事件類,用於封裝不同元件上所發生的特定操作, AWT 的事件類都是 AWTEvent 類的子類 , AWTEvent是 EventObject 的子類。

事件

AWT把事件分為了兩大類:

​ 1.低階事件:這類事件是基於某個特定動作的事件。比如進入、點選、拖放等動作的滑鼠事件,再比如得到焦點和失去焦點等焦點事件。

事件 觸發時機
ComponentEvent 元件事件 , 當 元件尺寸發生變化、位置發生移動、顯示/隱藏狀態發生改變時觸發該事件。
ContainerEvent 容器事件 , 當容器裡發生新增元件、刪除元件時觸發該事件 。
WindowEvent 視窗事件, 當窗 口狀態發生改變 ( 如開啟、關閉、最大化、最 小化)時觸發該事件 。
FocusEvent 焦點事件 , 當元件得到焦點或失去焦點 時觸發該事件 。
KeyEvent 鍵盤事件 , 當按鍵被按下、鬆開、單擊時觸發該事件。
MouseEvent 滑鼠事件,當進行單擊、按下、鬆開、移動滑鼠等動作 時觸發該事件。
PaintEvent 元件繪製事件 , 該事件是一個特殊的事件型別 , 當 GUI 元件調 用 update/paint 方法 來呈現自身時觸發該事件,該事件並非專用於事件處理模型 。

​ 2.高階事件:這類事件並不會基於某個特定動作,而是根據功能含義定義的事件。

事件 觸發時機
ActionEvent 動作事件 ,當按鈕、選單項被單擊,在 TextField 中按 Enter 鍵時觸發
AjustmentEvent 調節事件,在滑動條上移動滑塊以調節數值時觸發該事件。
ltemEvent 選項事件,當使用者選中某項, 或取消選中某項時觸發該事件 。
TextEvent 文字事件, 當文字框、文字域裡的文字發生改變時觸發該事件。

事件監聽器

不同的事件需要使用不同的監聽器監聽,不同的監聽器需要實現不同的監聽器介面, 當指定事件發生後 , 事件監聽器就會呼叫所包含的事件處理器(例項方法)來處理事件 。

事件類別 描述資訊 監聽器介面名
ActionEvent 啟用元件 ActionListener
ItemEvent 選擇了某些專案 ItemListener
MouseEvent 滑鼠移動 MouseMotionListener
MouseEvent 滑鼠點選等 MouseListener
KeyEvent 鍵盤輸入 KeyListener
FocusEvent 元件收到或失去焦點 FocusListener
AdjustmentEvent 移動了滾動條等元件 AdjustmentListener
ComponentEvent 物件移動縮放顯示隱藏等 ComponentListener
WindowEvent 視窗收到視窗級事件 WindowListener
ContainerEvent 容器中增加刪除了元件 ContainerListener
TextEvent 文字欄位或文字區發生改變 TextListener

案例

案例一:

​ 通過ContainerListener監聽Frame容器新增元件;

​ 通過TextListener監聽TextFiled內容變化;

​ 通過ItemListener監聽Choice條目選中狀態變化;

Java-GUI程式設計之事件處理
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class ListenerDemo1 {
    public static void main(String[] args) {
        Frame frame = new Frame("這裡測試監聽器");

        // 建立元件(事件源)
        TextField tf = new TextField(30);
        Choice names = new Choice();
        names.add("柳巖");
        names.add("舒淇");
        names.add("閆妮");

        // 給文字域新增TextListener,監聽內容的變化
        tf.addTextListener(new TextListener() {
            @Override
            public void textValueChanged(TextEvent e) {
                String text = tf.getText();
                System.out.println("當前文字框中的內容為:" + text);
            }
        });

        // 給下拉選擇框新增ItemListener,監聽條目選項的變化
        names.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                Object item = e.getItem();
                System.out.println("當前選中的條目為:" + item);
            }
        });

        // 給frame註冊ContainerListener監聽器,監聽容器中元件的新增
        frame.addContainerListener(new ContainerListener() {
            @Override
            public void componentAdded(ContainerEvent e) {
                Component child = e.getChild();
                System.out.println("frame中新增了:" + child);
            }

            @Override
            public void componentRemoved(ContainerEvent e) {

            }
        });

        // 新增到frame中
        Box hBox = Box.createHorizontalBox();
        hBox.add(names);
        hBox.add(tf);
        frame.add(hBox);

        // 設定frame最佳大小並可見
        frame.pack();
        frame.setVisible(true);
    }
}

案例2:

​ 給Frame設定WindowListner,監聽使用者點選 X 的動作,如果使用者點選X,則關閉當前視窗

演示程式碼2:

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class ListenerDemo2 {

    public static void main(String[] args) {

        Frame frame = new Frame("這裡測試WindowListener");

        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        frame.setBounds(200,200,500,300);

        frame.setVisible(true);
    }
}

公眾號文章地址:https://mp.weixin.qq.com/s/0BOBUP2pFrizTJ4mZNQP6w

個人部落格:https://kohler19.gitee.io/
公眾號:愚生淺末

相關文章