首頁  >  文章  >  Java  >  詳解JAVA事件處理機制

詳解JAVA事件處理機制

零下一度
零下一度原創
2017-06-25 10:38:392174瀏覽

我們連續寫了兩小節的教師-學生的例子,必然覺得無聊死了,這樣的例子我們就是玩上100遍,還是不知道該怎麼寫真實的程式碼。那從本節開始,我們開始往真實程式碼上面去靠攏。

事件最容易理解的例子是滑鼠事件:我們點擊滑鼠,滑鼠發送指令,執行程式碼。

 

一:滑鼠點選事件處理模型基礎版

這個時候,我們必須去查看下JDK中相關類型。對照著上一節《從零開始理解JAVA事件處理機制(2)》中的UML圖,我們很快發現,對應HomeworkListener,JDK中有MouseListener,其實我們靠分析也能得知,MouseListener繼承自EventListener。現在既然有了介面MouseListener了,那我們必定會有一個實作類,這個類別假設叫做:ConcreteMouseListener。不妨先實作之:

package com.zuikc.events;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class ConcreteMouseListener implements MouseListener {

##    public ConcreteMouseListener(){

    }

    @Over .printf("我被{%s}點了一下,MD癢死了~~", e.getSource().toString());
    }

    @Override
    public void mousePressed(MouseEvent e) {

        // TODO Auto-generated method stub

    }

#    @Override
 method stub

    }


    @Override
    public void mouseEntered(MouseEvent e) {
        // public void mouseExited(MouseEvent e) {

        // TODO Auto-generated method stub

    }

}

我們為點選的事件處理器新增商業程式碼。


事件處理器:監聽器的具體實作類別的實作方法,就叫事件處理器。

接下來要看什麼,當然是MouseEvent。 MouseEvent,這個JDK中的類別相對來說,就稍微有點大了,起構造方法的參數有點多,不過沒有關係呀,我們慢慢看,我先說這個類別要怎麼用,即怎麼new出來。

/** 這裡的new Component() {} 是event.getSource() 得到的事件來源source */

MouseEvent event = new MouseEvent(new Component () {}, 1, 1, 1,2,3,4,false);

在實際且正常的情況下,MouseEvent是沒有必要自己new的,JAVA運行時會捕獲硬體滑鼠的點擊動作,由虛擬機器底層為我們產生該實例物件(下文會為我們分析這一點),但是我們此時此刻我們是先模擬呀,所以不妨礙我們自己胡亂new一個出來。請注意,new不是問題,問題的關鍵我們必須知道其建構器參數的意義,而其中核心關鍵參數就是第一個參數,new Component(),這是什麼?這就是那個事件來源!回頭看看我們的教師學生版本是在哪裡生產事件的:


    public void setHomework(String homework) {
        System.out.printf("%s佈置了作業%s \ n", this.name, homework);
        homeworks.add(homework);

        HomeworkEventObject event = new HomeworkEventObject(this);
        /*

         * 在觀察者模式中,我們直接調用Observable的notifyObservers來通知被觀察者

         * 現在我們只通知被觀察者
         *  listener.update(event, homework);

        }

    }
#

是在Teacher的業務代碼setHomework中。所以,在目前的我們要寫的這個例子中,new MouseEvent要在哪裡呢?我們在Button的業務代碼中,Button是誰,Button就類似Teacher,但又不完全等同Teacher,在Teacher中,Teacher本身就是事件來源,所以它這個this作為參數傳入進了HomeworkEventObject,而Button不能作為參數傳入進MouseEvent,因為我不打算讓Button繼承自Component,所以我們先new了一個暫時的Component。 OK,分析到了這裡,我們自己的Button程式碼大概就出來了,是這個樣子的:

package com.zuikc.events;

import java.awt.AWTEvent;
import java.awt.AWTEventMulticaster;
import java.awt.Component;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java. awt.peer.LightweightPeer;

public class Button {
    private MouseListener mouseListener;
    public void addMouseListener(MouseListener l) {
        mouseListener = l;
    }
    public void doClick(){
        /*
         * 這裡的new Component() {} 為event.getSource() 所得到的事件來源onent() {}, 1, 1, 1,2,3,4,false);
       //event.getSource();
        this.mouseListener.mouseClicked(event)      this.mouseListener.mouseClicked(event)      this.mouseListener.mouseClicked(event));
#;

##至此,我們可以畫出清楚的類別圖了,來看:

#順便我們來看看Client端的程式碼:

詳解JAVA事件處理機制

public static void main(String[] args) {

    ConcreteMouseListener listener = new ConcreteMouseListener();

    Button button = new Button();
 List #    button.doClick();

}


運行一下吧,你應該得到一個類似這樣的輸出:

我被{com.zuikc.events.Button$1 [,0,0,0x0,invalid]}點了一下,MD癢死了~~

 

二,一個正常的窗體程式的樣子

上面,我們盡量偏向教師學生的例子,寫出了滑鼠事件的基礎版本,但是說好的程式本來的樣子呢?來,我們接下來寫個正常的程序,99.9%在人在寫窗體程序的時候就是如下這麼寫的。我知道你們又會有人上來罵了,什麼,java,窗體程式?我TMD學JAVA是為了EE開發的,企業開發的。現在,我們先說好不好互相傷害,要知道,即便是NB如JAVA,最先也是先從窗體發蹟的,並且,JAVA的窗體框架推倒重寫了還不止一次。所以,窗體的事件你明白了,EE中那些框架的事件碰到了簡直跟切白菜一樣。

言歸正傳,看程式碼:

##package com.zuikc.events;

import java.awt.event.MouseEvent;

import java.awt. event.MouseListener;

import javax.swing.JButton;
import javax.swing.JFrame;

public class Client {

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

class DemoFrame extends JFrame implements MouseListener {

    #        this.setSize(500, 400);
        this.setLocationRelativeTo(null);
     . ible(true);

JButton button1 = new JButton("ok");

        button1.setBounds(8, 8, 80, 80);

        button1.MouseList(1); 1) ;
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        System.out.printf}0 ", e.getSource().toString());

    }


    @Override
    public void mousePressed(MouseEvent e) {
    }
> #    public void mouseReleased(MouseEvent e) {

    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

##    @Override

    public v
#    @Override
    public v# mouse}

這段程式碼是什麼意思?最簡單了,就是創建了一個窗體,窗體上放置了一個按鈕,點擊了之後,執行了一行程式碼。這簡簡單單的一個文件,沒多少行程式碼,實際上就實現了我們上文中一堆類別中實現的功能。來吧,我們分析吧,把監聽器、事件處理器、事件、事件來源都指出來。

監聽器:DemoFrame就是監聽器,對應ConcreteMouseListener;

事件處理器:MouseClicked方法就是監聽器,ConcreteMouseListener裡面也有這個方法;

事件:

事件:看不到了,怎麼辦?

事件來源:看不到了,怎麼辦?

注意,窗體本身就監聽器,所以上文程式碼中為button新增監聽器怎麼做? button1.addMouseListener(this);沒錯,就是把自己加進去。

然後,事件和事件來源都看不見了,這時候怎麼辦?我們如果看輸出的話,上文程式碼的輸出為:

我被{javax.swing.JButton[,8,8,80x80,invalid,alignmentX=0.0,alignmentY=0.5,border=javax.swing .plaf.BorderUIResource$CompoundBorderUIResource@7fda7dfe,flags=296,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.pl. =2,right=14],paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=ok,defaultCapable=true]}點了一下,MD癢死了一下~ ~

看起來,類似我們上文第一部分程式碼的輸出,也是JButton業務程式碼運行過程中產生的一個變量,但它是在哪裡產生的,在哪裡產生的,我們並不知道。不過沒關係,我們看調試堆疊!

一步一步的往上追,我們終於追到了這裡:

 

詳解JAVA事件處理機制

#由此可見,MouseEvent也是在業務程式碼裡new出來了,大家可能要為,那這個重要的第一個參數target呢? target可是事件來源也很重要,道理很簡單,往上繼續追,限於篇幅,這裡不在展開,它在某個你願意看到它的地方被new出來了。

現在我們補齊回答,

事件:JAVA運行時捕獲到硬體滑鼠觸發,從而呼叫了事件處理器,在事件處理器內部產生的這個MouseEvent,就是事件;

事件來源:JAVA運行時捕獲硬體滑鼠觸發,從而呼叫了事件處理器,在事件處理器內部產生的這個target,就是事件來源;

三:正常版的上文第一部分的程式碼

依照二中的程式碼來寫,我們第一部分的程式碼應該是什麼樣子的呢?

一和二放在一起比較,其實只要改兩個地方,一中的程式碼就和二中完全一致了,

1:將ConcreteMouseListener命名為DemoFrame;

2:將Button實例由客戶端放置到ConcreteMouseListener內部;

OK,事件就是這麼簡單。

系列的第一部分和第二部分分別在:

1:從零開始理解JAVA事件處理機制(1)

2:從零開始理解JAVA事件處理機制(2)

以上是詳解JAVA事件處理機制的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn