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());
}
}
本文出自 “子 孑” 博客,請 務必保留此出處
http://zhangjunhd.blog.51cto.com/113473/36838
附件下載:
MyBoundBean.java: http://zhangjunhd.blog.51cto.com/attachment/200708/113473_ 1186136107.txt
MyCallBound1.java: http://zhangjunhd.blog.51cto.com/attachment/200708/113473_ 1186136117.txt
MyCallBound2.java: http://zhangjunhd.blog.51cto.com/attachment/200708/113473_ 1186136132.txt