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)