Советы по написанию классов BeanInfo для визуального редактора

В данном разделе приведены некоторые правила, которых можно придерживаться при написании класса BeanInfo для объекта JavaBean, предназначенного для использования в визуальном редакторе для Java.

Для создания списка записей в панели свойств, а также способов их редактирования визуальный редактор для Java использует дескрипторы свойств, описанные в классе BeanInfo.

Если дескриптор java.beans.PropertyDescriptor скрытый, то он недоступен для программы просмотра свойств. Впрочем, методы set скрытых свойств будут анализироваться генератором кода и применяться к активным объектам.

Скрытое свойство используется при анализе кода, но его нет в панелях или комплектах визуального редактора для Java. VisualAge for Java позволял исключать свойство из панели свойств, но оно оставалось при этом доступным для других функций. Например, для установки соединений путем присвоения этапу проектирования значения false. Хотя визуальный редактор для Java не способен самостоятельно устанавливать соединения, в нем также используется концепция свойств этапа проектирования. Для того чтобы задать значение false свойству этапа проектирования, нужно задать значение атрибута с помощью ключа ivjDesignTimeProperty и значения Boolean.FALSE. 

Например, если класс BeanInfo записывается в класс MyJavaBean, у которого есть свойство name (состоящее из пары методов public void setName(String) и public String getName()), то метод getPropertyDescriptors() может выглядеть следующим образом:

public PropertyDescriptor[] getPropertyDescriptors() {
    PropertyDescriptor[] result = new PropertyDescriptor[1];
    try{
        PropertyDescriptor directionDescriptor = new
PropertyDescriptor("direction",MyJavaBean.class);
        directionDescriptor.setValue("enumerationValues",new
Obj            "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;
 

При выборе свойства в панели свойств создается редактор в столбце значений, где вы можете указать новое значение. Для того чтобы вычислить редактор для свойства, в java.beans.PropertyDescriptor запрашивается редактор свойств. Если найден связанный редактор свойств, то используется именно он. В противном случае находится редактор, указанный для работы с данным типом свойств. Вы не можете изменять список заранее определенных редакторов свойств данного типа. Если java.beans.PropertyEditor найден в дескрипторе свойств или в типе свойств, то панель Свойства попытается определить тип создаваемого редактора. Ниже приведены применяемые правила:

  1. Если метод public boolean supportsCustomEdit() возвращает значение true, то создается редактор окон. Редактор, возвращенный внешним компонентом метода getCustomEditor(), запускается соответствующей кнопкой. Редактор должен быть производным классом java.awt.Component и в случае необходимости будет управляться кнопками OK и Отмена в 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() отправляется в качестве аргумента заданного метода, который описан в дескрипторе свойства.

Каждому java.beans.PropertyEditor должен соответствовать свой специализированный метод public String getJavaInitializationString(). Благодаря этому строка, использованная в исходном коде Java, возвращается в качестве аргумента в метод set дескриптора свойств. Эта строка возвращает значение, и все типы, упоминаемые в ней, должны быть приведены полностью, независимо от любых операторов импорта создаваемого класса. Если ваш BeanInfo подробно описывает класс шаблона JRE java.beans.SimpleBeanInfo, то метод не будет абстрактным и унаследуется для возвращения '???'. Не забывайте подробно описывать этот метод.

Кроме применения метода String[] getTags(), который используется в дескрипторе свойств для получения списка, есть возможность задать список значений гораздо быстрее. Значение атрибута создается с помощью ключа enumerationValues, оно является массивом трехкомпонентных записей (displayName в списке, собственно значение и initializationString). В качестве примера рассмотрим свойство direction типа int, которое может принимать значения 0, 1, 2 и 3. Это ссылки на статические поля NORTH, EAST, SOUTH и WEST класса myclasses.CompassPoint. Дескриптор свойств может выглядеть следующим образом:

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;
 

Второе значение каждой записи - это не собственно статическое поле int, как, например, myclasses.CompoassPoint.NORTH, а экземпляр java.lang.Integer. Это является следствием того, что простые типы не могут входить в массив, который вводится в Object; вместо этого необходимо использовать их java.lang equivalent.

События BeanInfo

Список событий, отображаемый в объекте JavaBean - это дескрипторы методов, предпочитаемые в дескрипторах данного события.

Если класс адаптера доступен, то его следует добавить в java.beans.EventDescriptor как именованный атрибут с ключом "eventAdapterClass", например:

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");

(C) Copyright IBM Corporation 1999, 2004. Все права защищены.