在本章中,我們將會詳細瞭解使用Swing組件的一個方面:事件處理。當使用Swing組件集合時,我們可以使用基於委託的事件處理機制,但是我們也可以使用其他的方法來響應使用者的動作。在本章中,我們將會探索所有這些事件處理響應機制。我們同時也會瞭解到Swing是如何管理輸入焦點以及控制輸入焦點處理的相關技術。
當我們探索事件處理功能時,我們將會開始瞭解一些實際的Swing組件。在本章中,我們將會以最簡單的方式來使用Swing組件。我們可以先閱讀本書後面章節中所探討的組件,然後再回到本章探討事件處理。本書的後面章節中也包含每一個組件特定的事件處理的詳細內容。
2.1 基於委託的事件處理
Sun在JDK.1.1及JavaBean的Java庫中引入了基於委託的事件處理機制。儘管Java 1.0庫中包含了遵循觀察者行為設計模式的對象觀察者對,但這並不是使用者介面編程的長久解決方案。
2.1.1 事件委託模型
基於委託的事件處理機制是觀察者設計模式的一種特殊形式。當一個觀察者希望希望一個被監視的對象狀態何時發生變化以及狀態變化是什麼時可以使用觀察者模式。在基於委託的事件處理機制中,觀察者並不監聽狀態改變,而是監聽事件發生。
圖2-1顯示了在Java庫中與事件處理的特定類相關的修改後的觀察者模式結構。模式中的通用Subject管理一個用於Subject可以產生的事件的通用觀察者對象列表。列表中的觀察者對象必須提供一個特定的介面,通過這個介面Subject參與者可以通知他們。當觀察者對象所感興趣的事件在Subject參與者中發生時,所有登入的觀察者對象都會被通知到。在Java世界中,觀察者對象要實現的介面必須擴充java.util.EventListener介面。Subject參與者必須建立的事件需要擴充java.util.EventObject類。
為了使得討論更為清晰,下面我們由非設計模式的角度來瞭解基於委託的事件處理機制。GUI組件(JavaBean)管理一個監聽器列表,每一個監聽器會有用於監聽器類型的一對方法:addXXXListener()與removeXXXListener()。當組件中有事件發生時,組件會通知所有註冊的事件監聽器。任何對該事件感興趣的觀察者類需要向組件註冊一個相應介面的實現器。當事件發生時,所有的實現都被通知。圖2-2嘗過了這個過程。
2.1.2 作為觀察者的事件監聽器
使用事件監聽器來處理事件分為三步:
- 定義一個類來實現相應的監聽器介面(這包括為所有的介面方法提供實現)。
- 建立這個監聽器的一個執行個體。
- 將監聽器註冊到我們所感興趣的的事件的組件上。
下面我們通過建立一個簡單的通過輸出訊息來響應選擇的按鈕來瞭解一下這三個特定步驟。
定義監聽器
要為了一個可選擇的按鈕設定事件處理,我們需要建立一個ActionListener,因為JButton在被選中時會產生ActionEvent對象。
class AnActionListener implements ActionListener { public void actionPerformed(ActionEvent actionEvent) { System.out.println("I was selected."); } }class AnActionListener implements ActionListener { public void actionPerformed(ActionEvent actionEvent) { System.out.println("I was selected."); }}
建立監聽器執行個體
接下來我們簡單的建立一個我們所定義的監聽器的執行個體。
ActionListener actionListener = new AnActionListener();ActionListener actionListener = new AnActionListener();
如果我們為事件監聽器使用匿名內聯類,我們就可以組合步驟1與2:
ActionListener actionListener = new ActionListener() { public void actionPerformed(ActionEvent actionEvent) { System.out.println("I was selected."); } };ActionListener actionListener = new ActionListener() { public void actionPerformed(ActionEvent actionEvent) { System.out.println("I was selected."); }};
向組件註冊監聽器
一旦我們建立了監聽器,我們就可以將其與相應的組件相關聯。假定我們已經建立JButton,並將其引用存入在變數button中,我們可以通過調用按鈕的addActionListener()方法來實現:
button.addActionListener(actionListener);button.addActionListener(actionListener);
如果我們當前所定義的類就是實現監聽器介面的類,那麼我們就不需要建立一個單獨的監聽器執行個體。我們只需要將作為監聽器的類與組件相關聯。如下面的範例程式碼所示:
public class YourClass implements ActionListener { ... // Other code for your class public void actionPerformed(ActionEvent actionEvent) { System.out.println("I was selected."); } // Code within some method JButton button = new JButton(...); button.addActionListener(this); // More code within some method }public class YourClass implements ActionListener { ... // Other code for your class public void actionPerformed(ActionEvent actionEvent) { System.out.println("I was selected."); } // Code within some method JButton button = new JButton(...); button.addActionListener(this); // More code within some method}
以如上所示建立監聽器並將其與組件相關聯的方法使用事件處理器是響應Swing組件事件的基本方法。哪一個監聽器與哪一個組件配合使用將會在後面的章節中描述相應的組件時進行討論。在下面的內容中,我們將會瞭解到響應事件的一些其他方法。