Swing圖形用戶界面編程之事件處理模式


圖形界面的組件要響應用戶操作,就必須添加事件處理機制。Swing採用AWT的事件處理模型進行事件處理。在事件處理的過程中涉及三個要素:

  • 事件:是用戶對界面的操作,例如按鈕單擊事件
  • 事件源:是事件發生的場所,就是各個組件,例如按鈕單擊事件的事件源是按鈕(Button)
  • 事件處理者:是事件處理程序,在Java中事件處理者是實現特定接口的事件對象。

在事件處理模型中最重要的是事件處理者,它根據事件(假設XXXEvent事件)的不同會實現不同的接 口,這些接口命名爲XXXListener,所以事件處理者也稱爲事件監聽器。最後事件源通過 addXXXListener()方法添加事件監聽,監聽XXXEvent事件。

事件處理者可以是實現了XXXListener接口任何形式,即:外部類、內部類、匿名內部類和Lambda表 達式;如果XXXListener接口只有一個抽象方法,事件處理者還可以是Lambda表達式。爲了訪問窗口 中的組件方便,往往使用內部類、匿名內部類和Lambda表達式情況很多。
事件類型和事件監聽器接口:
在這裏插入圖片描述

一、採用內部類處理事件

學習事件處理主要是複習之前所學的內部類以及Lambda知識;
事件處理模型示例 示例代碼如下:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * @author : 蔡政潔
 * @email :[email protected]
 * @date : 2020/2/23
 * @time : 9:04 上午
 */
public class MyFrame extends JFrame {
//    聲明標籤
    JLabel label;
    public MyFrame(String title){
        super(title);
//        創建標籤
        label = new JLabel("caizhengjie");
//        添加到內容面板
        getContentPane().add(label, BorderLayout.NORTH);

//        創建Button1
        JButton button1 = new JButton("Button1");
//        添加到內容面板
        getContentPane().add(button1,BorderLayout.CENTER);

//        創建Button2
        JButton button2 = new JButton("Button1");
//        添加到內容面板
        getContentPane().add(button2,BorderLayout.SOUTH);

//        設置窗口大小
        setSize(350,120);
//        設置窗口可見
        setVisible(true);

//        註冊事件監聽器,監聽Button2單機事件,這裏採用內部類寫法
        button2.addActionListener(new ActionEventerHandler());

//        註冊事件監聽器,監聽Button1單機事件,這裏採用匿名內部類寫法
        button1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                label.setText("Hello Swing");
            }
        });


    }
//        Button2事件處理者
    class ActionEventerHandler implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent e) {
            label.setText("Hello World!");
        }
    }
}

調用代碼:

public class HelloWorld {
    public static void main(String[] args) {
        MyFrame myFrame = new MyFrame("hehehe");
    }
}

運行結果:
在這裏插入圖片描述

二、採用Lambda表達式處理事件

如果一個事件監聽器接口只有一個抽象方法,則可以使用Lambda表達式實現事件處理
展示代碼:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * @author : 蔡政潔
 * @email :[email protected]
 * @date : 2020/2/23
 * @time : 9:25 上午
 */
public class MyFrame extends JFrame implements ActionListener {
//    聲明標籤
    JLabel label;
    public MyFrame(String title) {
        super(title);
//        創建標籤
        label = new JLabel("caizhengjie");
//        添加到內容面板
        getContentPane().add(label, BorderLayout.NORTH);

//        創建Button1
        JButton button1 = new JButton("Button1");
//        添加到內容面板
        getContentPane().add(button1, BorderLayout.CENTER);

//        創建Button2
        JButton button2 = new JButton("Button1");
//        添加到內容面板
        getContentPane().add(button2, BorderLayout.SOUTH);

//        設置窗口大小
        setSize(350, 120);
//        設置窗口可見
        setVisible(true);

//        註冊事件監聽器,監聽Button2單機事件
        button2.addActionListener(this);

//        註冊事件監聽器,監聽Button1單機事件,這裏採用Lambda表達式寫法
        button1.addActionListener((envent) ->{
            label.setText("Hello World");
        });

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        label.setText("Hello Swing");
    }
}

調用代碼:

public class Helloworld {
    public static void main(String[] args) {
        MyFrame myFrame = new MyFrame("caizhengjie");
    }
}

運行結果和上面一樣

三、使用適配器

事件監聽器都是接口,在Java中接口中定義的抽象方法必須全部是實現,哪怕你對某些方法並不關 心,你也要給一對空的大括號表示實現。
例如WindowListener是窗口事件(WindowEvent)監聽器接 口,爲了在窗口中接收到窗口事件,需要在窗口中註冊WindowListener事件監聽器,示例代碼如下:

this.addWindowListener(new WindowListener() {
          @Override
          public void windowActivated(WindowEvent e) {
          }
          @Override
          public void windowClosed(WindowEvent e) {
          }
          @Override
          public void windowClosing(WindowEvent e) {            
// 退出系統
				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還提供了一些與監聽器相配套的適配器。
監聽器是接 口,命名採用XXXListener,而適配器是類,命名採用XXX Adapter。
使用適配器的目的是:在使用時通過繼承事件所對應的 適配器類,覆蓋所需要的方法,無關方法不用實現,使代碼看起來簡潔。

採用適配器註冊接收窗口事件代碼如下:

this.addWindowListener(new WindowAdapter(){ 
@Override
	public void windowClosing(WindowEvent e) { 
	// 退出系統
		System.exit(0);
	}
});

可見代碼非常的簡潔。事件適配器提供了一種簡單的實現監聽器的手段,可以縮短程序代碼。
並非所有的監聽器接口都有對應的適配器類,一般定義了多個方法的監聽器接口,例如 WindowListener有多個方法對應多種不同的窗口事件時,才需要配套的適配器,主要的適配器如下:

  • ComponentAdapter:組件適配器。
  • ContainerAdapter:容器適配器。
  • FocusAdapter:焦點適配器。
  • KeyAdapter:鍵盤適配器。
  • MouseAdapter:鼠標適配器。
  • MouseMotionAdapter:鼠標運動適配器。
  • WindowAdapter:窗口適配器。

以上內容僅供參考學習,如有侵權請聯繫我刪除!
如果這篇文章對您有幫助,左下角的大拇指就是對博主最大的鼓勵。
您的鼓勵就是博主最大的動力!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章