Arena. Pantalla de edición general.
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):
- 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
o bien usamos la annotation @TransactionalAndObservable. Recuerden hacer esto, o la vista no actualizará sus valores ante un cambio en el modelo (Arena igualmente tira un error).
- 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... O bien en el evento onAccept...
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)