3. ¿Qué es GWT?
Es una herramienta que nos permite generar código
del lado del cliente con Java.
El código Java es compilado en código JavaScript.
Las sentencias JavaScript se ejecutan en el browser
del cliente.
El código JavaScript generado ha sido optimizado y
además soporta múltiples browser.
4. ¿Porqué Java?
Hay mucha gente que conoce Java, y para esta
gente aprender GWT es sencillo.
El soporte de IDE's en Java es bastante bueno
(incluyendo a los debuggers).
Podemos usar JUnit para probar código del lado del
cliente y del servidor
5. Nada es perfecto
Las páginas GWT no les gustan a los motores de
búsqueda.
Necesitas un browser decente para que tu
aplicación pueda ejecutarse.
Con JavaScript no tenía que compilar y desplegar.
Macho que se respeta programa en JavaScript.
6. Componentes GWT
Compilador JRE Emulation Library
Transforma el código Java Implementación parcial
en código JavaScript para de la JRE.
muchos browsers, y realiza
algunas optimizaciones. Contiene 4 paquetes, y
todos están incompletos:
Algunas de ellas: Dead java.io, java.lang,
Code Elimination, Constant java.sql y java.util.
Folding, String Interning y
Code Inlining Para funcionalidad extra,
podemos usar los
paquetes GWT
7. Componentes GWT
Biblioteca UI
Conjunto de Widgets, cuyo
uso es similar a Swing.
Soporta el uso de CSS para el
manejo de estilos.
Incluye algunos objetos
compuestos como DatePicker,
SuggestBox y RichTextArea.
9. Google Plugin for Eclipse
Disponible en: http://dl.google.com/eclipse/plugin/3.3
10. Estructura del Proyecto
El paquete client contiene código
que se ejecuta en el browser.
El paquete shared contiene código
usado tanto en el cliente como en el
servidor
El paquete server contiene código
que se ejecuta en el servidor.
Dentro de test se colocan las clases
para pruebas.
Dentro de war se colocará el código
de salida.
11. Definición de módulo
Con inherits podemos incluir contenido de otros módulos.
Mediante entry-point indicamos la clase que inicia la
aplicación.
Con source señalamos que carpetas serán consideradas en
la generación de código.
12. Página Host
El código de la aplicación se
ejecuta dentro de este
documento HTML.
Hace referencia a la hoja de
estilos de la aplicación
(Sampleproject.css) y al código
JavaScript generado por GWT.
Contiene un iFrame para el
soporte a Historial.
13. Modo Desarrollo
Nos permite depurar en Java utilizando un browser de
producción.
Requiere que el browser tenga instalado un plugin.
14. Un ejemplito
El usuario puede agregar stocks.
Por cada stock: mostrar símbolo,
precio y cambio desde la última
actualización
El usuario puede eliminar
stocks.
El precio de los stocks se
actualiza automáticamente.
Se debe mostrar la fecha de
última actualización
15. Root Panel
Definimos algunos elementos
HTML estáticos.
Incluimos un elemento div
para representar nuestro
Panel Root.
El Panel Root contiene los
elementos dinámicos de la
aplicación. Puede envolver a
la tag body u otro elemento
de la página Host.
16. Algunos Widgets
FlexTable nos crea un tabla con
celdas a pedido.
Button nos crea un botón HTML.
TextBox permite el ingreso de
texto en una línea.
Label se traduce en texto
arbitrario dentro de elementos
<div>.
Los Panels nos permiten
organizar los widgets. Pueden
incluir a su vez dentro de otros
Panels.
17. Eventos en el Cliente
Le asignamos una instancia de la
interfaz de manejo de eventos al
widget apropiado.
Usamos la interfaz ClickHandler
para manejar los clics al botón
“Add”.
La interfaz KeyPressHandler nos
permite almacenar el código de
Stock enviado al presionar
“Enter”
18. Seguimos con el cliente
Usamos ArrayList para almacenar
los códigos agregados.
Podemos agregar un botón a una
celda de FlexTable con setWidget.
Usamos Timer para actualizar
periódicamente los precios de los
stocks.
La clase StockPrice encapsula la
información de precios de stocks.
Usamos Random para generar los
precios y NumberFormat para
darle formato.
19. Cuestión de estilo
Definimos nuestros estilos sobre-
escribiendo StockWatcher.css.
Configuramos el valor del
atributo class de los elementos
HTML con addStyleName.
Podemos modificar ciertos
atributos HTML sin necesidad de
CSS, como con setCellPadding.
La página host puede incluir
elementos estáticos siempre que
los incluyamos en el directorio
público del proyecto (war).
20. Pase a producción
En modo producción, la aplicación sólamente es JavaScript y no
requiere plugins en el browser ni JVM.
Para desplegar, colocamos los archivos generados en un servidor
web.
Se generan implementaciones JavaScript para cada browser
soportado.
22. Las previas
Cuando la aplicación que se ejecuta en el browser quiere
comunicarse con el servidor, realiza una petición HTTP usando
una llamada RPC.
GWT incluye un mecanismo RPC basado en Servlets. Puedes
utilizarlo o no.
23. Recetario
Primero, definimos una interfaz para el servicio
extendiendo RemoteService.
Luego, definimos la clase del lado del servidor
extendiendo RemoteServiceServlet e
implementando la interfaz de arriba.
Finalmente, se define la interfaz asíncrona con la
que trabajará el código en el browser.
24. Interfaz Síncrona
Es una interfaz del lado del
cliente que extiende
RemoteService.
La implementación de esta
interfaz en el lado del servidor
debe extender
RemoteServiceServlet.
25. Interfaz Asíncrona
Cada método necesita un
Callback, que será notificado
cuando se complete la invocación
asíncrona.
Por lo general los métodos
retornan void.
Deben seguirse ciertas
convenciones de nombres para
generar el código RPC.
26. El Servicio
Basados en Servlets. No
implementan la interfaz
asíncrona.
RemoteServiceServlet se encarga
de la serialización de la data por
nosotros.
Para probar dentro del
contenedor en modo desarrollo,
registrar el servlet en web.xml
utilizando el valor de la anotación
RemoteServiceRelativePath en la
URL.
27. Invocar al Servicio
Instanciamos la interfaz síncrona
con GWT.create(). El Proxy
generado implementa la interfaz
asíncrona.
Creamos el objeto Callback,
instanciando AsyncCallback.
El parámetro de onSuccess es la
data que devuelve el servicio.
Todas las operaciones de red en
GWT son asíncronas
28. Tipos Serializables
La serialización permite transportar la data de un objeto
de una aplicación a otra.
Los parámetros y tipos de retorno de los métodos RPC
deben ser serializables.
Algunos tipos serializables: Primitivos y sus Wrappers,
String, Date, arreglos de tipos serializables, etc.
Una clase nuestra es serializable si es asignable a
Serializable/IsSerializable, sus atributos son
serializables*, y posee un constructor sin argumentos
30. Definir eventos
Almacena información asociada
al evento.
Debe heredar de GwtEvent, e
implementar los métodos
getAssociatedType y dispatch.
Recibe como parámetro la
interfaz que implementarán los
que manejen el evento.
31. Event Handler
Cada evento está
asociado a una interfaz
que representa a los que
manejarán el evento.
Debe heredar de
EventHandler y definir el
método a invocar cuando
ocurra el evento.
Este método tiene como
parámetro el evento.
32. Registrar Handlers
HandlerManager
administra a los que
manejan los eventos
(handlers).
Con addHandler,
notificamos que un
Handler específico está
interesado en recibir un
tipo de evento.
35. El patrón MVP
Model contiene la lógica de
negocio, y sólamente se
comunica con Presenter.
View tiene los componentes de
interacción de usuario, pero ya
no se comunica con Model.
Presenter es un intermediario
entre Model y View
36. Otro ejemplito
Crearemos una aplicación de administración de
contactos; para ver, editar y eliminar contactos de una
lista almacenada en el servidor.
En Model, tendremos Contact y ContactDetails.
En View, tendremos ContactsView y EditContactsView.
Nuestros Presenters se encargan de manejo de historial,
transición de vistas y envío de data al servidor.
Tendremos ContactsPresenter y EditContactPresenter
Y un AppController para lógica de nivel de aplicación.
38. El inicio
Se invoca el método
onModuleLoad de nuestro
EntryPoint.
Instanciamos el servicio RPC,
nuestro HandlerManager y
AppController.
Le pasamos a AppController
nuestra instancia de RootPanel.
Ahora puede crear Presenters y
suministrarles Views.
39. Presenters y Views
La interfaz Display permite el intercambio de vistas con mínimo
impacto.
El método setData permite agregar data del Model en el View.
40. Interfaz Display
Nuestro presenter no tiene acceso a código específico de cada Widget.
Pueden hacerse mocks de la interfaz display en las pruebas unitarias
41. Manejo de Eventos
En AppController registramos los
eventos y los Handlers que se
invocarán cuando se disparen.
Al invocar
HandlerManager.fireEvent(), se
buscan los handlers para ese tipo
de evento. Luego, se invoca al
método dispatch().
En el caso de invocaciones RPC,
por lo general se lanzan los
eventos al obtener el retorno.
42. Un paréntesis
Las aplicaciones Ajax no se integran con el Historial del
Browser. GWT incluye un mecanismo que lo soluciona.
Para cada página navegable se genera un token único.
Este token regresa a la aplicación cuando el usuario
presiona el botón “Atrás” o selecciona un link.
Para agregar un token al historial del browser podemos
usar History.newItem(token).
Con History.addValueChangeHandler(), designamos al
objeto encargado de restaurar el estado de acuerdo al
valor del token.
43. Transición de Vistas
La lógica de transición de vistas
la colocamos en AppController,
por lo que debe implementar
ValueChangeHandler.
Para que responda a los eventos
del historial, la registramos
mediante
History.addValueChangeHandler()
Es posible disparar una transición
de vista mediante
History.newItem().
44. Testing
Mediante MVP, nuestros Tests no
dependen del DOM ni de un
motor JavaScript.
Dado que el presenter sólo
depende de componentes JRE, la
mayoría de Casos de Prueba se
pueden implementar con JUnit.
Es posible crear mocks de la
interfaz Display
Se ha desaclopado el código de
los widgets de la lógica de la
aplicación.
46. Fuentes
Essential GWT de Federico Kereki.
Build a Sample GWT Application de Google Code:
http://code.google.com/webtoolkit/doc/latest/tutorial/gettingstarted.html
Communicate with a Server de Google Code:
http://code.google.com/webtoolkit/doc/latest/DevGuideServerCommunication.html
GWT Custom Events en StackOverFlow:
http://stackoverflow.com/questions/2951621/gwt-custom-events
Large scale application development and MVP de Chris Ramsdale:
http://code.google.com/webtoolkit/articles/mvp-architecture.html