gwt approfondissement - gti780 & mti780 - ets - a08
DESCRIPTION
Présentation dans le but d\'approfondir les connaissances sur GWT dans le cadre du cours combiné GTI780 / MTI780, Sujets spéciaux en TI, donné par Claude Coulombe, à l'Ecole de technologie supérieure, Montréal, Automne 2008TRANSCRIPT
Google Web Toolkit (GWT): Google Web Toolkit (GWT): approfondissementapprofondissement
Montréal, novembre 2008Montréal, novembre 2008GTI-780 / MTI-780GTI-780 / MTI-780
Sujets spéciaux en TISujets spéciaux en TI
Le Web 2.0 : concepts et outilsLe Web 2.0 : concepts et outils
École de technologie supérieureÉcole de technologie supérieureparpar
Claude Coulombe Claude Coulombe
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
ButBut
Dans cette présentation vous approfondirez Dans cette présentation vous approfondirez votre connaissance du Google Web Toolkit votre connaissance du Google Web Toolkit (GWT) qui permet le développement rapide (GWT) qui permet le développement rapide en Java d'applications Web 2.0 et AJAX. en Java d'applications Web 2.0 et AJAX.
http://code.google.com/webtoolkit/http://code.google.com/webtoolkit/
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Comprendre GWTComprendre GWT
GWTGWT
* Source Clipart : http://www.clipart.com* Source Clipart : http://www.clipart.com
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Transcompilateur Java à JavaScript Transcompilateur Java à JavaScript
JavaJava
JavaScriptJavaScript
GWT version 1.4 supporte :GWT version 1.4 supporte :
* Firefox 1.0, 1.5, 2, 3.x* Firefox 1.0, 1.5, 2, 3.x
* Internet Explorer 6, 7* Internet Explorer 6, 7
* Safari 2.0, 3.0* Safari 2.0, 3.0
* Opera 9.0* Opera 9.0
Run Everywhere!Run Everywhere!
Write Once...Write Once...
* Source Clipart : http://www.clipart.com* Source Clipart : http://www.clipart.com
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Transcompilateur Java à JavaScript Transcompilateur Java à JavaScript Transcompilateur GWT prend du code-client en Java et Transcompilateur GWT prend du code-client en Java et le traduit en JavaScript optimiséle traduit en JavaScript optimisé
JavaScript vu comme le code assembleur du fureteurJavaScript vu comme le code assembleur du fureteur
Élimination du code non-utilisé dans les bibliothèques, Élimination du code non-utilisé dans les bibliothèques, inférence de type, retrait du polymorphisme, inférence de type, retrait du polymorphisme, compression “agressive” du code, « Obfuscation »compression “agressive” du code, « Obfuscation »
Le JavaScript produit est généralement plus rapide Le JavaScript produit est généralement plus rapide que du JavaScript écrit à la main* que du JavaScript écrit à la main*
Emploi de la liaison différée (“Deferred Binding”) pour Emploi de la liaison différée (“Deferred Binding”) pour produire du code JavaScript optimal pour chaque produire du code JavaScript optimal pour chaque fureteur (i.e. génère du code spécifique à chaque fureteur (i.e. génère du code spécifique à chaque fureteur)fureteur)
« Ne payez que pour ce que vous utilisez »« Ne payez que pour ce que vous utilisez »
* Note : sauf si code < 100 lignes* Note : sauf si code < 100 lignes
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Copyright Google 2008Copyright Google 2008
* Source : http://www.google.com* Source : http://www.google.com
Transcompilateur – Liaison différée Transcompilateur – Liaison différée Générer du code optimal et spécifique à chaque fureteurGénérer du code optimal et spécifique à chaque fureteur
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Du JavaScript plus rapide que du code écrit à la main !!!Du JavaScript plus rapide que du code écrit à la main !!!
Ainsi, ceciAinsi, ceci
public static void onModuleLoad() {public static void onModuleLoad() {
Button b = (new Button()).Button();Button b = (new Button()).Button();
b.setText("Java vers JavaScript");b.setText("Java vers JavaScript");
}}
après compilation donnera quelque chose comme cela... après compilation donnera quelque chose comme cela...
function onModuleLoad(){function onModuleLoad(){
var b;var b;
b = $Button(new Button());b = $Button(new Button());
$setInnerText(b.element, 'Java vers JavaScript');$setInnerText(b.element, 'Java vers JavaScript');
}}
Transcompilateur Java à JavaScript Transcompilateur Java à JavaScript
* Note : -style : OBFUSCATED, DETAILED, PRETTY* Note : -style : OBFUSCATED, DETAILED, PRETTY
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Transcompilateur Java à JavaScript Transcompilateur Java à JavaScript
Transcompilateur Transcompilateur
gwt-user.jargwt-user.jarGwt-dev-Gwt-dev-
windows.jarwindows.jar
Autres .jarAutres .jar
Compatibles Compatibles
avec GWTavec GWT
Configuration Configuration Module Module
MonProjet.gMonProjet.gwt.xmlwt.xml
Code Java Code Java
MonProjet. MonProjet. javajava
RessourcesRessourcesMonProjet.
html
MonProjet.css,MonProjet.css,
.png, .jpg, .gif.png, .jpg, .gif
Code Code JavaScriptJavaScriptMonProjet.MonProjet.
jsjs
RessourcesRessourcesMonProjet.
html
MonProjet.css,MonProjet.css,
.png, .jpg, .gif.png, .jpg, .gif
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
« Ne payez que pour ce que vous utilisez »« Ne payez que pour ce que vous utilisez »
Copyright Google 2008Copyright Google 2008
* Source : http://www.google.com* Source : http://www.google.com
Transcompilateur – Code optimisé! Transcompilateur – Code optimisé!
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Emulation – JRE Emulation – JRE (Java Runtime Environment)(Java Runtime Environment)
Le transcompilateur de GWT fournit l'émulation en Le transcompilateur de GWT fournit l'émulation en JavaScript d'un sous-ensemble du langage Java (JRE) JavaScript d'un sous-ensemble du langage Java (JRE) généralement utilisé pour la programmation de basegénéralement utilisé pour la programmation de base
java.lang, java.util, java.io, java.sqljava.lang, java.util, java.io, java.sql
Restriction pour le code client Restriction pour le code client
devant être traduit en JavaScript. devant être traduit en JavaScript.
Aucune restriction n'est imposée Aucune restriction n'est imposée
du côté du code serveur.du côté du code serveur.
Java (JSP/JSF/Servlet), PHP, Java (JSP/JSF/Servlet), PHP,
ASP .NET, Perl, RoR, Python, Perl, ...ASP .NET, Perl, RoR, Python, Perl, ...
* Source image : http://www.sun.com* Source image : http://www.sun.com
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
JSNI : JavaScript Native InterfaceJSNI : JavaScript Native InterfaceGWT permet l'intégration facile avec des bibliothèques GWT permet l'intégration facile avec des bibliothèques JavaScript externes grâce à son JavaScript Native JavaScript externes grâce à son JavaScript Native Interface (JSNI)Interface (JSNI)
Interagir directement avec JavaScript (accès natif) à Interagir directement avec JavaScript (accès natif) à partir de Java et vice-versa partir de Java et vice-versa
Inclusion automatique des bibliothèques JavaScriptInclusion automatique des bibliothèques JavaScript
GWT 1.5 introduit le concept de JavaScript Overlay GWT 1.5 introduit le concept de JavaScript Overlay pour simplifier l'intégration de prototypes JavaScript pour simplifier l'intégration de prototypes JavaScript dans GWTdans GWT
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
JSNI : JavaScript Native InterfaceJSNI : JavaScript Native Interface GWT permet l'intégration facile avec des bibliothèques GWT permet l'intégration facile avec des bibliothèques
JavaScript externes grâce à son JavaScript Native JavaScript externes grâce à son JavaScript Native Interface (JSNI)Interface (JSNI)
Interagir directement avec JavaScript à partir de Java Interagir directement avec JavaScript à partir de Java et vice-versaet vice-versa
Inclusion automatique des bibliothèques JavaScriptInclusion automatique des bibliothèques JavaScript
// Déclaration de la méthode en Java...// Déclaration de la méthode en Java...
native String inverserNomPrenom(String nom) native String inverserNomPrenom(String nom)
/*-{/*-{
// Implémentation en JavaScript// Implémentation en JavaScript
var re = /(\w+)\s(\w+)/;var re = /(\w+)\s(\w+)/;
return name.replace(re, '$2, $1');return name.replace(re, '$2, $1');
}-*/;}-*/;
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
JSNI : Type Overlay JavaScript JSNI : Type Overlay JavaScript GWT 1.5 introduit le concept de JavaScript Overlay pour simplifier GWT 1.5 introduit le concept de JavaScript Overlay pour simplifier l'intégration de prototypes JavaScript dans GWTl'intégration de prototypes JavaScript dans GWTUne structure de données JSON (JavaScript Object Notation)Une structure de données JSON (JavaScript Object Notation)
var electionsJSON = [var electionsJSON = [
{ "Prenom" : "Pauline", "NomFamille" : "Marois" }, { "Prenom" : "Amir", "NomFamille" : "Khadir" },{ "Prenom" : "Pauline", "NomFamille" : "Marois" }, { "Prenom" : "Amir", "NomFamille" : "Khadir" },
{ "Prenom" : "Mario", "NomFamille" : "Dumont" }, { "Prenom" : "Jean", "NomFamille" : "Charest" }{ "Prenom" : "Mario", "NomFamille" : "Dumont" }, { "Prenom" : "Jean", "NomFamille" : "Charest" }
];];
// Un type Overlay JavaScript// Un type Overlay JavaScript
class PoliticienQC extends JavaScriptObject {class PoliticienQC extends JavaScriptObject {
// Un type Overlay JS a toujours un constructeur protected, à zéro argument// Un type Overlay JS a toujours un constructeur protected, à zéro argument
protected PoliticienQC() { } protected PoliticienQC() { }
// Les méthodes dans un Overlay JavaScript sont en JSNI// Les méthodes dans un Overlay JavaScript sont en JSNI
public final native String getPrenom() /*-{ return this.Prenom; }-*/;public final native String getPrenom() /*-{ return this.Prenom; }-*/;
public final native String getNomFamille() /*-{ return this.NomFamille; }-*/;public final native String getNomFamille() /*-{ return this.NomFamille; }-*/;
// Notez, toutefois, que toutes les méthodes ne sont pas obligatoirement en JSNI// Notez, toutefois, que toutes les méthodes ne sont pas obligatoirement en JSNI
public final String getNomComplet() {public final String getNomComplet() {
return getPrenom() + " " + getNomFamille(); return getPrenom() + " " + getNomFamille();
}}
}}
* Source : http://googlewebtoolkit.blogspot.com* Source : http://googlewebtoolkit.blogspot.com
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
JSNI : Type Overlay JavaScript JSNI : Type Overlay JavaScript // Obtenir un prototype JavaScript pour l'Overlay// Obtenir un prototype JavaScript pour l'Overlay
class MonModuleEntryPoint implements EntryPoint {class MonModuleEntryPoint implements EntryPoint {
public void onModuleLoad() {public void onModuleLoad() {
PoliticienQC p = getPremierPoliticien();PoliticienQC p = getPremierPoliticien();
// Youppi! Maintenant j'ai un prototype JavaScript qui est aussi un PoliticienQC// Youppi! Maintenant j'ai un prototype JavaScript qui est aussi un PoliticienQC
Window.alert("Bonjour, " + p.getPrenom());Window.alert("Bonjour, " + p.getPrenom());
}}
// Utilisation de JSNI pour obtenir le prototype JSON que nous désirons// Utilisation de JSNI pour obtenir le prototype JSON que nous désirons
// Le prototype JSON object reçoit un type Java implicitement // Le prototype JSON object reçoit un type Java implicitement
// en se basant sur le type retourné par la méthode// en se basant sur le type retourné par la méthode
private native PoliticienQC getPremierPoliticien() /*-{private native PoliticienQC getPremierPoliticien() /*-{
// Obtenir une référence au premier PoliticienQC dans le tableau JSON// Obtenir une référence au premier PoliticienQC dans le tableau JSON
return $wnd.electionsJSON[0]; return $wnd.electionsJSON[0];
}-*/;}-*/;
}}
* Source : http://googlewebtoolkit.blogspot.com* Source : http://googlewebtoolkit.blogspot.com
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
GWT GWT –– Structure bibliothèque & APIStructure bibliothèque & API
* Source Clipart : http://www.clipart.com* Source Clipart : http://www.clipart.com
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
BibliothèqueBibliothèque
IUGIUG
Widgets &Widgets &
PanelsPanels
CommunicationCommunication
avec le serveuravec le serveur
RPC & AjaxRPC & Ajax
Analyseur Analyseur
XMLXML
Gestion deGestion de
l'historiquel'historique
Intégration Intégration
à JUnità JUnit
GWT APIGWT API
Trans Trans
compilateur compilateur
Java àJava à
JavaScriptJavaScript
Interface Interface
NativeNative
JavaScriptJavaScript
JSNIJSNI
BibliothèqueBibliothèque
d'émulationd'émulation
JREJRE
La structure du gwt-user.jar de GWT 1.5.3La structure du gwt-user.jar de GWT 1.5.3 GWT GWT –– Structure bibliothèque & APIStructure bibliothèque & API
Note : Transcompilateur GWT Note : Transcompilateur GWT
dans gwt-dev-windows.jardans gwt-dev-windows.jar
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
La structure du gwt-user.jar de GWT 1.5.3La structure du gwt-user.jar de GWT 1.5.3
Cinq grandes catégories :Cinq grandes catégories :
- interface utilisateur- interface utilisateur
- - user.client.ui, dom, animation, user.themeuser.client.ui, dom, animation, user.theme
- communication client-serveur- communication client-serveur
- - http.client, user.client.rpc, user.server.rpchttp.client, user.client.rpc, user.server.rpc
- format des données échangées- format des données échangées
-- xml, json xml, json
- émulation JRE (emul)- émulation JRE (emul)
- - java.io, java.lang, java.sql, java.utiljava.io, java.lang, java.sql, java.util
- utilitaires- utilitaires
-- i18N, junit, benchmarks, user.tools i18N, junit, benchmarks, user.tools
GWT GWT –– Structure bibliothèque & APIStructure bibliothèque & API
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Bibliothèque de composants IUBibliothèque de composants IU
Bibliothèque de composants d'interface-utilisateur analogue Bibliothèque de composants d'interface-utilisateur analogue à SWING qui facilite le développement d'une interface-à SWING qui facilite le développement d'une interface-client qui fonctionne dans tous les fureteursclient qui fonctionne dans tous les fureteurs
Manipulation du DOM en JavaManipulation du DOM en Java
Gestion des événementsGestion des événements
Support des CSSSupport des CSS
I18NI18N
Support du glisser-déposerSupport du glisser-déposer
* Source Clipart : http://www.clipart.com* Source Clipart : http://www.clipart.com
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Interface Utilisateur - Interface Utilisateur - ComposantsComposantsÉléments statiques: étiquetteÉléments statiques: étiquette ( (LabelLabel), HTML, Image, hyperlien (), HTML, Image, hyperlien (HyperlinkHyperlink), champ ), champ caché (caché (HiddenHidden))
Widgets (E/S) : bouton (Widgets (E/S) : bouton (ButtonButton), bouton poussoir (), bouton poussoir (PushButtonPushButton), bouton à bascule ), bouton à bascule ((ToggleButtonToggleButton), case à cocher (), case à cocher (CheckBoxCheckBox), bouton radio (), bouton radio (RadioButtonRadioButton), menu ), menu déroulant (déroulant (ListBoxListBox), zone de texte (), zone de texte (TextBoxTextBox), zone de texte avec suggestions ), zone de texte avec suggestions ((SuggestBoxSuggestBox), zone d'entrée de mot de passe (), zone d'entrée de mot de passe (PasswordTextBoxPasswordTextBox), zone de texte ), zone de texte multiligne (multiligne (TextAreaTextArea), zone d'édition de texte enrichi (), zone d'édition de texte enrichi (RichTextAreaRichTextArea))
Widgets complexes : arbre (Widgets complexes : arbre (TreeTree), barre de menus (), barre de menus (MenuBarMenuBar), téléversement de ), téléversement de fichiers (fichiers (FileUploadFileUpload))
Panneaux de disposition simple : panneau en file (Panneaux de disposition simple : panneau en file (FlowPanelFlowPanel), panneau horizontal ), panneau horizontal ((Horizontal PanelHorizontal Panel), panneau vertical (), panneau vertical (Vertical PannelVertical Pannel), panneau à coulisse ), panneau à coulisse ((HorizontalSplitPanelHorizontalSplitPanel, , VerticalSplitPanelVerticalSplitPanel), panneau HTML (), panneau HTML (HTMLPanelHTMLPanel), panneau ), panneau superposé (superposé (DeckPanelDeckPanel))
Panneaux de disposition complexe : table flexible* (Panneaux de disposition complexe : table flexible* (FlexTableFlexTable), grille (), grille (GridGrid), panneau ), panneau polyptyque* (DockPanel)polyptyque* (DockPanel),, panneau à onglets ( panneau à onglets (TabPanelTabPanel), panneau en pile (), panneau en pile (StackPanelStackPanel))
Panneaux conteneurs simples : panneau composite ou composite (Panneaux conteneurs simples : panneau composite ou composite (CompositeComposite) panneau ) panneau simple (simple (SimplePanelSimplePanel), panneau à barre de défilement (), panneau à barre de défilement (ScrollPanelScrollPanel), panneau de focus ), panneau de focus ((FocusPanelFocusPanel))
Panneaux conteneurs complexes : panneau de formulaire (Panneaux conteneurs complexes : panneau de formulaire (FormPanelFormPanel), panneau à ), panneau à dévoilement* (dévoilement* (DisclosurePanelDisclosurePanel), panneau surprise* (), panneau surprise* (PopupPanelPopupPanel), boîte de dialogue ), boîte de dialogue ((DialogBoxDialogBox))
http://gwt.google.com/samples/Showcase/Showcase.htmlhttp://gwt.google.com/samples/Showcase/Showcase.html
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Gestion des événementsGestion des événements GWT utilise le concept de récepteur (« listener interface ») GWT utilise le concept de récepteur (« listener interface »)
pour traiter les événementspour traiter les événements
Semblable à d'autres canevas d'applications graphiques Semblable à d'autres canevas d'applications graphiques comme SWINGcomme SWING
Le récepteur via l'interface “listener interface” définit une Le récepteur via l'interface “listener interface” définit une ou plusieurs méthodes que le widget appelle en réaction à ou plusieurs méthodes que le widget appelle en réaction à un événementun événement
Button unBouton = new Button("Cliquez moi!");Button unBouton = new Button("Cliquez moi!"); unBouton.addClickListener(new ClickListener() {unBouton.addClickListener(new ClickListener() { public void onClick(Widget emetteur) {public void onClick(Widget emetteur) { // traitement du Clic// traitement du Clic }} });});
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Interface Utilisateur - Interface Utilisateur - ComposantsComposants
// Création d'un bouton qui réagit à un clic grâce à un récepteur de clic// Création d'un bouton qui réagit à un clic grâce à un récepteur de clic
Button bouton = new Button("Cliquez-moi", new ClickListener() {Button bouton = new Button("Cliquez-moi", new ClickListener() {
public void onClick(Widget sender) {public void onClick(Widget sender) {
Window.alert("Bonjour GWT");Window.alert("Bonjour GWT");
}}
});});
Bouton (Button)Bouton (Button)
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Interface Utilisateur - Interface Utilisateur - ComposantsComposants
Case à cocher (CheckBox)Case à cocher (CheckBox)
// Création d'une case à cocher// Création d'une case à cocher
CheckBox caseResidentMtl = new CheckBox("Résident de Montréal");CheckBox caseResidentMtl = new CheckBox("Résident de Montréal");
// La case est cochée par défaut// La case est cochée par défaut
caseResidentMtl.setChecked(true);caseResidentMtl.setChecked(true);
// Attacher un récepteur de clic à la case// Attacher un récepteur de clic à la case
caseResidentMtl.addClickListener(new ClickListener() {caseResidentMtl.addClickListener(new ClickListener() {
public void onClick(Widget sender) {public void onClick(Widget sender) {
boolean estMontrealais = ((CheckBox) sender).isChecked();boolean estMontrealais = ((CheckBox) sender).isChecked();
Window.alert( (estMontrealais ? "" : "non") + " Montréalais");Window.alert( (estMontrealais ? "" : "non") + " Montréalais");
}}
});});
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Interface Utilisateur – Interface Utilisateur – Bouton radioBouton radio
Bouton radio (RadioButton)Bouton radio (RadioButton)
// Création d'un groupe de boutons radio// Création d'un groupe de boutons radio
RadioButton rbBleu = new RadioButton("groupeRbCouleurs", "bleu");RadioButton rbBleu = new RadioButton("groupeRbCouleurs", "bleu");
RadioButton rbBlanc = new RadioButton("groupeRbCouleurs", "blanc");RadioButton rbBlanc = new RadioButton("groupeRbCouleurs", "blanc");
RadioButton rbRouge = new RadioButton("groupeRbCouleurs", "rouge");RadioButton rbRouge = new RadioButton("groupeRbCouleurs", "rouge");
// Cocher le bouton bleu par défaut// Cocher le bouton bleu par défaut
rbBleu.setChecked(true);rbBleu.setChecked(true);
// Ajouter le groupe de boutons radio à un panneau// Ajouter le groupe de boutons radio à un panneau
FlowPanel panneau = new FlowPanel();FlowPanel panneau = new FlowPanel();
panneau.add(rbBleu); panneau.add(rbBleu);
panneau.add(rbBlanc);panneau.add(rbBlanc);
panneau.add(rbRouge);panneau.add(rbRouge);
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Support des CSSSupport des CSS Séparation du code et de la présentationSéparation du code et de la présentation
Code Java :Code Java :public ListWidget(String Item) {public ListWidget(String Item) { ...... setStyleName(“gwt-ListWidget”);setStyleName(“gwt-ListWidget”);}}
Fichier CSS :Fichier CSS :.gwt-ListWidget {.gwt-ListWidget { background-color:black;background-color:black; color:lime;color:lime;}}
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Support des CSS - conseilsSupport des CSS - conseilsCode Java : (usage de CSS primaire et dépendant)
MonPetitWidget monPW = new MonPetitWidget();MonPetitWidget monPW = new MonPetitWidget();monPW.setStylePrimaryName("monPetitWidget");monPW.setStylePrimaryName("monPetitWidget");monPW.addStyleDependentName("selected");monPW.addStyleDependentName("selected");Fichier CSS :Fichier CSS :.monpetitWidget {.monpetitWidget { background-color:black;background-color:black; color:lime;color:lime;}}.monPetitWidget .monPetitWidget-selected {.monPetitWidget .monPetitWidget-selected { color:red;color:red;}}Permet de faire varier facilement l'apparence en fonction de l'étatPermet de faire varier facilement l'apparence en fonction de l'étatNote : Ne pas utiliser les CSS pour la disposition (ex. Note : Ne pas utiliser les CSS pour la disposition (ex.
.monPetitWidget .monPetitWidget { position: absolute; }{ position: absolute; } ))
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
I18N – InternationalisationI18N – Internationalisation
* Source Clipart : http://www.clipart.com* Source Clipart : http://www.clipart.com
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
I18NI18N Le transcompilateur GWT utilise la liaison différée Le transcompilateur GWT utilise la liaison différée
(« Deferred Binding ») pour générer une version (« Deferred Binding ») pour générer une version différente de l'application Web pour chaque langue différente de l'application Web pour chaque langue
Par exemple, puisque GWT supporte 4 navigateurs Par exemple, puisque GWT supporte 4 navigateurs différents, si votre application doit fonctionner en différents, si votre application doit fonctionner en 3 langues, le transcompilateur de GWT produira 3 langues, le transcompilateur de GWT produira 12 versions différentes de votre application au 12 versions différentes de votre application au moment de la compilation moment de la compilation
À l'exécution, GWT choisira la bonne version de À l'exécution, GWT choisira la bonne version de l'application à montrer à l'utilisateurl'application à montrer à l'utilisateur
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
I18N – I18N – mécanismes de localisationmécanismes de localisation ““Constants” pour des chaînes constantes et des Constants” pour des chaînes constantes et des
réglagesréglages ““Messages” pour les chaînes avec des argumentsMessages” pour les chaînes avec des arguments ““DateTimeFormat” pour les dates et l'heureDateTimeFormat” pour les dates et l'heure ““NumberFormat” pour les nombres et les unités NumberFormat” pour les nombres et les unités
de mesurede mesure Pas de processus dynamique (tout est statique et Pas de processus dynamique (tout est statique et
fait à la compilation), sinon il faut développer son fait à la compilation), sinon il faut développer son propre mécanismepropre mécanisme
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
GUI – Patrons de conceptionGUI – Patrons de conception
* Source Clipart : http://www.clipart.com* Source Clipart : http://www.clipart.com
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
GUI – Patrons de conception - MVCGUI – Patrons de conception - MVCPatron MVCPatron MVC
Client MVCClient MVC
VV CC
VueVue: :
Affiche les Affiche les informations et informations et achemine les achemine les actions de l'usageractions de l'usager
ContrôleurContrôleur::
Établit les liens Établit les liens entre le Modèle et entre le Modèle et la Vuela Vue
Reçoit les Reçoit les événements de la événements de la Vue et gère les Vue et gère les actions de l'usager actions de l'usager
accès en lecture
accès en lecture
aux données
aux donnéesnotification
notification
événementsévénements
mise
à jo
ur
mise
à jo
ur
chan
gem
ent d
es d
onné
es
chan
gem
ent d
es d
onné
es
Échages de Échages de
donnéesdonnées
Présentation découpléePrésentation découplée
mise à jourmise à jour
MM
ModèleModèle: :
Données de l'application Données de l'application (POJOs) Notifie les (POJOs) Notifie les changements du modèle changements du modèle par des événements par des événements transmis aux vues transmis aux vues abonnées abonnées
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
GUI – Patrons de conception - GUI – Patrons de conception - ObservateurObservateur
* Source figure : R. Dewsbury 2008 – Chap.2, p.96* Source figure : R. Dewsbury 2008 – Chap.2, p.96
Le Modèle utilise le patron de conception Observateur (Observer Pattern) pour informer la Le Modèle utilise le patron de conception Observateur (Observer Pattern) pour informer la Vue/Contrôleur du changement des données et bien découpler la Vue du ModèleVue/Contrôleur du changement des données et bien découpler la Vue du Modèle
Ainsi, différents éléments du Modèle servent de sujets ou données observables (Subjects) à Ainsi, différents éléments du Modèle servent de sujets ou données observables (Subjects) à un ensemble d'observateurs (Observers) contenus dans les Vues/Contrôleurs qui sont en un ensemble d'observateurs (Observers) contenus dans les Vues/Contrôleurs qui sont en quelque sorte abonnés aux modifications des données du modèle.quelque sorte abonnés aux modifications des données du modèle.
Programmation événementielle qui favorise un découplage des composants Programmation événementielle qui favorise un découplage des composants
Compromis entre un petit nombre d'événements généraux du genre « quelque chose » a Compromis entre un petit nombre d'événements généraux du genre « quelque chose » a changé dans le modèle (granularité grossière) et un grand nombre de petits événements changé dans le modèle (granularité grossière) et un grand nombre de petits événements reliés à des éléments très précis du modèle (granularité fine).reliés à des éléments très précis du modèle (granularité fine).
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
GUI – Patrons de conception - GUI – Patrons de conception - CompositeComposite
* Source : http://www.google.com* Source : http://www.google.com
Patron Composite (ou Object Composite)Patron Composite (ou Object Composite)
Facilite la création de WidgetsFacilite la création de Widgets
S'utilise chaque fois qu'on crée un nouveau widget à partir de widgets existantsS'utilise chaque fois qu'on crée un nouveau widget à partir de widgets existants
Offre un meilleur contrôle sur l'API exposéOffre un meilleur contrôle sur l'API exposé
Généralement préférable à l'utilisation de l'héritageGénéralement préférable à l'utilisation de l'héritage
* Source : http://fr.wikipedia.org/wiki/Objet_composite* Source : http://fr.wikipedia.org/wiki/Objet_composite
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
GUI – Patrons de conception - GUI – Patrons de conception - CompositeComposite
class MonPremierComposite extends Composite {
private VerticalPanel conteneur = new VerticalPanel();
private Label monTitre = new Label();
private TextBox maZoneTexte = new TextBox();
// Constructeur
public MonPremierComposite() {
conteneur.add(monTitre);
conteneur.add(maZoneTexte);
initWidget(conteneur);
}
}
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
GUI – Règle de codage – GUI – Règle de codage – Accès aux élémentsAccès aux éléments
Chaque composant « modifiable » d'une vue est muni Chaque composant « modifiable » d'une vue est muni d'un accesseur et d'un test d'existence.d'un accesseur et d'un test d'existence.
public Label getNom() {public Label getNom() {
if ( this.nom == null ) {if ( this.nom == null ) {
this.nom = new Label(“”);this.nom = new Label(“”);
}}
return this.nom;return this.nom;
}}
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Communication client-serveur & AjaxCommunication client-serveur & Ajax
* Source Clipart : http://www.clipart.com* Source Clipart : http://www.clipart.com
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Communication client-serveur & AjaxCommunication client-serveur & Ajax
* Source : http://www.google.com* Source : http://www.google.com
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Communication client-serveur & AjaxCommunication client-serveur & AjaxLe RPC (« Remote Procedure Call »), appel de procédure à Le RPC (« Remote Procedure Call »), appel de procédure à distancedistance
RPC rend facile l'échange d'objets Java (sérialisés) entre le code-RPC rend facile l'échange d'objets Java (sérialisés) entre le code-client et le code-serveurclient et le code-serveur
Fournit une procédure automatique de sérialisation des objetsFournit une procédure automatique de sérialisation des objets
Autres outils Ajax :Autres outils Ajax :
HTTPRequestHTTPRequest
RequestBuilderRequestBuilder
FormPanelFormPanel
Support de :Support de :
XMLXML
JSON (JavaScript Object Notation) JSON (JavaScript Object Notation)
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Compilation & déploiement serveur RPCCompilation & déploiement serveur RPC
Compilateur JavaCompilateur Java
gwt-user.jargwt-user.jar gwt-servlet.jargwt-servlet.jar
Autres .jarAutres .jar
serveurs sansserveurs sans
restrictionsrestrictions
Code Java Code Java serveur serveur (servlet) (servlet)
MonService MonService ImplImpl
Interfaces Interfaces client Java client Java MonService MonService MonService MonService
AsyncAsync
Données à Données à échanger échanger
MesDonnee MesDonnee DODO
WEB-INF/WEB-INF/classes/../client/
MonServiceImpl(servlet)
EclipseEclipse
Configuration Configuration web.xmlweb.xml
Configuration Configuration web.xmlweb.xml
gwt-servlet.jargwt-servlet.jar
lib/lib/
Model/Model/
MesDonneesDOMesDonneesDO
Services/Services/
MonService MonService
MonServiceAsyncMonServiceAsync
classes/../server/classes/../server/
Compilateur JavaCompilateur Java
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
RPC (Remote Procedure Call)RPC (Remote Procedure Call)
J
GWT offre le très utile mécanisme du RPC (Remote Procedure Call), GWT offre le très utile mécanisme du RPC (Remote Procedure Call),
comme moyen de communiquer avec les services hébergé sur un serveur JEEcomme moyen de communiquer avec les services hébergé sur un serveur JEE
Client et serveur parlent alors le même langage, i.e. le JavaClient et serveur parlent alors le même langage, i.e. le Java
Pratique! Le client et le serveur parlent le même langage (Java)Pratique! Le client et le serveur parlent le même langage (Java)
* Source : http://www.google.com* Source : http://www.google.com
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
RPC (Remote Procedure Call)RPC (Remote Procedure Call)import com.google.gwt.user.client.rpc.IsSerializable;import com.google.gwt.user.client.rpc.IsSerializable;
public class MesDonneesDO implements IsSerializable {public class MesDonneesDO implements IsSerializable {
//...//...
}}
Un objet Java MesDonneesDO à échangerUn objet Java MesDonneesDO à échanger
Une deuxième interface dite asynchrone spécifie getReponseMonservice( ) mais Une deuxième interface dite asynchrone spécifie getReponseMonservice( ) mais avec un paramètre supplémentaire sous la forme d'une procédure de rappel (« avec un paramètre supplémentaire sous la forme d'une procédure de rappel (« Callback ») que le code-client utilisera pour appeler le service. Callback ») que le code-client utilisera pour appeler le service.
Une première interface définit le serviceUne première interface définit le service
import com.google.gwt.user.client.rpc.RemoteService;import com.google.gwt.user.client.rpc.RemoteService;
public interface MonService extends RemoteService {public interface MonService extends RemoteService {
MesDonneesDO getReponseMonService(String requete);MesDonneesDO getReponseMonService(String requete);
}}
import com.google.gwt.user.client.rpc.AsyncCallback;import com.google.gwt.user.client.rpc.AsyncCallback;
public interface MonServiceAsync {public interface MonServiceAsync {
public void getReponseMonService(String requete,public void getReponseMonService(String requete,
AsyncCallback maProcedureDeRappel);AsyncCallback maProcedureDeRappel);
}}
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
import com.google.gwt.user.server.rpc.RemoteServiceServlet;import com.google.gwt.user.server.rpc.RemoteServiceServlet;import qc.ets.web2.gwt.client.MesDonneesDO; import qc.ets.web2.gwt.client.MesDonneesDO; import qc.ets.web2.gwt.client.MonService;import qc.ets.web2.gwt.client.MonService;public class MonServiceImpl extends RemoteServiceServlet implements MonService {public class MonServiceImpl extends RemoteServiceServlet implements MonService {
public MesDonneesDO getReponseMonService(String requete) {public MesDonneesDO getReponseMonService(String requete) { if (requete.length() < 1) {if (requete.length() < 1) { throw new IllegalArgumentException("Requete invalide.");throw new IllegalArgumentException("Requete invalide."); }} MesDonneesDO resultat = new MesDonneesDO();MesDonneesDO resultat = new MesDonneesDO(); resultat.setDonnees("...");resultat.setDonnees("..."); if ( isInvalide( resultat )) {if ( isInvalide( resultat )) {
return null;return null;}}
return resultat;return resultat;}}public boolean isInvalide(MesDonneesDO resultat) {public boolean isInvalide(MesDonneesDO resultat) {
Return true; // à modifierReturn true; // à modifier}}
}}
Classe à implémenter du côté serveur hérite de Classe à implémenter du côté serveur hérite de com.google.gwt.user.server.rpc.RemoteServiceServletcom.google.gwt.user.server.rpc.RemoteServiceServlet
RPC - Code-serveurRPC - Code-serveur
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT;import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT;import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.*;import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.*;import com.google.gwt.user.client.rpc.ServiceDefTarget; import qc.ets.web2.gwt.client.MesDonneesDO; import com.google.gwt.user.client.rpc.ServiceDefTarget; import qc.ets.web2.gwt.client.MesDonneesDO; import qc.ets.web2.gwt.client.MonService; import qc.ets.web2.gwt.client.MonServiceAsync;import qc.ets.web2.gwt.client.MonService; import qc.ets.web2.gwt.client.MonServiceAsync;public class MonClientRPC implements EntryPoint {public class MonClientRPC implements EntryPoint {
public void onModuleLoad() {public void onModuleLoad() {final Button bouton = new Button("Appel RPC");final Button bouton = new Button("Appel RPC");final MonServiceAsync serviceProxy = (MonServiceAsync)GWT.create(qc.ets.web2.gwt.client.MonService.class);final MonServiceAsync serviceProxy = (MonServiceAsync)GWT.create(qc.ets.web2.gwt.client.MonService.class);
ServiceDefTarget pointService = (ServiceDefTarget) serviceProxy;ServiceDefTarget pointService = (ServiceDefTarget) serviceProxy; pointService.setServiceEntryPoint(GWT.getModuleBaseURL() + "/reponseService");pointService.setServiceEntryPoint(GWT.getModuleBaseURL() + "/reponseService");
bouton.addClickListener(new ClickListener( ) {bouton.addClickListener(new ClickListener( ) {public void onClick(Widget emetteur) {public void onClick(Widget emetteur) {
AsyncCallback maProcedureDeRappel = new AsyncCallback() { AsyncCallback maProcedureDeRappel = new AsyncCallback() { public void onSuccess(Object resultat) {public void onSuccess(Object resultat) {
MesDonneesDO resultatDO = (MesDonneesDO) resultat;MesDonneesDO resultatDO = (MesDonneesDO) resultat;System.out.println("*** SUCCES RPC ***\n" + resultatDO.getDonnees());System.out.println("*** SUCCES RPC ***\n" + resultatDO.getDonnees());
}}public void onFailure(Throwable erreur) {public void onFailure(Throwable erreur) {
System.out.println("*** ERREUR RPC ***" + erreur.getMessage());System.out.println("*** ERREUR RPC ***" + erreur.getMessage());}}
};};serviceProxy.getReponseMonService("Requete bidon", maProcedureDeRappel);serviceProxy.getReponseMonService("Requete bidon", maProcedureDeRappel);
}});}});RootPanel.get("emprise1").add(bouton);RootPanel.get("emprise1").add(bouton);
}}}}
Le client n'est pas encore connecté au service. Nous pouvons faire cela en ajoutant un Le client n'est pas encore connecté au service. Nous pouvons faire cela en ajoutant un récepteur (Listener) à un élément de l'interface, ce qui peut être fait avec une classe interne.récepteur (Listener) à un élément de l'interface, ce qui peut être fait avec une classe interne.
RPC - Code-clientRPC - Code-client
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Gestion de l'historique du navigateurGestion de l'historique du navigateur La gestion de l'historique du navigateur s'occupe des La gestion de l'historique du navigateur s'occupe des
boutons « avancer » et « reculer » et des liensboutons « avancer » et « reculer » et des liens Une API simple de gestion de l'historique basée sur Une API simple de gestion de l'historique basée sur
une pile de jetonsune pile de jetons– Lorsque l'application démarre, la pile est videLorsque l'application démarre, la pile est vide– Lorsque l'utilisateur clique sur quelque choseLorsque l'utilisateur clique sur quelque chose
• Vous pouvez ajouter des jetons sur la pileVous pouvez ajouter des jetons sur la pile
History.newItem(“nouveauJeton”)History.newItem(“nouveauJeton”)• Classe Hyperlink ajoute des jetons automatiquementClasse Hyperlink ajoute des jetons automatiquement
– Vous pouvez aussi réagir aux événements “History Vous pouvez aussi réagir aux événements “History events” en utilisant un HistoryListenerevents” en utilisant un HistoryListener
History.addHistoryListener(controle)History.addHistoryListener(controle)
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Démo – Bâtir desDémo – Bâtir des applications GWT applications GWT
GWTGWTen Actionen Action
* Source Clipart : http://www.clipart.com* Source Clipart : http://www.clipart.com
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Créer un squelette d'application GWTCréer un squelette d'application GWT
G G W W TT
GWT crée automatiquement un code-client GWT crée automatiquement un code-client rudimentairerudimentaire
Vous pouvez ensuite mettre de la chair sur ce Vous pouvez ensuite mettre de la chair sur ce squelette dans le but de créer une application Web squelette dans le but de créer une application Web plus sophistiquéeplus sophistiquée
* Source Clipart : http://www.clipart.com* Source Clipart : http://www.clipart.com
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Créer un squelette d'application GWTCréer un squelette d'application GWT
public class Bonjour implements EntryPoint {public class Bonjour implements EntryPoint {
public void onModuleLoad() {public void onModuleLoad() {
Button bouton = new Button("Cliquez-moi!",Button bouton = new Button("Cliquez-moi!",
new ClickListener() {new ClickListener() {
public void onClick(Widget sender) {public void onClick(Widget sender) {
Window.alert("Bonjour GWT");Window.alert("Bonjour GWT");
}}
});});
RootPanel.get().add(bouton);RootPanel.get().add(bouton);
}}
}}
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Google Web Toolkit ApplicationsGoogle Web Toolkit Applications
par Ryan Dewsburypar Ryan Dewsbury
608 pages608 pages
Prentice Hall Prentice Hall
(15 décembre, 2007)(15 décembre, 2007)
www.gwtapps.comwww.gwtapps.com
GWT in Action: Easy Ajax with the Google Web GWT in Action: Easy Ajax with the Google Web
ToolkitToolkit
par Robert Hanson, Adam Tacypar Robert Hanson, Adam Tacy
600 pages600 pages
Manning Publications Manning Publications
(5 juin, 2007)(5 juin, 2007)
www.manning.com/hanson/www.manning.com/hanson/
Ressources - LivresRessources - Livres
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
Ressources - LivresRessources - Livres
GWT in PracticeGWT in Practice
par Robert T. Cooper, Charlie E. Collinspar Robert T. Cooper, Charlie E. Collins
358 pages358 pages
Manning Publications Manning Publications
(12 mai, 2008)(12 mai, 2008)
www.manning.com/cooper/www.manning.com/cooper/
Google Web Toolkit Solutions : More Cool & Google Web Toolkit Solutions : More Cool &
Useful StuffUseful Stuff
par David Geary, Rob Gordonpar David Geary, Rob Gordon
408 pages408 pages
Prentice HallPrentice Hall
(17 novembre, 2007)(17 novembre, 2007)
www.coolandusefulgwt.comwww.coolandusefulgwt.com
GTI-780 / MTI-780GTI-780 / MTI-780 Montréal, novembre 2008Montréal, novembre 2008
QuestionsQuestions
??
* Source Clipart : http://www.clipart.com* Source Clipart : http://www.clipart.com