記得以前看過事件監聽機制背后也是有一種設計模式的.(設計模式的名字記不清了,只記得背后實現的數據結構是數組.)
附上事件監聽機制的分析圖:
一個事件源可以承載多個事件(只要這個事件源支持這個事件就可以,男人就不支持生孩子的事件) 事件和監聽器有對應關系的.
下面用awt中的標准圖形化界面分析:
接口WindowListener 中有一個實現類WindowAdapter類.適配器類.
EventListener.java 下面是所有超級接口EventListener.java的源代碼 其實就是一個空接口.
1 package java.util; 2 3 /** 4 * A tagging interface that all event listener interfaces must extend. 5 * @since JDK1.1 6 */ 7 public interface EventListener { 8 }
WindowListener.java 這個接口的源代碼 定義了一些抽象方法
1 public interface WindowListener extends EventListener { 2 /** 3 * Invoked the first time a window is made visible. 4 */ 5 public void windowOpened(WindowEvent e); 6 7 public void windowClosing(WindowEvent e); 8 9 public void windowClosed(WindowEvent e); 10 11 public void windowIconified(WindowEvent e); 12 13 public void windowDeiconified(WindowEvent e); 14 15 public void windowActivated(WindowEvent e); 16 17 public void windowDeactivated(WindowEvent e); 18 }
WindowAdapter.java這個實現類的源代碼: WindowAdapter是一個抽象類.但是這個抽象類里面卻沒有抽象方法!!!!!!!
所有的方法都是空實現!!!空方法!!!
1 public abstract class WindowAdapter 2 implements WindowListener, WindowStateListener, WindowFocusListener 3 { 4 /** 5 * Invoked when a window has been opened. 6 */ 7 public void windowOpened(WindowEvent e) {} 8 9 public void windowClosing(WindowEvent e) {} 10 11 public void windowClosed(WindowEvent e) {} 12 13 public void windowIconified(WindowEvent e) {} 14 15 public void windowDeiconified(WindowEvent e) {} 16 17 public void windowActivated(WindowEvent e) {} 18 19 public void windowDeactivated(WindowEvent e) {} 20 21 public void windowStateChanged(WindowEvent e) {} 22 23 public void windowGainedFocus(WindowEvent e) {} 24 25 /** 26 * Invoked when the Window is no longer the focused Window, which means 27 * that keyboard events will no longer be delivered to the Window or any of 28 * its subcomponents. 29 * 30 * @since 1.4 31 */ 32 public void windowLostFocus(WindowEvent e) {} 33 }
窗口事件的抽象適配器類(WindowAdapter).此類中的方法為空.此類存在的目的是方便創建監聽器對象.
如果實現WindowListener 就要覆蓋其中的所有抽象方法,但是繼承WindowAdapter就不需要了,JDK為你定義好了這樣的一個適配器類,
實現了所有WindowListener接口中的抽象方法.所以只需繼承WindowAdapter類就可以了.需要什么方法就覆蓋其中的方法.
EventListener是接口,WindowListener 也是接口,WindowAdapter是一個抽象類.
EventListener接口是一個空接口,WindowListener接口定義了一些公用的抽象方法,WindowAdapter是一個抽象類,但是里面沒有任何的抽象方法.
要深入理解抽象類和接口的區別.
抽象類可以不含有抽象方法的!!!
因為這樣有兩個好處.
1.不讓該類創建對象.
2.方便創建該接口的對象.
繼承我這個抽象類,選擇其中的一個方法去覆蓋就可以了
在其中直接用匿名內部類就可以了.用哪個覆蓋哪個.
給一個按鈕增加一個活動監聽.ActionListener
在Button類中有一個addActionListener(Listener l) 添加指定的動作偵聽器,以接收發自此按鈕的動作事件。
其中要傳入一個ActionListener對象.看一下這個ActionListener對象
這個ActionListener對象有N多實現類,但是卻不像WindowsLisntener一樣有一個對應的適配器類.因為這個ActionListener接口中只有一個方法.
這就是一種原則,規則性的問題.
只要監聽器中的方法超過兩個一般都有一個對應的適配器,但是這個ActionListener接口中只有一個方法.
監聽器中有兩個或者兩個以內方法的話沒有對應適配器類的,創建本身就很方便.
addActionListener(ActionListener l)方法參數傳遞的是接口型引用,ActionListener本身方法又不多(就只有一個方法,只要覆寫一個或者兩個就可以了),
方法參數中用匿名內部類就可以了,這樣表示看着更簡潔明了.
窗體監聽(WindowListener)和活動監聽(ActionListener)
下面附上代碼Demo
1 import java.awt.Button; 2 import java.awt.FlowLayout; 3 import java.awt.Frame; 4 import java.awt.event.ActionEvent; 5 import java.awt.event.ActionListener; 6 import java.awt.event.WindowAdapter; 7 import java.awt.event.WindowEvent; 8 9 public class FrameDemo { 10 public static void main(String[] args) { 11 12 Frame f = new Frame("my frame"); 13 f.setBounds(400, 200, 500, 400); 14 f.setLayout(new FlowLayout());//設置流式布局 15 16 Button but = new Button("一個按鈕"); 17 f.add(but);//將按鈕添加到窗體中。 18 19 f.addWindowListener(new WindowAdapter() { 20 @Override 21 public void windowClosing(WindowEvent e) { 22 //System.out.println("closing......."+e); 23 System.exit(0); 24 } 25 }); 26 //在按鈕上加上一個監聽。 點擊按鈕"一個按鈕"就關閉 27 but.addActionListener(new ActionListener() { 28 @Override 29 public void actionPerformed(ActionEvent e) { 30 //System.out.println("button run ....."); 31 System.exit(0); 32 } 33 }); 34 f.setVisible(true); 35 System.out.println("over"); 36 } 37 }
點擊"右上角的×"和"一個按鈕"都是關閉的效果.