Java讀書筆記12 事件處理基礎 Observer設計模式


本文主要內容:事件處理的基礎概念,基本流程,還有一個簡單的按鈕事件例子(《Core Java》書中例子)。

1.事件處理基礎知識

  JDK 1.1開始,Java的事件處理采用事件委托(代理)模型(event delegation)。

  在這個模型中,比較重要的幾個概念如下:

  (也可以看完第二部分的事件處理過程之后再來看這些概念,或許思路明朗一些)。

  1.事件源(event source

    事件源是一個能夠注冊監聽器對象並發送事件對象的對象。例如按鈕或者滾動條就是事件源。

  2.事件,事件類型和事件對象

    事件一般是用戶在界面上的一個操作,當一個事件發生時,該事件用一個事件對象來表示,事件對象有對應的事件類

    不同的事件類描述不同類型的用戶動作,不同的事件源可以產生不同類別的事件。例如,按鈕可以發送ActionEvent對象,而窗口可以發送WindowEvent對象。

    在Java中,所有的事件對象都最終派生於java.util.EventObject類。

  3.事件監聽器(event listener

    監聽器對象是一個實現了特定監聽器接口(listener interface)的類的實例。

    事件監聽器類監聽器對象所屬的類必須實現事件監聽器接口或繼承事件監聽器適配器類。

    事件監聽器接口定義了處理事件必須實現的方法。

    事件監聽器適配器類是對事件監聽器接口的簡單實現。目的是為了減少編程的工作量。

    處理事件的方法被稱為事件處理器,即事件監聽器接口定義,並在事件監聽器類中實現的方法。

  4.注冊事件監聽器

    為了能夠讓事件監聽器檢查某個組件(事件源)是否發生了某些事件,並且在發生時激活事件處理器進行相應的處理,必須在事件源上注冊事件監聽器。

    這是通過使用事件源組件的以下方法來完成的:

    addXxxListener(事件監聽器對象)

    Xxx對應相應的事件類。

  5.再論事件和監聽器

    每一類事件有一個相應的事件監聽器接口,該接口定義了接收和處理事件的抽象方法。實現該接口的類,就是監聽器類。其對象可作為監聽器對象向相應的組件注冊。

    事件的類名通常為:XxxEvent

    對應的事件監聽器接口名通常為:XxxListener

    一個監聽器接口定義了一種以上的抽象事件處理方法(事件處理器)。

    事件監聽器類實現事件監聽器接口,其類名可以由我們自己取。事件監聽器類需要我們自己編寫。

2.事件處理過程

  在這個event delegation模型中,事件源產生事件對象,然后將其發送給所有注冊的的事件監聽器對象,監聽器對象利用事件對象中的信息決定如何對事件做出響應。

  從網上找的ppt中的一個圖:

              2012-9-8 星期六 10-35-17

3.實例:處理按鈕點擊事件

  為了加深理解,以一個簡單的例子來說明(《Core Java》書中例子)。

  這個例子中:在一個面板中放置三個按鈕,添加三個監聽器對象用來作為按鈕的動作監聽器。

  在這個情況下,只要用戶點擊面板上的任何一個按鈕,相關的監聽器對象就會接收到一個ActionEvent對象,它表示有個按鈕被點擊了。在示例程序中,監聽器對象將改變面板的背景顏色。

  具體流程如下:

  1.創建按鈕JButton,將按鈕添加到面板中(在面板中調用add方法);

  2.需要一個實現了ActionListerner接口的類(事件監聽器類),它應該包含一個actionPerformed方法,其簽名為:

public void actionPerformed(ActionEvent event);

 

  當按鈕被點擊時,我們希望將面板的背景顏色設置為指定的顏色。該顏色存儲在監聽器類中。

  3.為每種顏色構造一個監聽器對象,將這些對象設置為按鈕監聽器,即,調用按鈕的addActionListener方法注冊監聽器。

  代碼如下:

例8-1 ButtonTest
/**
   @version 1.32 2004-05-04
   @author Cay Horstmann
*/

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ButtonTest
{  
   public static void main(String[] args)
   {  
      ButtonFrame frame = new ButtonFrame();
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setVisible(true);
   }
}

/**
   A frame with a button panel
*/
class ButtonFrame extends JFrame
{
   public ButtonFrame()
   {
      setTitle("ButtonTest");
      setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);

      // add panel to frame

      ButtonPanel panel = new ButtonPanel();
      add(panel);
   }

   public static final int DEFAULT_WIDTH = 300;
   public static final int DEFAULT_HEIGHT = 200;  
}

/**
   A panel with three buttons.
*/
class ButtonPanel extends JPanel
{  
   public ButtonPanel()
   {  
      // create buttons

      JButton yellowButton = new JButton("Yellow");
      JButton blueButton = new JButton("Blue");
      JButton redButton = new JButton("Red");

      // add buttons to panel

      add(yellowButton);
      add(blueButton);
      add(redButton);

      // create button actions

      ColorAction yellowAction = new ColorAction(Color.YELLOW);
      ColorAction blueAction = new ColorAction(Color.BLUE);
      ColorAction redAction = new ColorAction(Color.RED);

      // associate actions with buttons

      yellowButton.addActionListener(yellowAction);
      blueButton.addActionListener(blueAction);
      redButton.addActionListener(redAction);
   }

   /**
      An action listener that sets the panel's background color. 
   */
   private class ColorAction implements ActionListener
   {  
      public ColorAction(Color c)
      {  
         backgroundColor = c;
      }

      public void actionPerformed(ActionEvent event)
      {  
         setBackground(backgroundColor);
      }

      private Color backgroundColor;
   }
}

 

  例如,如果有一個用戶在標有“Yellow”的按鈕上點擊了一下,那么yellowAction對象的actionPerformed方法就會被調用。這個對象的backgroudColor實例域設置為Color.YELLOW,然后就將面板的顏色設置為黃色了。

  有一個需要考慮的問題,是ColorAction對象(監聽器對象)沒有權限訪問panel變量。可以采用兩種方式解決這個問題:

    1.將面板存儲在ColorAction對象中,並在ColorAction構造器中設置它;

    2.將ColorAction作為ButtonPanel類的內部類。這樣一來,ColorAction就自動地擁有訪問外部類的權限了。

  這里使用的就是第二種方法,ColorAction類中調用過了外部類ButtonPanel中的setBackground方法。這種情形十分常見,事件監聽器對象通常需要執行一些對其他對象可能產生影響的操作,可以策略性地將監聽器類放置在需要修改狀態的那個類中。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM