Chinaunix首页 | 论坛 | 博客
  • 博客访问: 891360
  • 博文数量: 96
  • 博客积分: 10681
  • 博客等级: 上将
  • 技术积分: 2449
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-16 17:52
文章分类

全部博文(96)

文章存档

2011年(30)

2009年(36)

2008年(30)

分类: Java

2011-02-23 22:10:07

2.2.2 使用属性变化监听器作为观察者

除了基本的事件委托机制以外,JavaBean引入另一种观察者设计模式的变体,这次是通过属性变化监听器。PropertyChangeListener实现是观察者模式的确切表示。每一个观察者观察Subject的一个属性的变化。当Subject中发生变化时,观察者会被通知新的状态。图2-4显示了与JavaBean库中用于属性变化处理的特定类相关的观察者模式结构。在这种情况下,可观察的Subject具有一个add/remove属性变化监听器方法集合以及一个状态被监视的属性。

swing_2_4

使用PropertyChangeListener,注册的监听器集合是在PropertyChangeSupport类中进行管理的。当监视的属性值变化时,这个支持类会通知所有的注册监听器新的以及旧的属性状态值。

通过向支持这种监听器类型的各种组件注册PropertyChangleListener对象,我们可以减少在初始化监听设置之后必须生成的代码量。例如,绑定Swing组件的背景颜色,意味着可以向组件注册一个PropertyChangeListener,当背景设置发生变化时就可以得到通知。当组件的背景属性值发生变化时,监听者就可以得到通知,从而可以使得观察者将其背景颜色设置为一个新的设置。所以,如果我们希望我们程序中的所有组件具有相同的背景颜色,我们可以将他们注册到一个组件。然后,当那个组件改变其背景颜色时,所有其他的组件都会被通知这种改变,并修改其背景为新的设置。

列表2-3中的程序演示了PropertyChangeListener的使用。他创建了两个按钮。当任意一个被选中时,被选中按钮的背景就会修改为一个随机的颜色值。第二个按钮监听第一个按钮的属性变化。当第一个按钮的背景颜色变化时,第二个按钮的背景颜色也会修改为新值。第一个按钮并没有监听第二个按钮的属性变化,所以当第二个按钮被选中并改变及背景颜色时,这种变化并不会传播到第一个按钮。

  1. /**
  2.  *
  3.  */
  4. package swingstudy.ch02;
  5.  
  6. import java.awt.BorderLayout;
  7. import java.awt.Color;
  8. import java.awt.EventQueue;
  9. import java.awt.event.ActionEvent;
  10. import java.awt.event.ActionListener;
  11. import java.beans.PropertyChangeEvent;
  12. import java.beans.PropertyChangeListener;
  13. import java.util.Random;
  14.  
  15. import javax.swing.JButton;
  16. import javax.swing.JFrame;
  17.  
  18. /**
  19.  * @author lenovo
  20.  *
  21.  */
  22. public class ButtonSample3 {
  23.  
  24.     /**
  25.      * @param args
  26.      */
  27.     public static void main(String[] args) {
  28.         // TODO Auto-generated method stub
  29.  
  30.         Runnable runner = new Runnable() {
  31.             public void run() {
  32.                 JFrame frame = new JFrame("Button Sample");
  33.                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  34.  
  35.                 final JButton button1 = new JButton("Select Me");
  36.                 final JButton button2 = new JButton("No Select Me");
  37.  
  38.                 final Random random = new Random();
  39.  
  40.                 ActionListener actionListener = new ActionListener(){
  41.                     public void actionPerformed(ActionEvent event) {
  42.                         JButton button = (JButton)event.getSource();
  43.                         int red = random.nextInt(255);
  44.                         int green = random.nextInt(255);
  45.                         int blue = random.nextInt(255);
  46.                         button.setBackground(new Color(red, green, blue));
  47.                     }
  48.                 };
  49.  
  50.                 PropertyChangeListener propertyChangeListener = new PropertyChangeListener() {
  51.                     public void propertyChange(PropertyChangeEvent event) {
  52.                         String property = event.getPropertyName();
  53.                         if("background".equals(property)) {
  54.                             button2.setBackground((Color)event.getNewValue());
  55.                         }
  56.                     }
  57.                 };
  58.  
  59.                 button1.addActionListener(actionListener);
  60.                 button1.addPropertyChangeListener(propertyChangeListener);
  61.                 button2.addActionListener(actionListener);
  62.  
  63.                 frame.add(button1, BorderLayout.NORTH);
  64.                 frame.add(button2, BorderLayout.SOUTH);
  65.                 frame.setSize(300, 100);
  66.                 frame.setVisible(true);
  67.             }
  68.         };
  69.  
  70.         EventQueue.invokeLater(runner);
  71.     }
  72.  
  73. }

尽管这个例子只是实现了按钮选中中的一个颜色变化,想像一下,如果第一个按钮的背景颜色是由上百个不同位置变化的,而不是一个动作监听器。如果没有属性变化监听器,这些位置中的每一个都需要改变第二个按钮的背景颜色。借助于属性变化监听器,他只需要修改基本对象的背景颜色--在这种情况下是第一个按钮。然后这种变化会自动传播到其他的组件。

Swing库同时也会使用ChangeEvent/ChangeListener对来表示状态变化。尽管其与PropertyChangeEvent/PropertyChangeListener对相类似,但是ChangeEvent并不会带有新的以及旧的数据值设置。我们可以将其看作是属性变化监听器的一个轻量级版本。当多个属性值发生变化时ChangeEvent会非常有用,因为ChangeEvent并不需要包装变化。


 
阅读(916) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~