設計自己的JavaBean(一)

聲明: 內容參考自Java核心卷卷II第8版

1. Why Beans?
可重用組件,可視化編程。

 

2. The Bean-Writing Process。
JavaBean 無需繼承某個類。你可以提供一些屬性供用戶修改,
也可以提供監聽事件供用戶處理。

 

3. Using Beans to Build an Application
你需要將的JavaBean打包成一個jar文件。首先你需要提供一個manifest文件來說明你的
JavaBean,形如:
Manifest-Version: 1.0

Name: com/horstmann/corejava/ImageViewerBean.class
Java-Bean: True

Name: com/horstmann/corejava/FileNameBean.class
Java-Bean: True

說明:
a、在Manifest-Version與第一個Name段之間必須有一個空行;
b、你通過Name來指定你的JavaBean類文件,通過Java-Bean: True來指定這是一個JavaBean;
c、在第二個JavaBean說明與第一個JavaBean說明之間也必須有一個空行;
d、該manifest文件必須以一個空行結束。

     
接下來通過Jar命令打包你的JavaBean:
jar cvfm ImageViewerBean.jar ImageViewerBean.mf com/horstmann/corejava/*.class。
接着,在NetBeans等IDE中,通過添加組件的方式來將你的JavaBean集成到可視化開發環境中,
你就可以通過拖拽的方式來使用的可視化JavaBean啦。

 

4. Naming Patterns for Bean Properties and Events。
a、public Type getPropertyName()
     public void setPropertyName(Type newValue)
   此時你的屬性名爲propertyName(將方法的get/set去掉,然後將第一個字母轉爲小寫)
b、public boolean isPropertyName()
     public void setPropertyName(boolean b)
   對於boolean類型的屬性,使用isPropertyName來替代getPropertyName;然而getPropertyName
   也可以,但是推薦使用isPropertyName。此時,屬性名也是propertyName。
c、如果方法去掉set/get後得到的“PropertyName”串的前兩個字母都是大寫格式的,則映射
   屬性名時,不將第一個字母轉爲小寫,而直接使用PropertyName。(如:getURL()
d、如果你的JavaBean中包含添加或刪除事件監聽器的方法,那麼Bean Builder將會認爲你的
   JavaBean會產生事件。該事件類必須以Event結尾且繼承EventObject類,如果該類不繼承
   EventObject類,在編譯時並不會報錯,因爲EventObject類並不是必須的,然而你的JavaBean
   將無法對事件做出響應。
public void addEventNameListener(EventNameListener e)
public void removeEventNameListener(EventNameListener e)
public EventNameListener[] getEventNameListeners()

 

5. Bean Property Types。
a、Simple Properties。(單值屬性)
提供如下方法來設置/獲取屬性值.
public void setFileName(String f)
{
 ...
}

public String getFileName()
{
 ...
}
b、Indexed Properties。(數組屬性)
提供如下方法來設置/獲取屬性值.
public String[] getExtensions() { return extensions; }
public void setExtensions(String[] newValue) { extensions = newValue; }
public String getExtensions(int i)
{
   if (0 <= i && i < extensions.length) return extensions[i];
   else return "";
}
public void setExtensions(int i, String newValue)
{
   if (0 <= i && i < extensions.length) extensions[i] = value;
}

private String[] extensions;
c、Bound Properties。(捆綁屬性)
捆綁屬性的兩個要求:
I. 如果屬性值變了,bean必鬚髮送一個PropertyChange事件給所有註冊的監聽者。
II.爲了使監聽者能夠註冊到bean,bean必須實現如下兩個方法:
void addPropertyChangeListener(PropertyChangeListener listener)
void removePropertyChangeListener(PropertyChangeListener listener)
同時建議也實現下面的這個方法:
PropertyChangeListener[] getPropertyChangeListeners()
但是,如果你的JavaBean直接或者間接地繼承自Component類,則不需要實現上述的方法。
你只需在屬性更改以後通過調用firePropertyChange("propertyName", oldValue, newValue);
即可,但是數組屬性更改通知是不受支持的。
如果你的類不是繼承自Component類,對於上述的add/remove/get三個方法的實現,你可以藉助於
java.beans包中的PropertyChangeSupport類來簡化實現過程,示例如下:
private PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);

public void addPropertyChangeListener(PropertyChangeListener listener)
{
   changeSupport.addPropertyChangeListener(listener);
}

public void removePropertyChangeListener(PropertyChangeListener listener)
{
   changeSupport.removePropertyChangeListener(listener);
}

public PropertyChangeListener[] getPropertyChangeListeners()
{
   return changeSupport.getPropertyChangeListeners();
}
對於數組屬性,你需要調用:
changeSupport.fireIndexedPropertyChange("propertyName", index, oldValue, newValue);
d、Constrained Properties(受限屬性)
受限屬性的更改必須在所有監聽者都沒有投否決票的情況下才能生效,否則值將不會改變。
對於一個受限屬性,你的JavaBean需要提供以下兩個方法:
public void addVetoableChangeListener(VetoableChangeListener listener);
public void removeVetoableChangeListener(VetoableChangeListener listener);
同時建議提供另外一個方法:
public VetoableChangeListener[] getVetoableChangeListeners();
你可以像捆綁屬性一樣藉助於VetoableChangeSupport來實現上面的方法:
private VetoableChangeSupport vetoSupport = new VetoableChangeSupport(this);

public void addVetoableChangeListener(VetoableChangeListener listener)
{
   vetoSupport.addVetoableChangeListener(listener);
}
public void removeVetoableChangeListener(VetoableChangeListener listener)
{
   vetoSupport.removeVetoableChangeListener(listener);
}
爲了更新一個受限屬性的值,你需要參考如下步驟:
I. 通知所有的Vetoable Change Listeners來intent to(個人理解是檢測該屬性的新值是否合法
改變該屬性的值,通過如下方法:
vetoSupport.fireVetoableChange("value",oldValue,newValue);
II.如果所有的Vetoable Change Listeners都沒有拋出PropertyVetoException,那就更新該屬性
的值。
III.通知註冊到屬性的Property Change Listener。
示例實現如下:
public void setValue(Type newValue) throws PropertyVetoException
{
   Type oldValue = getValue();
   vetoSupport.fireVetoableChange("value", oldValue, newValue);
   // survived, therefore no veto
   value = newValue;
   changeSupport.firePropertyChange("value", oldValue, newValue);
}
如果你的JavaBean直接或間接地繼承自JComponet,則你可以不必藉助於VetoableChangeSupport
類,而可以直接使用JComponent類提供的同名方法。
注意:你不可以爲一個直接或間接繼承自JComponent類的JavaBean的單獨的某個屬性註冊
Vetoable Change Listener,你需要在一個方法中監聽所有的vetoable changes。

 

未完待續...

 

 

     

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章