Swing組件集合的事件處理(三) – JAVA編程語言程序開發技術文章

2.2.2 使用屬性變化監聽器作為觀察者
除瞭基本的事件委托機制以外,JavaBean引入另一種觀察者設計模式的變體,這次是通過屬性變化監聽器。PropertyChangeListener實現是觀察者模式的確切表示。每一個觀察者觀察Subject的一個屬性的變化。當Subject中發生變化時,觀察者會被通知新的狀態。圖2-4顯示瞭與JavaBean庫中用於屬性變化處理的特定類相關的觀察者模式結構。在這種情況下,可觀察的Subject具有一個add/remove屬性變化監聽器方法集合以及一個狀態被監視的屬性。


 swing_2_4


使用PropertyChangeListener,註冊的監聽器集合是在PropertyChangeSupport類中進行管理的。當監視的屬性值變化時,這個支持類會通知所有的註冊監聽器新的以及舊的屬性狀態值。


通過向支持這種監聽器類型的各種組件註冊PropertyChangleListener對象,我們可以減少在初始化監聽設置之後必須生成的代碼量。例如,綁定Swing組件的背景顏色,意味著可以向組件註冊一個PropertyChangeListener,當背景設置發生變化時就可以得到通知。當組件的背景屬性值發生變化時,監聽者就可以得到通知,從而可以使得觀察者將其背景顏色設置為一個新的設置。所以,如果我們希望我們程序中的所有組件具有相同的背景顏色,我們可以將他們註冊到一個組件。然後,當那個組件改變其背景顏色時,所有其他的組件都會被通知這種改變,並修改其背景為新的設置。


列表2-3中的程序演示瞭PropertyChangeListener的使用。他創建瞭兩個按鈕。當任意一個被選中時,被選中按鈕的背景就會修改為一個隨機的顏色值。第二個按鈕監聽第一個按鈕的屬性變化。當第一個按鈕的背景顏色變化時,第二個按鈕的背景顏色也會修改為新值。第一個按鈕並沒有監聽第二個按鈕的屬性變化,所以當第二個按鈕被選中並改變及背景顏色時,這種變化並不會傳播到第一個按鈕。


/**
 *
 */
package swingstudy.ch02;
 
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Random;
 
import javax.swing.JButton;
import javax.swing.JFrame;
 
/**
 * @author lenovo
 *
 */
public class ButtonSample3 {
 
 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
 
  Runnable runner = new Runnable() {
   public void run() {
    JFrame frame = new JFrame(“Button Sample”);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
    final JButton button1 = new JButton(“Select Me”);
    final JButton button2 = new JButton(“No Select Me”);
 
    final Random random = new Random();
 
    ActionListener actionListener = new ActionListener(){
     public void actionPerformed(ActionEvent event) {
      JButton button = (JButton)event.getSource();
      int red = random.nextInt(255);
      int green = random.nextInt(255);
      int blue = random.nextInt(255);
      button.setBackground(new Color(red, green, blue));
     }
    };
 
    PropertyChangeListener propertyChangeListener = new PropertyChangeListener() {
     public void propertyChange(PropertyChangeEvent event) {
      String property = event.getPropertyName();
      if(“background”.equals(property)) {
       button2.setBackground((Color)event.getNewValue());
      }
     }
    };
 
    button1.addActionListener(actionListener);
    button1.addPropertyChangeListener(propertyChangeListener);
    button2.addActionListener(actionListener);
 
    frame.add(button1, BorderLayout.NORTH);
    frame.add(button2, BorderLayout.SOUTH);
    frame.setSize(300, 100);
    frame.setVisible(true);
   }
  };
 
  EventQueue.invokeLater(runner);
 }
 
}盡管這個例子隻是實現瞭按鈕選中中的一個顏色變化,想像一下,如果第一個按鈕的背景顏色是由上百個不同位置變化的,而不是一個動作監聽器。如果沒有屬性變化監聽器,這些位置中的每一個都需要改變第二個按鈕的背景顏色。借助於屬性變化監聽器,他隻需要修改基本對象的背景顏色--在這種情況下是第一個按鈕。然後這種變化會自動傳播到其他的組件。


Swing庫同時也會使用ChangeEvent/ChangeListener對來表示狀態變化。盡管其與PropertyChangeEvent/PropertyChangeListener對相類似,但是ChangeEvent並不會帶有新的以及舊的數據值設置。我們可以將其看作是屬性變化監聽器的一個輕量級版本。當多個屬性值發生變化時ChangeEvent會非常有用,因為ChangeEvent並不需要包裝變化。


 

發佈留言