Google Web Toolkit (GWT) - Les bases

stuffinganiseedInternet and Web Development

Nov 18, 2012 (4 years and 8 months ago)

473 views

(c) 2011, Occello Audrey, POO/IHM
-
1
-
Google Web Toolkit (GWT)
Les bases

(c) 2011, Occello Audrey, POO/IHM
-
2
-
Apperçu de Ajax

Technologie” sous jacente de GWT
(c) 2011, Occello Audrey, POO/IHM
-
3
-

1er échange : le client accède à une URL et le serveur
envoie une page + du code javascript

Échanges suivants : Le client peut traiter des actions
localement grâce au javascript ou bien lancer une requête
HTTP asynchrone lorsque l'intervention du serveur est
nécessaire

Mise à jour partielle de l'interface coté client avec des
données du serveur au format XML ou texte
Serveur
web
Navigateur
réseau
requête
HTML
Page
HTML
Interprète
Javascript
appel
Javascript

HTML + CSS

données
XML
AJAX en bref
(c) 2011, Occello Audrey, POO/IHM
-
4
-

DHTML = Pages web dynamiques grace à l'utilisation conjointe de
Javascript, DOM et CSS

Javascript
 intervient lorsqu'un événement est déclenché sur la page
 sert de "glue" entre les différentes briques

DOM (Document Object Model)
 structure les pages web sous forme arbres
 permet d'accéder/mettre à jour le contenu/structure/style des
pages

CSS (Cascading Style Sheets)
 permet une séparation contenu (types des éléments)/forme
(apparence des éléments) de l'IHM
 modifiable par le code Javascript via DOM

XMLhttpRequest pour les communications asynchrones avec le serveur
(utilisé dans le code Javascript)
AJAX = XMLhttpRequest + DHTML
(c) 2011, Occello Audrey, POO/IHM
-
5
-

Scenario :
1.L'utilisateur tape une chaine de caractères et valide en
appuyant sur le bouton
2.Le message "Bonjour" concaténé à la chaine de caractères qu'il
vient de taper est affiché sur la page



Traitement coté serveur :
Lecture d'un fichier et renvoie du résultat ("Bonjour")

Traitement coté client :
Concaténation du résultat à la chaine de caractères et
mise à jour de la page

Plein de variantes possibles !
Exemple fil rouge : Hello world
(c) 2011, Occello Audrey, POO/IHM
-
6
-
Interactions et propagation des événements
(c) 2011, Occello Audrey, POO/IHM
-
7
-
...
<FORM method="get" action="">
<input type="text" id="texte" … >
<input type="button" id="bid" value="Submit" … >
</FORM>
<div id="zone"></div>
...
Manipulation de la page web avec DOM
Document
RootElement
<html>
Element
<head>
Element
<title>
text
"My title"
Element
<body>
Element
<form>
Element
<div>
input
""
text
""
input
"Submit"
id="zone" id="bid" id="texte"
(c) 2011, Occello Audrey, POO/IHM
-
8
-
Manipulation de la page web avec DOM
document.getElementById("zone").innerHTML =...
Permet de modifier le texte de la page à cet endroit

document.getElementById("bid").disabled = true;
Permet de rendre inaccessible le bouton "Submit"
Document
RootElement
<html>
Element
<head>
Element
<title>
text
"My title"
Element
<body>
Element
<form>
Element
<div>
input
""
text
""
input
"Submit"
id="zone" id="bid" id="texte"
(c) 2011, Occello Audrey, POO/IHM
-
9
-
1.Association d'un événement à une action utilisateur au
travers d'une widget
2.Implémentation d'une fonction javascript associée au
déclenchement de l'événement
(a) Création et configuration d'un objet XMLHttpRequest
(b) Envoi d'une requête asynchrone via l' objet
XMLHttpRequest
3.Implémentation d'une fonction de callback (utilisée au
moment de la configuration lors de l'étape 2) appelée
lorsque le serveur renvoie sa réponse
(a) Traitement de la réponse du serveur
(b) Mise à jour de la page HTML (DOM)

*. Traitement coté serveur + résultat sous forme d'un
document XML (ou texte)
Étapes de développement typiques avec Ajax

(c) 2011, Occello Audrey, POO/IHM
-
10
-
<html>
<head>
<script language="JavaScript">
function submitForm() {
... // voir page suivante
}
</script>
</head>

<body>
<FORM name="ajax" method="get" action="">
<input type="text" id="texte" size="32" value="">
<input type="button" value="Submit" onclick="submitForm()">

</FORM>
<div id="zone"> ... ligne de texte qui sera rafraichie ... </div>
</body>
</html>
Hello World en AJAX "ad-hoc"
(c) 2011, Occello Audrey, POO/IHM
-
11
-

var req = null; // à déclarer en dehors pour être partagée entre les 2 fonctions

function submitForm() { // fonction appelée par le client sur événement
document.getElementById("zone").innerHTML = "Wait server...";
if (window.XMLHttpRequest) req = new XMLHttpRequest();
else if (window.ActiveXObject) req = new ActiveXObject(Microsoft.XMLHTTP);

req.onreadystatechange = mycallback;
req.open("GET", "data.txt", true); // false pour appel synchrone
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.send(null);
}

function mycallback() { // fonction appelée par le serveur en fin de traitement
var res = null;
if(req.readyState == 4) {
if(req.status == 200) res = req.responseText + " " + document.ajax.texte.value;

else res = "Error: returned status code " + req.status + " " + req.statusText;

document.getElementById("zone").innerHTML = res;
}
}
Hello World en AJAX "ad-hoc"
(c) 2011, Occello Audrey, POO/IHM
-
12
-
<html>
<head>
<script language="JavaScript">
function submitForm() {
...
}
</script>
<style type="text/css">
@import "monstyle.css";
</style>
</head>
<body>
// le contenu de la
// page ne change pas
</html>
Personnalisation des widgets avec CSS

body { // fichier css
background-color: white;
color: blue;
font-family: Comic Sans MS;
font-size: small;
}

input[type=button] {
color:#050;
font: bold 84% Comic Sans MS;
background-color:#fed;
border: 1px solid;
border-color: #696 #363 #363 #696;

filter:progid:DXImageTransform.Micro
soft.Gradient

(GradientType=0,StartColorStr='#ffff
ffff',EndColorStr='#ffaaaaff');
}
(c) 2011, Occello Audrey, POO/IHM
-
13
-

Ajax complique les comportements habituels du navigateur
(bookmark, enregistrement des pages, boutons précédent
/ suivant, référencement, etc)

Différence de prise en charge des navigateurs au niveau
du DOM, Javascript, XMLhttpRequest, CSS, …

Multiplicité des navigateurs et fonctionnement différent
d'un OS à un autre

Développement “cross-navigateur” fastidieux
Une problématique sans cesse renouvelée par les nouvelles
versions des navigateurs
Gestion de l'indépendance vis à vis des navigateurs
(c) 2011, Occello Audrey, POO/IHM
-
14
-

Les librairies Ajax viennent à la rescousse !
 gèrent pour nous les différences de navigateurs

Les librairies Ajax offrent aussi

des widgets de haut niveau

des effets visuels (surbrillance, slider, drag&drop, transitions
visuelles : effets de flou, zoom, rotation, etc)

des fonctions pour la manipulation DOM, la gestion des
événements, la communication avec le serveur,
l'internationalisation et l'historique, …

Revient souvent à intégrer simplement un ou plusieurs
fichiers javascript dans votre page


Exemples : Prototype, Dojo, jQuery
Script.aculo.us, Yahoo UI library, ...
Gestion de l'indépendance vis à vis des navigateurs
Source : Google Insights
(c) 2011, Occello Audrey, POO/IHM
-
15
-
<html>
<head>
<script type="text/javascript"
src="http://o.aolcdn.com/dojo/1.2.0/dojo/dojo.xd.js">
</script>
<script type="text/javascript">
...
function submitForm() {
... // voir plus loin
}
</script>
<style type="text/css">
@import
"http://o.aolcdn.com/dojo/1.2.0/dijit/themes/tundra/tundra.css";
</style>
</head>
...

Hello World avec la librairie Dojo
Intégration de la librairie comme un simple "import" de fichier javascript
(c) 2011, Occello Audrey, POO/IHM
-
16
-

<body class="tundra">
<FORM name="ajax" method="post" action="">
<input type="text" size="20" id="texte"
dojoType="dijit.form.TextBox" trim="true"/>
<button id="submit" dojoType="dijit.form.Button">
Submit
<script type="dojo/method" event="onClick">
dijit.byId("zone").setContent('Wait server...');
submitForm();
</script>
</button>
</FORM>
<div id="zone" dojoType="dijit.layout.ContentPane">
... ligne de texte qui sera rafraichie ...
</div>
</body>
</html>

Hello World avec la librairie Dojo
(c) 2011, Occello Audrey, POO/IHM
-
17
-
<script type="text/javascript">
// importation des éléments de l'API Dojo requis
dojo.require("dijit.form.Button");
dojo.require("dijit.form.TextBox");
dojo.require("dijit.layout.ContentPane");

function submitForm() {
dojo.xhrGet( { // équivalent du XMLhttpRequest
url: "data.txt",
handleAs: "text", // autre possibilité : xml
load: function(data) {
dijit.byId("zone").setContent(data + ' ' +
dijit.byId("texte").getValue());
},
error: function(data, ioArgs) {
alert("Error: returned status code " + ioArgs.xhr.status);
}
});
}
</script>
Hello World avec la librairie Dojo
(c) 2011, Occello Audrey, POO/IHM
-
18
-

Encapsulation des communications asynchrones

Prise en charge de l’aspect cross-navigateur

Widgets de haut niveau




Code JavaScript difficile à écrire
(peu d'experts)

Code JavaScript compliqué à débugger (alert !)

Extensibilité ?
Intérêts des librairies
(c) 2011, Occello Audrey, POO/IHM
-
19
-

Conservent les avantages des librairies tout en évitant
généralement de manipuler directement le Javascript

Framework = librairies + IDE et outils dérivés


Exemples en Java :
GWT (Google Web Toolkit), Echo, DWR (Direct Web Remoting) ,
ICEfaces (java+JSF tags), ...


Exemples en .Net :
ASP.Net AJAX, Projet Volta (GWT-like) , ...


Exemples en Python :
Pyjamas (GWT-like)

Exemple avec de l'HTML étendu :
Spry
Frameworks AJAX
Source : Google Insights
(c) 2011, Occello Audrey, POO/IHM
-
20
-
Présentation générale de GWT
(c) 2011, Occello Audrey, POO/IHM
-
21
-
GWT : Développer, débugger, tester en Java
 Les IHM sont réalisées en Java
 Compilation vers Javascript

 Simplification de l'écriture d'applications cross
navigateurs …

 … dans un environnement pour les développeurs Java
 Typage fort de Java vs non typage de javascript
 Support des IDE (mode debug, JUnit, …)
 Possiblité de composer graphiquement les interfaces (GWT
designer, GWT editor)

(c) 2011, Occello Audrey, POO/IHM
-
22
-

Attention : tout java n'est pas
traductible en javascript !!!
 Partiellement java.lang et java.util
 Pas de support pour Java 5 et
Java 6 (for each, generics,
varargs, printf ou String.format,
enums, etc)

Meilleur support de java
à chaque nouvelle version
de GWT

Attention donc !
Architecture
Application
HelloWorld en Java
Java Runtime Library
(java.lang, java.util, etc)
GWT GUI Library
(Panels + widgets)
Compilateur
GWT
Navigateur
IE, Mozilla, Firefox, Safari, Opera, etc
Application
HelloWorld
en Javascript
(c) 2011, Occello Audrey, POO/IHM
-
23
-

Bibliothèque de widgets similaire à Java Swing mais :
– Gestion d’événements différente depuis GWT 1.6
– Notions de Panel/Layout fusionnées


CSS pour personnaliser
le style des widgets
GWT GUI Library
(c) 2011, Occello Audrey, POO/IHM
-
24
-
Aperçu des Widgets
 UIObject est la super classe, qui gère coordonnées, titre,
visibilité et taille de tout objet graphique
 Les widgets héritent de la super classe Widget qui propose
des opérations telles que :
L'attachement au parent
La gestion des événements :
basée sur des listeners Java
jusqu'à la version 1.5
basculement vers
les handlers depuis
la version 1.6 de
GWT
(c) 2011, Occello Audrey, POO/IHM
-
25
-
Aperçu des panneaux et des layouts
 En GWT, les notions de Layout et de Panel sont fusionnées
 4 grands types de Panel : Simple, Complex, Table, Split
 AbsolutePanel, FlowPanel, StackPanel
 CellPanel et ses enfants DockPanel, HorizontalPanel,
VerticalPanel
 PopUpPanel et DialogBox
 FormPanel : simule un formulaire HTML
 DisclosurePanel : possibilité de masquer/démasquer le contenu
 TabPanel : système d'onglets

...

 Des LayoutPanels pour gérer le placement par rapport à la
fenêtre du navigateur (à utiliser pour le panneau de plus
haut niveau) – depuis GWT 2.0
(c) 2011, Occello Audrey, POO/IHM
-
26
-
Organisation d'un module GWT

Module : unité d'organisation/réutilisation des applications GWT
(c) 2011, Occello Audrey, POO/IHM
-
27
-
Organisation d'un module GWT :

illustration avec le module hello
Les ressources (css, images, etc)
Le package du module
Le fichier de configuration du module
La page web de lancement du module
Le code de la partie cliente
Le code de la partie serveur
Répertoire auto-généré (code javascript)
Fichier des tâches Ant (pour ceux qui
utilisent le SDK seul)
Fichier de config pour le déploiement
Fichiers .class parties cliente et serveur
Librairies utilisées coté serveur
Le code commun au client et au serveur
(c) 2011, Occello Audrey, POO/IHM
-
28
-

Les modules écrits par les utilisateurs dépendent eux
mêmes d'autres modules : ceux fournis avec le framework

Chaque API GWT correspond à un module
Modules fournis par GWT
Module Nom logique Contenu
User com.google.gwt.user.User Fonctions de base :
Panels & Widgets, gestion historique, API
DOM, etc
HTTP com.google.gwt.http.HTTP Traitement des requêtes HTTP
i18n
com.google.gwt.i18n.client
Gestion de l'internationalisation
XML com.google.gwt.xml.XML Création et parsing de documents XML
JUnit com.google.gwt.junit.JUnit Intégration à JUnit
(c) 2011, Occello Audrey, POO/IHM
-
29
-

Représenté par un fichier XML


Composé de :
– modules dont hérite ce module (lié aux “import” effectués)
– point d'entrée de ce module (le “main”) :
classe Java chargée et exécutée au démarrage du module
– feuilles de style
– liste des navigateurs supportés
– internationalisation
–...


Le nom logique du module est le nom du fichier de
configuration (sans le suffixe gwt.xml) préfixé par le nom
du package complet
ex : pooihm.hello.Hello
Fichier de configuration d'un module
(c) 2011, Occello Audrey, POO/IHM
-
30
-
<!-- option rename-to permet de changer le nom logique -->
<!-- du module pour la génération du code javascript -->
<module rename-to=‘hello'>
<!-- Inherit the core Web Toolkit stuff. -->
<inherits name='com.google.gwt.user.User'/>
<!-- Inherit the default GWT style sheet. You can change -->
<!-- the theme of your GWT application by uncommenting -->
<!-- any one of the following lines. -->
<inherits name='com.google.gwt.user.theme.standard.Standard'/>
<!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> -->
<!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/> -->
<!-- Other module inherits (if needed) -->
<!-- Specify the app entry point class. -->
<entry-point class=' pooihm.hello.client.Hello'/>
<!-- Specify the application specific style sheet. -->
<stylesheet src=‘Hello.css' />
</module>
Fichier de configuration du module Hello
Ne pas inclure le css si déjà fait
dans fichier HTML
(c) 2011, Occello Audrey, POO/IHM
-
31
-
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link type="text/css" rel="stylesheet" href=“Hello.css">
<title>Hello</title>
<!-- This script loads your compiled module. -->
<!-- If you add any GWT meta tags, they must -->
<!-- be added before this line. -->
<script type="text/javascript" language="javascript"
src=“hello/hello.nocache.js"></script>
</head>

<!-- The body can have arbitrary html, or -->
<!-- you can leave the body empty if you want -->
<!-- to create a completely dynamic UI. -->
<body></body>
</html>
Page web d'intégration du module
Attention ici le chemin
sera plus long si le
module n'a pas été
renommé pour la
génération de code
(cf page précédente
rename-to)
Attention ici le chemin
sera plus long si le
module n'a pas été
renommé pour la
génération de code
(cf page précédente
rename-to)
Ne pas inclure le css si
déjà fait dans fichier
de config
(c) 2011, Occello Audrey, POO/IHM
-
32
-

Fichier web.xml dans le repertoire war/WEB-INF

Manière standard de dépoyer une application web pour des
serveurs web tels que WebLogic, Tomcat, Jetty, etc :
– indique quelle est la page par défaut à charger
– référence aux servlets (i.e. : code java coté serveur)
–...

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web
Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
<!-- Default page to serve -->
<welcome-file-list>
<welcome-file>Hello.html</welcome-file>
</welcome-file-list>
</web-app>
Fichier de configuration du déploiement du module
(c) 2011, Occello Audrey, POO/IHM
-
33
-
Développement d'un module
(c) 2011, Occello Audrey, POO/IHM
-
34
-

Créer un module



Implémenter le module : Editer le fichier Java généré

Créer les éléments d'IHM

Ajouter ces éléments à la page HTML (RootPanel) et choisir leur
mise en page (layout)

Gérer les événements associés aux éléments d'IHM pour définir
les actions utilisateur à prendre en compte


Editer le fichier HTML généré (optionel)

Définir des ids pour les différentes régions de l'IHM où seront
placés des éléments


Exécuter le module
Étapes de développement d'un module GWT
(c) 2011, Occello Audrey, POO/IHM
-
35
-
Créer un module
Pour ceux qui utilisent le SDK seul :
 Utiliser le script webAppCreator (à la racine de la distrib de GWT)
 En paramètre : le nom logique du module (ex : pooihm.hello.Hello)
 Option "-out" pour préciser le répertoire où placer les fichiers générés

Pour ceux qui utilisent le plugin Eclipse : cliquer sur cet item
(c) 2011, Occello Audrey, POO/IHM
-
36
-

La partie cliente du module doit implémenter l'interface EntryPoint et
plus particulièrement la méthode onModuleLoad qui sera invoquée au
chargement du module

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.TextBox;
public class Hello implements EntryPoint {
public void onModuleLoad() {
// création des widgets
final TextBox input = new TextBox();
final Button button = new Button(“Click me");
final HTML reply = new HTML();
...
Implémentation du module : création des widgets
(c) 2011, Occello Audrey, POO/IHM
-
37
-
Etape 1 : modifier la page HTML et ajouter des zones personnalisées
par un id auxquelles seront associé des widgets/panels

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Hello</title>
<script type="text/javascript" language="javascript"
src="hello/hello.nocache.js"></script>
</head>

<body>
<table border="0">
<tr><td id="textfield"></td> sur la même ligne
<td id="button"></td></tr>
</table>
<tr><div id="replyLabel"></div></tr> sur une autre
ligne
</body>
</html>
Implémentation du module : définition du layout

(à partir de la page web)
(c) 2011, Occello Audrey, POO/IHM
-
38
-
Implémentation du module : définition du layout

(à partir de la page web)
Etape 2 : associer à chaque zone HTML un widget (ou panel) dans la
méthode
onModuleLoad
du module

public class Hello implements EntryPoint {
public Hello() {}
public void onModuleLoad() {
// Partie création de widget (inchangée)

// Partie layout : à remplacer par le code ci-dessous
RootPanel.get("textfield").add(input);
RootPanel.get("button").add(button);
RootPanel.get("replyLabel").add(reply);
}

On aurait aussi pu ajouter directement panel1 et reply à la page via deux
zones l'une au dessous de l'autre …
Cette méthode sert surtout à incorporer du code GWT à des pages
préexistantes
(c) 2011, Occello Audrey, POO/IHM
-
39
-
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
public class Hello implements EntryPoint {
public void onModuleLoad() {
// Partie création de widget (inchangée)

// Layout
HorizontalPanel panel1 = new HorizontalPanel();
panel1.add(input);
panel1.add(button);
VerticalPanel panel2 = new VerticalPanel();
panel2.add(panel1);
panel2.add(reply);
RootPanel.get().add(panel2);
}
}
Autre méthode pour définir le layout

(par imbrication de panneaux)
(c) 2011, Occello Audrey, POO/IHM
-
40
-
Les widgets sont collées au coin supérieur gauche de la fenêtre du navigateur
Nous verrons en TD comment corriger ceci en utilisant les classes LayoutPanel
et XXXLayoutPanel

Autre méthode pour définir le layout

(par imbrication de panneaux)
(c) 2011, Occello Audrey, POO/IHM
-
41
-

A partir de GWT 1.6 les handlers remplacent les listeners
– Manière plus uniforme et plus fine de traiter les évènements
– Évite d'avoir à implémenter toutes les méthodes d'une interface d'écoute


Un listener par source d'évènement : définit plusieurs méthodes

Les méthodes du listener prennent en paramètre la Widget source de
l'évènement et un nombre variable d'autres paramètres
– ex : KeyboardListener a 3 méthodes : onKeyDown, onKeyUp, onKeyPressed


Un handler par évènement : définit une seule méthode

La méthode de tous les handlers prend toujours l'Event en paramètre et
rien d'autre
– ex : KeyPressedHandler et sa méthode onKeyPress(KeyPressEvent e)
– ex : KeyUpHandler et sa méthode onKeyUp(KeyUpEvent e)
– ex : KeyDownHandler et sa méthode onKeyDown(KeyDownEvent e)
Implémentation du module : définition des actions
(c) 2011, Occello Audrey, POO/IHM
-
42
-

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
public class Hello implements EntryPoint {
public void onModuleLoad() {
// Parties création de widget et layout (inchangées)
// Gestion des événements associés aux widgets
button.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
// vers la création de la salutation
}
});
input.addKeyUpHandler(new KeyUpHandler() {
public void onKeyUp(KeyUpEvent event) {
if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER)
// vers la création de la salutation
}
});
}
}
Définition des actions pour le module Hello

(exemple avec utilisation de classes anonymes)
2 façons de déclencher l'action
(c) 2011, Occello Audrey, POO/IHM
-
43
-

Il est utile d’écouter certains événements pour gérer ce qu’il se
passe au niveau de la fenêtre

Par exemple l'interface ResizeHandler sert à redimensionner notre
application en fonction de la taille de la fenêtre du navigateur

Autre exemple : CloseHandler (voir plus loin)

import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
public class Hello implements EntryPoint, ResizeHandler {
public void onModuleLoad() {
...
Window.addResizeHandler(this);
}
public void onResize(ResizeEvent event) {
...
}
}
Gérer les événements sur la fenêtre du navigateur
(c) 2011, Occello Audrey, POO/IHM
-
44
-

Development Mode (hosted mode avant GWT 2.0)

Compilation du Java en bytecode

Exécution au sein d'une JVM dans un navigateur standard

Mais nécessite l’installation du "Google Web Toolkit Developer
Plugin" et l’utilisation du “GWT's development mode server”
intégré (Jetty - qui accepte les servlets mais pas le php)

Dédié aux environnements de développement : possibilité de
modifier le code à chaud


Production Mode (web mode avant GWT 2.0)

Compilation du Java en javascript pour la partie cliente

Exécution dans un navigateur web normal

Mais nécessite le déploiement de l’application dans un serveur web

Dédié aux environnements de production
2 Modes d’exécution des modules GWT
(c) 2011, Occello Audrey, POO/IHM
-
45
-
Mode d’exécution “Development”
Avec le SDK seul : Utiliser le script build.xml avec ant (cible "devmode")
Avec le plugin Eclipse : Cliquer sur le bouton "run" (choisir “run as web application”)

Résultat :
(c) 2011, Occello Audrey, POO/IHM
-
46
-
Mode d’exécution “production”
Avec le SDK seul : Utiliser le script build.xml avec ant (cible "gwtc")
Avec le plugin Eclipse : Cliquer sur cet item





Dans les deux cas, déployer ensuite le répertoire war dans un serveur web et
ouvrir le fichier HTML point d'entrée de votre module (ici Hello.html) dans votre
navigateur préféré

(c) 2011, Occello Audrey, POO/IHM
-
47
-
<html>
<head>
<script type="text/javascript" language="javascript" src=“hello/hello.nocache.js"></script>
</head>
<body>
...
</body>
</html>
Génération de code pour le mode "production"
(c) 2011, Occello Audrey, POO/IHM
-
48
-
<html>
<head>
<script type="text/javascript" language="javascript" src=“hello/hello.nocache.js"></script>
</head>
<body>
...
</body>
</html>
Génération de code pour le mode "production"
Un fichier html
par navigateur
ciblé
(c) 2011, Occello Audrey, POO/IHM
-
49
-
Optimisation pour la compilation
 Création d'un fichier javascript par navigateur / locale
 GWT peut produire jusqu'à 60 combinaisons (permutations)
 6 browsers : ie6, ie8, opera, safari, gecko1_8, gecko
 10 locales : default, de_DE, en_UK, fr_FR, hr_HR, hu_HU, it_IT,
nl_NL, pl_PL, pt_PT
 Par défaut, si on ne précise rien dans le fichier de config :
support pour tous les browsers prévus mais pas
d'internationalisation = 6 permutations
 Le compilateur vers javascript passe beaucoup de temps à
calculer les permutations
 Idée : limiter les alternatives
(c) 2011, Occello Audrey, POO/IHM
-
50
-
Optimisation pour la compilation
 Il faut 1 min 37 sec pour générer les 12 combinaisons javascript avec
langue par défaut et français + support des 6 navigateurs
(c) 2011, Occello Audrey, POO/IHM
-
51
-
Optimisation pour la compilation

… et seulement 50 sec pour compiler une seule permutation !
ex : langue par défaut + support IE6

 Pour réduire le nb de langues supportées (attention il faut avoir défini
les traductions – cf prochain cours), utiliser la propriété suivante dans
le fichier de config :
<extend-property name="locale" values="default"/>
 Pour réduire le nb de navigateurs supportés, utiliser la propriété
suivante dans le fichier de config :
<set-property name="user.agent" value="ie6" />
(c) 2011, Occello Audrey, POO/IHM
-
52
-

Que faire si j'ai un très gros module ?


Doit-on tout mettre dans la classe "entry-point" ?


Comment modulariser tout cela ?


Comment réutiliser des bouts d'IHMs ?
Et maintenant ?
(c) 2011, Occello Audrey, POO/IHM
-
53
-
Vers plus de modularité
(c) 2011, Occello Audrey, POO/IHM
-
54
-
Conception des modules
 Découper l'IHM en widgets réutilisables

 Diviser le code en modules réutilisables

 Charger plusieurs points d'entrée dans la même page
(c) 2011, Occello Audrey, POO/IHM
-
55
-
Découper l'IHM en widgets réutilisables
 Trois solutions (du plus facile au plus complexe) :
 Créer une widget qui hérite de la classe Composite et qui contient
d’autres widgets organisées d’une certaine façon
ex : TabPanel est un composite contenant un TabBar et un DeckPanel
 Dériver de la classe Widget ou d’une de ses sous classes
 Encapsuler une widget écrite en Javascript et y accéder via JSNI
(JavaScript Native Interface)

 Ne pas dériver directement de UIObject car ne gère pas
les événements !
(c) 2011, Occello Audrey, POO/IHM
-
56
-
Découper l'IHM en widgets réutilisables :

Application de la méthode du composite au module Hello
public class FenetreHello extends Composite {
private TextBox input;
private Button button;
private HTML reply;

public FenetreHello(String buttonTitle) {
input = new TextBox();
button = new Button(buttonTitle);
reply = new HTML();
HorizontalPanel panel1 = new HorizontalPanel();
panel1.add(input); panel1.add(button);
VerticalPanel panel2 = new VerticalPanel();
panel2.add(panel1); panel2.add(reply);
initWidget(panel2); // très important sinon les évènements ne
// seront pas transmis aux sous composants !
}
public String getInput() { return input.getText(); }
}
(c) 2011, Occello Audrey, POO/IHM
-
57
-
Découper l'IHM en widgets réutilisables :

Impact sur le point d’entrée module Hello
public class MonAppli implements EntryPoint {
private FenetreHello fl;

public void onModuleLoad() {
// fenêtre réutilisable
fe = new FenetreHello("Click me");
RootPanel.get().add(fe);
}
}
(c) 2011, Occello Audrey, POO/IHM
-
58
-
Diviser le code en modules réutilisables

Utilisation de l'unité de regroupement en modules pour
mieux découper/cloisonner les briques d'une application


Un module peut hériter de plusieurs autres modules définis
par vous même (on n'hérite pas que des modules fournis par
GWT)
<inherits name="..." /> dans le fichier de config

 Il n'est pas obligatoire de définir un point d'entrée pour les
modules élémentaires que l’on crée
(c) 2011, Occello Audrey, POO/IHM
-
59
-
Charger plusieurs points d'entrée dans la même
page web
 Il n'est pas obligatoire pour un module d’avoir un unique
point d'entrée : on peut en avoir plusieurs y compris ceux
des modules hérités
 Ils sont chargés dans la page séquentiellement suivant
l'ordre défini par le fichier de configuration et
possiblement de façon paresseuse (optimisation des perf)
 Par contre, il n'est pas garanti que deux points d'entrée
déclenchent un événement en même temps ou dans un ordre
prédéfini lors d'une action utilisateur
 L'ordre de déclenchement peut aussi être différent de l'ordre de
chargement des modules