java中的事件機制
Java做的圖形界面軟件通過事件響應機制實現用戶與程序的交互,原理大概是這樣:
首先,在java控件對象(比如文本框)上添加一個監控對象,方法是one.addXXXListenner(two),這就相當于你要對某人進行監聽,先要在他身上綁定一個竊聽器一樣,這里“one”就是你要監聽的那個家伙,two就是你自己造的一個竊聽器。
第二步就是要考慮怎樣造這個竊聽器了,我們首先要搞清楚它要實現的功能:它不僅能夠監聽one的一舉一動,還能夠把監聽到的事件告訴系統,并讓系統對這個事件做出相應的處理。Java中是通過接口實現這樣的功能的。這些接口請參見jdk中java.awt.event包,里面那幾個XXXListener就是(不是很多,常用的更少)。在這些接口中定義了一些方法,這些方法就是相應的事件處理方式,它們只由系統調用并且都有一個事件類的對象作為參數,這個參數正是聯系發生事件主體one和操作系統的紐帶。當然接口是虛的,不能產生對象的;所以想必你也猜到,上面的“竊聽器”two的類型肯定是某個實現了XXXListener接口的類。
好了,現在在回顧一下這個過程:
(1)用戶通過鼠標、鍵盤等在one對象上做動作(比如點擊鼠標),
(2)這個動作被two監聽到并產生事件對象e(即XXXEvent的對象),
(3)two通過事件e對象向系統打報告,
(4)系統調用two中實現的方法對事件進行處理,并向方法傳送事件e。
如果你清楚了這個過程,再來細看一下這個XXXListener接口。我們必須用類來實現接口的方法(這是java基礎知識吧◎),再用這個類產生two這樣的對象。類實現接口必須實現接口中的每個方法,而實際上我們需要的也許只是該接口中的某一個方法(比如處理鼠標右鍵點擊的那個),那么每個方法還得去實現一個空的,真是浪費。Sun為了讓程序員省點事,在JDK中已經為我們把這些接口實現好了,這些類就是我們所謂的“適配器”(XXXAdapter),我們只需要繼承(extends)這些類并重寫里面我們需要的方法就OK了,所以,其實適配器就是類,只不過這些類中只有一些空的方法,別無所有。
到此,你大概明白程序員在事件處理過程中該做哪些事了吧:
(1)制造“竊聽器”,即:實現事件監聽接口,重寫相關方法,
(2)安裝竊聽器,即:為監控對象添加監聽器。
下面,我們通過程序再來仔細看看事件響應的實現方式(待續):
(以下內容參考陳剛《eclipse從入門到精通》)
(1)、 匿名內部類寫法
例程:
text.addMouseListener(new MouseAdapter() {
public void mouseDoubleClick(MouseEvent e) {//鼠標雙擊事件的方法
//打開一個信息框
MessageDialog.openInformation (null,"","Hello World");
}
});
new MouseAdapter()就是一個匿名內部類。其實就是在實現類的同時用new構造一個該類的對象,并把它作為addMouseListener的參數,它的效果和下面的一樣,只不過代碼比較集中。
(2)、命名內部類寫法
public class HelloWorld {
public static void main(String[] args) {
……
Text text = new Text(shell, SWT.BORDER);
//加入鼠標事件監聽器,并用下面代碼所定義的內部類生成一個對象
text.addMouseListener(new MyMouseDoubleClick());
……
}
//定義一個名為MyMouseDoubleClick的內部類
private static final class MyMouseDoubleClick extends MouseAdapter {
public void mouseDoubleClick(MouseEvent e) {
MessageDialog.openInformation(null, "", "Hello World");
}
}
}
(3)、外部類寫法
這種寫法和命名內部類有些相似,只不過是將MyMouseDoubleClick類從HelloWorld.java中拿出去,單獨寫成一個類文件。實現代碼如下
//文件1: HelloWorld.java
public class HelloWorld {
public static void main(String[] args) {
……
Text text = new Text(shell, SWT.BORDER);
//加入鼠標事件監聽器,并用下面代碼所定義的內部類生成一個對象
text.addMouseListener(new MyMouseDoubleClick());
……
}
}
//文件2:MyMouseDoubleClick.java
public class MyMouseDoubleClick extends MouseAdapter {
public void mouseDoubleClick(MouseEvent e) {
MessageDialog.openInformation(null, "", "Hello World");
}
}
(4)、實現監聽接口的寫法
將HelloWorld類實現MouseListener接口,這樣類本身就成了一個監聽器,使得加入監聽器的代碼可以更簡潔。這種方式適合加入監聽器的組件較多,且要求監聽器的事件處理代碼可以被組件共用。這種方式還有一個要注意的地方:事件方法和其他方法混合在了一起,容易引起誤讀,所以應該在事件方法前加入詳細的注釋說明。
實現MouseListener接口要寫的事件方法多一些,當然沒用的事件方法可以空實現。如果繼承MouseListener接口的適配器MouseAdapter,則只寫需要的方法就行了。另外要注意:只有接口才能有多繼承的特性,所以如果HelloWorld已經是某個類的子類,就只能用實現接口的方式,而不能繼承接口的適配器了。
給出示例代碼如下:
public class HelloWorld extends MouseAdapter{//或implements MouseListener
public static void main(String[] args) {
……
Text text1 = new Text(shell, SWT.BORDER);
Text text2 = new Text(shell, SWT.BORDER);
text1.addMouseListener(this);
text2.addMouseListener(this);
……
}
public void mouseDoubleClick(MouseEvent e) {
MessageDialog.openInformation(null, "", "Hello World");
}
}