JAVA教程第五講AWT圖形用戶界面設(shè)計(jì)5.2

字號(hào):

5.2 AWT事件處理模型
    上一節(jié)中的主要內(nèi)容是如何放置各種組件,使圖形界面更加豐富多彩,但是還不能響應(yīng)用戶的任何操作,要能夠讓圖形界面接收用戶的操作,就必須給各個(gè)組件加上事件處理機(jī)制。在事件處理的過(guò)程中,主要涉及三類(lèi)對(duì)象:
    ◇ Event-事件,用戶對(duì)界面操作在java語(yǔ)言上的描述,以類(lèi)的形式出現(xiàn),例如鍵盤(pán)操作對(duì)應(yīng)的事件類(lèi)是KeyEvent。
    ◇ Event Source-事件源,事件發(fā)生的場(chǎng)所,通常就是各個(gè)組件,例如按鈕Button。
    ◇ Event handler-事件處理者,接收事件對(duì)象并對(duì)其進(jìn)行處理的對(duì)象
    例如,如果用戶用鼠標(biāo)單擊了按鈕對(duì)象button,則該按鈕button就是事件源,而java運(yùn)行時(shí)系統(tǒng)會(huì)生成ActionEvent類(lèi)的對(duì)象actionE,該對(duì)象中描述了該單擊事件發(fā)生時(shí)的一些信息,然后,事件處理者對(duì)象將接收由java運(yùn)行時(shí)系統(tǒng)傳遞過(guò)來(lái)的事件對(duì)象actionE并進(jìn)行相應(yīng)的處理。
    由于同一個(gè)事件源上可能發(fā)生多種事件,因此java采取了授權(quán)處理機(jī)制(Delegation Model),事件源可以把在其自身所有可能發(fā)生的事件分別授權(quán)給不同的事件處理者來(lái)處理。比如在Canvas對(duì)象上既可能發(fā)生鼠標(biāo)事件,也可能發(fā)生鍵盤(pán)事件,該Canvas對(duì)象就可以授權(quán)給事件處理者一來(lái)處理鼠標(biāo)事件,同時(shí)授權(quán)給事件處理者二來(lái)處理鍵盤(pán)事件。有時(shí)也將事件處理者稱為監(jiān)聽(tīng)器,主要原因也在于監(jiān)聽(tīng)器時(shí)刻監(jiān)聽(tīng)著事件源上所有發(fā)生的事件類(lèi)型,一旦該事件類(lèi)型與自己所負(fù)責(zé)處理的事件類(lèi)型一致,就馬上進(jìn)行處理。授權(quán)模型把事件的處理委托給外部的處理實(shí)體進(jìn)行處理,實(shí)現(xiàn)了將事件源和監(jiān)聽(tīng)器分開(kāi)的機(jī)制。事件處理者(監(jiān)聽(tīng)器)通常是一個(gè)類(lèi),該類(lèi)如果要能夠處理某種類(lèi)型的事件,就必須實(shí)現(xiàn)與該事件類(lèi)型相對(duì)的接口。例如例5.9中類(lèi)ButtonHandler之所以能夠處理ActionEvent事件,原因在于它實(shí)現(xiàn)了與ActionEvent事件對(duì)應(yīng)的接口ActionListener。每個(gè)事件類(lèi)都有一個(gè)與之相對(duì)應(yīng)的接口。
    將事件源對(duì)象和事件處理器(事件監(jiān)聽(tīng)器)分開(kāi)。如圖5.2所示
     
    打個(gè)不太恰當(dāng)?shù)谋扔?,比如說(shuō)有一位李先生,李先生可能會(huì)發(fā)生很多法律糾紛,可能是民事法律糾紛,也可能是刑事法律糾紛,那么李先生可以請(qǐng)律師,他可以授權(quán)王律師負(fù)責(zé)幫他打民事法律的官司,同時(shí)也可以授權(quán)張律師幫他打刑事法律的官司。這個(gè)請(qǐng)律師的過(guò)程從李先生的角度來(lái)看,就是授權(quán)的過(guò)程,而從王律師和張律師的角度來(lái)看,一旦被授權(quán),他們就得時(shí)刻對(duì)李先生負(fù)責(zé),"監(jiān)聽(tīng)"著李先生,一旦發(fā)生民事糾紛了,王律師就要馬上去處理,而一旦發(fā)生刑事糾紛了,張律師就要馬上進(jìn)行處理。此時(shí)此刻,李先生就是事件源,王律師是一個(gè)事件處理者,張律師是另外一個(gè)事件處理者,民事糾紛和刑事糾紛就是不同類(lèi)型的事件。
    例5.9
     import java.awt.*;
     import java.awt.event.*;
     public class TestButton {
     public static void main(String args[])
     {
     Frame f = new Frame("Test");
     Button b = new Button("Press Me!");
     b.addActionListener(new ButtonHandler()); /*注冊(cè)監(jiān)聽(tīng)器進(jìn)行授權(quán),該方法的參數(shù)是事件處理者對(duì)象,要處理的事件類(lèi)型可以從方法名中看出,例如本方法要授權(quán)處理的是ActionEvent,因?yàn)榉椒莂ddActionListener。*/
     f.setLayout(new FlowLayout()); //設(shè)置布局管理器
     f.add(b);
     f.setSize(200,100);
     f.setVisible(true);
     }
     }
     class ButtonHandler implements ActionListener {
     //實(shí)現(xiàn)接口ActionListener才能做事件ActionEvent的處理者
     public void actionPerformed(ActionEvent e)
     //系統(tǒng)產(chǎn)生的ActionEvent事件對(duì)象被當(dāng)作參數(shù)傳遞給該方法
     {
     System.out.println("Action occurred");
     //本接口只有一個(gè)方法,因此事件發(fā)生時(shí),系統(tǒng)會(huì)自動(dòng)調(diào)用本方法,需要做的操作就把代碼寫(xiě)在則個(gè)方法里。
     }
     }
    使用授權(quán)處理模型進(jìn)行事件處理的一般方法歸納如下:
    1.對(duì)于某種類(lèi)型的事件XXXEvent, 要想接收并處理這類(lèi)事件,必須定義相應(yīng)的事件監(jiān)聽(tīng)器類(lèi),該類(lèi)需要實(shí)現(xiàn)與該事件相對(duì)應(yīng)的接口XXXListener;
    2.事件源實(shí)例化以后,必須進(jìn)行授權(quán),注冊(cè)該類(lèi)事件的監(jiān)聽(tīng)器,使用addXXXListener(XXXListener ) 方法來(lái)注冊(cè)監(jiān)聽(tīng)器。