2020/4/15學習筆記day40

java-day40

GUI事件監聽總結

1.AWT事件模型概述

使用AWT或者Swing中的容器、組件和佈局管理器就可以構建出圖形界面,但是這時候該界面還並不能和用戶進行交換,因爲圖形界面中的組件還沒有添加事件監聽器,所以還不能對用戶在界面中的操作進行處理。

在Java事件模型中,必須存在事件對象、事件源、事件監聽器三部分。事件對象是表示發生了什麼事件,事件源表示是誰產生的這個事件對象,事件處理器接收到事件對象後,可以對這個事件進行處理。
事件模型中的三要素:事件對象、事件源、事件監聽器
注:不光是GUI中,在java的其他地方也會使用到事件模型。

在Java中一個事件監聽器就是指事件發生時被通知的對象。它有兩個要求

首先,爲了可以接收到特殊類型事件的通知,它必須在事件源中已經註冊;

其次,它必須實現接收和處理事件的方法。

例如:

//btn就是事件源
JButton btn = new JButton("測試");
//給事件源btn註冊事件監聽器
//這裏使用了匿名內部類對象作爲監聽器
btn.addActionListener(new ActionListener() {
    //監聽器中實現接收和處理事件的方法
    //ActionEvent類型的引用e指向的就是按鈕上所產生的事件對象
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("hello");
    }
});

XxxxListener 監聽器接口
    事件源.addXxxxListener(new XxxxListener(){
        //實現接口中的抽象方法
    });

在事件源上註冊好監聽器之後,只要是在該事件源上產生了特定的事件對象,事件監聽器就會自動被觸發,並執行相應的方法處理。

例如:在上面的例子基礎上
當我們使用鼠標點擊btn這個按鈕之後,產生了一個鼠標點擊的事件對象(引用e會指向這個事件對象),然後註冊的事件監聽器會自動觸發(這裏的匿名內部類對象就是註冊的監聽器),並調用指定方法actionPerformed,對產生的事件進行處理。

2.事件源、事件對象、事件監聽器

1)事件源

AWT和Swing中的幾乎所有的組件都可以作爲事件源,注意容器也是一種組件。
例如:窗口、面板、按鈕、輸入框、下拉類別的菜單、單選複選框、標籤、滾動條、進度條等等
例如:AWT和Swing中的組件都是java.awt.Component類的子類型,Component類中定義了很多所有組件都可以調用的方法,這些方法中有很多是這種形式的:addXxxxListener
這些方法就是給組件中註冊事件監聽器的方法,只是不同類型的事件需要使用不同類型的監聽器來監聽,所以不同的addXxxxListener方法就表示給組件添加相應的事件監聽器。(Xxxx代表事件的類型)

2)事件對象及其對應的處理接口(也就是事件監聽器)

java.util.EventObject類

java.awt.Event類

java.awt.AWTEvent類

java.awt.event.ActionEvent類

java.awt.event.AdjustmentEvent類

java.awt.event.ComponentEvent類

java.awt.event.ContainerEvent類

java.awt.event.WindowEvent類

java.awt.event.FocusEvent類

java.awt.event.ItemEvent類

java.awt.event.TextEvent類

java.awt.event.KeyEvent類

java.awt.event.MouseEvent類

3.適配器 Adapter

很多監聽器接口中都定義了很多個方法,每個方法負責處理一種產生事件的情況,我們編寫實現類的時候就需要實現監聽器接口中的所有方法,但是很多時候我們其實只需要調用接口中的一個方法,但是由於語法要求我們還是必須把接口中的所有抽象全都實現了。

例如: 點擊按鈕輸出hello world

JButton btn = new JButton("test");
btn.addMouseListener(new MouseListener() {
    public void mouseClicked(MouseEvent e) {
        System.out.println("hello world");
    }
    public void mouseReleased(MouseEvent e) {}
    public void mousePressed(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
});

使用了MouseListener接口的匿名內部類對象,並且五個方法全都實現了,但是其實我們只需要調用mouseClicked方法.

爲了處理這個代碼中出現的情況,又引入了接口的適配器類:XxxxAdapter

MouseAdapter實現了MouseListener, MouseWheelListener, MouseMotionListener三個接口,並且把接口中抽象方法全都進行了空實現,將來我們只需要創建MouseAdapter類的匿名內部類然後重寫我們想調用的方法即可
例如: 點擊按鈕輸出hello world

JButton btn = new JButton("test");
btn.addMouseListener(new MouseAdapter() {
    public void mouseClicked(MouseEvent e) {
        System.out.println("hello world");
    }
});

​ 除了MouseAdapter實現MouseListener, MouseWheelListener, MouseMotionListener三個接口,是一個適配器類之外,還有其他的一些適配器類:

WindowAdapter適配器類實現了WindowListener, WindowStateListener, WindowFocusListener三個接口

ComponentAdapter適配器類實現了ComponentListener接口

ContainerAdapter適配器類實現了ContainerListener接口

FocusAdapter適配器類實現了FocusListener接口

KeyAdapter適配器類實現了KeyListener接口

MouseMotionAdapter適配器類實現了MouseMotionListener接口

HierarchyBoundsAdapter適配器類實現了HierarchyBoundsListener接口

4.定時器Timer

javax.swing.Timer類,可以定時觸發事件(ActionEvent),調用監聽器的指定方法。

例如:TimerTest1.java TimerTest2.java

JFrame jFrame = new JFrame();
JPanel panel = new JPanel();

JPanel north = new JPanel();
JButton startBtn = new JButton("開始");
JButton endBtn = new JButton("停止");

final Canvas canvas = new Canvas();

final Timer timer = new Timer(500,new ActionListener() {
    private int count;
    @Override
    public void actionPerformed(ActionEvent e) {
        if(count*10>=canvas.getWidth()){
            return ;
        }
        Graphics g = canvas.getGraphics();
        g.drawLine(count*10, 0, count*10, canvas.getWidth());
        count++;
    }
});

startBtn.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        timer.start();
    }
});
endBtn.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        timer.stop();
    }
});

north.add(startBtn);
north.add(endBtn);

panel.setLayout(new BorderLayout());
panel.add(canvas);

jFrame.add(north,BorderLayout.NORTH);
jFrame.add(panel);

jFrame.setSize(400, 400);
jFrame.setLocation(700, 300);
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setVisible(true);

5.讓當前類實現監聽器接口

當前對象this就成爲了監聽器對象

例如:

public class Test extends JFrame implements ActionListener{
    private static final long serialVersionUID = 1L;

    private JPanel jPanel;
    private JButton btn;

    public Test() {
        setBounds(700, 500, 500, 500);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        initComponet();
        setVisible(true);
    }

    private void initComponet(){
        //初始化組件
        jPanel = new JPanel();
        btn = new JButton("測試");

        //設置佈局管理器並添加組件
        jPanel.add(btn);

        add(jPanel);

        //給組件添加事件監聽器
        btn.addActionListener(this);
    }
    public void actionPerformed(ActionEvent e) {
        System.out.println("hello world");
    }

    public static void main(String[] args) {
        new Test();
    }
}

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