5.2. Interfaces y Abstracciones

Los componentes de la interfaz de usuario de Vaadin se basan en un esqueleto de interfaces y clases abstractas que definen e implementan las características comunes de todos los componentes y la lógica básica de cómo son serializados los estados del componente entre el servidor y el cliente.

Esta sección proporciona detalles sobre las interfaces de los componentes básicos y abstracciones. El diseño y otras abstracciones del contenedor de componentes se describen en el Capítulo 6, Administrar el Diseño. Las interfaces que definen el modelo de datos de Vaadin se describen en el Capítulo 9, Vincular Componentes a Datos.

Figura 5.2. Interfaces de Componentes y Abstracciones

Todos los componentes implementan la interfaz Paintable, que se utiliza para serializar ("pintando") los componentes para el cliente, y la interfaz inversa VariableOwner, que es necesaria para des serializar el estado del componente o la interacción del usuario desde el cliente.

Además de las interfaces definidas en el framework Vaadin, todos los componentes implementan la interfaz java.io.Serializable para permitir la serialización. La serialización es necesaria en muchas agrupaciones y soluciones de computación en la nube (cloud computing).

5.2.1 Interfaz Component

La interfaz Component se combina con la clase AbstractComponent, que implementa todos los métodos definidos en la interfaz.

Administración del Árbol de Componentes
Los componentes son presentados en la interfaz de usuario jerárquicamente. El diseño es administrado por los componentes de diseño, o más en general por los componentes que implementan la interfaz ComponentContainer. Este contenedor es el padre de los componentes contenidos.

El método getParent() permite recuperar el componente padre de un componente. Si bien existe un setParent(), que rara vez se necesita cuando por lo general agrega componentes con el método addComponent() de la interfaz ComponentContainer, el cual establece automáticamente al padre.

Un componente no conoce a su padre cuando el componente es creado, por lo que no puede referirse al padre en el constructor con getParent(). Además, no es posible traer una referencia al objeto application con getApplication() antes de tener un padre. Por ejemplo, lo siguiente es inválido:

public class EjemploAcoplar extends CustomComponent {
    public EjemploAcoplar() {
        // ERROR: No podemos tener acceso al objeto de application aún.
        ClassResource r = new ClassResource("smiley.jpg",
                                            getApplication());
        Embedded image = new Embedded("Image:", r); 
        setCompositionRoot(image);
    }
}

La adición de un componente a una aplicación provoca que se active el llamado del método attach() para el componente. En consecuencia, la eliminación de un componente de un contenedor activa el llamado al método detach(). Si el padre de un componente agregado ya está conectado a la aplicación, attach() es llamado inmediatamente desde setParent().

public class EjemploAcoplar extends CustomComponent {
    public EjemploAcoplar() {
    }
    
    @Override
    public void attach() {
        super.attach(); // Debe llamar.
        
        // Ahora sabemos quién es finalmente nuestro dueño.
        ClassResource r = new ClassResource("sonriente.jpg",
                                            getApplication());
        Embedded imagen = new Embedded("Imagen:", r); 
        setCompositionRoot(imagen);
    }
}

La lógica del acoplamiento es implementado en AbstractComponent, tal como se describe en la Sección 5.2.2, "AbstractComponent".

5.2.2 AbstractComponent

AbstractComponent es la clase base para todos los componentes de interfaz de usuario. Se trata (sólo) de la implementación de la interfaz Component, implementando todos los métodos definidos en la interfaz.

AbstractComponent tiene un único método abstracto, getTag(), el cual devuelve el identificador de la serialización de la clase de un componente en particular. Este tiene que ser implementado cuando (y sólo cuando) se creen componentes totalmente nuevos. AbstractComponent administra gran parte de la serialización de los estados de los componentes entre el cliente y el servidor. La creación de nuevos componentes y la serialización se describe en el Capítulo 11, Desarrollar Nuevos Componentes, y la API de serialización del lado del servidor en el Apéndice A, Definicion del Lenguaje de Interfaz de Usuario (UIDL).

Componentes Campo (Field y AbstractField)

Los Campos son los componentes que tienen un valor que el usuario puede cambiar a través de la interfaz de usuario. La Figura 5.3, "Componentes Campo", ilustra las relaciones de herencia y las interfaces importantes y las clases base.

Figura 5.3. Componentes Campo

Los componentes campo se basan en el framework definido en la interfaz Field y de la clase base AbstractField.

Los campos están fuertemente acoplados con el modelo de datos de Vaadin. El valor del campo es tratado como una Property del componente field. Los campos de selección permiten la administración de elementos seleccionables a través de la interfaz Container.

La descripción de las interfaces field y las clases base se divide en las siguientes secciones.

Interfaz Field
La interfaz Field hereda la superinterface Component y también la interfaz Property para tener un valor para el campo. AbstractField es la única clase que implementa directamente la interfaz Field. Las relaciones se ilustran en la Figura 5.4, "Diagrama de Herencia de la Interfaz Field".

Figura 5.4. Diagrama de Herencia de la Interfaz Field

Puede establecer el valor del field con setValue() y leerlo con el método getValue() definido en la interfaz Property. El tipo de valor actual depende del componente.

La interfaz Field define una serie de atributos, que se pueden recuperar o manipular con el setters y getters correspondiente.
  • description
    Todos los campos tienen una descripción. Tenga en cuenta que si bien, este atributo se define en el componente Field, el cual es implementado en AbstractField, que no implementa directamente a Field, pero sólo a través de la clase AbstractField.

    required
    Cuando está activado, un indicador de (por lo general el carácter * asterisco) es mostrado a la izquierda, arriba, o hacia la derecha del campo, dependiendo del diseño que lo contiene y si el campo tiene un título. Si estos campos son validados pero están vacíos y se activa la propiedad requiredError (ver más abajo), se muestra un indicador de error y el error del componente se establece en el texto definido con la propiedad error. Sin la validación, el indicador requerido no es más que una guía visual.

    requiredError
    Define el mensaje de error a mostrar cuando se requiere un valor para un campo, pero no se ingresa nada. El mensaje de error se establece como el error del componente para el campo y por lo general se muestra en un texto de ayuda cuando el puntero del mouse se desplaza sobre el indicador de error. El componente Form puede mostrar el mensaje de error en un área indicadora de error especial.
Controlar Cambios de Valor en Field
Field hereda a Property.ValueChangeListener para permitir escuchar los cambios de valor en los campos y Property.Editor para permitir editar los valores.

Cuando el valor de un campo cambia, es desencadenado un Property.ValueChangeEvent para el campo. No debería implementar el método valueChange() en una clase que herede a AbstractField, ya que se ha implementado en AbstractField. En su lugar, debe implementar el método explícitamente añadiendo la implementación del objeto como un oyente.

Clase Base AbstractField
AbstractField es la clase base para todos los componentes field. Además de las características de los componentes heredadas de AbstractComponent, esta implementa varias características definidas en las interfaces Property, Buffered, Validatable, y Component.Focusable.



Anterior
Capítulo 5. Componentes de Interfaz de Usuario
Siguiente
5.3. Características Comunes de los Componentes

2 comentarios:

  1. Lastima que no se pudo terminar el tutorial , pero lo que se pudo escribir esta muy bien explicado y muy interesante . Muchas gracias por tu aporte.

    ResponderBorrar
    Respuestas
    1. estoy proximo a empezar con la version 8 para actualizar.

      Borrar