Después de los dos primeros capítulos de este tutorial donde instalamos y configuramos nuestra aplicación en OpenXava, donde creamos las clases para definir nuestras tablas e implementar la aplicación para darle funcionalidad, toca profundizar un poco más.

OpenXava View

La anotación @View se puede usar en una entidad o una clase incrustable para definir la disposición de sus miembros en la interfaz de usuario. OpenXava

Vamos a ver como configuramos los formularios en OpenXava, como modificamos los campos utilizados y otras propiedades. Para ello en este capítulo vamos a estudiar con nuestro proyecto: las vistas (Views), los estereotipos (Stereotype y la internacionalización (i18n), además de otras cosas.

 

Actualizamos la presentación de CbLanguage

Vamos a definir la vista de presentación de CbLanguage, para ello siguiendo las indicaciones de OpenXava creamos una vista:

@Entity
@View(members = // Vista sin nombre, será la vista por defecto.
        "idlanguage, name;" +
        "isactive, isbaselanguage, issystemlanguage;" +
        "languageiso, countrycode; "
        )
@Table(name="cblanguage")
public class CbLanguage {

Para más información sobre las vista accede al wiki de OpenXava: OpenXava View, para definir una vista la sintaxis básica es:

@View(
 name="nombre", // Nombre de la vista, no es obligatorio
 members="miembros", // Definimos que miembros se visualizan y como se presentan
 extendsView="view" // Nos permite extender una vista heredando todos sus valores
)
public class MiEntidad {

Como en nuestro caso no hemos definido un nombre a la vista (name=»nombre») esta será la que se use por defecto.

Veamos que significado tiene lo que hemos escrito, en la variable members podemos escoger que miembros queremos que aparezcan y en que orden, además de esto, decidimos la colocación de los elementos. Observando nuestra vista podemos ver que hemos utilizados comas y puntos y coma para separar los elementos, esto nos sirve para indicar la disposición, con la coma la variables se pone a continuación, y con punto y coma en la línea siguiente, con esta vista el resultado es el siguiente:

OpenXava Customerdb 03 CbLanguage detalle

CbLanguage detalle con la nueva vista

Así es como veíamos antes el formulario de CbLanguage:

OpenXava Customerdb 03 CbLanguage detalle antes

CbLanguage detalle antes de configurar la vista

Si te fijas y comparas las imágenes comprobarás que la colocación de los campos es diferente, y también se actualizado los valores de todas las etiquetas y los menús.

Una vez colocados los elementos vamos a cambiar los nombre de las etiquetas que salen asociados hasta ahora, como vimos antes los nombres que salían son los nombres de los campos en al base de datos. Para ello vamos a editar el fichero EtiquetasCustomerdb_es.properties en la carpeta i18n, con el nombre del campo y un igual indicamos el nuevo valor:

Customerdb=Gestión de clientes

# Componentes de CbLanguage
cbLanguage=Idioma
idlanguage=Idioma
name=Nombre
isactive=Activo
isbaselanguage=Base del sistema
issystemlanguage=Idioma del sistema
languageiso=Iso idioma
countrycode=Código país

Una vez hecho esto la presentación quedaría así:

OpenXava Customerdb 03 CbLanguage detalle

CbLanguage detalle con la nueva vista


 

Actualizamos la presentación de CbCurrency

Vamos a definir la vista de presentación de CbCurrency, para ello siguiendo las indicaciones de OpenXava creamos una vista:

@Entity
@View(members =
        "description;" +
        "isactive, iso_code, cursymbol;" +
        "precisionstd, precisioncost, precisionprize"
)
@Table(name="cbcurrency")
public class CbCurrency {

En este caso, no tiene más complicación, igual que antes colocamos los elementos según como queramos colocarlos elementos y actualizamos el fichero EtiquetasCustomerdb_es.properties en la carpeta i18n con las nuevas etiquetas para esta clase:

# Componentes de CbCurrency
cbCurrency=Moneda
currency=Moneda
isocode=Iso moneda
cursymbol=Símbolo
precisionstd=Precisión base
precisioncost=Precisión coste
precisionprize=Precisión precio

Este es el resultado final:

OpenXava Customerdb 03 CbCurrency detalle

CbCurrency detalle con View

 

Actualizamos la presentación de CbCountry

Vamos a definir la vista de presentación de CbCountry, para ello siguiendo las indicaciones de OpenXava creamos una vista:

@Entity
@View(members = // This view has no name, so it will be the view used by default
        "country, isactive;" +
        "description;" +
        "countrycode;" +
        "hasregion, regionname;" +
        "expressionphone;" +
        "cbCurrency, cbLanguage;"
)
@Table(name="cb_country")
public class CbCountry {

Igual que antes colocamos los elementos y actualizamos el fichero EtiquetasCustomerdb_es.properties en la carpeta i18n con las nuevas etiquetas para esta clase:

# Componentes de CbCountry
cbCountry=País
country=País
countrycode=Código de país
hasregion=Tiene región
regionname=Nombre región
expressionphone= Extensión tlf.

Lo único que podemos resaltar aquí en la vista es que para mostrar la posición y colocación de las tablas relacionadas (cbCurrency y cbLanguage) procedemos de la misma forma con la colocación de las variables si queremos que aparezcan.

Aquí, vamos a hacer algo más, como ya hemos definido y presentado la variable @DescriptionList, vamos a ir un poco más allá, para evitar presentar todos los idiomas y todas las monedas vamos a establecer unos filtros y a indicar el orden de las tablas que se presentan.

    @ManyToOne
    @JoinColumn(
            name = "idcurrency",
            nullable = true,
            foreignKey = @ForeignKey(name = "fk_cb_country_idcurrency"))
    @DescriptionsList(
            descriptionProperties = "currency",
            condition = "${isactive} = 'Y'", // 5
            order = "${description}" // 6
    )
    private CbCurrency cbCurrency;
   
    @ManyToOne
    @JoinColumn(
            name = "idlanguage",
            nullable = true,
            foreignKey = @ForeignKey(name = "fk_cb_country_idlanguage"))
    @DescriptionsList(
            descriptionProperties = "name",
            condition = "${isactive} = 'Y'", // 5
            order = "${name} " // 6
    )
    private CbLanguage cbLanguage;

Los campos utilizados son los siguientes (para más informacion en  OpenXava View: @DescriptionList, aquí tenéis otros campos que se pueden utilizar para personalizar la presentación en los combos y una explicación detallada):

  • descriptionProperties (= «name»): con esta propiedad indicamos que campo vamos a mostrar en el combo de selección.
  • condition (= «${isactive} = ‘Y'»): aquí establecemos una condición de filtrado.
  • order (= «${name} » ): indicamos el campo por el que ordenamos en la presentación.

Una vez hecho esto la presentación quedaría así:

OpenXava Customerdb 03 CbCountry detalle con la nueva vista

CbCountry detalle con la nueva vista

Veamos que valores se muestran en la moneda y el idioma,  para las monedas he actualizado la base de datos directamente para dejar como activos (isactive = ‘Y’) los valores de Euro y US Dollar, como se puede ver en la imagen:

OpenXava Customerdb 03 CbCountry detalle Monedas @DescriptionList

CbCountry detalle Monedas @DescriptionList

Para los idiomas he hecho lo mismo dejando solo los valores que se ven en la imagen como activos.

OpenXava Customerdb 03 CbCountry detalle Idiomas @DescriptionList

CbCountry detalle Idiomas @DescriptionList

Compruébalo tu mismo compilando y reiniciando el servidor con el filtro activo y desactivado, así de fácil.

Actualizamos la presentación de CbPaymentmethod

Vamos a definir la vista de presentación de CbPaymentmethod, para ello siguiendo las indicaciones de OpenXava creamos una vista:

@Entity
@View(members =
    "paymentmethod;" +
    "description;" +
    "paymententity;" +
    "paymentterms"
)
@Table(name = "cb_paymentmethod")
public class CbPaymentmethod {

    @Id
    @Hidden
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name = "idpaymentmethod", nullable = true)
    private Integer idpaymentmethod;

    ...

    @Stereotype("MEMO")
    @Column(name = "paymentterms", length = 250, nullable = true)
    private String paymentterms;

La vista sigue las misma instrucciones que antes en este caso ponemos cada valor en una línea diferente. Incorporamos una etiqueta nueva: @Hidden ,con ello indicamos que este campo se oculta en las presentaciones aunque se utilice internamente.

Igual que antes colocamos los elementos y actualizamos el fichero EtiquetasCustomerdb_es.properties en la carpeta i18n con las nuevas etiquetas para esta clase:

# Componentes de CbPaymentmethod
cbPaymentmethod= Método de pago
paymentmethod= Método
paymententity= Entidad
paymentterms= Términos de pago

Vamos a empezar a utilizar también los estereotipos: @Stereotype, que son la forma de determinar un comportamiento específico dentro de un tipo, en este caso usamos: MEMO, que nos presentará un cajetín de texto en vez de una entrada normal en la imagen aparece marcado en azul:

OpenXava Customerdb 03 CbPaymentMethod detalle con nuevo estererotipo memo

CbPaymentMethod detalle con nueva vista y estererotipo MEMO

 

Los esteriotipos con los que OpenXava viene configurado son (para más información consulta la wiki del modelo: OpenXava model Estereotipo:

  • DINERO, MONEY
  • FOTO, PHOTO, IMAGEN, IMAGE
  • TEXTO_GRANDE, MEMO, TEXT_AREA
  • ETIQUETA, LABEL
  • ETIQUETA_NEGRITA, BOLD_LABEL
  • HORA, TIME
  • FECHAHORA, DATETIME
  • GALERIA_IMAGENES, IMAGES_GALLERY (instrucciones)
  • RELLENADO_CON_CEROS, ZEROS_FILLED
  • TEXTO_HTML, HTML_TEXT (texto con formato editable)
  • ETIQUETA_IMAGEN, IMAGE_LABEL (imagen que depende del contenido de la propiedad)
  • EMAIL
  • TELEFONO, TELEPHONE
  • WEBURL
  • IP
  • ISBN
  • TARJETA_CREDITO, CREDIT_CARD
  • LISTA_EMAIL, EMAIL_LIST
  • LIBRERIA_DOCUMENTOS, DOCUMENT_LIBRARY (nuevo en v4m6, sólo funciona dentro de Liferay)
  • CONTRASENA, PASSWORD (nuevo en v4.1)
  • MAC (nuevo en v4.8)
  • ARCHIVO, FILE (nuevo en v5.0) (instrucciones)
  • ARCHIVOS, FILES (nuevo en v5.1) (instrucciones

También se pueden crear esteriotipos propios, pero esto lo veremos en este tutorial más adelante, si quieres adelantes aquí tienes todas la información: OpenXava model Estereotipo, está bien explicado y se puede hacer en pocos siguiente las instrucciones.

 

Definimos la información de los módulos

Para finalizar esta publicación vamos a definir los módulos en nuestro fichero EtiquetasCustomerdb_es.properties, que hemos estado actualizando a lo largo de este tutorial.

Para añadir las etiquetas y definiciones para los módulos de la aplicación Customerdb procedemos como te indico a continuación:

Customerdb=Gestión de clientes

# Módulos
CbEnterprise.module=Empresas
CbEnterprise.module[description]=Definición de las empresas
CbCustomer.module=Clientes
CbCustomer.module[description]=Definición de los clientes
CbCountry.module=Paises
CbCountry.module[description]=Definición de los países
CbLanguage.module=Idiomas
CbLanguage.module[description]=Definición de los idiomas
CbCurrency.module=Monedas
CbCurrency.module[description]=Definición de las monedas
CbPaymentmethod.module=Métodos de pago
CbPaymentmethod.module[description]=Definición de los métodos de pago
CbAddress.module=Dirección
CbAddress[description]=Definición de la dirección
CbAddresses.module=Direcciones
CbAddresses[description]=Definición de la direcciones de una entidad (clientes)

Donde CbEnterprise.module se utiliza para darle nombre al módulo y CbEnterprise.module[description] se usa para dar una descripción, que se muestra por ejemplo al seleccionar Inicio en el menú, como se puede ver en la imagen.

Hasta aquí hemos llegado hoy, en la continuación de esta publicación, que será Tutorial Openxava  (3.2): Finalizando la presentación, finalizaremos la presentación definiendo las clases que nos faltan y entrando más en detalle en algunas posibilidades adicionales que podemos utilizar para las vistas.

Espero que te haya sido útil.

Continuación: Tutorial Openxava (3.2): Finalizando la presentación con Tab

En esta segunda parte veremos el desarrollo de CbAddresses, CbAddress, CbEnterprise y CbCustomer

Datos tabulares son aquellos que se visualizan en formato de tabla, OpenXava tiene una presentación por defecto de estas listas, mediante la anotación @Tab dentro de la definición de la entidad podemos modificar esta presentación.

Después de los dos primeros capítulos de este tutorial donde instalamos y configuramos nuestra aplicación en OpenXava, donde creamos las clases para definir nuestras tablas e implementar la aplicación para darle funcionalidad, toca profundizar un poco más.

OpenXava View

La anotación @View se puede usar en una entidad o una clase incrustable para definir la disposición de sus miembros en la interfaz de usuario. OpenXava

Vamos a ver como configuramos los formularios en OpenXava, como modificamos los campos utilizados y otras propiedades. Para ello en este capítulo vamos a estudiar con nuestro proyecto: las vistas (Views), los estereotipos (Stereotype y la internacionalización (i18n), además de otras cosas.

 

Actualizamos la presentación de CbLanguage

Vamos a definir la vista de presentación de CbLanguage, para ello siguiendo las indicaciones de OpenXava creamos una vista:

@Entity
@View(members = // Vista sin nombre, será la vista por defecto.
        "idlanguage, name;" +
        "isactive, isbaselanguage, issystemlanguage;" +
        "languageiso, countrycode; "
        )
@Table(name="cblanguage")
public class CbLanguage {

Para más información sobre las vista accede al wiki de OpenXava: OpenXava View, para definir una vista la sintaxis básica es:

@View(
 name="nombre", // Nombre de la vista, no es obligatorio
 members="miembros", // Definimos que miembros se visualizan y como se presentan
 extendsView="view" // Nos permite extender una vista heredando todos sus valores
)
public class MiEntidad {

Como en nuestro caso no hemos definido un nombre a la vista (name=»nombre») esta será la que se use por defecto.

Veamos que significado tiene lo que hemos escrito, en la variable members podemos escoger que miembros queremos que aparezcan y en que orden, además de esto, decidimos la colocación de los elementos. Observando nuestra vista podemos ver que hemos utilizados comas y puntos y coma para separar los elementos, esto nos sirve para indicar la disposición, con la coma la variables se pone a continuación, y con punto y coma en la línea siguiente, con esta vista el resultado es el siguiente:

OpenXava Customerdb 03 CbLanguage detalle

CbLanguage detalle con la nueva vista

Así es como veíamos antes el formulario de CbLanguage:

OpenXava Customerdb 03 CbLanguage detalle antes

CbLanguage detalle antes de configurar la vista

Si te fijas y comparas las imágenes comprobarás que la colocación de los campos es diferente, y también se actualizado los valores de todas las etiquetas y los menús.

Una vez colocados los elementos vamos a cambiar los nombre de las etiquetas que salen asociados hasta ahora, como vimos antes los nombres que salían son los nombres de los campos en al base de datos. Para ello vamos a editar el fichero EtiquetasCustomerdb_es.properties en la carpeta i18n, con el nombre del campo y un igual indicamos el nuevo valor:

Customerdb=Gestión de clientes

# Componentes de CbLanguage
cbLanguage=Idioma
idlanguage=Idioma
name=Nombre
isactive=Activo
isbaselanguage=Base del sistema
issystemlanguage=Idioma del sistema
languageiso=Iso idioma
countrycode=Código país

Una vez hecho esto la presentación quedaría así:

OpenXava Customerdb 03 CbLanguage detalle

CbLanguage detalle con la nueva vista


 

Actualizamos la presentación de CbCurrency

Vamos a definir la vista de presentación de CbCurrency, para ello siguiendo las indicaciones de OpenXava creamos una vista:

@Entity
@View(members =
        "description;" +
        "isactive, iso_code, cursymbol;" +
        "precisionstd, precisioncost, precisionprize"
)
@Table(name="cbcurrency")
public class CbCurrency {

En este caso, no tiene más complicación, igual que antes colocamos los elementos según como queramos colocarlos elementos y actualizamos el fichero EtiquetasCustomerdb_es.properties en la carpeta i18n con las nuevas etiquetas para esta clase:

# Componentes de CbCurrency
cbCurrency=Moneda
currency=Moneda
isocode=Iso moneda
cursymbol=Símbolo
precisionstd=Precisión base
precisioncost=Precisión coste
precisionprize=Precisión precio

Este es el resultado final:

OpenXava Customerdb 03 CbCurrency detalle

CbCurrency detalle con View

 

Actualizamos la presentación de CbCountry

Vamos a definir la vista de presentación de CbCountry, para ello siguiendo las indicaciones de OpenXava creamos una vista:

@Entity
@View(members = // This view has no name, so it will be the view used by default
        "country, isactive;" +
        "description;" +
        "countrycode;" +
        "hasregion, regionname;" +
        "expressionphone;" +
        "cbCurrency, cbLanguage;"
)
@Table(name="cb_country")
public class CbCountry {

Igual que antes colocamos los elementos y actualizamos el fichero EtiquetasCustomerdb_es.properties en la carpeta i18n con las nuevas etiquetas para esta clase:

# Componentes de CbCountry
cbCountry=País
country=País
countrycode=Código de país
hasregion=Tiene región
regionname=Nombre región
expressionphone= Extensión tlf.

Lo único que podemos resaltar aquí en la vista es que para mostrar la posición y colocación de las tablas relacionadas (cbCurrency y cbLanguage) procedemos de la misma forma con la colocación de las variables si queremos que aparezcan.

Aquí, vamos a hacer algo más, como ya hemos definido y presentado la variable @DescriptionList, vamos a ir un poco más allá, para evitar presentar todos los idiomas y todas las monedas vamos a establecer unos filtros y a indicar el orden de las tablas que se presentan.

    @ManyToOne
    @JoinColumn(
            name = "idcurrency",
            nullable = true,
            foreignKey = @ForeignKey(name = "fk_cb_country_idcurrency"))
    @DescriptionsList(
            descriptionProperties = "currency",
            condition = "${isactive} = 'Y'", // 5
            order = "${description}" // 6
    )
    private CbCurrency cbCurrency;
   
    @ManyToOne
    @JoinColumn(
            name = "idlanguage",
            nullable = true,
            foreignKey = @ForeignKey(name = "fk_cb_country_idlanguage"))
    @DescriptionsList(
            descriptionProperties = "name",
            condition = "${isactive} = 'Y'", // 5
            order = "${name} " // 6
    )
    private CbLanguage cbLanguage;

Los campos utilizados son los siguientes (para más informacion en  OpenXava View: @DescriptionList, aquí tenéis otros campos que se pueden utilizar para personalizar la presentación en los combos y una explicación detallada):

  • descriptionProperties (= «name»): con esta propiedad indicamos que campo vamos a mostrar en el combo de selección.
  • condition (= «${isactive} = ‘Y'»): aquí establecemos una condición de filtrado.
  • order (= «${name} » ): indicamos el campo por el que ordenamos en la presentación.

Una vez hecho esto la presentación quedaría así:

OpenXava Customerdb 03 CbCountry detalle con la nueva vista

CbCountry detalle con la nueva vista

Veamos que valores se muestran en la moneda y el idioma,  para las monedas he actualizado la base de datos directamente para dejar como activos (isactive = ‘Y’) los valores de Euro y US Dollar, como se puede ver en la imagen:

OpenXava Customerdb 03 CbCountry detalle Monedas @DescriptionList

CbCountry detalle Monedas @DescriptionList

Para los idiomas he hecho lo mismo dejando solo los valores que se ven en la imagen como activos.

OpenXava Customerdb 03 CbCountry detalle Idiomas @DescriptionList

CbCountry detalle Idiomas @DescriptionList

Compruébalo tu mismo compilando y reiniciando el servidor con el filtro activo y desactivado, así de fácil.

Actualizamos la presentación de CbPaymentmethod

Vamos a definir la vista de presentación de CbPaymentmethod, para ello siguiendo las indicaciones de OpenXava creamos una vista:

@Entity
@View(members =
    "paymentmethod;" +
    "description;" +
    "paymententity;" +
    "paymentterms"
)
@Table(name = "cb_paymentmethod")
public class CbPaymentmethod {

    @Id
    @Hidden
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name = "idpaymentmethod", nullable = true)
    private Integer idpaymentmethod;

    ...

    @Stereotype("MEMO")
    @Column(name = "paymentterms", length = 250, nullable = true)
    private String paymentterms;

La vista sigue las misma instrucciones que antes en este caso ponemos cada valor en una línea diferente. Incorporamos una etiqueta nueva: @Hidden ,con ello indicamos que este campo se oculta en las presentaciones aunque se utilice internamente.

Igual que antes colocamos los elementos y actualizamos el fichero EtiquetasCustomerdb_es.properties en la carpeta i18n con las nuevas etiquetas para esta clase:

# Componentes de CbPaymentmethod
cbPaymentmethod= Método de pago
paymentmethod= Método
paymententity= Entidad
paymentterms= Términos de pago

Vamos a empezar a utilizar también los estereotipos: @Stereotype, que son la forma de determinar un comportamiento específico dentro de un tipo, en este caso usamos: MEMO, que nos presentará un cajetín de texto en vez de una entrada normal en la imagen aparece marcado en azul:

OpenXava Customerdb 03 CbPaymentMethod detalle con nuevo estererotipo memo

CbPaymentMethod detalle con nueva vista y estererotipo MEMO

 

Los esteriotipos con los que OpenXava viene configurado son (para más información consulta la wiki del modelo: OpenXava model Estereotipo:

  • DINERO, MONEY
  • FOTO, PHOTO, IMAGEN, IMAGE
  • TEXTO_GRANDE, MEMO, TEXT_AREA
  • ETIQUETA, LABEL
  • ETIQUETA_NEGRITA, BOLD_LABEL
  • HORA, TIME
  • FECHAHORA, DATETIME
  • GALERIA_IMAGENES, IMAGES_GALLERY (instrucciones)
  • RELLENADO_CON_CEROS, ZEROS_FILLED
  • TEXTO_HTML, HTML_TEXT (texto con formato editable)
  • ETIQUETA_IMAGEN, IMAGE_LABEL (imagen que depende del contenido de la propiedad)
  • EMAIL
  • TELEFONO, TELEPHONE
  • WEBURL
  • IP
  • ISBN
  • TARJETA_CREDITO, CREDIT_CARD
  • LISTA_EMAIL, EMAIL_LIST
  • LIBRERIA_DOCUMENTOS, DOCUMENT_LIBRARY (nuevo en v4m6, sólo funciona dentro de Liferay)
  • CONTRASENA, PASSWORD (nuevo en v4.1)
  • MAC (nuevo en v4.8)
  • ARCHIVO, FILE (nuevo en v5.0) (instrucciones)
  • ARCHIVOS, FILES (nuevo en v5.1) (instrucciones

También se pueden crear esteriotipos propios, pero esto lo veremos en este tutorial más adelante, si quieres adelantes aquí tienes todas la información: OpenXava model Estereotipo, está bien explicado y se puede hacer en pocos siguiente las instrucciones.

 

Definimos la información de los módulos

Para finalizar esta publicación vamos a definir los módulos en nuestro fichero EtiquetasCustomerdb_es.properties, que hemos estado actualizando a lo largo de este tutorial.

Para añadir las etiquetas y definiciones para los módulos de la aplicación Customerdb procedemos como te indico a continuación:

Customerdb=Gestión de clientes

# Módulos
CbEnterprise.module=Empresas
CbEnterprise.module[description]=Definición de las empresas
CbCustomer.module=Clientes
CbCustomer.module[description]=Definición de los clientes
CbCountry.module=Paises
CbCountry.module[description]=Definición de los países
CbLanguage.module=Idiomas
CbLanguage.module[description]=Definición de los idiomas
CbCurrency.module=Monedas
CbCurrency.module[description]=Definición de las monedas
CbPaymentmethod.module=Métodos de pago
CbPaymentmethod.module[description]=Definición de los métodos de pago
CbAddress.module=Dirección
CbAddress[description]=Definición de la dirección
CbAddresses.module=Direcciones
CbAddresses[description]=Definición de la direcciones de una entidad (clientes)

Donde CbEnterprise.module se utiliza para darle nombre al módulo y CbEnterprise.module[description] se usa para dar una descripción, que se muestra por ejemplo al seleccionar Inicio en el menú, como se puede ver en la imagen.

Hasta aquí hemos llegado hoy, en la continuación de esta publicación, que será Tutorial Openxava  (3.2): Finalizando la presentación, finalizaremos la presentación definiendo las clases que nos faltan y entrando más en detalle en algunas posibilidades adicionales que podemos utilizar para las vistas.

Espero que te haya sido útil.