我們連續寫了兩小節的教師-學生的例子,必然覺得無聊死了,這樣的例子我們就是玩上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());
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {}
}
# @Override
method stub// TODO Auto-generated method stub
@Override
public void mouseEntered(MouseEvent e) {
// public void mouseExited(MouseEvent e) {}
}我們為點選的事件處理器新增商業程式碼。
事件處理器:監聽器的具體實作類別的實作方法,就叫事件處理器。
接下來要看什麼,當然是MouseEvent。 MouseEvent,這個JDK中的類別相對來說,就稍微有點大了,起構造方法的參數有點多,不過沒有關係呀,我們慢慢看,我先說這個類別要怎麼用,即怎麼new出來。
在實際且正常的情況下,MouseEvent是沒有必要自己new的,JAVA運行時會捕獲硬體滑鼠的點擊動作,由虛擬機器底層為我們產生該實例物件(下文會為我們分析這一點),但是我們此時此刻我們是先模擬呀,所以不妨礙我們自己胡亂new一個出來。請注意,new不是問題,問題的關鍵我們必須知道其建構器參數的意義,而其中核心關鍵參數就是第一個參數,new Component(),這是什麼?這就是那個事件來源!回頭看看我們的教師學生版本是在哪裡生產事件的:/** 這裡的new Component() {} 是event.getSource() 得到的事件來源source */
MouseEvent event = new MouseEvent(new Component () {}, 1, 1, 1,2,3,4,false);
/*HomeworkEventObject event = new HomeworkEventObject(this);
public void setHomework(String homework) {
System.out.printf("%s佈置了作業%s \ n", this.name, homework);
homeworks.add(homework);
* 在觀察者模式中,我們直接調用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程式碼大概就出來了,是這個樣子的:
#順便我們來看看Client端的程式碼:public static void main(String[] args) {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));
#;
##至此,我們可以畫出清楚的類別圖了,來看:
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 {監聽器:DemoFrame就是監聽器,對應ConcreteMouseListener;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
## @Override
public void mouseEntered(MouseEvent e) {
}public v
這段程式碼是什麼意思?最簡單了,就是創建了一個窗體,窗體上放置了一個按鈕,點擊了之後,執行了一行程式碼。這簡簡單單的一個文件,沒多少行程式碼,實際上就實現了我們上文中一堆類別中實現的功能。來吧,我們分析吧,把監聽器、事件處理器、事件、事件來源都指出來。
# @Override
public v# mouse}
事件處理器: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業務程式碼運行過程中產生的一個變量,但它是在哪裡產生的,在哪裡產生的,我們並不知道。不過沒關係,我們看調試堆疊!
一步一步的往上追,我們終於追到了這裡:
#由此可見,MouseEvent也是在業務程式碼裡new出來了,大家可能要為,那這個重要的第一個參數target呢? target可是事件來源也很重要,道理很簡單,往上繼續追,限於篇幅,這裡不在展開,它在某個你願意看到它的地方被new出來了。
現在我們補齊回答,
事件:JAVA運行時捕獲到硬體滑鼠觸發,從而呼叫了事件處理器,在事件處理器內部產生的這個MouseEvent,就是事件;
事件來源:JAVA運行時捕獲硬體滑鼠觸發,從而呼叫了事件處理器,在事件處理器內部產生的這個target,就是事件來源;
三:正常版的上文第一部分的程式碼
依照二中的程式碼來寫,我們第一部分的程式碼應該是什麼樣子的呢?
一和二放在一起比較,其實只要改兩個地方,一中的程式碼就和二中完全一致了,
1:將ConcreteMouseListener命名為DemoFrame;
2:將Button實例由客戶端放置到ConcreteMouseListener內部;
OK,事件就是這麼簡單。
系列的第一部分和第二部分分別在:
1:從零開始理解JAVA事件處理機制(1)
2:從零開始理解JAVA事件處理機制(2)
以上是詳解JAVA事件處理機制的詳細內容。更多資訊請關注PHP中文網其他相關文章!