撰寫視覺化編輯器的 BeanInfo 類別的要訣

本節將說明當您撰寫要在 Java 視覺化編輯器中使用之 Java Bean 的 BeanInfo 類別時,可以使用的一些規則。

Java 視覺化編輯器會使用 BeanInfo 類別中說明的內容描述子, 在「內容」視圖中建立項目清單,以及設定編輯它們的方式。

如果 java.beans.PropertyDescriptor 隱藏起來,就不能在「內容」檢視器中使用。但是,隱藏內容的 set 方法仍然會由程式碼產生器剖析,並套用到即時 Bean 中。

當內容隱藏時,程式碼剖析作業還是會使用它,但是不會將它包含在其他視覺化編輯器視圖或特性中。VisualAge Age for Java 可讓您從「內容」視圖中將內容排除,但排除的內容還是可以供其他功能使用。 例如,將連線的設計時期設為 false 來建立連線。雖然 Java 視覺化編輯器沒有連線功能,但是它還是保有設計時期內容的概念。如果要將內容的設計時期設為 false,就應該以 ivjDesignTimeProperty 索引鍵以及 Boolean.FALSE 值來設定屬性值。

比方說,如果您為具有 name 內容(來自 public void setName(String) 和 public String getName() 方法組合)的類別 MyJavaBean,撰寫了 BeanInfo 類別, 則 getPropertyDescriptors() 方法可撰寫如下:

public PropertyDescriptor[] getPropertyDescriptors() { 
    PropertyDescriptor[] result = new PropertyDescriptor[1]; 
    try{ 
        PropertyDescriptor directionDescriptor = new
PropertyDescriptor("direction",MyJavaBean.class); 
        directionDescriptor.setValue("enumerationValues",new
Object[]{ 
            "North",new
Integer(myclasses.CompassPoint.NORTH),"myclasses.CompassPoint.NORTH",

            "East",new
Integer(myclasses.CompassPoint.EAST),"myclasses.CompassPoint.EAST",

            "South",new
Integer(myclasses.CompassPoint.SOUTH),"myclasses.CompassPoint.SOUTH",

            "West",new
Integer(myclasses.CompassPoint.WEST),"myclasses.CompassPoint.WEST" 
        }); 
        result[0] = directionDescriptor; 
    } catch ( IntrospectionError exc ) { 
    } 
    return result;
}

當您在「內容」視圖中選取某個內容時,「值」直欄便會建立一個編輯器,讓您指定一個新值。 如果要計算編輯器以尋找內容,系統會查詢 java.beans.PropertyDescriptor,看看它是否具備內容編輯器。 如果找到相關聯的內容編輯器,則採用它。否則就會找出一個定義要使用內容類型的編輯器。 您不能改變某一類型預先定義之內容編輯器的清單。如果在內容描述子中或是針對內容的類型找到 java.beans.PropertyEditor, 「內容」視圖便會試圖判定要建立哪一種編輯器。 所使用的規則如下:

  1. 如果方法 public boolean supportsCustomEdit() 傳回 true,則會建立對話編輯器。對話框按鈕會啟動從方法 public Component getCustomEditor() 傳回的編輯器。傳回的編輯器應該是 java.awt.Component 的子類別,它會利用 Frame 或 JFrame(視需要而定)中的確定取消按鈕來控管。
  2. 如果方法 public String[] getTags() 傳回字串陣列,它們會顯示在清單中。以內容值呼叫 public void setValue(Object), 然後再呼叫 public String getAsText(), 來判斷所要使用的「字串」,會產生「內容」視圖中現有值所用的標籤。當您選取清單中的新值時,會呼叫編輯器的方法 public void setAsText(String), 並且利用 public Object getValue() 擷取新的內容值。
  3. 如果上述兩個方法都未傳回自訂編輯器或標示,內容表便會建立文字欄位編輯器。最初顯示的文字值, 是呼叫 public void setValue(Object)public String getAsText() 的結果。當您在文字編輯器中輸入新字串時,系統會針對每個按鍵呼叫 public void setAsText(String) 方法。如果方法擲出 java.lang.IllegalArgumentException,則狀態列中會顯示異常狀況訊息,且不會套用這個值。如果沒有擲出異常狀況, 則當您在文字編輯器中按一下 Enter 鍵時(或是「內容」視圖中的另一個內容成為作用中時),呼叫 public Object getValue() 所產生的結果,會被當作引數,傳送到內容描述子中所描述的 set 方法。

針對每一個 java.beans.PropertyEditor,方法 public String getJavaInitializationString() 也必須要特殊化。這會傳回 Java 程式碼中使用的字串,作為內容描述子之 set 方法的引數。這個字串應該傳回值, 且該字串所參照的任何類型都應該是完整的,同時不是取決於要編製之類別中的任何 import 陳述式。 如果您的 BeanInfo 會將範本 JRE 類別 java.beans.SimpleBeanInfo 特殊化, 則該方法不是抽象的,且會被繼承而傳回 "???"。因此您一定要記得將它正確地特殊化。

除了對內容描述子利用 public String[] getTags() 方法來取得清單之外, 還有一種較簡單的方法可用來指定值的清單。這個方法是利用 enumerationValues 索引鍵、一個值(該值是清單中 displayName 三個項目的陣列)、值的本身以及 initializationString,來建立一個屬性值。比方說, 假設一個名為 direction 的內容,其類型為 int,且可指定 0、1、2 和 3 作為其值。 這些值實際上會參照到類別 myclasses.CompassPoint 上的靜態欄位 NORTH、EAST、SOUTH其內容描述子可以撰寫如下:

public PropertyDescriptor[] getPropertyDescriptors() {
    PropertyDescriptor[] result = new PropertyDescriptor[1];
    try{
        PropertyDescriptor directionDescriptor
= new PropertyDescriptor("direction",MyJavaBean.class);
        directionDescriptor.setValue("enumerationValues",new
Object[]{
           
"North",new
Integer(myclasses.CompassPoint.NORTH),"myclasses.CompassPoint.NORTH",
           
"East",new
Integer(myclasses.CompassPoint.EAST),"myclasses.CompassPoint.EAST",
           
"South",new
Integer(myclasses.CompassPoint.SOUTH),"myclasses.CompassPoint.SOUTH",
           
"West",new
Integer(myclasses.CompassPoint.WEST),"myclasses.CompassPoint.WEST"
        });
        result[0] = directionDescriptor;
    } catch ( IntrospectionError exc ) {
    }
    return result;
}

每一個項目中的第二個值本身都不是 int 靜態欄位(如 myclasses.CompoassPoint.NORTH),而是 java.lang.Integer 的實例。這是因為初始類型不能放進類型為 Object 的陣列中,因此必須使用其 java.lang equivalent 來取代。

BeanInfo 事件

Java Bean 所顯示的事件清單,是其事件描述子的偏好方法描述子。

如果有配接器類別可用,它會被當作含有 "eventAdapterClass" 索引鍵的具名屬性加入 java.beans.EventDescriptor 中,比方說,

EventSetDescriptor focusEventSetDescriptor = new EventSetDescriptor(  
  java.awt.Component.class,  
  "focus",  
  java.awt.event.FocusListener.class,  
  new String[] { "focusGained(java.awt.event.FocusEvent)", "focusLost(java.awt.event.FocusEvent)" },  
  "addFocusListener(java.awt.event.FocusListener)",
  "removeFocusListener(java.awt.event.FocusListener"
);
focusEventSetDescriptor.setValue("eventAdapterClass", "java.awt.event.FocusAdapter");

母主題: BeanInfo 類別和內部檢查

相關作業
控制外掛程式開發人員的 BeanInfo 資訊
指定 BeanInfo 類別的位置

(C) Copyright IBM Corporation 1999, 2004. All Rights Reserved.