Google Web Toolkit 1.5 JW-GWT
Ce qui précède n'affecte en rien vos droits en tant qu'utilisateur  (exceptions au droit d'auteur : copies réservées à l'u...
Plan du séminaire
Google Web Toolkit – Plan Général (1) <ul><li>Introduction </li></ul><ul><ul><li>Les technologies du Web 2.0 </li></ul></u...
Google Web Toolkit – Plan Général (2) <ul><li>Communications asynchrones </li></ul><ul><ul><li>Présentation de GWT RPC </l...
Introduction
Naissance des RIA (1) <ul><li>L'histoire du développement d'applications a connu plusieurs grandes phases </li></ul><ul><u...
Naissance des RIA (2) <ul><li>Les terminaux passifs </li></ul><ul><ul><li>Terminaux connectés à un mainframe (3270), inter...
Naissance des RIA (3) <ul><li>La révolution internet et intranet </li></ul><ul><ul><li>A partir de 1995, internet se dével...
Naissance des RIA (4) <ul><li>L'évolution vers les 'clients riches' </li></ul><ul><ul><li>Les demandes d'applications intr...
RIA, Web 2.0 et Ajax <ul><li>Le terme Web 2.0 résume l'évolution vers plus de richesse des sites internet </li></ul><ul><u...
Ajax <ul><li>En 2005, le terme Ajax est apparu mettant un nom sur une pratique de plus en plus courante </li></ul><ul><ul>...
DHTML <ul><li>Après avoir téléchargé un fichier HTML, le navigateur créé en mémoire un arbre représentant la structure de ...
L’approche de GWT <ul><li>Mai 2006 : annonce de GWT à la conférence JavaOne </li></ul><ul><ul><li>Google Web Toolkit </li>...
Avantages de l'approche GWT <ul><li>Développer et maintenir des applis Javascript </li></ul><ul><ul><li>Supportant les spé...
Principes généraux (1) <ul><li>Mise à disposition de librairies de classe Java </li></ul><ul><ul><li>Classes graphiques (w...
Principes généraux (2) <ul><li>Développement des applications reste difficile </li></ul><ul><ul><li>Tests unitaires avec J...
Schéma général Compilateur Java->Javascript JRE Emulation JSNI JavaScript Native Interface Widgets &Panels I18n RPC Gestio...
Compilation Java <ul><li>Transformation du code source Java </li></ul><ul><ul><li>Décrivant des classes, des méthodes </li...
Compilation GWT Java vers JavaScript <ul><li>Exécuter la classe com.google.gwt.dev.GWTCompiler </li></ul><ul><ul><li>Avec ...
Modes de compilation <ul><li>Mode &quot;OBFUSCATE&quot; </li></ul><ul><ul><li>Nom de classes, d'attributs, de méthodes, … ...
Fichiers générés (&quot;permutation&quot;) <ul><li>Autant de fichiers que de combinaisons </li></ul><ul><ul><li>Type de na...
Intégration JSNI <ul><li>Méthodes natives </li></ul><ul><ul><li>En Java : méthodes dont le code existera dans la jvm </li>...
JRE Emulation <ul><li>Reprend un sous ensemble des classes de base Java </li></ul><ul><ul><li>Fournit un équivalent JavaSc...
Limitations <ul><li>Syntaxe Java 5 (enum, types génériques, …) </li></ul><ul><ul><li>Supportée depuis GWT 1.5 </li></ul></...
Comparaisons <ul><li>Swing </li></ul><ul><ul><li>Logique similaire mais pas de MVC (pas de modèle), pas de Layout </li></u...
Développer une appli GWT
Installation <ul><li>Vérifier la présence d'un JRE </li></ul><ul><ul><li>Version 1.5 supportée depuis GWT 1.5 </li></ul></...
Installation : arborescence obtenue C:GWT │  about.html  │  about.txt │  applicationCreator.cmd  script de création d'appl...
Créer et tester une application <ul><li>Script &quot;applicationCreator&quot; </li></ul><ul><ul><li>Fait partie des fichie...
Créer et tester une application : création <ul><li>Création d'une application simple App </li></ul><ul><li>Fichiers produi...
Tester l'application : mode &quot;hosted&quot; <ul><li>Utiliser le script &quot;App-shell&quot; généré </li></ul><ul><ul><...
Fichiers ajoutés par le mode &quot;Hosted&quot; <ul><li>Mode &quot;Hosted&quot; ajoute une arborescence tomcat </li></ul><...
Tester l'application : mode &quot;Web&quot; <ul><li>Utiliser le script &quot;App-compile&quot; généré </li></ul><ul><li>Ou...
Fichiers ajoutés par le mode &quot;Web&quot; <ul><li>Mode &quot;Web&quot; utilise la version compilée JavaScript </li></ul...
Utilisation dans un IDE <ul><li>Développement GWT = Développement Java pur </li></ul><ul><ul><li>N'importe quel IDE convie...
Cycle de développement <ul><li>Scripts = cycle de dév </li></ul><ul><li>Ne pas oublier &quot;-eclipse&quot; </li></ul><ul>...
Script &quot;projectCreator&quot; <ul><li>Création de la structure de projet </li></ul><ul><li>Remarques </li></ul><ul><ul...
Script &quot;applicationCreator&quot; <ul><li>Création de l'application par défaut </li></ul><ul><li>Remarques </li></ul><...
Script &quot;i18nCreator&quot; <ul><li>Création du support de l'internationalisation </li></ul><ul><li>On étudiera cela en...
Script &quot;junitCreator&quot; <ul><li>Création du support de JUnit </li></ul><ul><li>On étudiera cela en détail plus tar...
Import dans eclipse <ul><li>Import de projet existant </li></ul><ul><ul><li>Recopier les fichiers dans le workspace </li><...
Autres alternatives de création de projet <ul><li>Ecrire les fichiers à la main </li></ul><ul><ul><li>Pas très réaliste </...
Cypal Studio (1) <ul><li>Plugin eclipse pour simplifier l'utilisation de GWT </li></ul><ul><ul><li>Site http://code.google...
Cypal Studio (2) <ul><li>Installation </li></ul><ul><ul><li>Pré-requis :  Eclipse IDE for Java EE Developers  (Eclipse + W...
Cypal Studio (3) <ul><li>Création d'un projet </li></ul><ul><ul><li>Cypal fonctionne pour les projets de type 'Dynamic Web...
Cypal Studio (4) <ul><li>Création d'un module GWT </li></ul><ul><ul><li>A partir de menu 'File->New…' lancer l'assistant d...
Cypal Studio (5) <ul><li>Pour tester </li></ul><ul><ul><li>Ouvrir le gestionnaire des configurations de lancement </li></u...
Les composants graphiques
Interface EntryPoint <ul><li>L'interface désignant un point d'entrée d'application </li></ul><ul><li>Méthode onModuleLoad(...
Les fenêtres et les panels <ul><li>Notions classiques des interfaces graphiques </li></ul><ul><ul><li>Widget = contrôle ut...
Window <ul><li>Classe encapsulant la fenêtre du navigateur </li></ul><ul><ul><li>Équivalent de l'objet &quot;window&quot; ...
RootPanel <ul><li>Panel racine </li></ul><ul><ul><li>Associé à un élément de la page </li></ul></ul><ul><ul><li>Créé par l...
Les composants graphiques <ul><li>Widget : classe Java </li></ul><ul><ul><li>En général en correspondance avec un équivale...
UIObject <ul><li>La racine des objets graphiques </li></ul><ul><ul><li>Encapsule un élément DOM </li></ul></ul><ul><ul><ul...
Début de hiérarchie (UIObject) UIObject MenuItem MenuItemSeparator TreeItem Widget Composite FileUpload FocusWidget Frame ...
Widget <ul><li>Classe abstraite héritant de UIObject </li></ul><ul><ul><li>Possède une représentation DOM interne </li></u...
MenuBar, MenuItem et Command <ul><li>MenuBar </li></ul><ul><ul><li>Contient des MenuItem et MenuItemSeparator </li></ul></...
Interfaces HasText et HasHTML <ul><li>HasText </li></ul><ul><ul><li>Identifie un composant contenant un texte </li></ul></...
Interface HasAnimation <ul><li>Marque un widget utilisant une animation </li></ul><ul><li>Propose de quoi tester et active...
MenuBar : exemple MenuBar menu = new MenuBar(); MenuBar menuFichier = new MenuBar(true); menuFichier.addSeparator(); Comma...
Widget : Image <ul><li>Un widget pour afficher une image </li></ul><ul><li>Préciser une URL </li></ul><ul><ul><li>Soit dan...
Widget : Frame <ul><li>Un widget pour encapsuler un site </li></ul><ul><ul><li>Utilise un frame invisible (IFRAME) </li></...
Widget : Hidden <ul><li>Un widget pour encapsuler un champ caché </li></ul><ul><ul><li>Permet de gérer le nom et la valeur...
Widget : Hyperlink <ul><li>Un widget pour spécifier un hyperlien &quot;interne&quot; </li></ul><ul><ul><li>Un lien vers un...
Interface HasDirection <ul><li>Indiquer qu'un widget possède son sens de lecture </li></ul><ul><ul><li>Propose les accesse...
Interface HasWordWrap <ul><li>Marque un widget disposant de la propriété WordWrap </li></ul><ul><ul><li>Permet d'activer l...
Interface HasAlignment <ul><li>Marque un widget avec alignement horizontal et vertical </li></ul><ul><li>Hérite de l'inter...
Hiérarchie partielle (Label) UIObject Widget Label HTML InlineLabel InlineHTML
Widget : Label <ul><li>Un widget contenant du texte brut </li></ul><ul><li>Implémente </li></ul><ul><ul><li>HasText (mais ...
Widget : HTML <ul><li>Un label contenant du texte HTML </li></ul><ul><ul><li>Hérite des interfaces de Label et ajoute HasH...
Widget : Tree <ul><li>Un widget pour représenter une arborescence </li></ul><ul><ul><li>Implémente HasAnimation, HasFocus ...
Widget : FileUpload <ul><li>Encapsule la fonctionnalité du navigateur </li></ul><ul><ul><li>L'utilisateur choisit un fichi...
Hiérarchie partielle (FocusWidget) UIObject Widget FocusWidget Anchor ListBox SimpleCheckBox ButtonBase RichTextArea Butto...
Interface HasFocus <ul><li>Marque un widget capable de gérer le focus </li></ul><ul><ul><li>Hérite de SourcesFocusEvent et...
Widget : FocusWidget <ul><li>Racine des widgets capables de gérer le focus </li></ul><ul><ul><li>D'autres widgets implémen...
Interface HasName <ul><li>Marque un widget disposant d'un nom </li></ul><ul><ul><li>Propose les méthodes getName() et setN...
Widget : Anchor <ul><li>Un widget représentant un ancrage </li></ul><ul><ul><li>Encapsule un élément <a> </li></ul></ul><u...
Widget : ButtonBase et Button <ul><li>Racine des widgets de type Bouton </li></ul><ul><ul><li>Traditionnellement les Butto...
Widget : CheckBox, SimpleCheckBox <ul><li>Widget représentant une case à cocher </li></ul><ul><ul><li>Introduit une propri...
Widget : RadioButton, SimpleRadioButton <ul><li>Des boutons exclusifs </li></ul><ul><ul><li>Doivent appartenir à un même &...
Widget : CustomButton <ul><li>Racine des boutons personnalisables </li></ul><ul><li>Associer des images ou des textes </li...
Widget : PushButton <ul><li>Un bouton d'action personnalisable </li></ul><ul><ul><li>Permet de lui associer des images </l...
Widget : ToggleButton <ul><li>Un CheckBox personnalisable </li></ul><ul><ul><li>Spécifier des images, le bouton peut reste...
Widget : TextBoxBase <ul><li>Racine des widgets de saisie textuelle </li></ul><ul><ul><li>Implémente HasText, HasName et H...
Widget : TextBox, PasswordTextBox <ul><li>Le champ de saisie standard </li></ul><ul><ul><li>Une seule ligne </li></ul></ul...
Widget : TextArea <ul><li>Une zone de texte multi-lignes </li></ul><ul><ul><li>Implémente HasDirection en plus </li></ul><...
Widget : RichTextArea <ul><li>Saisie de texte riche (HTML) </li></ul><ul><ul><li>Style et formatage </li></ul></ul><ul><ul...
Widget : ListBox (1) <ul><li>Liste de choix </li></ul><ul><ul><li>Items sont des String, gérés par leur indice </li></ul><...
Widget : ListBox (2) <ul><li>Possibilité de distinguer item et sa valeur </li></ul><ul><ul><li>Méthode addItem(String item...
La notion de layout <ul><li>Logique différente de Swing </li></ul><ul><ul><li>Difficile de mapper vers des éléments HTLM <...
Panel, Composite et HasWidgets <ul><li>Pattern &quot;composite&quot; classique dans les GUI </li></ul><ul><ul><li>Certains...
Interface HasWidgets <ul><li>Marque un widget qui peut contenir des widgets </li></ul><ul><ul><li>Hérite de Iterable qui p...
Hiérarchie partielle (Panel) UIObject Widget Panel ComplexPanel HorizontalSplitPanel AbsolutePanel HTMLTable SimplePanel V...
Panel <ul><li>Racine des conteneurs de widgets </li></ul><ul><ul><li>Plutôt destiné au layout </li></ul></ul><ul><ul><li>I...
Panel : attachement et détachement (1) <ul><li>Fuite mémoire en JavaScript : problème classique </li></ul><ul><ul><li>Garb...
Panel : attachement et détachement (2) <ul><li>Respecter quelques règles </li></ul><ul><ul><li>Appeler super.onAttach() si...
SimplePanel, ComplexPanel <ul><li>Contenir un seul ou plusieurs widgets </li></ul><ul><li>SimplePanel </li></ul><ul><ul><l...
Interface IndexedPanel <ul><li>Marque un panel aux widgets accessibles pas indice </li></ul><ul><ul><li>Implique un ordre ...
FlowPanel <ul><li>Organise ses widgets en lignes </li></ul><ul><ul><li>C'est le layout naturel de HTML </li></ul></ul><ul>...
CellPanel <ul><li>Dispose ses widgets dans une table </li></ul><ul><ul><li>Un widget par cellule </li></ul></ul><ul><ul><l...
HorizontalPanel, VerticalPanel <ul><li>Dispose ses widgets horizontalement </li></ul><ul><ul><li>Pas de retour à la ligne ...
DockPanel <ul><li>Organise ses widgets dans des zones </li></ul><ul><ul><li>NORTH, SOUTH, EAST, WEST, CENTER </li></ul></u...
Exemple DockPanel
DeckPanel <ul><li>Organise ses widgets en un tas </li></ul><ul><ul><li>Comme un tas de carte </li></ul></ul><ul><ul><li>Un...
StackPanel <ul><li>Organise ses widgets en une pile verticale </li></ul><ul><ul><li>Un seul montré à la fois : showStack(i...
DecoratedStackPanel <ul><li>Ajoute simplement une décoration </li></ul><ul><ul><li>Gestion de coins arrondis à l'aide d'im...
AbsolutePanel <ul><li>Positionnement absolu de ses widgets </li></ul><ul><ul><li>Widgets peuvent se chevaucher </li></ul><...
HTMLPanel <ul><li>Approche complètement différente </li></ul><ul><ul><li>Encapsuler du code HTML </li></ul></ul><ul><ul><l...
HTMLTable <ul><li>Panel à base de cellules en colonnes </li></ul><ul><ul><li>Ne pas confondre avec HTMLPanel </li></ul></u...
Grid <ul><li>Une table avec des dimensions prédéfinies </li></ul><ul><ul><li>Constructeur Grid(int numRow, int numColumn) ...
FlexTable <ul><li>Une table flexible </li></ul><ul><ul><li>Permet de créer des cellules à la demande </li></ul></ul><ul><u...
DecoratorPanel <ul><li>Ajouter une décoration autour d'un widget </li></ul><ul><ul><li>En général, le widget contenu est u...
PopupPanel <ul><li>Un panel qui &quot;surgit&quot; au dessus des autres </li></ul><ul><ul><li>Typiquement tooltip, menu, d...
DialogBox <ul><li>Les boîtes de dialogues </li></ul><ul><ul><li>Implémente HasText (le titre appelé &quot;Caption&quot;) <...
Exemple DialogBox
ScrollPanel <ul><li>Placer un widget dans une zone scrollable </li></ul><ul><ul><li>Affiche une partie de ce widget conten...
HorizontalSplitPanel <ul><li>Dispose deux widgets horizontalement </li></ul><ul><ul><li>Barre de séparation permet de redi...
VerticalSplitPanel <ul><li>Dispose deux widgets verticalement </li></ul><ul><ul><li>Barre de séparation permet de redimens...
Intégrer GWT dans une page HTML <ul><li>On peut ajouter du code HTML dans la page </li></ul><ul><ul><li>Ressources dans le...
Hiérarchie partielle (Composite) UIObject Widget Composite CaptionPanel TabPanel DisclosurePanel SuggestBox DecoratedTabPa...
Widget : Composite <ul><li>Racine des widgets &quot;composite&quot; </li></ul><ul><ul><li>Des widgets constitués de plusie...
Widget : CaptionPanel <ul><li>Cadre avec label autours d'un composant </li></ul><ul><ul><li>Le label peut être texte ou HT...
Widget : DisclosurePanel <ul><li>Contient &quot;header&quot; et widget escamotable </li></ul><ul><ul><li>Cliquer sur le &q...
Widget : SuggestBox <ul><li>Un champs de saisie avec suggestion </li></ul><ul><ul><li>Propose dynamiquement une liste en c...
Widget : TabBar, DecoratedTabBar <ul><li>Une barre d'onglets (utilisée avec TabPanel) </li></ul><ul><ul><li>Onglet de type...
Widget : TabPanel <ul><li>Gestion d'onglets </li></ul><ul><ul><li>Composite agrégeant un TabPanel et un DeckPanel </li></u...
Autres composants <ul><li>Projets open sources proposent d'autres widgets </li></ul><ul><ul><li>Calendrier, table triée, c...
S'abstraire du JavaScript ? <ul><li>Philosophie générale mais pas toujours possible </li></ul><ul><ul><li>Besoin parfois d...
Gestion de l'i18n
Gestion de l’internationalisation <ul><li>Couvre plusieurs aspects </li></ul><ul><ul><li>Configuration de l'application </...
DeferredBinding <ul><li>Technique pour pallier l'absence de &quot;dynamic binding&quot; </li></ul><ul><ul><li>En clair : p...
I18n : configuration <ul><li>Déclaration dans le fichier de description de module </li></ul><ul><ul><li>Déclarer une dépen...
NumberFormat <ul><li>La classe pour formater des nombres et monnaies </li></ul><ul><ul><li>Méthode format(double) pour for...
DateTimeFormat <ul><li>La classe pour formater les dates </li></ul><ul><ul><li>Méthodes format() pour formater une Date </...
Gestion des messages <ul><li>Similaire aux fichiers de properties </li></ul><ul><ul><li>Stoquer des strings et nombres dan...
I18n : interface Constants <ul><li>Déclarer une interface héritant de Constants </li></ul><ul><ul><li>Créer des méthodes d...
I18n : interface ConstantsWithLookup <ul><li>Même principe mais ajoute une méthode de lookup </li></ul><ul><ul><li>Permet ...
I18n : interface Messages <ul><li>Même mécanisme mais avec des paramètres </li></ul><ul><li>Hériter de l'interface Message...
(Dés)Avantages de l'inclusion statique <ul><li>Inclus dans le code compilé </li></ul><ul><li>Aussi performant qu'une const...
I18n : inclusion dynamique <ul><li>Classe Dictionary </li></ul><ul><ul><li>N'utilise pas de fichier de propriétés </li></u...
Les styles CSS
Les styles CSS (1) <ul><li>Rappel (pour plus d'info http://fr.selfhtml.org) </li></ul><ul><ul><li>Sert à séparer la présen...
Les styles CSS (2) <ul><li>Peuvent se combiner pour plus de concision </li></ul><ul><ul><li>Regrouper des sélecteurs </li>...
Les styles CSS (3) <ul><li>Formatage d'écriture </li></ul><ul><ul><li>Plusieurs attributs </li></ul></ul><ul><ul><ul><li>F...
Style des widgets <ul><li>Méthode setStyleName() pour affecter un style </li></ul><ul><ul><li>Indiquer le nom du style en ...
Style par défaut <ul><li>Chaque widget dispose d'un style spécifique </li></ul><ul><li>Formé par convention : [projet]-[wi...
Thèmes <ul><li>Installation propose trois thèmes </li></ul><ul><ul><li>Standard, Chrome et Dark </li></ul></ul><ul><ul><li...
Modification du style <ul><li>UIObject propose des méthodes liées au style </li></ul><ul><ul><li>Méthode setStyleName(Stri...
Style primaire  <ul><li>La classe de style CSS pour un UIObject </li></ul><ul><ul><li>Chaque widget dispose de son style p...
Style secondaire <ul><li>Un widget peut se voir affecter plusieurs styles </li></ul><ul><ul><li>Ajouter avec addStyleName(...
Style dépendant  <ul><li>Un style secondaire un peu spécial </li></ul><ul><li>Caractérise une propriété, un état du compos...
Les styles CSS
Le modèle événementiel <ul><li>Navigateurs reçoivent les événements (clavier, souris) </li></ul><ul><li>Puis les redirigen...
Event <ul><li>Représente un événement natif (du navigateur) </li></ul><ul><li>Une classe &quot;opaque&quot; </li></ul><ul>...
Interface EventListener <ul><li>Ecouter les événements du navigateur </li></ul><ul><ul><li>Ceux qui arrivent sur les widge...
Interface EventPreview <ul><li>Listener pour &quot;prévisualiser&quot; les événements </li></ul><ul><ul><li>Capture les év...
Schéma général SourcesConceptEvents -addConceptListener -removeConceptListener ConceptListener -onEtat1(…) -onEtat2(…) Con...
Exemple avec Button et Click SourcesClickEvents -addClickListener -removeClickListener ClickListener -onClick(Widget) Clic...
Interface ClickListener <ul><li>Interface de listener d'un événement de type &quot;click&quot; </li></ul><ul><ul><li>Réagi...
Interface LoadListener <ul><li>Interface de listener pour un événement 'load' </li></ul><ul><ul><li>Typiquement chargement...
Interface ChangeListener <ul><li>Interface de listener d'un événement de type &quot;change&quot; </li></ul><ul><ul><li>Réa...
Interface FocusListener <ul><li>Interface de listener d'un événement de focus </li></ul><ul><ul><li>Réagir à la prise ou p...
Interface KeyboardListener <ul><li>Interface de listener des événements clavier </li></ul><ul><ul><li>Réagir à l'enfonceme...
Interface MouseListener <ul><li>Interface de listener des événements souris </li></ul><ul><ul><li>Réagir à l'enfoncement/r...
Interface MouseWheelListener <ul><li>Interface de listener de la molette de la souris </li></ul><ul><ul><li>Réagir à l'uti...
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Google Web Toolkit 1.5 Presentation Web Creative Common
Prochain SlideShare
Chargement dans…5
×

Google Web Toolkit 1.5 Presentation Web Creative Common

7 803 vues

Publié le

Présentation GWT en ligne

Support de formation GWT en version 1.5. Vous pouvez le consulter en ligne. Ce support est proposé sous licence Creative Commons.

Publié dans : Technologie
0 commentaire
5 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

Aucun téléchargement
Vues
Nombre de vues
7 803
Sur SlideShare
0
Issues des intégrations
0
Intégrations
13
Actions
Partages
0
Téléchargements
0
Commentaires
0
J’aime
5
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Google Web Toolkit 1.5 Presentation Web Creative Common

  1. 1. Google Web Toolkit 1.5 JW-GWT
  2. 2. Ce qui précède n'affecte en rien vos droits en tant qu'utilisateur (exceptions au droit d'auteur : copies réservées à l'usage privé du copiste, courtes citations, parodie...) Ceci est le Résumé Explicatif du Code Juridique (la version intégrale du contrat) .
  3. 3. Plan du séminaire
  4. 4. Google Web Toolkit – Plan Général (1) <ul><li>Introduction </li></ul><ul><ul><li>Les technologies du Web 2.0 </li></ul></ul><ul><ul><li>Les principes d’Ajax </li></ul></ul><ul><ul><li>Les applications RIA </li></ul></ul><ul><ul><li>L’approche de GWT </li></ul></ul><ul><li>Développer une appli GWT </li></ul><ul><ul><li>Installation </li></ul></ul><ul><ul><li>Créer et tester une application </li></ul></ul><ul><ul><li>Les fenêtres et les panels </li></ul></ul><ul><ul><li>Les composants graphiques </li></ul></ul><ul><ul><li>Gestion de l’internationalisation </li></ul></ul><ul><ul><li>Les feuilles de styles CSS </li></ul></ul><ul><ul><li>Le modèle événementiel </li></ul></ul>
  5. 5. Google Web Toolkit – Plan Général (2) <ul><li>Communications asynchrones </li></ul><ul><ul><li>Présentation de GWT RPC </li></ul></ul><ul><ul><li>Impact des comm. asynchrones </li></ul></ul><ul><ul><li>Implémenter un service </li></ul></ul><ul><ul><li>Sérialisation </li></ul></ul><ul><ul><li>Gestion des exceptions </li></ul></ul><ul><ul><li>Utilisation de JSON </li></ul></ul><ul><ul><li>Gestion de l'historique </li></ul></ul><ul><li>Notions avancées </li></ul><ul><ul><li>Utilisation d’images </li></ul></ul><ul><ul><li>Intégration Java EE </li></ul></ul><ul><ul><li>Tester avec Junit </li></ul></ul><ul><ul><li>Présentation de JSNI </li></ul></ul>
  6. 6. Introduction
  7. 7. Naissance des RIA (1) <ul><li>L'histoire du développement d'applications a connu plusieurs grandes phases </li></ul><ul><ul><li>Les terminaux passifs (années 70) </li></ul></ul><ul><ul><li>La révolution du client-serveur (années 80) </li></ul></ul><ul><ul><li>La révolution internet et intranet (années 90) </li></ul></ul><ul><ul><li>L'évolution vers les 'clients riches' (années 2000) </li></ul></ul><ul><ul><ul><li>RIA = Rich Internet Application. </li></ul></ul></ul><ul><ul><ul><li>RDA = Rich Desktop Application </li></ul></ul></ul>GWT
  8. 8. Naissance des RIA (2) <ul><li>Les terminaux passifs </li></ul><ul><ul><li>Terminaux connectés à un mainframe (3270), interface en mode texte, tout est géré par le serveur </li></ul></ul><ul><li>La révolution du client-serveur </li></ul><ul><ul><li>L'équipement des utilisateurs en postes de travail (PC) a permis le développement de la bureautique dans un premier temps puis celui du client-serveur </li></ul></ul><ul><ul><li>Client serveur 1ère génération : toute la logique sur le client, communication avec un serveur de données (bases de données, mainframes…), souvent nommé 'Client lourd' </li></ul></ul><ul><ul><li>Client serveur 2ème génération : gestion de l'interface graphique sur le poste client et interaction avec une partie applicative exécutée côté serveur (CORBA, DCOM, …) </li></ul></ul>
  9. 9. Naissance des RIA (3) <ul><li>La révolution internet et intranet </li></ul><ul><ul><li>A partir de 1995, internet se développe et les utilisateurs se familiarisent avec l'utilisation d'un navigateur </li></ul></ul><ul><ul><li>En parallèle, les équipes de développement sont confrontées aux limites du client-serveur (essentiellement le problème de déploiement et de gestion des mises à jour) </li></ul></ul><ul><ul><li>L'infrastructure technique d'internet (HTTP, HTML, navigateur) va progressivement se généraliser en entreprise. Les applications intranet sont, au début, surtout réservées pour de la consultation. Au fil des ans, elles vont devenir de plus en plus sophistiquées </li></ul></ul><ul><ul><li>Pour les utilisateurs et les exploitants l'architecture Web est un progrès majeur. Pour les développeurs, le passage est plus délicat : le couple HTTP/HTML n'a pas été conçu pour faire des applications. </li></ul></ul><ul><ul><li>Principales technologies pour le développement d'applications Intranet : Java EE, PHP, .NET </li></ul></ul>
  10. 10. Naissance des RIA (4) <ul><li>L'évolution vers les 'clients riches' </li></ul><ul><ul><li>Les demandes d'applications intranet de plus en plus sophistiquées se sont heurtées aux limites graphiques du HTML </li></ul></ul><ul><ul><ul><li>Manque d'interactivité, composants graphiques basiques, nécessité de faire des allers-retours pour une simple information à rafraîchir… </li></ul></ul></ul><ul><ul><li>Plusieurs solutions ont émergé, regroupées sous le terme 'clients riches'. Leur but : combiner la richesse ergonomique du client-serveur avec la souplesse de l'architecture Web </li></ul></ul><ul><ul><li>RIA (Rich Internet Application) : le navigateur web reste le socle côté client. Les possibilités du navigateur sont soit exploitées au maximum (Javascript et CSS) soit enrichies par l'ajout de plugins (Flash, Silverlight, JavaFX, …) </li></ul></ul><ul><ul><li>RDA (Rich Desktop Application) : renaissance du client-serveur 2ème génération, prévoit des solutions pour le problème d'installation et de mise à jour (ex: Eclipse RCP) </li></ul></ul>
  11. 11. RIA, Web 2.0 et Ajax <ul><li>Le terme Web 2.0 résume l'évolution vers plus de richesse des sites internet </li></ul><ul><ul><li>Désigne surtout des aspects non techniques (les sites deviennent plus collaboratifs, participatifs, …) </li></ul></ul><ul><ul><li>Techniquement utilisation importante de JavaScript </li></ul></ul><ul><li>JavaScript </li></ul><ul><ul><li>Créé en 1995 par Netscape. Permet d'intégrer, dans les pages HTML, des scripts interprétés par le navigateur </li></ul></ul><ul><ul><li>D'abord utilisé pour limiter les échanges avec le serveur en assurant des contrôles de saisie côté client </li></ul></ul><ul><ul><li>Progressivement deux utilisations majeures se sont démocratisées : Ajax et DHTML </li></ul></ul>
  12. 12. Ajax <ul><li>En 2005, le terme Ajax est apparu mettant un nom sur une pratique de plus en plus courante </li></ul><ul><ul><li>Ajax = Asynchronous JavaScript and XML </li></ul></ul><ul><ul><li>Du code JavaScript émet des requêtes HTTP pour échanger des flux XML avec la partie serveur (objet XMLHttpRequest) </li></ul></ul><ul><ul><li>Ce code peut s'exécuter indépendamment des actions de l'utilisateur </li></ul></ul><ul><ul><li>Permet, par exemple, le rafraîchissement d'une partie de la page ou encore le remplissage progressif d'un arbre ou d'une table </li></ul></ul><ul><ul><li>Rend les applications plus interactives en évitant les rafraîchissements complets des pages </li></ul></ul><ul><ul><li>Réduit les flux échangés avec le serveur en se limitant aux données nécessaires </li></ul></ul>
  13. 13. DHTML <ul><li>Après avoir téléchargé un fichier HTML, le navigateur créé en mémoire un arbre représentant la structure de la page puis l'affiche </li></ul><ul><ul><li>Le DOM : Document Objet Model </li></ul></ul><ul><li>Le contenu du DOM peut être manipulé dynamiquement en utilisant JavaScript </li></ul><ul><ul><li>Ajout et suppression de nœuds </li></ul></ul><ul><ul><li>Modification d'attributs (emplacement, style, …) </li></ul></ul><ul><li>La mise au point du JavaScript est délicate </li></ul><ul><ul><li>Différences de fonctionnement entre les navigateurs. Environnements de développement sommaires </li></ul></ul><ul><ul><li>Des frameworks JavaScript ont émergés : jQuery, prototypeJS, Scriptaculous… </li></ul></ul>
  14. 14. L’approche de GWT <ul><li>Mai 2006 : annonce de GWT à la conférence JavaOne </li></ul><ul><ul><li>Google Web Toolkit </li></ul></ul><ul><ul><li>Ecrire ses applications clientes en Java </li></ul></ul><ul><ul><li>Les compiler en Javascript </li></ul></ul><ul><li>Javascript = le bytecode du web </li></ul><ul><ul><li>Compris par tous les navigateurs </li></ul></ul><ul><ul><li>Bas niveau, puissant </li></ul></ul>
  15. 15. Avantages de l'approche GWT <ul><li>Développer et maintenir des applis Javascript </li></ul><ul><ul><li>Supportant les spécificités des navigateurs </li></ul></ul><ul><ul><ul><li>Gère automatiquement Internet Explorer, FireFox, Mozilla, Safari, Opéra </li></ul></ul></ul><ul><ul><ul><li>Gère automatiquement les différences entre les versions des navigateurs </li></ul></ul></ul><ul><ul><li>Supportant l'internationalisation </li></ul></ul><ul><ul><li>Supportant des alternatives de configuration (intranet/extranet) </li></ul></ul><ul><ul><li>De plus en plus complexes </li></ul></ul><ul><ul><ul><li>Java est conçu pour gérer des développements complexes </li></ul></ul></ul><ul><ul><li>Optimales </li></ul></ul><ul><ul><ul><li>Produit des versions spécifiques plutôt que génériques des fichiers </li></ul></ul></ul><ul><li>Utiliser la myriade d'outils du monde Java </li></ul><ul><ul><li>IDE, conception, analyse de code, test, intégration continue, … </li></ul></ul><ul><ul><li>Ne pas redévelopper tout ça une nouvelle fois </li></ul></ul>
  16. 16. Principes généraux (1) <ul><li>Mise à disposition de librairies de classe Java </li></ul><ul><ul><li>Classes graphiques (widgets, panels) </li></ul></ul><ul><ul><ul><li>Permettent de composer une application type &quot;client desktop&quot; comme du Swing </li></ul></ul></ul><ul><ul><li>Classes de communication avec le serveur </li></ul></ul><ul><ul><ul><li>Permettent d'échanger des informations structurées (XML, JSON, …) </li></ul></ul></ul><ul><ul><ul><li>Permettent même d'échanger directement des objets Java </li></ul></ul></ul><ul><ul><ul><li>Permettent d'intégrer coté client des services écrits dans différents langages </li></ul></ul></ul><ul><li>Compilateur de Java vers Javascript </li></ul><ul><ul><li>Supporte une version simplifiée du JRE </li></ul></ul><ul><li>Possibilité d'intégrer des frameworks Javascript </li></ul><ul><ul><li>Scriptaculous, JSCalendar, TinyMCE, MooTools, Ext-JS… </li></ul></ul><ul><li>Intégration possible avec les frameworks j2ee </li></ul><ul><ul><li>JSF, Spring, Struts, EJB, … </li></ul></ul>
  17. 17. Principes généraux (2) <ul><li>Développement des applications reste difficile </li></ul><ul><ul><li>Tests unitaires avec JUnit </li></ul></ul><ul><ul><li>Navigateur interne pour la mise au point (mode &quot;hosted&quot;) </li></ul></ul><ul><ul><ul><li>Pas de déploiement préalable </li></ul></ul></ul><ul><ul><ul><li>Le code qui s'exécute est du code Java </li></ul></ul></ul><ul><ul><ul><li>Debug en Java, points d'arrêt, … </li></ul></ul></ul><ul><li>Compiler en JavaScript ensuite </li></ul><ul><ul><li>Déployer et tester (mode &quot;web&quot;) </li></ul></ul>
  18. 18. Schéma général Compilateur Java->Javascript JRE Emulation JSNI JavaScript Native Interface Widgets &Panels I18n RPC Gestion de l'historique (bouton &quot;Back&quot;) XML Parser Intégration JUnit
  19. 19. Compilation Java <ul><li>Transformation du code source Java </li></ul><ul><ul><li>Décrivant des classes, des méthodes </li></ul></ul><ul><ul><li>Respectant la syntaxe </li></ul></ul><ul><li>Vers du bytecode </li></ul><ul><ul><li>Code binaire 'interprétable' par une machine virtuelle (JVM) </li></ul></ul><ul><ul><li>Des instructions machines mais pour une machine virtuelle </li></ul></ul><ul><ul><li>JVM = fonctions de base (natives) + gestion mémoire </li></ul></ul><ul><li>Résolution des références avec le ClassPath </li></ul><ul><ul><li>Contient notamment le JRE (les classes de base du système) </li></ul></ul><ul><ul><li>En particulier le noyau (java.lang) </li></ul></ul>
  20. 20. Compilation GWT Java vers JavaScript <ul><li>Exécuter la classe com.google.gwt.dev.GWTCompiler </li></ul><ul><ul><li>Avec une définition de &quot;module&quot; et un fichier de configuration </li></ul></ul><ul><ul><ul><li>Module = ensemble de fichiers liés (Java et autres) </li></ul></ul></ul><ul><ul><ul><li>Configuration indique typiquement un point d'entrée : la classe principale </li></ul></ul></ul><ul><li>Le compilateur part de ce point d'entrée </li></ul><ul><ul><li>Et suit les dépendances </li></ul></ul><ul><ul><li>Ne compile que ce qui est utilisé </li></ul></ul><ul><ul><ul><li>Minimiser la taille des fichiers générés </li></ul></ul></ul><ul><ul><ul><li>Utiliser des grosses bibliothèques sans risquer de surcharger le runtime final </li></ul></ul></ul><ul><ul><li>Produit des fichiers JavaScript </li></ul></ul><ul><ul><ul><li>Spécifiques pour chaque navigateur et pour chaque locale </li></ul></ul></ul><ul><li>Attention : n'utilise que les fichiers Java (pas les .class) </li></ul><ul><ul><li>Nécessité de disposer des sources de toutes ses librairies utilisées </li></ul></ul>
  21. 21. Modes de compilation <ul><li>Mode &quot;OBFUSCATE&quot; </li></ul><ul><ul><li>Nom de classes, d'attributs, de méthodes, … sont compressés </li></ul></ul><ul><ul><li>Illisible mais compact (protège aussi son code) </li></ul></ul><ul><li>Mode &quot;PRETTY&quot; </li></ul><ul><ul><li>Noms courts </li></ul></ul><ul><ul><li>On reconnaît au moins le nom des méthodes </li></ul></ul><ul><li>Mode &quot;DETAILED&quot; </li></ul><ul><ul><li>Noms complets </li></ul></ul><ul><ul><li>Permet de refaire le lien avec le code Java en cas de bug </li></ul></ul>
  22. 22. Fichiers générés (&quot;permutation&quot;) <ul><li>Autant de fichiers que de combinaisons </li></ul><ul><ul><li>Type de navigateur </li></ul></ul><ul><ul><li>Locale </li></ul></ul><ul><ul><li>Propriété de configuration (typiquement internet/intranet) </li></ul></ul><ul><li>Les fichiers ne sont pas génériques </li></ul><ul><ul><li>Ne contiennent pas des &quot;if&quot; pour gérer les spécificités </li></ul></ul><ul><li>Un fichier de sortie = une &quot;permutation&quot; </li></ul><ul><li>Le navigateur ne reçoit pas de code inutile </li></ul><ul><ul><li>Diminue l'utilisation de la bande passante </li></ul></ul><ul><ul><li>Diminue l'empreinte mémoire dans le navigateur </li></ul></ul>
  23. 23. Intégration JSNI <ul><li>Méthodes natives </li></ul><ul><ul><li>En Java : méthodes dont le code existera dans la jvm </li></ul></ul><ul><li>JavaScript Native Interface </li></ul><ul><ul><li>Spécifier des méthodes &quot;natives&quot;, dont le code existera au runtime </li></ul></ul><ul><ul><li>Intégrer le code JavaScript directement dans le code Java </li></ul></ul><ul><ul><ul><li>On met le code en commentaire derrière la définition </li></ul></ul></ul><ul><ul><ul><li>Ça reste du code Java valide puisque dans des commentaires </li></ul></ul></ul><ul><ul><ul><li>Le compilateur insère ce code dans le fichier généré </li></ul></ul></ul><ul><li>Permet </li></ul><ul><ul><li>D'optimiser </li></ul></ul><ul><ul><li>De gérer des spécifités, d'intégrer des librairies existantes </li></ul></ul>public static native void alert(String msg) /*-{ $wnd.alert(msg); }-*/;
  24. 24. JRE Emulation <ul><li>Reprend un sous ensemble des classes de base Java </li></ul><ul><ul><li>Fournit un équivalent JavaScript de ces classes </li></ul></ul><ul><li>Packages java.lang, java.util, java.lang.annotation </li></ul><ul><ul><li>Assez complet mais pas toutes les méthodes </li></ul></ul><ul><li>Package java.io </li></ul><ul><ul><li>OutputStream, PrintStream, Serializable </li></ul></ul><ul><li>Package java.sql </li></ul><ul><ul><li>Date, Time, Timestamp </li></ul></ul>
  25. 25. Limitations <ul><li>Syntaxe Java 5 (enum, types génériques, …) </li></ul><ul><ul><li>Supportée depuis GWT 1.5 </li></ul></ul><ul><li>La librairie du JRE est volontairement limitée </li></ul><ul><li>Certaines subtilités </li></ul><ul><ul><li>Float/Double ne peuvent pas servir de clé dans une HashMap </li></ul></ul><ul><ul><li>String.replaceAll, replaceFirst, split : regexp de JavaScript </li></ul></ul><ul><ul><li>StringBuffer(int) et StringBuffer se comportent pareils </li></ul></ul><ul><ul><li>System.out et err existent mais ne servent pas en mode web </li></ul></ul><ul><ul><li>Pas de support des stack-trace dans les Throwable </li></ul></ul><ul><ul><li>Vector : pas de capacité, de grossissement, de vérification d'indices </li></ul></ul><ul><li>Laisse entrevoir les types de problèmes à prévoir </li></ul><ul><ul><li>Mais pas si gênant que ça, il suffit de créer/utiliser d'autres librairies </li></ul></ul>
  26. 26. Comparaisons <ul><li>Swing </li></ul><ul><ul><li>Logique similaire mais pas de MVC (pas de modèle), pas de Layout </li></ul></ul><ul><li>Echo2 </li></ul><ul><ul><li>Logique similaire mais tourne côté serveur </li></ul></ul><ul><ul><ul><li>Beaucoup plus d'appels vers le serveur et nécessité d'un serveur J2EE </li></ul></ul></ul><ul><li>JSF </li></ul><ul><ul><li>Compliqué, tourne côté serveur, pas vraiment du client riche </li></ul></ul><ul><ul><li>On peut intégrer du GWT dans des applis JSF et autres &quot;struts like&quot; </li></ul></ul><ul><li>Ruby on Rail </li></ul><ul><ul><li>Plutôt côté serveur avec automatismes ajax générés sur le client </li></ul></ul><ul><ul><li>Pas aussi interactif (GWT est plus orienté client) </li></ul></ul>
  27. 27. Développer une appli GWT
  28. 28. Installation <ul><li>Vérifier la présence d'un JRE </li></ul><ul><ul><li>Version 1.5 supportée depuis GWT 1.5 </li></ul></ul><ul><li>Téléchargement sur le site officiel </li></ul><ul><ul><li>http://code.google.com/intl/fr/webtoolkit/download.html </li></ul></ul><ul><ul><li>Fichier compressé (gwt-windows-1.5.3.zip pour Windows) </li></ul></ul><ul><li>Décompresser : c'est prêt </li></ul><ul><li>On utilisera aussi un IDE </li></ul><ul><ul><li>Outillage offre des facilités pour eclipse </li></ul></ul><ul><ul><li>Mais tout autre IDE convient aussi </li></ul></ul>
  29. 29. Installation : arborescence obtenue C:GWT │ about.html │ about.txt │ applicationCreator.cmd script de création d'application │ benchmarkViewer.cmd │ COPYING │ COPYING.html │ gwt-benchmark-viewer.jar │ gwt-dev-windows.jar │ gwt-ll.dll │ gwt-module.dtd │ gwt-servlet.jar │ gwt-user.jar │ i18nCreator.cmd script d'internationalisation │ index.html point d'entrée html (doc et exemples) │ junitCreator.cmd script de création tests junit │ projectCreator.cmd script de création de projet (eclipse) │ release_notes.html │ swt-win32-3235.dll │ ├─── doc répertoire de documentation ... └─── samples répertoires d'exemples
  30. 30. Créer et tester une application <ul><li>Script &quot;applicationCreator&quot; </li></ul><ul><ul><li>Fait partie des fichiers installés </li></ul></ul><ul><ul><li>Pour créer une application simple (type &quot;Hello World&quot;) </li></ul></ul><ul><ul><li>Permet de créer l'arborescence et les fichiers de base </li></ul></ul><ul><li>Package doit se terminer par le sous package &quot;.client&quot; </li></ul><ul><li>Propose des options (qu'on verra plus tard) </li></ul>applicationCreator -out dir className
  31. 31. Créer et tester une application : création <ul><li>Création d'une application simple App </li></ul><ul><li>Fichiers produits </li></ul>applicationCreator -out TP1 com.oxiane.formation.tp1.client.App C:GWTTP1 │ App-compile.cmd script compilation JavaScript │ App-shell.cmd script exécution mode hosted │ └─── src répertoire source └─── com └─── oxiane └─── formation └─── tp1 package de l'application │ App.gwt.xml description du module GWT │ ├─── client package client (code du client) │ App.java classe &quot;point d'entrée&quot; │ └─── public package public (fichiers web) App.css Feuille de style css de l'appli App.html Fichier html de chargement web
  32. 32. Tester l'application : mode &quot;hosted&quot; <ul><li>Utiliser le script &quot;App-shell&quot; généré </li></ul><ul><ul><li>Ouvre un &quot;GWT Development Shell&quot; </li></ul></ul><ul><ul><ul><li>Sert de console (trace) </li></ul></ul></ul><ul><ul><li>Ouvre un &quot;Hosted Browser&quot; </li></ul></ul><ul><ul><ul><li>Internet Explorer sous Windows </li></ul></ul></ul><ul><ul><ul><li>Mozilla sur les autres OS </li></ul></ul></ul><ul><li>Exécution en Java </li></ul><ul><ul><li>Exceptions capturées </li></ul></ul><ul><ul><li>Debug Java possible </li></ul></ul><ul><li>Moteur tomcat embarqué </li></ul><ul><ul><li>Moteur de servlet </li></ul></ul><ul><ul><li>Déploiement automatique du code serveur </li></ul></ul>
  33. 33. Fichiers ajoutés par le mode &quot;Hosted&quot; <ul><li>Mode &quot;Hosted&quot; ajoute une arborescence tomcat </li></ul><ul><ul><li>Tomcat embarqué dans le GWT Shell Development </li></ul></ul>C:GWTTP1 … code de l'application inchangé └─── tomcat arborescence simplifiée tomcat ├─── conf │ │ web.xml │ │ │ └─── gwt │ └─── localhost ├─── webapps │ └─── ROOT │ └─── WEB-INF │ web.xml conf de l'application web │ └─── work répertoire de travail tomcat └─── gwt └─── localhost └─── _ tldCache.ser cache des taglib descriptors
  34. 34. Tester l'application : mode &quot;Web&quot; <ul><li>Utiliser le script &quot;App-compile&quot; généré </li></ul><ul><li>Ou utiliser le bouton Compile/Browse du &quot;Hosted Browser&quot; </li></ul>
  35. 35. Fichiers ajoutés par le mode &quot;Web&quot; <ul><li>Mode &quot;Web&quot; utilise la version compilée JavaScript </li></ul>C:GWTTP1 ... répertoires inchangés └─── www répertoire ajouté ├─── .gwt-tmp tmp de compilation │ └─── compiler │ └─── com.oxiane.formation.tp1.App … └─── com.oxiane.formation.tp1.App répertoire de l'appli … │ App.css │ App.html … │ com.oxiane.formation.tp1.App.nocache.js appli JavaScript … └─── gwt fichiers gwt TP 1
  36. 36. Utilisation dans un IDE <ul><li>Développement GWT = Développement Java pur </li></ul><ul><ul><li>N'importe quel IDE convient si on respecte l'arborescence </li></ul></ul><ul><li>Outillage spécifique pour eclipse </li></ul><ul><ul><li>Scripts proposent l'option &quot;-eclipse&quot; </li></ul></ul><ul><ul><li>Gère les fichiers spécifiques tels que </li></ul></ul><ul><ul><ul><li>&quot;.project&quot; et &quot;.classpath&quot; </li></ul></ul></ul><ul><ul><ul><li>&quot;.launch&quot; pour lancer les scripts avec les menus &quot;Run as&quot; </li></ul></ul></ul><ul><li>Projet directement importable dans eclipse </li></ul><ul><ul><li>Ou IDE capable d'importer des projets eclipse (Netbeans,…) </li></ul></ul><ul><li>Utiliser le script &quot;projectCreator&quot; en premier </li></ul><ul><ul><li>Création de la structure de projet </li></ul></ul><ul><ul><li>Ne pas oublier l'option &quot;-eclipse nomProjet&quot; avec les autres scripts </li></ul></ul>
  37. 37. Cycle de développement <ul><li>Scripts = cycle de dév </li></ul><ul><li>Ne pas oublier &quot;-eclipse&quot; </li></ul><ul><li>Internationalisation </li></ul><ul><ul><li>Préparation du projet </li></ul></ul><ul><ul><li>Fichier de propriétés </li></ul></ul><ul><li>JUnit </li></ul><ul><ul><li>Préparation du projet </li></ul></ul><ul><ul><li>Classe de test prête à remplir </li></ul></ul>projectCreator Eclipse ? applicationCreator I18n ? i18nCreator JUnit ? junitCreator Import du projet Fin Début Eclipse ? O N O O O N N N
  38. 38. Script &quot;projectCreator&quot; <ul><li>Création de la structure de projet </li></ul><ul><li>Remarques </li></ul><ul><ul><li>Utiliser au moins &quot;-ant&quot; ou &quot;-eclipse&quot; (les deux sont possibles) </li></ul></ul>projectCreator [-ant nomProjet] Générer un script Ant de compilation des sources (extension &quot;.ant.xml&quot; ajoutée) [-eclipse nomProjet] Création pour un projet eclipse [-out répertoire] Répertoire de génération (&quot;.&quot; par défaut) [-overwrite] Ecraser les fichiers existants (alerte sinon) [-ignore] Ignorer les fichiers existants (ne pas écraser) [-addToClassPath entrée] Ajouter une entrée au classPath
  39. 39. Script &quot;applicationCreator&quot; <ul><li>Création de l'application par défaut </li></ul><ul><li>Remarques </li></ul><ul><ul><li>Classe doit être dans un sous-package &quot;client&quot; (alerte sinon) </li></ul></ul><ul><ul><li>En mode eclipse </li></ul></ul><ul><ul><ul><li>Génération de &quot;.launch&quot; pour lancer les scripts </li></ul></ul></ul><ul><ul><ul><li>Mise à jour des fichiers spécifiques eclipse (.classpath, .project, …) </li></ul></ul></ul>applicationCreator [-eclipse nomProjet] Création pour un projet eclipse [-out dir] Répertoire de génération (&quot;.&quot; par défaut) [-overwrite] Ecraser les fichiers existants (alerte sinon) [-ignore] Ignorer les fichiers existants (ne pas écraser) [-addToClassPath entrée] Ajouter une entrée au classPath [-addModule module] Ajouter un module GWT dans l'héritage nomCompletClasse Nom complet de la classe à créer
  40. 40. Script &quot;i18nCreator&quot; <ul><li>Création du support de l'internationalisation </li></ul><ul><li>On étudiera cela en détail plus tard </li></ul><ul><ul><li>Le principe général est d'utiliser une interface dans le code </li></ul></ul><ul><ul><ul><li>Propose une méthode pour chaque &quot;constante&quot; à internationaliser </li></ul></ul></ul><ul><ul><ul><li>Implémentation automatique à partir de fichiers de propriétés </li></ul></ul></ul>i18nCreator [-eclipse nomProjet] Création pour un projet eclipse [-out répertoire] Répertoire de génération (&quot;.&quot; par défaut) [-createConstantsWithLookup] ConstantsWithLookup plutôt que Constants [-createMessages] Messages plutôt que Constants [-overwrite] Ecraser les fichiers existants (alerte sinon) [-ignore] Ignorer les fichiers existants (ne pas écraser) nomCompletInterface Nom complet de l'interface à créer
  41. 41. Script &quot;junitCreator&quot; <ul><li>Création du support de JUnit </li></ul><ul><li>On étudiera cela en détail plus tard </li></ul><ul><ul><li>Le principe général est de préparer le projet à l'utilisation de JUnit </li></ul></ul><ul><ul><ul><li>Création des répertoires </li></ul></ul></ul><ul><ul><ul><li>Création d'une classe pour écrire ses tests </li></ul></ul></ul><ul><ul><ul><li>En mode eclipse, création d'un &quot;.launch&quot; pour lancer l'exécution des tests </li></ul></ul></ul>junitCreator -junit cheminJUnit Chemin vers le jar de junit -module nomModule Nom du module GWT à utiliser [-eclipse nomProjet] Création pour un projet eclipse [-out répertoire] Répertoire de génération (&quot;.&quot; par défaut) [-overwrite] Ecraser les fichiers existants (alerte sinon) [-ignore] Ignorer les fichiers existants (ne pas écraser) [-addToClassPath entrée] Ajouter une entrée au classPath
  42. 42. Import dans eclipse <ul><li>Import de projet existant </li></ul><ul><ul><li>Recopier les fichiers dans le workspace </li></ul></ul><ul><ul><li>Ou bien générer directement dans le répertoire du workspace </li></ul></ul>
  43. 43. Autres alternatives de création de projet <ul><li>Ecrire les fichiers à la main </li></ul><ul><ul><li>Pas très réaliste </li></ul></ul><ul><li>Disposer d'un assistant de création dans l'IDE </li></ul><ul><ul><li>Plugin eclipse GWT, support natif de GWT dans IntelliJ, … </li></ul></ul><ul><ul><li>Existent mais n'apportent pas énormément </li></ul></ul><ul><ul><li>GWT évolue encore, mieux vaut utiliser les outils fournis </li></ul></ul><ul><li>Recopier/générer l'arborescence de fichiers </li></ul><ul><ul><li>Permettrait de préparer un squelette institutionnel d'application </li></ul></ul><ul><li>Dans tous les cas, même structure finale </li></ul>TP 2
  44. 44. Cypal Studio (1) <ul><li>Plugin eclipse pour simplifier l'utilisation de GWT </li></ul><ul><ul><li>Site http://code.google.com/p/cypal-studio/ </li></ul></ul><ul><li>Assistants </li></ul><ul><ul><li>Création de modules : remplace projectCreator et applicationCreator </li></ul></ul><ul><ul><li>Création de services (concerne la communication serveur) </li></ul></ul><ul><ul><li>Lanceur en mode Hosted </li></ul></ul><ul><li>Problèmes </li></ul><ul><ul><li>Projet peu actif </li></ul></ul><ul><ul><li>Ne couvre pas les possibilités des outils GWT tels que junitCreator </li></ul></ul><ul><li>Intéressant mais pas fondamental </li></ul>
  45. 45. Cypal Studio (2) <ul><li>Installation </li></ul><ul><ul><li>Pré-requis : Eclipse IDE for Java EE Developers (Eclipse + WTP) </li></ul></ul><ul><ul><li>Dézipper dans le répertoire 'dropins' d'Eclipse et relancer Eclipse </li></ul></ul><ul><li>Configuration </li></ul><ul><ul><li>Indiquer l'emplacement de GWT dans les préférences </li></ul></ul>
  46. 46. Cypal Studio (3) <ul><li>Création d'un projet </li></ul><ul><ul><li>Cypal fonctionne pour les projets de type 'Dynamic Web Project' </li></ul></ul><ul><ul><li>Module Version 2.4 obligatoire (version de la spec servlet) </li></ul></ul><ul><ul><li>Choisir la configuration 'Cypal Studio for GWT' </li></ul></ul>
  47. 47. Cypal Studio (4) <ul><li>Création d'un module GWT </li></ul><ul><ul><li>A partir de menu 'File->New…' lancer l'assistant de création de module GWT </li></ul></ul>
  48. 48. Cypal Studio (5) <ul><li>Pour tester </li></ul><ul><ul><li>Ouvrir le gestionnaire des configurations de lancement </li></ul></ul><ul><ul><li>Créer une configuration de lancement 'GWT Hosted Mode Application' </li></ul></ul><ul><ul><li>Sélectionner le projet associé et le module GWT à lancer </li></ul></ul>
  49. 49. Les composants graphiques
  50. 50. Interface EntryPoint <ul><li>L'interface désignant un point d'entrée d'application </li></ul><ul><li>Méthode onModuleLoad() </li></ul><ul><ul><li>Equivalent au main() de l'application ou au service() des Servlets </li></ul></ul><ul><li>Coder une classe implémentant cette interface </li></ul><ul><li>La désigner dans le fichier de description de module </li></ul><ul><ul><li><entry-point class='com.oxiane.formation.tp1.client.App'/> </li></ul></ul><ul><li>Le compilateur part de cette classe </li></ul><ul><ul><li>Et suit les dépendances </li></ul></ul>public class App implements EntryPoint { public void onModuleLoad() { Label label = new Label(&quot;Hello world !&quot;); RootPanel.get().add(label); } }
  51. 51. Les fenêtres et les panels <ul><li>Notions classiques des interfaces graphiques </li></ul><ul><ul><li>Widget = contrôle utilisé par l'utilisateur </li></ul></ul><ul><ul><ul><li>Exemple : boutons, champs de saisie, etc. </li></ul></ul></ul><ul><ul><li>Panel = conteneur de widgets (ou d'autres panels) </li></ul></ul><ul><ul><ul><li>Exemple : table disposant un bouton et un champ en ligne </li></ul></ul></ul><ul><ul><ul><li>En réalité, un panel peut aussi offrir de l'interactivité </li></ul></ul></ul><ul><ul><li>Window = la fenêtre du navigateur </li></ul></ul><ul><ul><ul><li>Accès aux méthodes, propriétés et événements du navigateur </li></ul></ul></ul><ul><li>Dans la pratique, trois types de composants </li></ul><ul><ul><li>Widget </li></ul></ul><ul><ul><li>Panel pour disposer (layout) </li></ul></ul><ul><ul><li>Panel pour interagir </li></ul></ul>Panel Widget Widget Panel Widget
  52. 52. Window <ul><li>Classe encapsulant la fenêtre du navigateur </li></ul><ul><ul><li>Équivalent de l'objet &quot;window&quot; de JavaScript </li></ul></ul><ul><ul><li>Méthodes statiques, permettent d'interroger/piloter le navigateur </li></ul></ul><ul><li>Méthodes et propriétés (getter et/ou setter) diverses </li></ul><ul><ul><li>Accès aux dimensions utiles, au titre, à la zone de status, au scroll </li></ul></ul><ul><ul><li>Dialogues simples : alert, confirm, prompt </li></ul></ul><ul><ul><li>Pilotage : print, open (ouverture d'un autre navigateur) </li></ul></ul><ul><li>Gère des listeners (WindowClose et WindowResize) </li></ul><ul><li>Contient une autre classe Window.Location </li></ul><ul><ul><li>Pour tout ce qui est spécifique à l'url </li></ul></ul>
  53. 53. RootPanel <ul><li>Panel racine </li></ul><ul><ul><li>Associé à un élément de la page </li></ul></ul><ul><ul><li>Créé par le framework </li></ul></ul><ul><ul><li>Obtenu par la méthode statique get(String) </li></ul></ul><ul><ul><ul><li>Paramètre identifie un élément html </li></ul></ul></ul><ul><ul><ul><li>Permet d'ajouter des widgets sur n'importe quel élément html identifié </li></ul></ul></ul><ul><li>Panel racine par défaut </li></ul><ul><ul><li>Méthode get() sans paramètre </li></ul></ul><ul><li>Utilisé généralement dans le EntryPoint </li></ul><ul><ul><li>Dans le onLoadModule(), pour ajouter les widgets </li></ul></ul>
  54. 54. Les composants graphiques <ul><li>Widget : classe Java </li></ul><ul><ul><li>En général en correspondance avec un équivalent HTML </li></ul></ul><ul><ul><ul><li>Button, TextBox, TextArea, CheckBox, RadioButton, … </li></ul></ul></ul><ul><li>Différentes variations de la table </li></ul><ul><ul><li>HTMLTable, Grid, FlexTable </li></ul></ul><ul><li>Des composants plus spécifiques </li></ul><ul><ul><li>TabPanel : widgets dans différents onglets </li></ul></ul><ul><ul><li>PopUpPanel </li></ul></ul><ul><ul><li>StackPanel </li></ul></ul><ul><li>Plus de 30 widgets et panels en tout </li></ul><ul><ul><li>Présentés dans le Showcase (exemples de l'aide) </li></ul></ul>TP 3
  55. 55. UIObject <ul><li>La racine des objets graphiques </li></ul><ul><ul><li>Encapsule un élément DOM </li></ul></ul><ul><ul><ul><li>Propriété &quot;element&quot; </li></ul></ul></ul><ul><ul><li>Gère un style associé à cet élément </li></ul></ul><ul><ul><ul><li>Méthodes getStyleName, addStyleName, … (on verra plus tard les styles CSS) </li></ul></ul></ul><ul><ul><li>Gère un positionnement et des dimensions </li></ul></ul><ul><ul><ul><li>Propriétés &quot;width, &quot;height&quot;, &quot;size&quot;, &quot;pixelSize&quot;, &quot;absoluteLeft&quot;, &quot;absoluteTop&quot;, … </li></ul></ul></ul><ul><ul><li>Gère un &quot;title&quot; </li></ul></ul><ul><ul><ul><li>Attention : texte de bulle d'aide et non un titre </li></ul></ul></ul><ul><ul><li>Gère la visibilité de l'élément </li></ul></ul><ul><ul><li>Gère un masque d'événements </li></ul></ul><ul><ul><ul><li>Méthodes sinkEvents() et unsinkEvents() (on verra plus tard les événements) </li></ul></ul></ul>
  56. 56. Début de hiérarchie (UIObject) UIObject MenuItem MenuItemSeparator TreeItem Widget Composite FileUpload FocusWidget Frame Hidden Hyperlink Image Label MenuBar Panel Tree NamedFrame
  57. 57. Widget <ul><li>Classe abstraite héritant de UIObject </li></ul><ul><ul><li>Possède une représentation DOM interne </li></ul></ul><ul><ul><ul><li>Correspond à la &quot;vision&quot; JavaScript </li></ul></ul></ul><ul><li>Méthodes positionnant des propriétés </li></ul><ul><ul><li>Positionne en réalité des attributs de style </li></ul></ul><ul><ul><li>Exemple : setHeight(&quot;100px&quot;); setPixelSize(100,200); </li></ul></ul><ul><ul><li>Propriété &quot;title&quot; correspond à la bulle d'aide </li></ul></ul><ul><li>Préférer l'utilisation des feuilles styles </li></ul><ul><ul><li>Permet de bien séparer le fonctionnel de la présentation </li></ul></ul><ul><li>Propose aussi d'autres méthodes </li></ul><ul><ul><li>Accès au panel conteneur et gestion des événements (plus tard) </li></ul></ul>UIObject Widget
  58. 58. MenuBar, MenuItem et Command <ul><li>MenuBar </li></ul><ul><ul><li>Contient des MenuItem et MenuItemSeparator </li></ul></ul><ul><ul><li>Horizontal par défaut (booléen pour basculer) </li></ul></ul><ul><li>MenuItem </li></ul><ul><ul><li>Libellé + Command ou MenuBar (menus hiérarchiques) </li></ul></ul><ul><ul><li>Construction simplifiée avec addItem() </li></ul></ul><ul><li>MenuItemSeparator </li></ul><ul><ul><li>addSeparator() </li></ul></ul><ul><li>Command </li></ul><ul><ul><li>Interface pour représenter une action </li></ul></ul><ul><ul><li>Méthode execute() invoquée lorsqu'on cliquera sur l'item </li></ul></ul><ul><ul><li>Généralement implémentée avec une classe interne anonyme </li></ul></ul>UIObject Widget MenuBar
  59. 59. Interfaces HasText et HasHTML <ul><li>HasText </li></ul><ul><ul><li>Identifie un composant contenant un texte </li></ul></ul><ul><ul><ul><li>Propose les méthodes setText() et getText() </li></ul></ul></ul><ul><ul><ul><li>Propose en général un constructeur avec String </li></ul></ul></ul><ul><ul><li>Exemples : MenuItem, Button, Label, Hyperlink, … </li></ul></ul><ul><li>HasHTML </li></ul><ul><ul><li>Identifie un composant contenant du texte HTML </li></ul></ul><ul><ul><ul><li>Hérite de HasText </li></ul></ul></ul><ul><ul><ul><li>Propose les méthodes setHTML() et getHTML() </li></ul></ul></ul><ul><ul><ul><li>Propose en général un constructeur avec un String et un booléen &quot;asHTML&quot; </li></ul></ul></ul><ul><ul><ul><ul><li>Booléen indique si le texte doit être interprété comme texte HTML ou non </li></ul></ul></ul></ul><ul><ul><li>Exemples : MenuItem, TreeItem, Button, … </li></ul></ul>
  60. 60. Interface HasAnimation <ul><li>Marque un widget utilisant une animation </li></ul><ul><li>Propose de quoi tester et activer l'animation </li></ul><ul><ul><li>Méthode isAnimationEnabled() </li></ul></ul><ul><ul><li>Méthode setAnimationEnabled(boolean) </li></ul></ul><ul><li>Exemple MenuBar, DialogBox, TabPanel, … </li></ul>
  61. 61. MenuBar : exemple MenuBar menu = new MenuBar(); MenuBar menuFichier = new MenuBar(true); menuFichier.addSeparator(); Command cmdPlusTard = new Command() { public void execute() { Window.alert(&quot;pas implémentée !&quot;); } }; menuFichier.addItem(&quot;Quitter&quot;, cmdPlusTard); menu.addItem(&quot;Fichier&quot;, menuFichier); MenuBar menuAide = new MenuBar(true); menuAide.addItem(&quot;A propos&quot;, new Command() { public void execute() { ouvrirAPropos(); } }); menu.addItem(&quot;Aide&quot;, menuAide); RootPanel.get().add(menu); TP 4
  62. 62. Widget : Image <ul><li>Un widget pour afficher une image </li></ul><ul><li>Préciser une URL </li></ul><ul><ul><li>Soit dans le constructeur </li></ul></ul><ul><ul><li>Soit dynamiquement avec le setter </li></ul></ul><ul><ul><li>Répertoire &quot;public&quot; de l'application </li></ul></ul><ul><ul><ul><li>Pour les ressources statiques </li></ul></ul></ul><ul><li>Notion de &quot;ViewPort&quot; </li></ul><ul><ul><li>Permet de n'afficher qu'une partie de l'image </li></ul></ul><ul><ul><li>Préciser le rectangle visible dans le constructeur ou avec le setter </li></ul></ul><ul><li>Peut réagir à des événements (on verra plus tard) </li></ul>UIObject Widget Image
  63. 63. Widget : Frame <ul><li>Un widget pour encapsuler un site </li></ul><ul><ul><li>Utilise un frame invisible (IFRAME) </li></ul></ul><ul><ul><li>Préciser l'url (on peut la changer dynamiquement) </li></ul></ul><ul><li>La sous-classe NamedFrame </li></ul><ul><ul><li>Ajoute une propriété &quot;nom&quot; </li></ul></ul><ul><ul><li>Permettra de l'utiliser comme cible d'un FormPanel </li></ul></ul>UIObject Widget Frame NamedFrame
  64. 64. Widget : Hidden <ul><li>Un widget pour encapsuler un champ caché </li></ul><ul><ul><li>Permet de gérer le nom et la valeur du champ </li></ul></ul>UIObject Widget Hidden
  65. 65. Widget : Hyperlink <ul><li>Un widget pour spécifier un hyperlien &quot;interne&quot; </li></ul><ul><ul><li>Un lien vers un &quot;état&quot; de l'application </li></ul></ul><ul><ul><li>On y reviendra plus tard avec la gestion de l'historique </li></ul></ul><ul><li>Implémente HasText et HasHTML </li></ul>UIObject Widget Hyperlink
  66. 66. Interface HasDirection <ul><li>Indiquer qu'un widget possède son sens de lecture </li></ul><ul><ul><li>Propose les accesseurs getDirection() et setDirection() </li></ul></ul><ul><li>Enumeration Direction proposant les constantes </li></ul><ul><ul><li>LTR : lecture de gauche à droite </li></ul></ul><ul><ul><li>RTL : lecture de droite à gauche </li></ul></ul><ul><ul><li>DEFAULT : le sens de lecture naturel (hérité de son parent) </li></ul></ul><ul><li>Concerne les widgets textuels comme les Label </li></ul>
  67. 67. Interface HasWordWrap <ul><li>Marque un widget disposant de la propriété WordWrap </li></ul><ul><ul><li>Permet d'activer le passage à la ligne sans césure </li></ul></ul><ul><ul><li>Propose les méthodes getWordWrap() et setWordWrap(boolean) </li></ul></ul><ul><li>Concerne les widgets textuels </li></ul><ul><ul><li>Label, HTML, Anchor, … </li></ul></ul>
  68. 68. Interface HasAlignment <ul><li>Marque un widget avec alignement horizontal et vertical </li></ul><ul><li>Hérite de l'interface HasHorizontalAlignment </li></ul><ul><ul><li>Classe interne HorizontalAlignmentConstant définit les constantes </li></ul></ul><ul><ul><ul><li>ALIGN_LEFT : alignement à gauche </li></ul></ul></ul><ul><ul><ul><li>ALIGN_CENTER : alignement centré </li></ul></ul></ul><ul><ul><ul><li>ALIGN_RIGHT : alignement à droite </li></ul></ul></ul><ul><ul><ul><li>ALIGN_DEFAULT : alignement &quot;naturel&quot; (gauche si on lit de gauche à droite) </li></ul></ul></ul><ul><ul><li>Propose les accesseurs de la propriété &quot;horizontalAlignment&quot; </li></ul></ul><ul><li>Hérite de l'interface HasVerticalAlignment </li></ul><ul><ul><li>Classe interne VerticalAlignmentConstant définit les constantes </li></ul></ul><ul><ul><ul><li>ALIGN_BOTTOM : alignement en bas </li></ul></ul></ul><ul><ul><ul><li>ALIGN_MIDDLE : alignement centré vertical </li></ul></ul></ul><ul><ul><ul><li>ALIGN_TOP : alignement en haut </li></ul></ul></ul><ul><ul><li>Propose les accesseurs de la propriété &quot;verticalAlignment&quot; </li></ul></ul>
  69. 69. Hiérarchie partielle (Label) UIObject Widget Label HTML InlineLabel InlineHTML
  70. 70. Widget : Label <ul><li>Un widget contenant du texte brut </li></ul><ul><li>Implémente </li></ul><ul><ul><li>HasText (mais pas HasHTML) </li></ul></ul><ul><ul><li>HasWordWrap </li></ul></ul><ul><ul><li>HasDirection </li></ul></ul><ul><ul><li>HasHorizontalAlignment </li></ul></ul><ul><li>Une sous classe InlineLabel ? </li></ul><ul><ul><li>Label utilise un élément <div> </li></ul></ul><ul><ul><li>InlineLabel utilise un élément <span> produisant un layout en ligne </li></ul></ul>UIObject Widget Label InlineLabel
  71. 71. Widget : HTML <ul><li>Un label contenant du texte HTML </li></ul><ul><ul><li>Hérite des interfaces de Label et ajoute HasHTML </li></ul></ul><ul><li>Comme pour Label, version &quot;inline&quot; </li></ul><ul><ul><li>HTML utilise un élément <div> </li></ul></ul><ul><ul><li>InlineHTML utilise un élément <span> </li></ul></ul>UIObject Widget HTML InlineHTML
  72. 72. Widget : Tree <ul><li>Un widget pour représenter une arborescence </li></ul><ul><ul><li>Implémente HasAnimation, HasFocus </li></ul></ul><ul><ul><li>Contient des TreeItem </li></ul></ul><ul><ul><li>Similaire au MenuBar et ses MenuItem </li></ul></ul><ul><ul><li>TreeItem contient lui même un widget </li></ul></ul><ul><ul><li>TreeItem : un texte et un &quot;UserObject&quot; </li></ul></ul><ul><li>Propose </li></ul><ul><ul><li>Méthodes addItem(TreeItem) et ses variantes avec String et Widget </li></ul></ul><ul><ul><li>Méthodes remove(), removeItem(), removeItems(), clear() </li></ul></ul><ul><ul><li>Méthodes iterator() et treeItemsIterator() : parcours des items </li></ul></ul><ul><ul><li>Méthodes de gestion de la sélection </li></ul></ul>UIObject Widget Tree
  73. 73. Widget : FileUpload <ul><li>Encapsule la fonctionnalité du navigateur </li></ul><ul><ul><li>L'utilisateur choisit un fichier local </li></ul></ul><ul><ul><li>Fonctionnalité généralement sensible et protégée </li></ul></ul><ul><ul><ul><li>Seul moyen d’accéder au système de fichier </li></ul></ul></ul><ul><ul><ul><li>Pas de valeur par défaut sur certains navigateurs </li></ul></ul></ul><ul><ul><li>Doit être intégré dans un formulaire avec un encoding multi-part </li></ul></ul><ul><li>Nécessite une partie serveur </li></ul><ul><ul><li>Pour recevoir le fichier </li></ul></ul>UIObject Widget FileUpload
  74. 74. Hiérarchie partielle (FocusWidget) UIObject Widget FocusWidget Anchor ListBox SimpleCheckBox ButtonBase RichTextArea Button SimpleRadioButton TextBoxBase CheckBox CustomButton RadioButton PushButton ToggleButton TextArea TextBox PasswordTextBox
  75. 75. Interface HasFocus <ul><li>Marque un widget capable de gérer le focus </li></ul><ul><ul><li>Hérite de SourcesFocusEvent et SourcesKeyboardEvent </li></ul></ul><ul><ul><ul><li>Capable d'avoir des FocusListener et des KeyboardListener </li></ul></ul></ul><ul><ul><li>On verra plus tard la gestion des événements </li></ul></ul><ul><li>Propose de quoi gérer le focus et le tabIndex </li></ul><ul><ul><li>Méthode getTabIndex() : position dans la chaîne de tabulation </li></ul></ul><ul><ul><li>Méthode setTabIndex(int index) : définir cette position </li></ul></ul><ul><ul><ul><li>Valeur -1 pour enlever le widget de la chaine </li></ul></ul></ul><ul><ul><li>Méthode setFocus(boolean) : prendre/laisser le focus </li></ul></ul><ul><ul><ul><li>Un seul widget peut avoir le focus, il prend alors tous les événements clavier </li></ul></ul></ul><ul><ul><li>Méthode setAccessKey(char) : raccourcis pour prendre le focus </li></ul></ul><ul><ul><ul><li>Combiner avec une touche spéciale (exemple Alt) pour prendre le focus </li></ul></ul></ul>
  76. 76. Widget : FocusWidget <ul><li>Racine des widgets capables de gérer le focus </li></ul><ul><ul><li>D'autres widgets implémentent aussi HasFocus </li></ul></ul><ul><li>Les widgets dans lesquels on peut saisir </li></ul><ul><li>Les widgets manipulables au clavier </li></ul><ul><li>Apporte aussi la notion &quot;enabled&quot; </li></ul><ul><ul><li>Propose les accesseurs isEnabled() et setEnabled() </li></ul></ul>UIObject Widget FocusWidget
  77. 77. Interface HasName <ul><li>Marque un widget disposant d'un nom </li></ul><ul><ul><li>Propose les méthodes getName() et setName(String) </li></ul></ul><ul><ul><li>Permet de l'utiliser dans un FormPanel </li></ul></ul><ul><ul><ul><li>Nom associé au widget quand le formulaire est soumis </li></ul></ul></ul>
  78. 78. Widget : Anchor <ul><li>Un widget représentant un ancrage </li></ul><ul><ul><li>Encapsule un élément <a> </li></ul></ul><ul><li>Implémente </li></ul><ul><ul><li>HasText </li></ul></ul><ul><ul><li>HasHTML </li></ul></ul><ul><ul><li>HasHorizontalAlignment </li></ul></ul><ul><ul><li>HasWordWrap </li></ul></ul><ul><ul><li>HasDirection </li></ul></ul><ul><ul><li>HasName </li></ul></ul>UIObject Widget FocusWidget Anchor
  79. 79. Widget : ButtonBase et Button <ul><li>Racine des widgets de type Bouton </li></ul><ul><ul><li>Traditionnellement les Button, CheckBox et RadioButton </li></ul></ul><ul><li>Implémente HasHTML </li></ul><ul><li>Button </li></ul><ul><ul><li>Un bouton d'action </li></ul></ul><ul><ul><li>On lui associe un ClickListener pour réagir au clic </li></ul></ul><ul><ul><li>Méthode click() pour simuler programmatiquement le clic </li></ul></ul>UIObject Widget FocusWidget ButtonBase Button
  80. 80. Widget : CheckBox, SimpleCheckBox <ul><li>Widget représentant une case à cocher </li></ul><ul><ul><li>Introduit une propriété &quot;checked&quot; </li></ul></ul><ul><ul><li>Propose les accesseurs isChecked() et setChecked() </li></ul></ul><ul><ul><li>Implémente HasName (utilisable dans un formulaire) </li></ul></ul><ul><li>CheckBox affiche son label </li></ul><ul><ul><li>Passé dans le constructeur </li></ul></ul><ul><li>SimpleCheckBox n'a pas de label </li></ul>UIObject Widget FocusWidget ButtonBase CheckBox SimpleCheckBox
  81. 81. Widget : RadioButton, SimpleRadioButton <ul><li>Des boutons exclusifs </li></ul><ul><ul><li>Doivent appartenir à un même &quot;groupe&quot; </li></ul></ul><ul><ul><li>Le &quot;name&quot; hérité sert à définir le groupe </li></ul></ul><ul><ul><li>L'indiquer dans le constructeur </li></ul></ul><ul><li>RadioButton affiche son label </li></ul><ul><li>SimpleRadioButton n'as pas de label </li></ul>UIObject Widget FocusWidget ButtonBase CheckBox SimpleCheckBox RadioButton SimpleRadioButton
  82. 82. Widget : CustomButton <ul><li>Racine des boutons personnalisables </li></ul><ul><li>Associer des images ou des textes </li></ul><ul><ul><li>Selon que le bouton est enfoncé ou non </li></ul></ul>UIObject Widget FocusWidget ButtonBase CustomButton
  83. 83. Widget : PushButton <ul><li>Un bouton d'action personnalisable </li></ul><ul><ul><li>Permet de lui associer des images </li></ul></ul><ul><li>Permet de gérer le déroulement d'un clic </li></ul><ul><ul><li>Méthode onClickStart() : début du clic </li></ul></ul><ul><ul><li>Méthode onClickCancel() : clic annulé </li></ul></ul><ul><ul><li>Méthode onClick() : clic de l'utilisateur </li></ul></ul>UIObject Widget FocusWidget ButtonBase CustomButton PushButton
  84. 84. Widget : ToggleButton <ul><li>Un CheckBox personnalisable </li></ul><ul><ul><li>Spécifier des images, le bouton peut rester enfoncé </li></ul></ul><ul><li>Méthodes pour gérer la sélection </li></ul><ul><ul><li>Méthode isDown() </li></ul></ul><ul><ul><li>Méthode setDown() </li></ul></ul><ul><ul><li>Méthode onClick() </li></ul></ul>UIObject Widget FocusWidget ButtonBase CustomButton ToggleButton
  85. 85. Widget : TextBoxBase <ul><li>Racine des widgets de saisie textuelle </li></ul><ul><ul><li>Implémente HasText, HasName et HasFocus </li></ul></ul><ul><li>Introduit les propriétés </li></ul><ul><ul><li>&quot;readOnly&quot; : lecture seule </li></ul></ul><ul><ul><li>&quot;cursorPos&quot; : position du curseur </li></ul></ul><ul><ul><li>&quot;textAlignment&quot; : alignement du text </li></ul></ul><ul><ul><ul><li>Constantes ALIGN_[LEFT, CENTER, RIGHT, JUSTIFY] </li></ul></ul></ul><ul><ul><li>Accès au text sélectionné </li></ul></ul><ul><ul><ul><li>getSelectedText(), getSelectedLength(), selectAll(), setSelectionRange() </li></ul></ul></ul><ul><ul><li>Filtrage de la saisie </li></ul></ul><ul><ul><ul><li>setKey(char) : réception d'un caractère </li></ul></ul></ul><ul><ul><ul><li>cancelKey() : refuser le caractère en cours de saisie </li></ul></ul></ul>UIObject Widget FocusWidget TextBoxBase
  86. 86. Widget : TextBox, PasswordTextBox <ul><li>Le champ de saisie standard </li></ul><ul><ul><li>Une seule ligne </li></ul></ul><ul><ul><li>Implémente HasDirection en plus </li></ul></ul><ul><li>Introduit les propriétés </li></ul><ul><ul><li>&quot;maxLength&quot; : nombre maxi de caractères </li></ul></ul><ul><ul><li>&quot;visibleLength&quot; : nombre visible de caractères </li></ul></ul><ul><li>PasswordTextBox </li></ul><ul><ul><li>Masque la saisie </li></ul></ul>UIObject Widget FocusWidget TextBoxBase TextBox
  87. 87. Widget : TextArea <ul><li>Une zone de texte multi-lignes </li></ul><ul><ul><li>Implémente HasDirection en plus </li></ul></ul><ul><li>Introduit les propriétés </li></ul><ul><ul><li>&quot;visibleLines&quot; : nombre de lignes visibles </li></ul></ul><ul><ul><li>&quot;characterWidth&quot; : longueur des lignes </li></ul></ul>UIObject Widget FocusWidget TextBoxBase TextArea
  88. 88. Widget : RichTextArea <ul><li>Saisie de texte riche (HTML) </li></ul><ul><ul><li>Style et formatage </li></ul></ul><ul><ul><li>Implémente HasText, HasHTML et HasFocus </li></ul></ul><ul><ul><ul><li>getText() : le texte brut sans formatage </li></ul></ul></ul><ul><ul><ul><li>getHTML() : le texte HTML </li></ul></ul></ul><ul><ul><li>Intéressant de lui adjoindre une barre d'outil </li></ul></ul><ul><ul><ul><li>RichTextToolBar dans le Showcase (pas inclus de base) </li></ul></ul></ul><ul><ul><ul><li>Copier la classe et les ressources du répertoire </li></ul></ul></ul><ul><ul><ul><li>Répertoire com.google.gwt.sample.showcase.client.content.text </li></ul></ul></ul>UIObject Widget FocusWidget RichTextArea
  89. 89. Widget : ListBox (1) <ul><li>Liste de choix </li></ul><ul><ul><li>Items sont des String, gérés par leur indice </li></ul></ul><ul><ul><li>Ajout des items avec addItem(String) </li></ul></ul><ul><ul><li>Implémente HasName et HasFocus </li></ul></ul><ul><li>Propriété </li></ul><ul><ul><li>&quot;selectedIndex&quot; : indice sélectionné </li></ul></ul><ul><ul><li>&quot;visibleItemCount&quot; : nombre de lignes </li></ul></ul><ul><ul><li>&quot;multipleSelect&quot; : sélection multiple </li></ul></ul><ul><ul><li>Méthode insertItem et removeItem (par indice) </li></ul></ul><ul><ul><li>Méthode getItemCount() : nombre d'items </li></ul></ul><ul><li>Drop-down (combo) avec setVisibleItemCount(1) </li></ul>UIObject Widget FocusWidget ListBox
  90. 90. Widget : ListBox (2) <ul><li>Possibilité de distinguer item et sa valeur </li></ul><ul><ul><li>Méthode addItem(String item, String valeur) </li></ul></ul><ul><ul><li>Méthode insert(String item, String value, int index) </li></ul></ul><ul><ul><li>Accès getItemText(int) et getValue(int) </li></ul></ul><ul><ul><li>Modification setItemText(int, String) et setValue(int, String) </li></ul></ul><ul><li>Insertion à l'indice, en fin si négatif ou trop grand </li></ul><ul><li>Sélection multiple </li></ul><ul><ul><li>Obligation de parcours </li></ul></ul><ul><ul><li>Méthode isItemSelected(int) </li></ul></ul><ul><ul><li>Méthode setItemSelected(int, boolean) </li></ul></ul><ul><ul><li>Différent de setSelectedItem(int) : sélection simple </li></ul></ul>TP 5
  91. 91. La notion de layout <ul><li>Logique différente de Swing </li></ul><ul><ul><li>Difficile de mapper vers des éléments HTLM </li></ul></ul><ul><ul><li>=> approche différente </li></ul></ul><ul><li>GWT propose un ensemble de Panel </li></ul><ul><ul><li>Affichent de manière spécifique leurs widgets </li></ul></ul><ul><li>Exemples </li></ul><ul><ul><li>HorizontalPanel : widgets de gauche à droite </li></ul></ul><ul><ul><li>FlowPanel : comme HTML, de gauche à droite mais passe à la ligne </li></ul></ul><ul><ul><li>AbsolutePanel : positionnement absolu </li></ul></ul>
  92. 92. Panel, Composite et HasWidgets <ul><li>Pattern &quot;composite&quot; classique dans les GUI </li></ul><ul><ul><li>Certains widgets contiennent d'autres widgets </li></ul></ul><ul><ul><li>Permet d'assembler de manière récursive les interfaces </li></ul></ul><ul><ul><li>Remarque : ce sont eux-mêmes des widgets (récursivité) </li></ul></ul><ul><li>Panel </li></ul><ul><ul><li>Classe naturelle pour effectuer un &quot;regroupement&quot; (plutôt layout) </li></ul></ul><ul><li>Composite </li></ul><ul><ul><li>Plutôt un widget complexe contenant déjà des widgets </li></ul></ul><ul><ul><li>Propose de l'intéraction, ce que ne fait généralement pas le panel </li></ul></ul><ul><li>Interface HasWidgets </li></ul><ul><ul><li>Une interface pour marquer les widgets conteneurs </li></ul></ul>
  93. 93. Interface HasWidgets <ul><li>Marque un widget qui peut contenir des widgets </li></ul><ul><ul><li>Hérite de Iterable qui propose la méthode iterator() </li></ul></ul><ul><ul><li>Typiquement les Panel et les Composite </li></ul></ul><ul><li>Propose de quoi énumérer les widgets contenus </li></ul><ul><ul><li>Méthode add(Widget) </li></ul></ul><ul><ul><li>Méthode remove(Widget) </li></ul></ul><ul><ul><li>Méthode clear() : supprime tous les widgets </li></ul></ul><ul><ul><li>Méthode iterator() : retourne un Iterator<Widget> sur les widgets </li></ul></ul><ul><li>Panel et Composite l'implémentent </li></ul>
  94. 94. Hiérarchie partielle (Panel) UIObject Widget Panel ComplexPanel HorizontalSplitPanel AbsolutePanel HTMLTable SimplePanel VerticalSplitPanel CellPanel DeckPanel FlowPanel HTMLPanel StackPanel RootPanel DockPanel HorizontalPanel VerticalPanel DecoratedStackPanel DecoratorPanel FocusPanel FormPanel PopupPanel ScrollPanel DecoratedPopupPanel DialogBox
  95. 95. Panel <ul><li>Racine des conteneurs de widgets </li></ul><ul><ul><li>Plutôt destiné au layout </li></ul></ul><ul><ul><li>Implémente HasWidgets </li></ul></ul><ul><li>La hiérarchie de composition est accessible </li></ul><ul><ul><li>Tout widget connaît son conteneur parent </li></ul></ul><ul><ul><li>En haut de la hiérarchie se trouve le RootPanel </li></ul></ul><ul><li>Nécessité de garantir l'intégrité de cette composition </li></ul><ul><ul><li>Gérée dans les méthodes add, remove et setWidget </li></ul></ul><ul><ul><li>Nécessité de gérer l'attachement et le détachement </li></ul></ul>UIObject Widget Panel
  96. 96. Panel : attachement et détachement (1) <ul><li>Fuite mémoire en JavaScript : problème classique </li></ul><ul><ul><li>Garbage Collector ne peut ramasser les références cycliques </li></ul></ul><ul><ul><ul><li>En particulier les gestionnaires d'événements (qu'on verra plus tard) </li></ul></ul></ul><ul><ul><li>Importance de nettoyer ces références cycliques (tâche rébarbative) </li></ul></ul><ul><ul><li>GWT gère en proposant des méthodes à éventuellement redéfinir </li></ul></ul>Widget conteneur Widget contenu setWidget (ou add) adopt ->setParent() onAttach() //positionne les listeners doAttachChildren() //propager à ses widgets onLoad() setWidget(avec null ou remove) orphan ->setParent(null) onDetach() onUnload doDetachChildren() //propager à ses widgets //retire les listeners
  97. 97. Panel : attachement et détachement (2) <ul><li>Respecter quelques règles </li></ul><ul><ul><li>Appeler super.onAttach() si on redéfinit cette méthode </li></ul></ul><ul><ul><li>Redéfinir doAttachChildren() si on implémente HasWidgets </li></ul></ul><ul><ul><li>Ainsi que doDetachChildren() </li></ul></ul><ul><ul><li>Plutôt redéfinir onLoad() et onOnload() </li></ul></ul>
  98. 98. SimplePanel, ComplexPanel <ul><li>Contenir un seul ou plusieurs widgets </li></ul><ul><li>SimplePanel </li></ul><ul><ul><li>Un seul widget : accesseurs get et setWidget() </li></ul></ul><ul><ul><li>Ajout visuel autour du widget </li></ul></ul><ul><ul><ul><li>DecoratorPanel </li></ul></ul></ul><ul><ul><li>Ou regroupement de fonctionnement </li></ul></ul><ul><ul><ul><li>PopupPanel, FormPanel, ScrollPanel, … </li></ul></ul></ul><ul><ul><li>Ce widget contenu peut bien sûr être un Panel </li></ul></ul><ul><li>ComplexPanel </li></ul><ul><ul><li>Plusieurs widgets </li></ul></ul><ul><ul><li>Permet le layout </li></ul></ul><ul><ul><ul><li>DeckPanel, FlowPanel, StackPanel, … </li></ul></ul></ul>UIObject Widget Panel SimplePanel UIObject Widget Panel ComplexPanel
  99. 99. Interface IndexedPanel <ul><li>Marque un panel aux widgets accessibles pas indice </li></ul><ul><ul><li>Implique un ordre explicite des widgets contenus </li></ul></ul><ul><li>Propose </li></ul><ul><ul><li>Méthode getWidgetCount() : nombre de widgets </li></ul></ul><ul><ul><li>Méthode getWidget(int) : widget par son indice </li></ul></ul><ul><ul><li>Méthode getWidgetIndex(Widget) : indice du widget </li></ul></ul><ul><ul><li>Méthode remove(int) : enlever un widget </li></ul></ul><ul><li>Concerne la plupart des ComplexPanel </li></ul>
  100. 100. FlowPanel <ul><li>Organise ses widgets en lignes </li></ul><ul><ul><li>C'est le layout naturel de HTML </li></ul></ul><ul><ul><li>Plusieurs lignes si pas assez large </li></ul></ul><ul><ul><li>Implémente HasIndexedPanel </li></ul></ul><ul><li>Propose </li></ul><ul><ul><li>Méthode addWidget(Widget) </li></ul></ul><ul><ul><li>Méthode insertWidget(Widget, index) </li></ul></ul>UIObject Widget Panel ComplexPanel FlowPanel
  101. 101. CellPanel <ul><li>Dispose ses widgets dans une table </li></ul><ul><ul><li>Un widget par cellule </li></ul></ul><ul><ul><li>Implémente HasIndexedPanel </li></ul></ul><ul><ul><li>C'est une classe abstraite </li></ul></ul><ul><li>Propriétés </li></ul><ul><ul><li>&quot;spacing&quot; : espace entre les cellules </li></ul></ul><ul><ul><li>&quot;borderWidth&quot; : épaisseur de bordure </li></ul></ul><ul><ul><li>Dimension de cellule </li></ul></ul><ul><ul><ul><li>Méthodes setCellWidth(), setCellHeight() </li></ul></ul></ul><ul><ul><li>Alignement de cellule </li></ul></ul><ul><ul><ul><li>setCellHorizontalAlignment(), setCellVerticalAlignment() </li></ul></ul></ul>UIObject Widget Panel ComplexPanel CellPanel
  102. 102. HorizontalPanel, VerticalPanel <ul><li>Dispose ses widgets horizontalement </li></ul><ul><ul><li>Pas de retour à la ligne (différent de FlowPanel) </li></ul></ul><ul><ul><li>Implémente IndexedPanel, HasAlignment </li></ul></ul><ul><li>Autorise aussi l'insertion </li></ul><ul><ul><li>Méthode insert(Widget, int) </li></ul></ul><ul><li>VerticalPanel dispose verticalement </li></ul><ul><ul><li>Sur une seule colonne </li></ul></ul>UIObject Widget Panel ComplexPanel CellPanel HorizontalPanel
  103. 103. DockPanel <ul><li>Organise ses widgets dans des zones </li></ul><ul><ul><li>NORTH, SOUTH, EAST, WEST, CENTER </li></ul></ul><ul><ul><li>Correspond au BorderLayout de Swing </li></ul></ul><ul><ul><li>Implémente HasAlignment </li></ul></ul><ul><ul><li>Méthode add(Widget, DockPanel.Direction) </li></ul></ul><ul><li>Chaque zone peut contenir plusieurs widgets </li></ul><ul><ul><li>On peut ajouter plusieurs widgets dans une zone </li></ul></ul><ul><ul><li>NORTH et SOUTH subsidiaires s'empilent au milieu </li></ul></ul><ul><li>Deux autres constantes </li></ul><ul><ul><li>LINE_START et Line_END </li></ul></ul><ul><ul><li>Gérer le sens de lecture plutôt que EAST-WEST </li></ul></ul>UIObject Widget Panel ComplexPanel CellPanel DockPanel
  104. 104. Exemple DockPanel
  105. 105. DeckPanel <ul><li>Organise ses widgets en un tas </li></ul><ul><ul><li>Comme un tas de carte </li></ul></ul><ul><ul><li>Un seul visible à la fois : showWidget(int) </li></ul></ul><ul><ul><li>Ne pas confondre avec le DockPanel </li></ul></ul><ul><ul><li>Implémente HasAnimation et HasIndexed </li></ul></ul><ul><ul><li>C'est le panel interne utilisé par le TabPanel (onglet) </li></ul></ul><ul><ul><li>Attention : impacte les dimensions de ses widgets </li></ul></ul><ul><li>Propose </li></ul><ul><ul><li>Méthode getVisibleWidget() : indice du widget montré </li></ul></ul><ul><ul><li>Méthode showWidget(int) : montrer le widget indiqué </li></ul></ul><ul><ul><li>Méthode insert(Widget, int) : insertion </li></ul></ul>UIObject Widget Panel ComplexPanel DeckPanel
  106. 106. StackPanel <ul><li>Organise ses widgets en une pile verticale </li></ul><ul><ul><li>Un seul montré à la fois : showStack(int) </li></ul></ul><ul><ul><li>Les autres représentés par un header sensible au click </li></ul></ul><ul><ul><li>Implémente IndexedPanel </li></ul></ul><ul><li>Propose </li></ul><ul><ul><li>Méthode getSelectedIndex() : sélection </li></ul></ul><ul><ul><li>Méthode showStack(int) : sélectionner </li></ul></ul><ul><ul><li>Gestion des headers </li></ul></ul><ul><ul><ul><li>Méthodes addWidget(Widget, String) </li></ul></ul></ul><ul><ul><ul><li>Méthode setStackText(int, String) </li></ul></ul></ul><ul><ul><li>Gestion des headers HTML </li></ul></ul><ul><ul><ul><li>Méthodes addWidget(Widget, String, boolean) </li></ul></ul></ul><ul><ul><ul><li>Méthode setStackText(int, String, boolean) </li></ul></ul></ul>UIObject Widget Panel ComplexPanel StackPanel
  107. 107. DecoratedStackPanel <ul><li>Ajoute simplement une décoration </li></ul><ul><ul><li>Gestion de coins arrondis à l'aide d'images </li></ul></ul>UIObject Widget Panel ComplexPanel StackPanel Decorated StackPanel
  108. 108. AbsolutePanel <ul><li>Positionnement absolu de ses widgets </li></ul><ul><ul><li>Widgets peuvent se chevaucher </li></ul></ul><ul><ul><li>Implémente IndexedPanel </li></ul></ul><ul><ul><li>Positionnement left et top </li></ul></ul><ul><ul><li>Widgets gardent leurs dimensions </li></ul></ul><ul><li>Propose </li></ul><ul><ul><li>Méthode add(Widget, int, int) : ajouter en positionnant </li></ul></ul><ul><ul><li>Méthode setWidgetPosition(Widget, int, int) </li></ul></ul><ul><ul><li>Méthodes getWidgetLeft(Widget), getWidgetTop(Widget) </li></ul></ul><ul><ul><li>Méthode addWidget(Widget) : ajouter en empilant verticalement </li></ul></ul><ul><li>RootPanel en hérite !!! </li></ul>UIObject Widget Panel ComplexPanel AbsolutePanel RootPanel
  109. 109. HTMLPanel <ul><li>Approche complètement différente </li></ul><ul><ul><li>Encapsuler du code HTML </li></ul></ul><ul><ul><li>Attacher les widgets aux éléments identifiés de ce code </li></ul></ul><ul><ul><li>Le layout est géré ailleurs (dans le code HTML) </li></ul></ul><ul><ul><li>Implémente IndexedPanel </li></ul></ul><ul><li>Propose </li></ul><ul><ul><li>Constructeur acceptant le code HTML </li></ul></ul><ul><ul><li>Méthode add(Widget, String) : ajoute le widget à l'élément identifié </li></ul></ul><ul><ul><li>Méthode addAndReplaceElement(Widget, id) : ajoute et remplace </li></ul></ul><ul><ul><li>Méthode createUniqueId() : helper pour créer des id uniques </li></ul></ul>UIObject Widget Panel ComplexPanel HTMLPanel
  110. 110. HTMLTable <ul><li>Panel à base de cellules en colonnes </li></ul><ul><ul><li>Ne pas confondre avec HTMLPanel </li></ul></ul><ul><ul><li>Widgets dans les cellules, coordonnées row, column </li></ul></ul><ul><li>Propose </li></ul><ul><ul><li>Propriété borderWidth : épaisseur de bordure </li></ul></ul><ul><ul><li>Propriété cellPadding et cellSpacing : espace entre les cellules </li></ul></ul><ul><ul><li>Méthodes d'accès général </li></ul></ul><ul><ul><ul><li>Méthodes clear(), clearCell(int, int) et remove(Widget) </li></ul></ul></ul><ul><ul><ul><li>Méthodes getRowCount(), getCellCount(int), isCellPresent(int, int) </li></ul></ul></ul><ul><ul><ul><li>Méthodes getWidget(int, int) : version avec Text et HTML </li></ul></ul></ul><ul><ul><ul><li>Méthodes setWidget(int, int, Widget) : idem </li></ul></ul></ul><ul><ul><li>Méthodes d'accès aux formatters </li></ul></ul><ul><ul><ul><li>getColumnFormatter(), getRowFormatter(), getCellFormatter() </li></ul></ul></ul>UIObject Widget Panel HTMLTable
  111. 111. Grid <ul><li>Une table avec des dimensions prédéfinies </li></ul><ul><ul><li>Constructeur Grid(int numRow, int numColumn) </li></ul></ul><ul><ul><li>Possibilité de redimensionner après coup : resize() </li></ul></ul><ul><li>Dimensions des rangées et colonnes </li></ul><ul><ul><li>Pas imposées et variables </li></ul></ul><ul><ul><li>Largeur de colonne imposée par son widget le plus grand </li></ul></ul><ul><ul><li>Hauteur de ligne imposée par son widget le plus large </li></ul></ul><ul><li>Idéal pour organiser dans une structure tabulaire </li></ul>UIObject Widget Panel HTMLTable Grid
  112. 112. FlexTable <ul><li>Une table flexible </li></ul><ul><ul><li>Permet de créer des cellules à la demande </li></ul></ul><ul><ul><li>Un widget peut s'étaler sur plusieurs cellules </li></ul></ul><ul><ul><li>Organisation logique en rangées de taille variable </li></ul></ul><ul><li>Propose </li></ul><ul><ul><li>Méthodes insertRow(int), removeRow(int) </li></ul></ul><ul><ul><li>Méthodes getRowCount() et getCellCount(int) : cellules d'une row </li></ul></ul><ul><ul><li>Méthodes insertCell, insertCells : insertion de cellules dans une row </li></ul></ul><ul><ul><li>Accès au formateur avec getFlexCellFormatter() </li></ul></ul><ul><ul><ul><li>Permet de fusionner des cellules </li></ul></ul></ul>UIObject Widget Panel HTMLTable FlexTable
  113. 113. DecoratorPanel <ul><li>Ajouter une décoration autour d'un widget </li></ul><ul><ul><li>En général, le widget contenu est un panel </li></ul></ul><ul><li>La bordure est constituée d'images </li></ul><ul><ul><li>Neuf zones : les bords, les coins et le centre </li></ul></ul><ul><ul><li>Permet de faire des coins arrondis </li></ul></ul><ul><ul><li>Permet de redimensionner sans détruire le look </li></ul></ul><ul><ul><li>Définies dans les styles (on verra plus tard) </li></ul></ul>UIObject Widget Panel SimplePanel DecoratorPanel
  114. 114. PopupPanel <ul><li>Un panel qui &quot;surgit&quot; au dessus des autres </li></ul><ul><ul><li>Typiquement tooltip, menu, dialog </li></ul></ul><ul><ul><li>Ne pas les ajouter à un panel : show() et hide() </li></ul></ul><ul><ul><li>Dimensions déterminées par son widget contenu </li></ul></ul><ul><ul><ul><li>Méthodes setWidth() et setHeight() redirigées sur ce contenu </li></ul></ul></ul><ul><ul><li>Implémente HasAnimation </li></ul></ul><ul><li>Propriétés </li></ul><ul><ul><li>&quot;autoHide&quot; : se ferme tout seul (sur clic en dehors) </li></ul></ul><ul><ul><li>&quot;modal&quot; : capture tous les événements des autres widgets </li></ul></ul><ul><ul><li>Positionnement : setPopupPosition(), center(), … </li></ul></ul><ul><li>DecoratedPopupPanel : décore aussi le centre </li></ul>UIObject Widget Panel PopupPanel Decorated PopupPanel SimplePanel
  115. 115. DialogBox <ul><li>Les boîtes de dialogues </li></ul><ul><ul><li>Implémente HasText (le titre appelé &quot;Caption&quot;) </li></ul></ul><ul><ul><li>Implémente HasHTML (le titre peut être HTML) </li></ul></ul><ul><li>SimplePanel donc setWidget(Widget) </li></ul><ul><ul><li>Renseigner son contenu avec un Panel </li></ul></ul><ul><ul><li>En géréral ajouter des boutons de fermeture </li></ul></ul><ul><ul><ul><li>Invoquer la méthode hide() </li></ul></ul></ul><ul><ul><li>Mais &quot;autoHide&quot; et &quot;modal&quot; sont héritées </li></ul></ul><ul><li>Méthodes liées aux événements souris </li></ul><ul><ul><li>Méthodes onMouse[Enter,Move, Down, Up, Leave] </li></ul></ul><ul><ul><li>Typiquement utiles pour la gestion d'un menu </li></ul></ul>UIObject Widget Panel PopupPanel Decorated PopupPanel DialogBox SimplePanel
  116. 116. Exemple DialogBox
  117. 117. ScrollPanel <ul><li>Placer un widget dans une zone scrollable </li></ul><ul><ul><li>Affiche une partie de ce widget contenu </li></ul></ul><ul><ul><li>Utilise des scrollbars pour représenter la partie visible </li></ul></ul><ul><li>Propose </li></ul><ul><ul><li>Propriété &quot;scrollPosition&quot; : la position verticale </li></ul></ul><ul><ul><li>Propriété &quot;HorizontalScrollPosition&quot; : horizontale </li></ul></ul><ul><ul><li>Méthodes pour scroller : scrollToBottom(), scrollToRight(), … </li></ul></ul><ul><ul><li>Méthodes pour indiquer la dimension : setWidth(), setHeight() </li></ul></ul><ul><ul><li>Méthode setAlwaysShowScrollBars() : masquer les scrollbars </li></ul></ul><ul><ul><li>Méthode ensureVisible(UIObject) : scroll pour rendre visible </li></ul></ul>UIObject Widget Panel ScrollPanel SimplePanel
  118. 118. HorizontalSplitPanel <ul><li>Dispose deux widgets horizontalement </li></ul><ul><ul><li>Barre de séparation permet de redimensionner </li></ul></ul><ul><li>Propose </li></ul><ul><ul><li>Propriétés &quot;leftWidget&quot; et &quot;rightWidget&quot; </li></ul></ul><ul><ul><li>Propriétés &quot;startOfLineWidget&quot; et &quot;endOfLineWidget&quot; </li></ul></ul><ul><ul><li>Méthode isResizing() : redimensionnement en cours ? </li></ul></ul><ul><ul><li>Méthode setSplitPosition(String) : redimensionner </li></ul></ul>UIObject Widget Panel Horizontal SplitPanel
  119. 119. VerticalSplitPanel <ul><li>Dispose deux widgets verticalement </li></ul><ul><ul><li>Barre de séparation permet de redimensionner </li></ul></ul><ul><li>Propose </li></ul><ul><ul><li>Propriétés &quot;bottomWidget&quot; et &quot;topWidget&quot; </li></ul></ul><ul><ul><li>Méthode isResizing() : redimensionnement en cours ? </li></ul></ul><ul><ul><li>Méthode setSplitPosition(String) : redimensionner </li></ul></ul>UIObject Widget Panel Vertical SplitPanel
  120. 120. Intégrer GWT dans une page HTML <ul><li>On peut ajouter du code HTML dans la page </li></ul><ul><ul><li>Ressources dans le répertoire &quot;public&quot; sont copiées </li></ul></ul><ul><ul><li>On peut les utiliser directement dans la page HTML </li></ul></ul><ul><ul><li>Exemple ajout d'une image dans le <body> de la page </li></ul></ul><ul><ul><ul><li><img src=&quot;images/logo.png&quot; /> </li></ul></ul></ul><ul><li>Associer des RootPanel aux éléments de la page </li></ul><ul><ul><li>Nécessite que ces éléments soient identifiés (attribut id) </li></ul></ul><ul><ul><li>RootPanel.get(&quot;xxx&quot;) </li></ul></ul>TP 6
  121. 121. Hiérarchie partielle (Composite) UIObject Widget Composite CaptionPanel TabPanel DisclosurePanel SuggestBox DecoratedTabPanel TabBar DecoratedTabBar
  122. 122. Widget : Composite <ul><li>Racine des widgets &quot;composite&quot; </li></ul><ul><ul><li>Des widgets constitués de plusieurs parties </li></ul></ul><ul><ul><li>Garder une certaine intégrité du composite </li></ul></ul><ul><li>Souvent pour construire ses propres widgets </li></ul><ul><ul><li>On en hérite et on compose avec des widgets existants </li></ul></ul><ul><ul><li>En gérant spécifiquement les événements (qu'on verra plus tard) </li></ul></ul><ul><ul><li>Toujours invoquer initWidget() dans le constructeur </li></ul></ul>UIObject Widget Composite
  123. 123. Widget : CaptionPanel <ul><li>Cadre avec label autours d'un composant </li></ul><ul><ul><li>Le label peut être texte ou HTML </li></ul></ul><ul><ul><li>Implémente HasWidgets </li></ul></ul><ul><ul><ul><li>Mais n'en contient qu'un seul </li></ul></ul></ul><ul><li>Propose </li></ul><ul><ul><li>Propriétés &quot;captionText&quot; et &quot;captionHTML&quot; </li></ul></ul>UIObject Widget Composite CaptionPanel
  124. 124. Widget : DisclosurePanel <ul><li>Contient &quot;header&quot; et widget escamotable </li></ul><ul><ul><li>Cliquer sur le &quot;header&quot; bascule la visibilité </li></ul></ul><ul><ul><li>&quot;header&quot; peut être Widget ou String </li></ul></ul><ul><ul><li>Implémente HasAnimation et HasWidgets </li></ul></ul><ul><ul><ul><li>Mais n'en contient qu'un seul </li></ul></ul></ul><ul><li>Propose </li></ul><ul><ul><li>Propriété &quot;header&quot; (Widget) </li></ul></ul><ul><ul><li>Propriété &quot;contents&quot; (Widget) </li></ul></ul><ul><ul><li>Propriété &quot;open&quot; (boolean) </li></ul></ul>UIObject Widget Composite DisclosurePanel
  125. 125. Widget : SuggestBox <ul><li>Un champs de saisie avec suggestion </li></ul><ul><ul><li>Propose dynamiquement une liste en cours de saisie </li></ul></ul><ul><ul><li>Implémente HasText, HasAnimation, HasFocus </li></ul></ul><ul><ul><li>Suggestions proviennent d'un SuggestOracle </li></ul></ul><ul><ul><ul><li>Une classe permettant de proposer une liste de suggestions </li></ul></ul></ul><ul><ul><li>Par défaut, MultiWordSuggestOracle </li></ul></ul><ul><ul><ul><li>Facile à renseigner : ajouter des string </li></ul></ul></ul><ul><li>Propose </li></ul><ul><ul><li>Propriété &quot;text&quot; (vient du HasText) : le texte du champs </li></ul></ul><ul><ul><li>Propriété &quot;suggestOracle&quot; : l'oracle qui va proposer les suggestions </li></ul></ul><ul><ul><li>Propriété &quot;limit&quot; : limite le nombre de suggestions </li></ul></ul><ul><ul><li>Méthode setPopupStyleName(String) : le style CSS du popup </li></ul></ul>UIObject Widget Composite SuggestBox
  126. 126. Widget : TabBar, DecoratedTabBar <ul><li>Une barre d'onglets (utilisée avec TabPanel) </li></ul><ul><ul><li>Onglet de type texte, HTML ou Widget </li></ul></ul><ul><ul><li>Sélection gérée par indice </li></ul></ul><ul><li>Propose </li></ul><ul><ul><li>Méthodes add et insert pour les 3 types </li></ul></ul><ul><ul><li>Méthodes getTabCount() et removeTab(int) </li></ul></ul><ul><ul><li>Méthodes getSelectedTab() et selectTab(int) </li></ul></ul><ul><ul><li>Méthodes getTabText(int) et setTabText(int, String) </li></ul></ul><ul><ul><li>Méthodes getTabHTML(int) et setTabHTML(int, String) </li></ul></ul><ul><ul><li>Méthodes pour gérer les événements </li></ul></ul><ul><li>DecoratedTabBar ajoute la décoration (coins arrondis) </li></ul>UIObject Widget Composite Decorated TabBar TabBar
  127. 127. Widget : TabPanel <ul><li>Gestion d'onglets </li></ul><ul><ul><li>Composite agrégeant un TabPanel et un DeckPanel </li></ul></ul><ul><ul><li>Montre le widget associé à un &quot;tab&quot; </li></ul></ul><ul><ul><li>Implémente HasAnimation, IndexedPanel, HasWidgets </li></ul></ul>UIObject Widget Composite Decorated TabPanel TabPanel
  128. 128. Autres composants <ul><li>Projets open sources proposent d'autres widgets </li></ul><ul><ul><li>Calendrier, table triée, calculatrice, panel de dessin, bulle d'aide,… </li></ul></ul><ul><ul><li>Widgets wrappant des librairies JavaScript existantes </li></ul></ul><ul><ul><ul><li>Google Map API </li></ul></ul></ul><ul><ul><ul><li>Google Search API </li></ul></ul></ul><ul><ul><ul><li>Scriptaculous </li></ul></ul></ul><ul><ul><ul><li>Ext-GWT </li></ul></ul></ul><ul><ul><ul><li>GWT-Ext </li></ul></ul></ul><ul><ul><ul><li>SmartGWT </li></ul></ul></ul><ul><ul><li>Widget pour intégrer du SVG (Scalar Vector Graphics) </li></ul></ul><ul><ul><ul><li>Intégration de graphiques vectoriels </li></ul></ul></ul>
  129. 129. S'abstraire du JavaScript ? <ul><li>Philosophie générale mais pas toujours possible </li></ul><ul><ul><li>Besoin parfois d'intégrer des librairies ou des effets JavaScript </li></ul></ul><ul><li>Dangers de l’encapsulation de librairies JavaScript </li></ul><ul><ul><li>Sympa mais souvent un seul développeur </li></ul></ul><ul><ul><ul><li>Pas toujours bien développée ou adaptée à la philosophie GWT </li></ul></ul></ul><ul><ul><ul><li>Exemple : arrêt du support GWT-Ext par le changement de licence de ext-js </li></ul></ul></ul><ul><ul><ul><li>On retombe dans les problèmes de compatibilité de navigateur et de version </li></ul></ul></ul><ul><li>Privilégier les librairies &quot;pures GWT&quot; </li></ul><ul><ul><li>Plutôt que les encapsulations de librairies JavaScript </li></ul></ul><ul><li>Garder à l’esprit que JavaScript = Assembleur du web </li></ul><ul><ul><li>Qui intègrerait des librairies en assembleurs dans ses applis ? </li></ul></ul><ul><ul><ul><li>Même dans le monde du jeu vidéo ça se fait de moins en moins </li></ul></ul></ul>
  130. 130. Gestion de l'i18n
  131. 131. Gestion de l’internationalisation <ul><li>Couvre plusieurs aspects </li></ul><ul><ul><li>Configuration de l'application </li></ul></ul><ul><ul><li>Formatage des nombres et monnaies </li></ul></ul><ul><ul><li>Traduction des messages et libellés </li></ul></ul><ul><li>L'approche de GWT est originale </li></ul><ul><ul><li>Ne pas gérer ces problèmes dynamiquement mais à la compilation </li></ul></ul><ul><ul><li>Générer un fichier JavaScript pour chaque locale </li></ul></ul><ul><li>Technique récurrente de GWT : le &quot;DeferredBinding&quot; </li></ul>
  132. 132. DeferredBinding <ul><li>Technique pour pallier l'absence de &quot;dynamic binding&quot; </li></ul><ul><ul><li>En clair : pas de ClassLoader en JavaScript </li></ul></ul><ul><ul><li>Implique de tout charger et utiliser ce qui convient </li></ul></ul><ul><ul><ul><li>Typiquement gestion des spécificités des navigateurs, des locales, … </li></ul></ul></ul><ul><li>GWT gère autrement </li></ul><ul><ul><li>Fichier spécifique pour chaque navigateur et pour chaque locale </li></ul></ul><ul><ul><ul><li>Exemple : support de 5 navigateurs et 3 langues produit 15 fichiers différents </li></ul></ul></ul><ul><ul><li>On peut ajouter son propre axe de variance </li></ul></ul><ul><ul><ul><li>Exemple intranet / internet </li></ul></ul></ul><ul><ul><li>GWT gère automatiquement ces &quot;permutations&quot; </li></ul></ul><ul><li>En pratique : utiliser les méthodes de la classe GWT </li></ul><ul><ul><li>GWT.create(Interface) : obtenir une implémentation d'une interface </li></ul></ul>
  133. 133. I18n : configuration <ul><li>Déclaration dans le fichier de description de module </li></ul><ul><ul><li>Déclarer une dépendance vers le module i18n </li></ul></ul><ul><ul><li>Déclarer les locales supportées </li></ul></ul><ul><li>Test avec le mode &quot;Hosted&quot; </li></ul><ul><ul><li>Ajouter &quot;?locale=fr&quot; à la fin de l'URL </li></ul></ul><ul><ul><li>Utiliser le bouton Go (Refresh ne convient pas) </li></ul></ul><module> <inherits name='com.google.gwt.user.User'/> <inherits name='com.google.gwt.i18n.I18N'/> <extend-property name=&quot;locale&quot; value=&quot;fr&quot;/> … </module>
  134. 134. NumberFormat <ul><li>La classe pour formater des nombres et monnaies </li></ul><ul><ul><li>Méthode format(double) pour formater une valeur </li></ul></ul><ul><ul><li>Méthode parse(String) pour décoder une chaîne </li></ul></ul><ul><ul><li>Méthode statiques pour obtenir les formats standards </li></ul></ul><ul><ul><ul><li>Décimal : getDecimalFormat() </li></ul></ul></ul><ul><ul><ul><li>Pourcent : getPercentFormat() </li></ul></ul></ul><ul><ul><ul><li>Scientifique getScientificFormat() </li></ul></ul></ul><ul><ul><ul><li>Monnaie : getCurrencyFormat() </li></ul></ul></ul><ul><ul><li>Possibilité de construire son propre format (règles assez classiques) </li></ul></ul><ul><ul><ul><li>Méthode getFormat(String, String) (voir NumberFormat dans la javadoc) </li></ul></ul></ul>NumberFormat fmt1 = NumberFormat.getDecimalFormat(); double value1 = 12345.6789; String formatted = fmt1.format(value1); double value2 = fmt1.parse(&quot;12345.6789&quot;); NumberFormat fmt2 = NumberFormat.getFormat(&quot;000000.000000&quot;); formatted = fmt2.format(value1);
  135. 135. DateTimeFormat <ul><li>La classe pour formater les dates </li></ul><ul><ul><li>Méthodes format() pour formater une Date </li></ul></ul><ul><ul><li>Méthode parse() pour décoder (s'accomode des dates invalides) </li></ul></ul><ul><ul><li>Méthode parseStrict() pour décoder en refusant les dates invalides </li></ul></ul><ul><ul><li>Variante pour modifier une Date existante </li></ul></ul><ul><ul><li>Formats standards pour les Date, Time et DateTime </li></ul></ul><ul><ul><ul><li>getFullDateFormat(), getFullDateTimeFormat(), getFullTimeFormat() </li></ul></ul></ul><ul><ul><ul><li>Variantes pour Long, Medium et Short </li></ul></ul></ul><ul><ul><li>Format spécifique avec getFormat(pattern) </li></ul></ul><ul><ul><ul><li>Règles classiques (voir DateTimeFormat dans javadoc) </li></ul></ul></ul>
  136. 136. Gestion des messages <ul><li>Similaire aux fichiers de properties </li></ul><ul><ul><li>Stoquer des strings et nombres dans des fichiers </li></ul></ul><ul><ul><li>Y accéder depuis l'application </li></ul></ul><ul><li>Deux mécanismes </li></ul><ul><ul><li>Inclusion statique (à la compilation) </li></ul></ul><ul><ul><li>Inclusion dynamique (à l'exécution) </li></ul></ul>
  137. 137. I18n : interface Constants <ul><li>Déclarer une interface héritant de Constants </li></ul><ul><ul><li>Créer des méthodes d'accès à l'information </li></ul></ul><ul><li>Créer les fichiers .properties </li></ul><ul><ul><li>AppConstants.properties </li></ul></ul><ul><ul><li>AppConstants_fr.properties </li></ul></ul><ul><li>Utiliser le DeferredBinding </li></ul><ul><ul><li>GWT.create() </li></ul></ul><ul><ul><ul><li>Implémentation à partir du fichier properties adéquat </li></ul></ul></ul><ul><ul><ul><li>Autant de fichiers que de locales </li></ul></ul></ul><ul><ul><li>Penser à déclarer les locales </li></ul></ul><ul><ul><li>Penser à écrire en UTF8 </li></ul></ul><ul><li>Plus simplement, utiliser le script i18nCreator </li></ul>Créer l'interface public interface MySettings extends Constants { String welcomeMsg(); String logoImage(); } Dans MySettings.properties welcomeMsg = Bonjour logoImage = /images/logo.jpg Utilisation dans le code MySettings s = GWT.create( MySettings.class); String msg = s.getWelcomeMsg();
  138. 138. I18n : interface ConstantsWithLookup <ul><li>Même principe mais ajoute une méthode de lookup </li></ul><ul><ul><li>Permet de rechercher dans les constantes </li></ul></ul><ul><ul><li>Méthode getString(String) </li></ul></ul><ul><li>A éviter car ne permet pas le &quot;pruning&quot; </li></ul><ul><ul><li>C'est-à-dire la suppression des constantes non utilisées </li></ul></ul>
  139. 139. I18n : interface Messages <ul><li>Même mécanisme mais avec des paramètres </li></ul><ul><li>Hériter de l'interface Messages </li></ul><ul><ul><li>Option du i18nCreator </li></ul></ul>Dans MySettings.properties welcomeMessage = Bonjour {0} {1} logoImage = /images/logo.jpg Interface correspondante public interface MySettings extends Constants { String welcomeMessage(String nom, String prenom); String logoImage(); } Utilisation dans le code MySettings settings = GWT.create(MySettings.class); String msg = settings.getWelcomeMessage( login.getNom(), login.getPrenom());
  140. 140. (Dés)Avantages de l'inclusion statique <ul><li>Inclus dans le code compilé </li></ul><ul><li>Aussi performant qu'une constante en dur </li></ul><ul><ul><li>Le compilateur optimise en faisant des &quot;inlines&quot; </li></ul></ul><ul><li>Seuls les messages utilisés sont embarqués </li></ul><ul><ul><li>Gros fichiers de propriétés institutionnels ne pénalisent pas l'appli </li></ul></ul><ul><li>Mais </li></ul><ul><ul><li>Génère beaucoup de fichiers si beaucoup de locales supportées </li></ul></ul><ul><ul><li>Parfois on a besoin de valeurs plus dynamiques </li></ul></ul>
  141. 141. I18n : inclusion dynamique <ul><li>Classe Dictionary </li></ul><ul><ul><li>N'utilise pas de fichier de propriétés </li></ul></ul><ul><li>Données dans le HTML, sous forme d'objet JavaScript </li></ul><ul><ul><li>Données ne sont plus fixées à la compilation mais au runtime </li></ul></ul><ul><ul><li>Lecture par la méthode Dictionary.getDictionary(String) </li></ul></ul>var MySettings = { welcomeMessage: &quot;Bienvenue&quot;, logoImage: &quot;/images/logo.jpg&quot; }; Dictionary settings = Dictionary.getDictionary(&quot;MySettings&quot;); TP 7
  142. 142. Les styles CSS
  143. 143. Les styles CSS (1) <ul><li>Rappel (pour plus d'info http://fr.selfhtml.org) </li></ul><ul><ul><li>Sert à séparer la présentation du contenu HTML (style) </li></ul></ul><ul><ul><li>Forme : sélecteur { propriété: valeur } </li></ul></ul><ul><ul><li>CSS1 : environ 50 propriétés </li></ul></ul><ul><ul><li>CSS2 : 70 de plus </li></ul></ul><ul><li>Selecteurs possibles </li></ul><ul><ul><li><H1> => H1 { } </li></ul></ul><ul><ul><li><… class=&quot;grand&quot; … => .grand { } </li></ul></ul><ul><ul><li><… id=&quot;titre&quot; … => #titre </li></ul></ul><ul><ul><li>Peuvent se combiner : H1.grand = éléments H1 de classe &quot;grand&quot; </li></ul></ul><ul><ul><li>Pseudo classe : exemple a.link = lien (balise <a>) pas encore visité </li></ul></ul>H1 { text-align: center } .grand { font-size: 20pt } #titre { color: red } H1.grand { color: blue }
  144. 144. Les styles CSS (2) <ul><li>Peuvent se combiner pour plus de concision </li></ul><ul><ul><li>Regrouper des sélecteurs </li></ul></ul><ul><ul><li>Regrouper des propriétés </li></ul></ul><ul><li>Héritage </li></ul><ul><ul><li>Styles des éléments englobants </li></ul></ul><ul><li>Sélectionner </li></ul><ul><ul><li>Séparer avec un espace </li></ul></ul>H1, H2, H3 { font-style: bold } H1 { color: green; text-align: center; } --- <BODY> <H1>Un exemple</H1> <P>Avec un <STRONG>paragraphe</STRONG> </P> </BODY> --- /* bleu pour contenu du BODY */ BODY { color: blue } /* rouge pour STRONG dans P */ P STRONG { color: red }
  145. 145. Les styles CSS (3) <ul><li>Formatage d'écriture </li></ul><ul><ul><li>Plusieurs attributs </li></ul></ul><ul><ul><ul><li>Famille, Style, Variante </li></ul></ul></ul><ul><ul><ul><li>Taille, Poids, Etirement </li></ul></ul></ul><ul><ul><li>Forme simplifiée </li></ul></ul><ul><ul><ul><li>Espace entre les valeurs </li></ul></ul></ul><ul><ul><li>Surcharge partielle </li></ul></ul><ul><li>Styles présents dans : </li></ul><ul><ul><li>HTML, fichiers CSS, config navigateur, préférences utilisateur </li></ul></ul><ul><li>Firefox + FireBug sont nos amis </li></ul>H1 { font-family: 'Times New Roman', serif; font-style: italic; font-variant: normal; font-size: large; font-weight: bold; font-stretch: expanded; } H2 { font: Times 13px bold; } H3 { font-weight: bold }
  146. 146. Style des widgets <ul><li>Méthode setStyleName() pour affecter un style </li></ul><ul><ul><li>Indiquer le nom du style en paramètre (String) </li></ul></ul><ul><li>Nécessite la présence du nom dans le fichier de styles </li></ul><ul><ul><li>Préfixé par &quot;.&quot; (oubli fréquent) </li></ul></ul><ul><li>Lien vers la feuille de styles </li></ul><ul><ul><li>Dans le HEAD du HTML : <link rel=&quot;stylesheet&quot; href=&quot;styles.css&quot;> </li></ul></ul><ul><ul><li>Ou plutôt dans le fichier module : <stylesheet src=&quot;styles.css&quot;/> </li></ul></ul><ul><ul><ul><li>Mieux car lié à l'appli et non au fichier HTML </li></ul></ul></ul>Dans le code : Dans le fichier de styles : widget.setStyleName(&quot;special&quot;); .special { float: right; margin: 5px; }
  147. 147. Style par défaut <ul><li>Chaque widget dispose d'un style spécifique </li></ul><ul><li>Formé par convention : [projet]-[widget] </li></ul><ul><ul><li>Exemple : gwt-TextBox (style des boites de texte) </li></ul></ul><ul><ul><li>Attention au préfixe &quot;.&quot; </li></ul></ul><ul><li>On peut modifier ces styles dans son fichier de styles </li></ul><ul><ul><li>Fichier public/App.css généré par l'applicationCreator </li></ul></ul>
  148. 148. Thèmes <ul><li>Installation propose trois thèmes </li></ul><ul><ul><li>Standard, Chrome et Dark </li></ul></ul><ul><ul><li>Configuré dans le fichier de description de module (&quot;App.gwt.xml&quot;) </li></ul></ul><ul><li>Existe en version RTL (lecture de droite à gauche) </li></ul><ul><ul><li><inherits name=&quot;com.google.gwt.user.theme.dark.DarkRTL&quot;/> </li></ul></ul><ul><li>Ces thèmes produisent un fichier &quot;.css&quot; </li></ul><ul><ul><li>On le retrouve dans le répertoire gwt de l'appli compilé </li></ul></ul><ul><ul><li>Exemple : gwt/standard/standard.css pour le thème standard </li></ul></ul><ul><ul><li>C'est le fichier qui précise les styles par défaut </li></ul></ul>
  149. 149. Modification du style <ul><li>UIObject propose des méthodes liées au style </li></ul><ul><ul><li>Méthode setStyleName(String) : permet d'affecter un style </li></ul></ul><ul><ul><li>Remplace le style existant </li></ul></ul><ul><ul><li>Utilisé comme une classe CSS => préfixe &quot;.&quot; dans les fichiers CSS </li></ul></ul><ul><li>L'intérêt des styles est de se combiner </li></ul><ul><ul><li>Pour combiner des effets graphiques, pour placer, … </li></ul></ul><ul><li>GWT propose 3 notions simplifiant cette combinaison </li></ul><ul><ul><li>Style primaire </li></ul></ul><ul><ul><li>Style secondaire </li></ul></ul><ul><ul><li>Style dépendant </li></ul></ul>
  150. 150. Style primaire <ul><li>La classe de style CSS pour un UIObject </li></ul><ul><ul><li>Chaque widget dispose de son style par défaut </li></ul></ul><ul><ul><li>Forme &quot;gwt-&quot; suivi de la classe du widget (ex: gwt-Label) </li></ul></ul><ul><li>On peut changer ce style </li></ul><ul><ul><li>Avec setStylePrimaryName(String) </li></ul></ul><ul><ul><li>Ou avec setStyleName(String) </li></ul></ul><ul><ul><li>Subtile différence qu'on comprendra dans deux minutes </li></ul></ul>
  151. 151. Style secondaire <ul><li>Un widget peut se voir affecter plusieurs styles </li></ul><ul><ul><li>Ajouter avec addStyleName(String) </li></ul></ul><ul><ul><li>Supprimer avec removeStyleName(String) </li></ul></ul><ul><ul><li>Séparation par un espace dans attribut class </li></ul></ul><ul><ul><ul><li><… class=&quot;style1 style2&quot; …> </li></ul></ul></ul><ul><li>Permet de combiner des effets dynamiquement </li></ul><ul><ul><li>Exemple : ajout d'une bordure rouge autour d'un widget en erreur </li></ul></ul>
  152. 152. Style dépendant <ul><li>Un style secondaire un peu spécial </li></ul><ul><li>Caractérise une propriété, un état du composant </li></ul><ul><ul><li>Positionné avec addStyleDependentName(String) </li></ul></ul><ul><ul><li>Ou plutôt avec des méthodes prévues (setReadonly()) </li></ul></ul><ul><ul><li>Concatène le style primaire, un tiret et le style dépendant </li></ul></ul><ul><li>Exemple : .gwt-TextBox-readonly </li></ul><ul><ul><li>Style spécifique de boite de texte dans le cas readonly </li></ul></ul><ul><li>Conservé en cas de changement de style primaire </li></ul><ul><ul><li>Avec setStyleName => on efface tout </li></ul></ul><ul><ul><li>Avec setStylePrimaryName => on renomme </li></ul></ul>TP 8
  153. 153. Les styles CSS
  154. 154. Le modèle événementiel <ul><li>Navigateurs reçoivent les événements (clavier, souris) </li></ul><ul><li>Puis les redirigent vers les éléments du DOM </li></ul><ul><li>Deux modes possibles (bubbling ou capture) </li></ul><ul><ul><li>W3C impose aux navigateurs de respecter les 2 modes </li></ul></ul><ul><ul><li>GWT masque et propose un modèle généralisé </li></ul></ul>Document Elément2 Element1 Document Elément2 Element1 Event bubbling (modèle Internet Exporer) Event capture (modèle Netscape)
  155. 155. Event <ul><li>Représente un événement natif (du navigateur) </li></ul><ul><li>Une classe &quot;opaque&quot; </li></ul><ul><ul><li>Encapsule un objet JavaScript </li></ul></ul><ul><li>Propose des constantes pour les types d'événement </li></ul><ul><li>Propose des méthodes pour tester l'événement </li></ul><ul><li>Propose quelques méthodes un peu spécifiques </li></ul>
  156. 156. Interface EventListener <ul><li>Ecouter les événements du navigateur </li></ul><ul><ul><li>Ceux qui arrivent sur les widgets via le DOM </li></ul></ul><ul><ul><li>Seules les sous-classes de Widget devraient l'implémenter </li></ul></ul><ul><li>Le widget s'enregistre auprès du DOM </li></ul><ul><ul><li>Dans le onAttach() (vu précédemment) </li></ul></ul><ul><ul><ul><li>Méthode DOM.setEventListener(Element, EventListener) </li></ul></ul></ul><ul><ul><li>Doit déclarer le type d'événements qu'il consomme </li></ul></ul><ul><ul><ul><li>Méthodes sinkEvents() et unsinkEvents() </li></ul></ul></ul><ul><li>Méthode onBrowserEvent(Event) </li></ul><ul><ul><li>C'est elle que les widgets vont redéfinir pour nous masquer tout ça </li></ul></ul>
  157. 157. Interface EventPreview <ul><li>Listener pour &quot;prévisualiser&quot; les événements </li></ul><ul><ul><li>Capture les événèments et permet de les annuler </li></ul></ul><ul><ul><li>Méthode onEventPreview(Event) : retourne false pour annuler </li></ul></ul><ul><li>Typiquement implémenté par les DialogBox </li></ul><ul><ul><li>Capturer les événéments sur les autres widgets </li></ul></ul><ul><ul><ul><li>Tant que le popup est ouvert </li></ul></ul></ul><ul><ul><li>Et les annuler </li></ul></ul><ul><li>Méthodes statiques de la classe Event </li></ul><ul><ul><li>Pour installer : Event.addEventPreview() </li></ul></ul><ul><ul><li>Pour désinstaller : Event.removeEventPreview() </li></ul></ul>
  158. 158. Schéma général SourcesConceptEvents -addConceptListener -removeConceptListener ConceptListener -onEtat1(…) -onEtat2(…) ConceptListenerCollection -fireEtat1(…) -fireEtat2(,…) ConceptListenerAdapter -onEtat1(…) { } -onEtat2(…) { } Widget Reçoit des Event du DOM, les retraduit en &quot;Concept&quot; en invoquant les &quot;fire&quot; MyListener1 -onEtat1(…) { … } -onEtat2(…) { … } MyListener2 -onEtat1(…) Interface Class implémente Class contient un Class hérite de Marque la capacité de contenir des listeners Simplifie la gestion de la collection de listeners en propageant les &quot;fire&quot; (invoque les &quot;on&quot;) Réagit aux événements Les méthodes reçoivent le widget en paramètre et éventuellement d'autres valeurs Marque un listener Simplifie si méthodes &quot;on&quot; nombreuses (implémentation vide) Ne redéfinit pas toutes les méthodes &quot;on&quot; Classe développée
  159. 159. Exemple avec Button et Click SourcesClickEvents -addClickListener -removeClickListener ClickListener -onClick(Widget) ClickListenerCollection -fireClick(Widget) Button MyClickListener() { public void onClick(Widget) { Window.alert(&quot;Click !&quot;); } } Pas de ClickListenerAdapter (une seule méthode dans l'interface)
  160. 160. Interface ClickListener <ul><li>Interface de listener d'un événement de type &quot;click&quot; </li></ul><ul><ul><li>Réagir à un clic sur le widget </li></ul></ul><ul><ul><li>Propose la méthode onClick(Widget) </li></ul></ul><ul><li>Enregistrer auprès d'un SourcesClickEvents </li></ul><ul><ul><li>La plupart des widgets </li></ul></ul>
  161. 161. Interface LoadListener <ul><li>Interface de listener pour un événement 'load' </li></ul><ul><ul><li>Typiquement chargement d'image </li></ul></ul><ul><ul><li>Hérite de java.util.EventListener </li></ul></ul><ul><li>Réagir aux événements de chargement d'un widget </li></ul><ul><ul><li>Méthode onLoad(Widget) </li></ul></ul><ul><ul><ul><li>Chargement terminé avec succès </li></ul></ul></ul><ul><ul><li>Méthode onError(Widget) </li></ul></ul><ul><ul><ul><li>Chargement vient d'échouer </li></ul></ul></ul><ul><li>Enregistrer auprès d'un SourcesLoadEvents </li></ul><ul><ul><li>Uniquement Image </li></ul></ul>
  162. 162. Interface ChangeListener <ul><li>Interface de listener d'un événement de type &quot;change&quot; </li></ul><ul><ul><li>Réagir à une modification du widget </li></ul></ul><ul><ul><li>Propose la méthode onChange(Widget) </li></ul></ul><ul><li>Enregistrer auprès d'un SourcesChangeEvents </li></ul><ul><ul><li>Typiquement les TextBox et les ListBox </li></ul></ul>
  163. 163. Interface FocusListener <ul><li>Interface de listener d'un événement de focus </li></ul><ul><ul><li>Réagir à la prise ou perte de focus sur le widget </li></ul></ul><ul><ul><li>Propose les méthodes onFocus(Widget) et onLostFocus(Widget) </li></ul></ul><ul><li>Enregistrer auprès d'un SourcesFocusEvents </li></ul><ul><ul><li>Les FocusWidget bien sûr mais aussi FocusPanel, SuggestBox, … </li></ul></ul>
  164. 164. Interface KeyboardListener <ul><li>Interface de listener des événements clavier </li></ul><ul><ul><li>Réagir à l'enfoncement/relachement des touches du clavier </li></ul></ul><ul><ul><li>Méthodes onKeyDown, onKeyPress, onKeyUp </li></ul></ul><ul><ul><ul><li>Recoivent le widget source, le caractère et le modificateur (ALT, SHIFT, CTRL) </li></ul></ul></ul><ul><ul><li>Constantes </li></ul></ul><ul><ul><ul><li>KEY_UP, KEY_TAB, KEY_ENTER, KEY_ESCAPE, … </li></ul></ul></ul><ul><ul><ul><li>MODIFIER_ALT, MODIFIER_CTRL, MODIFIER_META, MODIFIER_SHIFT </li></ul></ul></ul><ul><li>Enregistrer auprès d'un SourcesKeyboardEvents </li></ul><ul><ul><li>La plupart des widgets </li></ul></ul>
  165. 165. Interface MouseListener <ul><li>Interface de listener des événements souris </li></ul><ul><ul><li>Réagir à l'enfoncement/relachement des boutons de la souris </li></ul></ul><ul><ul><li>Réagir à l'entrée, survol, sortie de la souris dans la zone du widget </li></ul></ul><ul><ul><li>Méthodes onMouseDown, onMouseUp, onMouseMove </li></ul></ul><ul><ul><ul><li>Reçoivent le widget source, les coordonnées x et y de la souris </li></ul></ul></ul><ul><ul><li>Méthode onMouseEnter, onMouseLeave </li></ul></ul><ul><ul><ul><li>Reçoivent seulement le widget </li></ul></ul></ul><ul><li>Enregistrer auprès d'un SourcesMouseEvents </li></ul><ul><ul><li>Les Label, HTML, Image, … </li></ul></ul>
  166. 166. Interface MouseWheelListener <ul><li>Interface de listener de la molette de la souris </li></ul><ul><ul><li>Réagir à l'utilisation de la molette de la souris </li></ul></ul><ul><ul><li>Méthodes onMouseDown, onMouseUp, onMouseMove </li></ul></ul><ul><ul><ul><li>Reçoivent le widget source, les coordonnées x et y de la souris </li></ul></ul></ul><ul><ul><li>Méthode onMouseWheel(Widget, MouseWheelVelocity) </li></ul></ul><ul><ul><ul><li>Le MouseWheelVelocity contient les info

×