Bean中PropertyChangeSupport的使用

JavaBean的属性与一般Java程序中所指的属性,或者说与所有面向对象的程序设计语言中对象的属性是一个概念,在程序中的具体体现就是类中的变量。在JavaBean的设计中,按照属性的不同作用又细分为四类:单值属性;索引属性;关联属性;限制属性。

本文主要介绍如何使用PropertyChangeSupport类来支持关联属性事件的触发。

1.关联属性

关联属性,也称之为绑定属性。绑定属性会在属性值发生变化时,通知所有相关的监听器。为了实现一个绑定属性,必须实现两个机制。

1) 无论何时,只要属性的值发生变化,该bean必须发送一个PropertyChange事件给所有已注册的监听器。该变化可能发生在调用set方法时,或者程序的用户做出某种动作时。

2) 为了使感兴趣的监听器能够进行注册,bean必须实现以下两个方法:

void addPropertyChangeListener(PropertyChangeListener listener);

void removePropertyChangeListener(PropertyChangeListener listener);

2.使用PropertyChangeSupport管理监听器

可以通过java.bean包下的PropertyChangeSupport类来管理监听器。要使用这个类,bean必须有一个此类的数据域。

private PropertyChangeSupport changes = new PropertyChangeSupport(this);

这样就可以将添加和移除监听器的任务交给这个对象。

public void addPropertyChangeListener(PropertyChangeListener listener) {

changes.addPropertyChangeListener(listener);

}

public void removePropertyChangeListener(PropertyChangeListener listener) {

changes.removePropertyChangeListener(listener);

}

当bean的属性发生变化时,使用PropertyChangeSupport对象的firePropertyChange方法,它会将一个事件发送给所有已经注册的监听器。该方法有三个参数:属性的名字、旧的值以及新的值。属性的值必须是对象,如果是简单数据类型,则必须进行包装。

changes.firePropertyChange("ourString", oldString, newString);

所有注册的监听器实现PropertyChangeListener接口,该接口中只有一个方法。

public void propertyChange(PropertyChangeEvent e);

当bean的属性值发生变化时,该方法中的代码就会被触发。可以通过

e.getOldValue();

e.getNewValue();

来得到changes.firePropertyChange("ourString", oldString, newString);中的oldString和newString。

3.为什么要使用PropertyChangeSupport

使用这个类管理监听器的好处是,它是线程安全的。如果使用一个循环体来set Bean的属性,则这个类可以保证所有监听器执行触发事件的有序。

还有一个好处是,这个类支持fire带索引的属性改变事件(详见java.bean.IndexedPropertyChangeEvent)。此时向注册的监听器发送一个PropertyChangeEvent的方法为:

void fireIndexedPropertyChange(String PropertyName,int index,Object oldValue,Object newValue);

 

4.示例

MyBoundBean类(具体代码见附件)是一个JavaBean,我们关注它的唯一一个属性ourString的变化情况,它的初始值是Hello。并通过PropertyChange类来管理监听器。注意在set方法中会调用firePropertyChange方法。

MyBoundBean.java

import java.beans.PropertyChangeListener;

import java.beans.PropertyChangeSupport;

public class MyBoundBean {

String ourString = "Hello";

private PropertyChangeSupport changes = new PropertyChangeSupport(this);

public void setString(String newString) {

String oldString = ourString;

ourString = newString;

changes.firePropertyChange("ourString", oldString, newString);

}

public String getString() {

return ourString;

}

public void addPropertyChangeListener(PropertyChangeListener listener) {

changes.addPropertyChangeListener(listener);

}

public void removePropertyChangeListener(PropertyChangeListener listener) {

changes.removePropertyChangeListener(listener);

}

}

 

MyCallBound1类(具体代码见附件)是它的一个监听器。整个动作是这样的,点击jButton1或jButton2会触发Button的action事件,将jButton1的test设置为文本框中的内容,同时,目标bean的ourString属性的内容也会设置为文本框中的内容。

MyBoundBean b = new MyBoundBean();

public void actionPerformed(ActionEvent e) {

jButton1.setText(textBox.getText());

b.setString(textBox.getText());

}

目标bean的属性一改变(注意,初始值是"Hello"),将会触发propertyChange方法的执行。将文本框的内容设置为目标bean的ourString属性的旧值,同时,将jButton2的test设置成目标bean的ourString属性的新值。

public void propertyChange(PropertyChangeEvent e) {

if (e.getSource() == b) {

textBox.setText(e.getOldValue().toString());

jButton2.setText(e.getNewValue().toString());

}

}

如果不实现PropertyChangeListener接口的话,可以使用匿名内部类来达到同样的效果。(具体代码见附件MyCallBound2.java)

MyBoundBean b = new MyBoundBean();

b.addPropertyChangeListener(new PropertyChangeListener() {

public void propertyChange(PropertyChangeEvent e) {

// 这样一来,我们就可以用自己定义的名字实现事件

ourString_propertyChange(e);

}

});

这样一来,我们就可以用自己定义的名字实现事件。

void ourString_propertyChange(PropertyChangeEvent e) {

if (e.getSource() == b) {

textBox.setText(e.getOldValue().toString());

jButton2.setText(e.getNewValue().toString());

}

}

5.参考资料

[1]Core Java2,VolumeⅡ-Advanced Features

[2]R.J. Lorimer, Beans: Use PropertyChangeSupport When Supporting PropertyChangeListeners,

http://www.javalobby.org/java/forums/t19476.html

[3] JavaBean编程, http://feelingsea.blog.hexun.com/7293978_d.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java的监听器是一种设计模式,它允许对象在其状态发生改变时通知其他对象。监听器通常用于GUI应用程序,以响应用户的操作并执行相应的操作。 Java的监听器分为三种类型: 1. 事件监听器(Event Listeners):用于处理和响应事件,例如按钮点击或鼠标移动等。 2. 属性监听器(Property Listeners):用于监视对象属性的更改,并在发生更改时通知其他对象。 3. 容器监听器(Container Listeners):用于监视容器组件(例如面板或窗口)的更改,并在更改发生时通知其他对象。 下面是一个简单的Java代码示例,它演示了如何使用事件监听器: ``` import java.awt.*; import java.awt.event.*; public class MyFrame extends Frame implements ActionListener { Button btn; public MyFrame() { super("My Frame"); btn = new Button("Click Me!"); btn.addActionListener(this); add(btn); setSize(300, 300); setVisible(true); } public void actionPerformed(ActionEvent e) { if (e.getSource() == btn) { System.out.println("Button Clicked!"); } } public static void main(String[] args) { new MyFrame(); } } ``` 在这个例子,我们创建了一个按钮并添加了一个`ActionListener`,当按钮被点击时,`actionPerformed()`方法将被调用并打印一条消息。 使用属性监听器的示例代码如下: ``` import java.beans.*; public class MyBean { private String name; private PropertyChangeSupport pcs = new PropertyChangeSupport(this); public void setName(String newName) { String oldName = name; name = newName; pcs.firePropertyChange("name", oldName, newName); } public String getName() { return name; } public void addPropertyChangeListener(PropertyChangeListener listener) { pcs.addPropertyChangeListener(listener); } public void removePropertyChangeListener(PropertyChangeListener listener) { pcs.removePropertyChangeListener(listener); } } ``` 在这个例子,我们创建了一个`MyBean`类,它具有一个`name`属性。当属性更改时,我们使用`PropertyChangeSupport`类通知所有已注册的属性监听器。 最后,以下是一个容器监听器的示例代码: ``` import java.awt.*; import java.awt.event.*; public class MyFrame extends Frame implements ComponentListener { public MyFrame() { super("My Frame"); addComponentListener(this); setSize(300, 300); setVisible(true); } public void componentResized(ComponentEvent e) { System.out.println("Frame Resized!"); } public void componentMoved(ComponentEvent e) { System.out.println("Frame Moved!"); } public void componentShown(ComponentEvent e) { System.out.println("Frame Shown!"); } public void componentHidden(ComponentEvent e) { System.out.println("Frame Hidden!"); } public static void main(String[] args) { new MyFrame(); } } ``` 在这个例子,我们创建了一个`MyFrame`类,并添加了一个`ComponentListener`来监听组件事件。当窗口调整大小、移动、显示或隐藏时,`componentResized()`、`componentMoved()`、`componentShown()`或`componentHidden()`方法将被调用并打印一条消息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值