有关编写 Visual Editor 的 BeanInfo 类的技巧

本节描述在编写要在 Visual Editor for Java 中使用的 Java bean 的 BeanInfo 类时您可以使用的一些规则。

Visual Editor for Java 使用 BeanInfo 类中描述的属性描述符来建立“属性”视图中的条目列表以及确定编辑这些条目的方式。

如果隐藏了 java.beans.PropertyDescriptor,则它在“属性”查看器中将不可用。但是,代码生成器仍将解析已隐藏属性的 set 方法,并且将把其应用到活动 bean。

当属性隐藏时,代码解析仍将使用它,但是它不会包括在任何其它 Visual Editor 视图或功能部件中。VisualAge for Java 允许将属性从“属性”视图中排除,但是该属性对于其它功能仍旧可用。例如,通过使其设计时为 false 来建立连接。尽管 Visual Editor for 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,或找到了针对该属性类型的 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 和 WEST 的引用。可按如下所示编写属性描述符:

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 等价对象

Bean Info 事件

显示在 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.