Sugestões para escrever classes BeanInfo para o editor visual

Esta secção descreve algumas regras que se podem empregar ao escrever uma classe BeanInfo para um Java bean que se destine a utilização no editor visual para Java.

O editor visual para Java utiliza os descritores de propriedade descritos na classe BeanInfo para estabelecer a lista de entradas na vista Propriedades, bem como o respectivo modo de edição.

Se houver um java.beans.PropertyDescriptor oculto, não estará disponível no visualizador Propriedades. Todavia, os métodos definidos de propriedades ocultas ainda são interpretados pelo gerador de código e aplicados aos beans activos.

Quando uma propriedade está oculta ainda é utilizada pela interpretação de código, mas não á incluída em nenhuma outra vista ou função de editor visual. O VisualAge for Java permitia que uma propriedade fosse excluída da vista Propriedades, mas ainda assim ficasse disponível para outras funções. Por exemplo, estabelecer ligações tornando o momento de concepção false. Embora o editor visual para Java não tenha capacidades de ligação, o conceito de propriedades de momento de concepção é continuado. Para tornar falso o momento de concepção de uma propriedade, deve ser definido um valor de atributo com a chave ivjDesignTimeProperty, e o valor Boolean.FALSE.

Por exemplo, se uma classe BeanInfo estiver a ser escrita para a classe MeuJavaBean que tenha uma propriedade de nome (de uma setName(String) vazia pública e um par de métodos getName()), o método getPropertyDescriptors() poderia ser escrito do seguinte modo:

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

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

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

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

Quando é seleccionada uma propriedade na vista Propriedades, é criado um editor na coluna Valor onde se pode especificar novo valor. Para calcular o editor para uma propriedade, é consultado o java.beans.PropertyDescriptor relativamente a um editor de propriedade. Se for detectado um editor de propriedade associado, este será utilizado. Caso contrário, será localizado um que esteja definido para trabalhar com o tipo de propriedade. Não é possível afectar a lista de editores de propriedade predeterminados para dado tipo. Se for detectado um java.beans.PropertyEditor no descritor de propriedade ou detectado para o tipo de propriedade, a vista Propriedades irá tentar determinar o tipo de editor a criar. As regras utilizadas são:

  1. Se o método public boolean supportsCustomEdit() devolver true, é criado um editor de diálogos. O botão diálogo lança o editor devolvido pelo método public Component getCustomEditor(). O editor devolvido deve ser uma subclasse de java.awt.Component, e será alojado com botões OK e Cancelar numa Frame ou JFrame, conforme o necessário.
  2. Se o método public String[] getTags() devolver uma matriz de cadeias, estas são mostradas numa çista. A etiqueta usada para um valor existente na vista Propriedades é o resultado de chamar public void setValue(Object) com o valor de propriedade, e depois de chamar public String getAsText() para determinar a cadeia (String) a utilizar. Quando se selecciona um novo valor na lista, é chamado o método method public void setAsText(String) do editor, e é obtido o novo valor de propriedade mediante public Object getValue().
  3. Se nenhum dos métodos supracitados devolver um editor personalizado ou controlos, é criado um editor de campos de texto na folha Propriedades. O valor de texto inicialmente apresentado é o resultado de chamar public void setValue(Object) e public String getAsText(). Quando se insere uma nova cadeia no editor de texto a cada batimento de tecla, é chamado o método public void setAsText(String). Se o método devolver uma java.lang.IllegalArgumentException, a mensagem de excepção será apresentada na barra de estado e o valor não será aplicado. Se não for devolvida excepção alguma, quando faz clique na tecla Enter no editor de texto (ou se outra propriedade na vista Propriedades ficar com o foco), o resultado de chamar public Object getValue() é enviado como argumento para o método set descrito no descritor de propriedades.

Para cada java.beans.PropertyEditor, também deve ser especializado o método public String getJavaInitializationString(). Este devolve a cadeia que é utilizada no código fonte Java como argumento para o método set do descritor de propriedades. Esta cadeia deve devolver o valor e os eventuais tipos referenciados na cadeia devem ser totalmente qualificados, e não depender de instruções de importação na classe que estiver a ser composta. Se BeanInfo especializar a classe JRE de modelo java.beans.SimpleBeanInfo, o método não é abstracto e será herdado para devolver '???'. Não deixe de a especializar correctamente.

Além de utilizar o método public String[] getTags() method num descritor de propriedade para obter uma lista, existe um caminho mais curto para especificar uma lista de valores. É criado um valor de atributo com a chave enumerationValues, um valor que é uma matriz de entradas triplicadas do displayName na lista, o valor propriamente dito, e a initializationString. Como exemplo, considere uma propriedade chamada direction que seja introduzida em int e possam ser-lhe atribuídos valores de 0, 1, 2 e 3. Estes são referências a campos estáticos NORTE, LESTE, SUL e OESTE na classe minhasclasses.CompassPoint. O descritor de propriedade poderia ser escrito do seguinte modo:

public PropertyDescriptor[] getPropertyDescriptors() {
    PropertyDescriptor[] result = new PropertyDescriptor[1];
    try{
        PropertyDescriptor directionDescriptor
= new PropertyDescriptor("direction",MeuJavaBean.class);
        directionDescriptor.setValue("enumerationValues",new
Object[]{

"Norte",new
	Integer(minhasclasses.CompassPoint.NORTE),"minhasclasses.CompassPoint.NORTH",

"Leste",new
	Integer(minhasclasses.CompassPoint.LESTE),"minhasclasses.CompassPoint.EAST",

"Sul",new
	Integer(minhasclasses.CompassPoint.SUL),"minhasclasses.CompassPoint.SOUTH",

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

O segundo valor em cada uma das entradas não é o campo estático int propriamente dito como, por exemplo, myclasses.CompoassPoint.NORTE, mas sim uma instância de java.lang.Integer. Tal deve-se ao facto de não ser possível colocar tipos primitivos numa matriz que seja introduzida em Object, de modo que tem que ser usado o respectivo java.lang equivalente.

Eventos Bean Info

A lista de eventos que é apresentada num Java bean é o descritor de método preferido nos respectivos descritores de eventos.

Se estiver disponível uma classe de adaptador, deverá ser adicionada ao java.beans.EventDescriptor como atributo denominado, com uma chave "eventAdapterClass", por exemplo

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. Todos os direitos reservados.