Arena - Guía de componentes

A continuación, explicamos los mecanismos de binding que tiene cada uno de los componentes de Arena (llamados widgets), así como también cómo lucen y para qué se suele utilizar.

Jerarquía de Widgets en Arena

La clase más abstracta de componentes en Arena es Widget. A partir de ella podemos ver la jerarquía con todos los componentes que existen.

Pueden explorar esas clases para información extra a esta página.

Window

La clase window es el contenedor principal de los controles. Se le puede configurar

  • minHeight
  • minWidth

que son el ancho y el largo mínimo que debe tener la pantalla, a menos de que se requiera más espacio (en ese caso se utilizará más ancho o alto).

Errors Panel

Todas las ventanas que heredan de SimpleWindow tienen un ErrorsPanel, que es básicamente un label que escucha mensajes de error que aparecen por la interacción del usuario con la aplicación. Se le puede configurar

  • la cantidad de líneas preferida

Para eso, o bien construimos un ErrorsPanel en una ventana MainWindow o Window (que no heredan de SimpleWindow):

o bien tendremos que redefinir el método createErrorsPanel si heredamos de SimpleWindow... para cambiar la cantidad de líneas que queremos mostrar por defecto.

Si nuestra intención es simplemente mostrar los errores en una línea y nuestra ventana hereda de SimpleWindow, no es necesario hacer nada.

Control

org.uqbar.arena.widgets.Control es la subclase de Widget más importante en Arena. Es abstracta, sirve para proveer los siguientes bindings genéricos:

  • enabled: indica si está habilitado el control, se asocia a una propiedad que devuelve un boolean.
  • visible: indica si el control está visible, se asocia a una propiedad que devuelve un boolean.
  • background: el fondo del control, se asocia a una propiedad que devuelve un ViewObservable.

El binding de estas propiedades se puede hacer de dos maneras:

  1. enviando el mensaje bindXXXToProperty(String nombreDeLaPropiedadDelModelo)
    • si trabajás en Xtend tenés el operador <=> como shortcut (fijate en esta página)
  2. enviando el mensaje bindXXX(ObservableProperty)donde XXX es el nombre de la propiedad de la vista.

Vemos un ejemplo de cada caso:

en este caso el checkbox se habilita en base a la propiedad "habilitaResumenCuenta" definido en el modelo de la vista. Recordemos que la propiedad se implementa con un método boolean getHabilitaResumenCuenta().

Vemos el mismo ejemplo creando un ObservableProperty:

La ventaja de esta alternativa es que permite modificar el modelo default de la vista para un control particular (reemplazando this.modelObject por otro objeto observable).

Además se puede asignar manualmente las siguientes propiedades (no bindeables):

  • width(int)
  • height(Int)

IMPORTANTE: Todos los controles se instancian pasando como parámetro un panel que los contiene

Checkbox

org.uqbar.arena.widgets.CheckBox representa un cuadro que se asocia a un valor verdadero (seleccionado) o falso (no seleccionado)

Al extender de Control hereda las propiedades bindeables enabled, visible, background y las propiedades manuales height y width.

Un checkbox debe bindear la propiedad

  • value: el valor booleano true/false

Ejemplo de bindings para un checkbox:

Selector / Combo

org.uqbar.arena.widgets.Selector<T> es un control que muestra una lista desplegable de opciones y permite al usuario seleccionar una de ellas. Se visualiza como un ComboBox.

Un selector tiene dos propiedades que deben bindearse:

  • value: el elemento seleccionado (un T)
  • items: la lista de opciones disponibles a mostrar. Es un conjunto de elementos T, donde T debe ser observable.

Otros bindings opcionales son:

  • onSelection(Action): evento que se dispara cuando se selecciona una opción

Al extender de Control hereda las propiedades bindeables enabled, visible, background y las propiedades manuales height y width.

Ejemplo de un selector que muestra el país de fabricación de una computadora. Cada opción muestra la descripción del país:

List

org.uqbar.arena.widgets.List<T> extiende de Selector y tiene el mismo comportamiento pero se muestra como una lista que permite visualizar varios valores al mismo tiempo. Ejemplo que muestra cómo llenar un List de Productos para un pedido (dentro de un panel con layout horizontal):

Para más referencias ver el control Selector

Radio Selector

org.uqbar.arena.widgets.RadioSelector<T> extiende de Selector y tiene el mismo comportamiento pero se muestra como una lista de radio buttons (botones con selección excluyente).

Constructores: además del constructor default de todos los controles (que reciben el panel padre que hace de container) tenemos el

  • RadioSelector(Container container, String itemsProperty)

que permite establecer la propiedad de donde salen los ítems a seleccionar.

Para más referencias ver el control Selector

Ejemplo: una vista que tiene una propiedad estadosCiviles sólo lectura

Skinnable Controls

Todos los controles que heredan de SkinnableControls aceptan estas propiedades configurables manualmente:

  • foreground(Color)
  • background(Color)
  • fontSize(int)

Además heredan las propiedades bindeables del control (enabled, visible, height, width)

Label

org.uqbar.arena.widgets.Label representa un texto con el formato de una etiqueta. Puede o no tener binding, en el primer caso se trabaja con la propiedad value, en el segundo caso se setea en el inicio una constante String a partir de la propiedad text que no es observable.

Ejemplo de un label fijo:

muestra el valor fijo "Monto"

Ejemplo de un label que se bindea contra una propiedad (es dinámico, responde ante los cambios en el modelo):

La propiedad contra la que se bindea un label suele ser de sólo lectura (aunque no es obligatorio que así lo sea).

Es obligatorio para cada label definir la propiedad text o bien la propiedad value (no tiene sentido definir ambas ya que el value estará pisando el text original).

Propiedades opcionales son:

  • las que hereda de Control:
    • manuales: height y width. También admite mensajes para alineación: alignLeft(), alignRight(), alignCenter()
    • bindeables: enabled, visible
  • las que hereda de SkinnableControl: fontSize, foreground, background, todas manuales

Imágenes: un label puede tener asociada una imagen (siempre que no tenga binding contra un value). Por ejemplo, podemos establecer una propiedad en el modelo contra el path donde se encuentra una imagen

Y luego en el Label establecer el binding contra un transformer que tome el path y lo convierta a una imagen:

Es conveniente que la imagen esté en un source folder definido en el pom:

Para más información recomendamos descargar este ejemplo.

Link

org.uqbar.arena.widgets.Link permite definir el link a una acción. Es obligatorio el binding

  • de la propiedad caption, ya sea
    • manual mediante la asignación de la propiedad caption
    • o bindeable a través del mensaje bindCaptionToProperty
  • de la propiedad onClick(Action).

Ejemplo:

Propiedades opcionales son:

  • las que hereda de Control:
    • manuales: height y width
    • bindeables: enabled, visible
  • las que hereda de SkinnableControl: fontSize, foreground, background, todas manuales

Button

org.uqbar.arena.widgets.Button permite definir un botón para que el usuario dispare una acción.

Es obligatorio el binding de la propiedad onClick. Además es conveniente definirle

  • la propiedad caption (bindeable o como un string fijo)
  • o bien la propiedad image (bindeable)

Propiedades opcionales son:

  • las que hereda de Control:
    • manuales: height y width
    • bindeables: enabled, visible
  • las que hereda de SkinnableControl: fontSize, foreground, background, todas manuales
  • setAsDefault: se asocia con el <Enter> del usuario
  • disableOnError: cuando la vista recibe una excepción se deshabilita el botón hasta un nuevo evento

Ejemplos de uso:

FileSelector

org.uqbar.arena.widgets.FileSelector extiende de Button y además permite seleccionar un archivo mediante un cuadro de diálogo. Es obligatorio establecer el binding de la propiedad value, contra una propiedad del modelo:

Al apretar el botón, se abrirá un dialog para seleccionar el archivo.

Lo que va a bindear es el path del archivo seleccionado a la propiedad "archivo" de nuestro modelo.

Se pueden configurar las siguientes propiedades manuales:

  • title: el título de la ventana de diálogo al abrirse
  • caption: label del botón
  • path: el directorio a visualizar al abrir la ventana
  • extensions: las extensiones de archivo a filtrar. Esto es opcional, si no se configura, se puede seleccionar cualquier archivo.

TextBox

org.uqbar.arena.widgets.TextBox permite ingresar valores al usuario. Por default todos los textboxes asumen que se pueden cargar tanto números como caracteres alfabéticos y símbolos, así que el valor asociado es un String. Se visualiza como una caja de texto. Es obligatorio establecer el binding de la propiedad value, contra una propiedad del modelo:

Recordemos que las opciones para bindear el value son:

  • a partir del bindValueToProperty
  • o a través del bindValue(new ObservableProperty(this, "millas"))

Propiedades que pueden setearse manualmente, además de las del control:

  • las que hereda de Control:
    • manuales: height y width. También admite mensajes para alineación: alignLeft() y alignRight(). El mensaje alignCenter() no tiene efecto ya que SWT no lo permite.
    • bindeables: enabled, visible
  • las que hereda de SkinnableControl: fontSize, foreground, background, todas manuales
  • withFilter(TextFilter): permite filtrar el input del control (para más información ver Filter controllers)

NumericField

org.uqbar.arena.widgets.NumericField es un TextBox adaptado (tiene un filtro que evita los caracteres alfabéticos, y solo permite ingresar dígitos numéricos, comas y puntos). A partir de la versión 3.6.3 de Arena

  • se alinea a derecha
  • se pueden ingresar valores negativos
  • por defecto admite decimales (tomados de la configuración regional como coma o punto). Si se requiere ingresar solo valores enteros, debe construirse como new Numeric(contenedor, false) donde el segundo parámetro indica si se permite trabajar con decimales

PasswordField

org.uqbar.arena.widgets.PasswordField es un TextBox adaptado para datos sensibles que no muestra los caracteres ingresados en pantalla. Es ideal para contraseñas.

Table / Grid

org.uqbar.arena.widgets.tables.Table<R> permite crear una grilla para mostrar elementos de tipo R:

Es obligatorio definir

  • la propiedad items contra una colección de elementos de tipo R
  • al menos una columna

Opcionalmente se puede definir una propiedad value para bindear el elemento seleccionado.

Propiedades que pueden setearse manualmente, además de las del control:

  • las que hereda de Control:
    • bindeables: enabled, visible
  • las que hereda de SkinnableControl: fontSize, foreground, background, todas manuales
  • IMPORTANTE: las propiedades height y width no tienen efecto, van algunos tips
    • ¿Cómo cambiar el alto? Definiendo la cantidad de filas a mostrar mediante la propiedad numberVisibleRows(int)
    • ¿Cómo cambiar el ancho? Definiendo un tamaño fijo para cada columna mediante la propiedad fixedSize(int), esto redibuja finalmente el ancho de la tabla.

Ejemplo: para definir una tabla que muestra los clientes de una empresa de celulares

Para agregar una columna que muestre el nombre de un cliente de esa empresa:

La propiedad nombre está asociada a un celular.

Las columnas

  • se pueden alinear mediante los mensajes alignLeft(), alignRight() y alignCenter()
  • se relacionan con una propiedad o bien podemos aplicarle un Transformer, como se explica en esta página.

Spinner

org.uqbar.arena.widgets.Spinner permite editar un valor numérico con dos botones que permiten incrementar/decrementar ese valor.

La propiedad value se bindea mediante el mensaje bindValueToProperty.

Opcionalmente se pueden definir:

  • minimumValue: el valor mínimo que puede tomar
  • maximumValue: el valor máximo que puede tomar
  • las que hereda de Control:
    • manuales: height y width
    • bindeables: enabled, visible
  • las que hereda de SkinnableControl: fontSize, foreground, background, todas manuales

Ejemplo: tenemos un pedido y queremos asignar la cantidad a comprar para un producto:

El pedido tiene una propiedad cantidadIngresada int o Integer.

Tree

org.uqbar.arena.widgets.tree.Tree<T> permite definir un control que muestre nodos en forma jerárquica

Panel

org.uqbar.arena.widgets.Panel sirve como contenedor de widgets o controles.

Todo panel tiene

  • un model, que puede coincidir con el de la pantalla principal
  • un layout, que por default es vertical

Group Panel

org.uqbar.arena.widgets.GroupPanel extiende de Panel y le agrega un borde + un título (propiedad title manual).