Implementación de una pantalla de edición en Arena

Ayuda para entender cómo funciona un panel de edición 

Un panel de edición permite al usuario definir una nueva entidad o modificar la información de una entidad existente. Cada atributo que queremos que el usuario modifique/visualice tenemos que asociarlo con un control visual (widget).


En amarillo los packages que deberías definir vos. En blanco los que vienen con Arena. Nota: la interfaz Home<T> se renombró a Repo<T>.

Se muestran en el diagrama el comportamiento más relevante de cada objeto. 
Dialog implementa la interfaz TaskWindow, TransactionalDialog<T> implementa la interfaz TaskOwner: se ocultaron estas interfaces para conservar el diagrama simple y legible (el lector puede investigar al respecto).
  • Si te interesa que tu formulario sea modal (por lo general está bien que sea así) tu panel debería extender de Dialog<T>.
  • Si querés que además de ser modal el formulario trabaje dentro de una transacción, tu panel debería extender de TransactionalDialog<T>.
  • T es 
    • un objeto de tu dominio (Socio en el caso del videoclub, Celular en el caso de los celulares). En el diagrama mostramos que T extiende de Entity (pero esto es opcional).
    • o podría ser un application model o view model, por ejemplo para encapsular el conocimiento del repo, o para ayudar en el caso de uso si es complejo
  • T es obviamente el model de tu vista, es el atributo "model" de la clase Window<T> (la clase madre de todas las ventanas de Arena):
private IModel<T> model;
  • El modelo de la vista debe notificar los cambios a sus interesados, esto se logra a través de la annotation @Observable. Si además querés que se mantenga la edición en una transacción, la annotation debe ser @TransactionalAndObservable.
Ejemplo: en la clase Celular (que es nuestro modelo de vista de ejemplo) escribimos

@Observable
class Celular {

o

@TransactionalAndObservable
class Celular {

Recuerden hacer esto, o la vista no actualizará sus valores ante un cambio en el modelo.
  • La vista de edición define
    • en createMainTemplate, el título (opcional)
    • en createFormPanel, el layout y los controles que van a aparecer (cada control se bindea con un atributo del objeto de dominio a editar)
    • en addActions, las posibles acciones (que se implementan con botones Aceptar y Cancelar que bindean con métodos)
    • en executeTask, qué debería hacer el usuario en caso de Aceptar (en general, delegar a un repo, anteriormente home, la acción de agregar/modificar el objeto). En este método que definas es importante que llames al executeTask() de tu superclase (como última línea del método), para que se haga commit de la transacción y se active el circuito de notificaciones...
override def executeTask() {
    ...
    super.executeTask()
}

Y lo acompañamos con dos diagramas de secuencia que muestran:

1) cómo se crea el formulario

  • Al crearse el panel, también
  • se instancia el model (new Socio)
  • Luego se dispara el createContents(), que define
    • el layout
    • el panel de errores (que está arriba): aquí se van a mostrar errores propios del binding
    • el formulario donde van los controles
      • se instancian los textboxes, comboboxes, etc.
      • se bindean contra cada propiedad del modelo (que ya está instanciado)
    • por último van las acciones que el usuario puede disparar (la botonera)
      • el "aceptar", bindeado contra el método executeTask
      • opcionalmente podemos definir el cancelar, bindeado contra el método cancelTask
2) Lo que ocurre cuando el usuario ingresa los datos del socio y luego presiona el botón Aceptar:
  • Si se ingresa un valor en el campo nombre
    • lo escrito en el control TextBox dispara una notificación a los interesados
    • uno de los interesados es el modelo, esto se definió al bindear la propiedad "nombre" de un Socio con el valor del textbox
    • se dispara un setNombre pasando como argumento el valor del textbox al objeto Socio que es el modelo de la vista
    • a su vez, esto dispara notificaciones a la vista, pero hay un mecanismo inteligente que evita entrar en loop infinito
  • Al presionar el botón Aceptar
    • El model ya está actualizado (esto sucede conforme el usuario va ingresando la información por pantalla)
    • Se dispara la validación al model (el tipo T debe ser responsable de esto)
    • Se crea o modifica el model en el repositorio, el responsable de esto es el objeto repositorio

Páginas históricas