## Personalización de Beans

La apariencia y el comportamiento de un Bean pueden ser personalizados en el momento del diseño dentro de las herramientas de desarrollo compatibles con los Beans. Aquí podemos ver las dos formas más típicas de personalizar un Bean:

- Utilizando un editor de propiedades. Cada propiedad del Bean tiene su propio editor. Normalmente las herramientas de desarrollo muestran los editores de propiedades de un Bean en una hoja de propiedades. Un editor de propiedades está asociado y edita un tipo de propiedad particular.

- Utilizando personalizadores. Los personalizadores ofrecen un completo control GUI sobre la personalización del Bean. Estos personalizadores se utilizan allí donde los editores de propiedades no son prácticos o no se pueden aplicar. Al contrario que un editor de propiedad, que está asociado con una propiedad, un personalizador está asociado con un Bean.

### Editores de Propiedades

Un editor de propiedad es una herramienta para personalizar un tipo de propiedad particular. Los editores de propiedades se muestran, o se activan desde la hoja de propiedades. Una hoja de propiedades determinará el tipo de la propidad, buscará un editor de propiedad adecuado, y mostrará el valor actual de la propiedad de una forma adecuada.

Los editores de propiedades deben implementar el interface PropertyEditor. Este interface proporciona métodos que especifican cuando una propiedad debe ser mostrada en una hoja de propiedades.

Aquí tienes la hoja de propiedades del BeanBox contiendo las propiedades de OurButton:

Se empieza el proceso de edición de estas propiedades pulsando sobre la entrada de la propiedad en la hoja.

- Las propiedades label y fontSize se muestran en un campo de texto editable. Los cambios se realizan allí mismo.
- Las propiedades largeFont y debug son cajas de selección con elecciones discretas.
- Pulsando sobre las entradas foreground, background,y font se desplegarán paneles separados.

Cada uno de ellos se muestra dependiendo de los métodos de PropertyEditor que hayamos implementado para que devuelvan valores distintos de null.

Por ejemplo, el editor de propiedad int implementa el método setAsText(). Esto indica a la hoja de propiedades que la propiedad puede ser mostrada como un String, y lo hace en un campo de texto editable.

Los editores de propiedades Color y Font utilizan un panel separado, y sólo utilizan la hoja de propiedades para mostrar el valor actual de la propiedad. Este editor se muestra pulsando sobre ese valor.

Para mostar el valor actual de la propiedad dentro de la hoja de propiedades, necesitamos sobreesciribr isPaintable() para que devuelva true, y paintValue() para que dibuje el nuevo valor de la propiedad en un rectángulo en la hoja de propiedades. Aquí tienes como ColorEditor implementa paintValue():

    public void paintValue(java.awt.Graphics gfx, java.awt.Rectangle box) {
            Color oldColor = gfx.getColor();
            gfx.setColor(Color.black);
            gfx.drawRect(box.x, box.y, box.width-3, box.height-3);
            gfx.setColor(color);
            gfx.fillRect(box.x+1, box.y+1, box.width-4, box.height-4);
            gfx.setColor(oldColor);
    }

Para soportar el editor de propiedades personalizado, necesitamos sobreescribir dos métodos más: supportsCustomEditor() para que devuelva true, y getCustomEditor() para que devuelve un ejemplar del editor personalizado. ColorEditor.getCustomEditor() devuelve this.

Además, la clase PropertyEditorSupport mantiene una lista de PropertyChangeListener y lanza notificaciones de eventos de cambio de propiedad a dichos oyentes cuando una propiedad compartida ha cambiado.

### Como se Asocian los Editores de Propiedades con las Propiedades

Los editores de propiedades son descubiertos y asociados con una propiedad dada mediante:

- La asociación explícita mediante un objeto BeanInfo. El Bean Molecule utiliza esta técnica. Dentro de la clase MoleculeBeanInfo, el editor de propiedades del Bean Molecule se selecciona con la siguiente línea de código:

            pd.setPropertyEditorClass(MoleculeNameEditor.class);

- Registro explícito mediante java.Beans.PropertyEditorManager.registerEditor(). Este método toma un par de argumentos: el tipo de la clase, y el editor asociado con ese tipo.

- Busqueda por nombre. Si una clase no tiene asociado explícitamente un editor de propiedades, entonces el PropertyEditorManager busca la clase del editor de propiedad mediante:
  - Añadiendo "Editor" al nombre totalmente cualificado de la clase. Por ejemplo, para la clase java.beans.ComplexNumber, el manejador del editor de propiedades buscará la clase java.beans.ComplexNumberEditor class.
  - Añadiendo "Editor" al nombre de la clase y buscando la clase en el path de búsqueda. El path de búsqueda por defecto del BeanBox está en sun.beans.editors.

#### Los Editores de Propiedades del BDK

El DBK proporciona editores para tipos de datos primitivos como int, bool, float, y para los tipos de clases como Color y Font. El código fuente para estos editores está en beans/apis/sun/beans/editors. Estos fuentes son un buen punto de entrada para escribir tus propios editores. Algunas cosas a observar sobre los editores de propiedades del BDK:

- Todas las propiedades "numéricas" están representadas como objetos String. El IntEditor sobreescribe PropertyEditorSupport.setAsText().
- El editor de propiedades bool es un menú de elecciones discretas. Sobreescribiendo el método PropertyEditorSupport.getTags() para que devuelva un String[] que contenga "True" y "False":

           public String[] getTags() {
              String result[] = { "True", "False" };
              return result;
           }

- Los editores de propiedades Color y Font implementan un editor personalizado. Porque estos objetos requieren un interface más sofisticado para ser fácilmente editados en un componente separado que se despliega para hacer la edición de la propiedad. Sobreescibir supportsCustomEditor() para que devuelva true indica a la hoja de propiedades que este editor de propiedad es un componente personalizado. Los métodos isPaintable() y paintValue() también son sobreescritos para proporcionar el color y la fuente en las áreas de ejemplo de la hoja de propiedades.

El código fuente de estos editores de propiedades está en beans/apis/sun/beans/editors.

Observa que si no se encuentra un editor de propiedades para una propiedad, el BeanBox no mostrará esa propiedad en la hoja de propiedades.

### Personalizadores

Cuando se utiliza un Personalizador de Bean, se obtiene el control completo sobre la configuración o edición del Bean. Un personalizador es como una aplicación que específicamente contiene la personalización de un Bean. Algunas veces las propiedades son insuficientes para representar los atributos configurables de un Bean. Los Personalizadores se usan cuando se necesita utilizar instrucciones sofisticadas para modificar un Bean, y cuando los editores de propiedades son demasiados primitivos para conseguir la personalización del Bean.

Todos los personalizadores deben:

- Descender de java.awt.Component o de una de sus subclases.
- Implementar el interface java.beans.Customizer. Esto significa la implementación de métodos para registrar objetos PropertyChangeListener, y lanzar eventos de cambio de propiedad a dichos oyentes cuando ocurre un cambio en el Bean fuente.
- Implementar un constructor por defecto.
- Asociar el personalizador con la clase fuente mediante BeanInfo.getBeanDescriptor().

Si un Bean asociado con un Personalizador es arrastrado dentro del BeanBox, podrás ver un ítem "Customize..." en el menú Edit.

#### Personalizadores del BDK

El OurButtonCustomizer sirve como ejemplo para demostrar el mecanismo de construcción de un personalizador.OurButtonCustomizer:

- Desciende de java.awt.Panel (una subclase de Component).
- Implementa el interface Customizer, y utiliza un objeto PropertyChangeSupport para manejar el registro y notificación de PropertyChangeListener. Puedes ver la página Propiedades Compartidas para una descripción de PropertyChangeSupport.
- Implementa un constructor por defecto:

           public OurButtonCustomizer() {
              setLayout(null);
           }

- Esta asociado con su clase fuente, ExplicitButton, mediante ExplicitButtonBeanInfo. Aquí ienes las sentencias de ExplicitButtonBeanInfo que hacen la asociación:

           public BeanDescriptor getBeanDescriptor() {
              return new BeanDescriptor(beanClass, customizerClass);
           }
           ...
           private final static Class customizerClass =
                                     OurButtonCustomizer.class;

Los Beans BridgeTester y JDBC Select también tienen personalizadores.

Ozito