Datei wird geladen, bitte warten...
Zitiervorschau
Copyright © 2008 Micro Application - 20-22, rue des Petits-Hôtels - 75010 Paris 1ère Édition - Octobre 2008 Auteurs - Vianney BARON, Jessy BERNAL, Adrien MONTOILLE, Edouard RUIZ et Nicolas YUEN
Toute représentation ou reproduction, intégrale ou partielle, faite sans le consentement de MICRO APPLICATION est illicite (article L122-4 du code de la propriété intellectuelle). Avertissement aux utilisateurs Cette représentation ou reproduction illicite, par quelque procédé que ce soit, constituerait une contrefaçon sanctionnée par les articles L335-2 et suivants du code de la propriété intellectuelle. Le code de la propriété intellectuelle n’autorise, aux termes de l’article L122-5, que les reproductions strictement destinées à l’usage privé et non destinées à l’utilisation collective d’une part, et d’autre part, que les analyses et courtes citations dans un but d’exemple et d’illustration. Les informations contenues dans cet ouvrage sont données à titre indicatif et n’ont aucun caractère exhaustif voire certain. A titre d’exemple non limitatif, cet ouvrage peut vous proposer une ou plusieurs adresses de sites Web qui ne seront plus d’actualité ou dont le contenu aura changé au moment où vous en prendrez connaissance. Aussi, ces informations ne sauraient engager la responsabilité de l’Editeur. La société MICRO APPLICATION ne pourra être tenue pour responsable de toute omission, erreur ou lacune qui aurait pu se glisser dans cet ouvrage ainsi que des conséquences, quelles qu’elles soient, qui résulteraient des informations et indications fournies ainsi que de leur utilisation. Tous les produits cités dans cet ouvrage sont protégés, et les marques déposées par leurs titulaires de droits respectifs. Cet ouvrage n’est ni édité, ni produit par le(s) propriétaire(s) de(s) programme(s) sur le(s)quel(s) il porte et les marques ne sont utilisées qu’à seule fin de désignation des produits en tant que noms de ces derniers. ISBN : 978-2-300-016783 Couverture réalisée par Sébastien Wiegant MICRO APPLICATION 20-22, rue des Petits-Hôtels 75010 PARIS Tél. : 01 53 34 20 20 Fax : 01 53 34 20 00
Support technique : Également disponible sur www.microapp.com http://www.microapp.com
Retrouvez des informations sur cet ouvrage ! Rendez-vous sur le site Internet de Micro Application www.microapp.com. Dans le module de recherche, sur la page d’accueil du site, entrez la référence à 4 chiffres indiquée sur le présent livre. Vous accédez directement à sa fiche produit.
1678
Avant-propos La collection Atelier du webmaster s’adresse aux personnes initiées au développement de sites web qui souhaitent découvrir et mettre en pratique les nouvelles technologies Internet. Sans négliger les aspects théoriques, nous donnons toujours priorité à la pratique afin que vous puissiez rapidement être autonome. À travers les différents titres de cette collection vous découvrirez les technologies qui font le web 2.0 et feront ce que certains nomment déjà le web 3.0.
Conventions typographiques Afin de faciliter la compréhension des techniques décrites, nous avons adopté les conventions typographiques suivantes : j j j j
gras : menu, commande, boîte de dialogue, bouton, onglet. italique : zone de texte, liste déroulante, case à cocher, bouton radio. Police bâton : instruction, listing, texte à saisir. ➥ : dans les scripts, indique un retour à la ligne volontaire dû aux contraintes de la mise en page.
Il s’agit d’informations complémentaires relatives au sujet traité. Propose conseils et trucs pratiques.
Mise en garde sur un point important à ne pas négliger.
bas
Sommaire 1
2
Créer son premier projet avec Flex
25
1.1
Initiation à Flex Builder 3 ................................................... Flex Builder 3 et Eclipse ...................................................... Installer Flex Builder 3 ........................................................ Comprendre l’arborescence du dossier d’installation .................. Présentation de l’environnement de développement ...................
26 26 27 32 33
1.2
Créer sa première application ............................................ Création d’un nouveau projet ............................................... Comprendre l’arborescence d’un projet Flex ............................ MXML ............................................................................ Mode Source .................................................................. Mode Design ..................................................................
34 35 38 38 39 42
1.3
Compiler une application Flex ............................................ 44 Du MXML au SWF ............................................................ 44 Fichiers générés ................................................................ 44
1.4
Check-list ....................................................................... 45
Découvrir l’ActionScript 3.0
47
2.1
Démarrer avec ActionScript dans Flex Builder ....................... Créer l’application Flex ...................................................... Le code ActionScript dans vos fichiers MXML ........................... Le code ActionScript dans des fichiers séparés ......................... Importer du code ActionScript dans un fichier MXML ..................
48 48 49 52 54
2.2
Les bases de la programmation .......................................... Les packages et namespaces ............................................... Les types de données et les variables ...................................... Les fonctions et opérateurs ................................................... Les boucles et conditions .....................................................
55 55 59 62 66
2.3
La programmation orientée objet dans ActionScript ................ Les avantages de la programmation orientée objet .................... Les classes ...................................................................... Les interfaces ................................................................... L’héritage ........................................................................
68 68 69 73 74
2.4
Déboguer de l’ActionScript 3.0 dans Flex Builder .................. Création d’une application Flex utilisant ActionScript .................. Le mode Debug ................................................................ Ajouter un point d’arrêt ....................................................... Le pas à pas .................................................................... Afficher le contenu d’une variable ..........................................
77 77 78 79 83 83
Sommaire
La fonction trace ............................................................... 85 Corriger les erreurs ............................................................ 86 2.5 3
4
Check-list ....................................................................... 87
Réaliser sa première interface
89
3.1
Les composants MXML ...................................................... Définition d’un composant ................................................... Travailler avec les contrôles Flex ............................................ Différencier les composants ................................................. Utiliser un composant en MXML et en ActionScript .....................
90 90 91 93 94
3.2
Les conteneurs d’agencement ............................................. Comprendre l’utilité des conteneurs ....................................... Maîtriser les conteneurs primordiaux : HBox et VBox .................. Reconnaître les cadres d’utilisation des autres conteneurs d’agencement ..................................................................
96 96 97 99
3.3
Mise en forme de l’interface ............................................. 108 Comprendre le redimensionnent d’un composant .................... 108 Comprendre le positionnement absolu et les contraintes ............ 111
3.4
Les contrôles simples ....................................................... Utiliser Flex Component Explorer pour appréhender les contrôles simples ........................................................ Afficher des images ......................................................... Utiliser les Text Controls .....................................................
113 113 114 117
3.5
Mise en pratique : une interface d’annuaire ........................ 120 Mettre en place les conteneurs ........................................... 121 Ajouter les contrôles simples en mode Design ......................... 121
3.6
Check-list ..................................................................... 124
Gérer les événements
127
4.1
Introduction aux événements ............................................ Comprendre le flux des événements ..................................... À propos de l’objet Event .................................................. La classe EventDispatcher ..................................................
128 128 128 129
4.2
Utiliser les événements .................................................... Utiliser les événements inline .............................................. Utiliser les événements dans le code ..................................... Manipuler l’objet Event ..................................................... Les événements à connaître ...............................................
129 130 130 131 132
4.3
Les événements clavier .................................................... 133
Sommaire
Gérer les événements clavier .............................................. 133 Récupérer les codes clavier ............................................... 135 Les événements clavier-souris .............................................. 136
5
4.4
Créer ses propres événements .......................................... La méthode dispatchEvent() ................................................ Déclencher un événement en MXML ..................................... Personnaliser votre événement ............................................
137 137 138 138
4.5
Mise en pratique : un convertisseur de devises ..................... Mise en place du projet .................................................... L’interface ..................................................................... Mettre en place la logique métier ........................................ Associer la logique à l’interface avec MXML .......................... Associer la logique à l’interface avec ActionScript ...................
138 139 139 140 141 142
4.6
Check-list ..................................................................... 143
Gérer les données
145
5.1
Définir un data model ..................................................... Création d’un formulaire ................................................... La balise ...................................................... La balise ......................................................... Les modèles basés sur du script ........................................... Les modèles basés sur des classes ActionScript .......................
146 146 149 151 152 153
5.2
Lier des données ............................................................ Les accolades en MXML ................................................... Utiliser du code ActionScript dans les accolades ..................... La balise en MXML ....................................... Plusieurs sources ou plusieurs destinations .............................. Lier des données en ActionScript .........................................
156 156 157 158 159 160
5.3
Valider des données ....................................................... Les validateurs prédéfinis ................................................... Utiliser des validateurs dans un formulaire .............................. Personnalisation de la validation .........................................
161 161 163 166
5.4
Formater les données ...................................................... Utiliser les formateurs de base ............................................ Récupérer les erreurs de formatage ...................................... Formater à l’intérieur d’une liste de données ...........................
168 168 169 170
5.5
Travailler avec XML ........................................................ Accéder aux éléments ...................................................... Modifier les données ....................................................... Créer ou assembler des objets XML .....................................
171 171 173 175
5.6
Check-list ..................................................................... 175
Sommaire
6
7
Aller vers une interface riche
177
6.1
Les contrôles avancés ..................................................... Les List, les HorizontalList et les ComboBox ............................ Les DataGrid ................................................................. Les Tree ........................................................................
178 178 180 181
6.2
Créer ses propres composants .......................................... Un nouveau conteneur racine pour les composants MXML ......... Utilisons nos nouveaux composants ..................................... La création de composants en ActionScript ............................ ActionScript vs MXML pour la création de nouveaux composants . Pourquoi créer ses propres composants ? ..............................
182 182 184 189 189 190
6.3
Mise en pratique : une interface maître-détail ...................... Qu’est-ce qu’une interface maître-détail ? .............................. Mise en place du projet .................................................... Le découpage du projet .................................................... Le module maître ............................................................. Le module détail ............................................................. L’assemblage des deux modules .........................................
190 190 191 191 192 197 199
6.4
Check-list ..................................................................... 201
Naviguer dans son application
203
7.1
Introduction à la navigation ............................................. 204
7.2
Manipuler une ViewStack ................................................ Introduction au composant ViewStack .................................. Ajouter une ViewStack dans une application .......................... Manipuler une ViewStack ................................................. Dimension des conteneurs enfants .......................................
204 204 206 210 214
7.3
Les contrôles TabNavigator et Accordion ............................ Le composant TabNavigator .............................................. Le composant Accordion ................................................... Navigation au clavier ...................................................... Ajouter des boutons pour faciliter la navigation .......................
215 215 216 217 218
7.4
Mise en pratique : mon CV en ligne ................................... Création du projet ........................................................... Ajout d’un composant de navigation .................................... Ajout des informations ...................................................... Mise en forme et design .................................................... Résultat final ..................................................................
218 219 221 221 222 222
7.5
Check-list ..................................................................... 225
Sommaire
8
Personnaliser son application
227
8.1
Utiliser les comportements ............................................... Comment fonctionnent les comportements ? ........................... Les effets disponibles dans Flex ........................................... Appliquer les comportements aux composants ........................
228 228 229 230
8.2
Ajouter des effets ........................................................... Retarder le lancement d’un effet .......................................... Combiner plusieurs effets .................................................. Créer son propre effet d’apparition ......................................
234 234 234 236
8.3
ViewStates et transitions .................................................. 238 Mettre en œuvre les ViewStates .......................................... 238 Appliquer des transitions ................................................... 241
8.4
Styliser l’interface .......................................................... La balise ........................................................ Les classes de style .......................................................... Le StyleManager ............................................................. Le style inline ..................................................................
242 243 243 243 244
8.5
Item renderers et editors ................................................. Utiliser des renderers et des editors en méthode drop-in ............. La méthode inline ............................................................ Quels sont les composants Flex qui peuvent servir de renderer ou d’editor ? ...................................................................... Utiliser des items renderers et editors complexes ......................
244 245 246
8.6 9
247 248
Check-list ..................................................................... 249
Améliorer l’expérience utilisateur
251
9.1
Le glisser-déposer (drag-and-drop) ..................................... 252
9.2
L’historique de navigation (deep linking) ............................ Pour quoi faire ? ............................................................. Comment ça marche ? ..................................................... Concrètement ? ..............................................................
9.3
Impression .................................................................... 260
9.4
Internationalisation ........................................................ Faire une application localisée pas à pas .............................. Mettre autre chose que des objets string dans les ressources ....... Charger les fichiers de langue à l’exécution ...........................
9.5
Check-list ..................................................................... 267
256 256 257 257 263 263 266 267
Sommaire
10
11
Communiquer avec un serveur
269
10.1
Comprendre les possibilités de récupération de données ....... 270 Chargement dynamique des données XML ............................ 270 Un point sur le Player Flash et la sécurité ................................ 273
10.2
HTTPService ................................................................. Récupération de données via une requête http ........................ Utiliser le binding ............................................................ Récupérer les résultats de manière événementielle .................... Gérer les erreurs .............................................................
274 275 280 281 283
10.3
Services web ................................................................ Utiliser des services web de type SOAP ................................ Appeler des méthodes distantes .......................................... Passer des arguments aux méthodes de services web ............... Différence d’utilisation entre service web et HTTPService ...........
285 286 287 287 289
10.4
RemoteObject ............................................................... 290
10.5
Mise en pratique : une application avec Amazon ................. 291
10.6
Check-list ..................................................................... 301
Présenter les données graphiquement
303
11.1
Introduction à Flex Charting ............................................. 304 Utiliser un composant de Flex Charting ................................. 304
11.2
Les différents types de graphiques ..................................... Le PieChart .................................................................... L’AreaChart ................................................................... Le ColumnChart et le BarChart ........................................... Le LineChart ................................................................... Le BubbleChart et le PlotChart ............................................
305 305 306 307 308 308
11.3
Mettre en forme les graphiques ......................................... Les données ................................................................... Les séries ...................................................................... Les axes ........................................................................
309 309 310 312
11.4
Interaction avec les graphiques ......................................... Les bulles d’information ..................................................... Les légendes .................................................................. Animer un graphique .......................................................
315 315 317 319
11.5
Mise en pratique : un module de statistiques ........................ 321
11.6
Check-list ..................................................................... 327
Sommaire
12
13
Utiliser AIR
329
12.1
Passer de Flex à AIR ....................................................... Les outils pour utiliser et développer une application AIR ............ Un projet AIR dans Flex Builder 3 ........................................ Les caractéristiques d’un projet AIR ...................................... Créer un package AIR ......................................................
330 330 331 334 336
12.2
Utiliser HTML ................................................................ La classe HTMLControl ..................................................... Les possibilités avancées ................................................... HTMLControl dans le composant HTML ................................
337 337 340 343
12.3
Gérer des fichiers .......................................................... Les classes pour gérer les fichiers ......................................... Manipuler des répertoires ................................................. Gérer les fichiers .............................................................
344 344 347 349
12.4
Utiliser SQLite ............................................................... Se connecter à une base ................................................... Créer des tables ............................................................. Manipuler des données ....................................................
352 352 354 355
12.5
Personnaliser ses fenêtres ................................................ 357 Les types de fenêtres ........................................................ 357 Gérer les événements des fenêtres ....................................... 360
12.6
Check-list ..................................................................... 361
Aller plus loin
363
13.1
Cairngorm ................................................................... Le motif de conception modèle vue contrôleur ......................... L’architecture MVC selon Cairngorm .................................... Utiliser Cairngorm dans votre application .............................. Mise en pratique ............................................................
364 364 365 366 368
13.2
Tests unitaires ................................................................ Le principe des tests unitaires .............................................. FlexUnit ........................................................................ Mise en pratique ............................................................
372 373 374 378
13.3
LiveCycle Data Services et BlazeDS ................................... Remote Procedure Call ..................................................... Data Management .......................................................... Messaging ....................................................................
383 383 384 384
13.4
Obtenir de l’aide ........................................................... 384 L’aide officielle ............................................................... 384
Sommaire
Le forum Adobe Flex ........................................................ 386 13.5 14
15
Check-list ..................................................................... 387
Annexes
389
14.1
Webographie ............................................................... Sources officielles ............................................................ Communauté ................................................................. Flex en France ................................................................
390 390 391 392
14.2
Antisèches .................................................................... Les composants .............................................................. Les propriétés ................................................................. Utiliser ActionScript .......................................................... AIR ..............................................................................
392 392 402 403 403
14.3
Glossaire ..................................................................... 405
Index
409
Préface Enfin un livre, sur l’une des technologies les plus en vogue « FLEX » ! Dévorez ce livre et développez de nouvelles applications « riches et ergonomiques ». Croyez-moi, ensuite vous aurez du mal à vous en passer ! La planète Web est encore et sera toujours en pleine effervescence ! Aujourd’hui la vente de services et de biens en ligne est en pleine croissance et il est déjà possible de construire de vrais modèles économiques ! Il y a une course effrénée autour des standards technologiques de demain (Flash/Flex, SilverLight, Ajax, XUL, …) qui proposent aussi des environnements de développements accélérant la productivité des développeurs et la qualité de leurs applications. Le terme RIA (Riche Internet Application) est dans toutes les bouches, et dans tout les esprits ! Ce sont les mots magiques des Applications Intuitives et Riches de demain. La volonté de simplifier et de rendre plus interactives les interfaces utilisateurs préoccupe de plus en plus les chefs de projets IT (Technologies de l’Information) mais aussi et surtout les managers métiers des grands groupes. En effet, cela doit permettre d’accroître la productivité des équipes au quotidien et dans beaucoup de cas, d’acquérir et de fidéliser de nouveaux clients. Tous les domaines d’activités sont concernés, de la finance à l’industrie en passant par le gouvernement. Le monde de la banque, par exemple, proposera de nouveaux services en ligne comme la consultation des comptes avec des outils pratiques d’analyse et de budgétisation. Dans l’univers de l’assurance c’est par exemple la simplification de la souscription en ligne d’un nouveau contrat où le meilleur des technologies peut être utilisé, de l’application RIA guidant l’utilisateur, à la génération du contrat en PDF et l’archivage dans un coffre-fort personnel, en passant par la signature électronique ! Et demain ! Aujourd’hui déjà ! S’échappe de quelques bouches le mot RDA pour Rich Desktop Application et les grands acteurs se lancent dans la bataille comme Google avec Google Gear ! Adobe avec Flex/AIR, Microsoft avec WPF… Qui gagnera ? Et oui les applications RDA sont aussi riches que les applications RIA mais peuvent fonctionner en mode déconnecté. C’est-à-dire, en dehors d’un navigateur Web et sans être connectées à un service Internet ! Imaginez la consultation de vos comptes en ligne ! L’application RDA vous permettrait de synchroniser vos relevés de comptes lorsque vous êtes connectés au service de la banque. Et en mode déconnecté, vous pourrez analyser vos dépenses en les catégorisant, en effectuant des statistiques, ou en générant des rapports avec de beaux graphes… et cela
13
en toute transparence et de façon simple et intuitive. Plus besoin de télécharger des fichiers textes et de les importer dans un logiciel de gestion de comptes rarement intuitif ! Quelle est le devenir du Logiciel dans ce nouveau monde où les personnes seront tout le temps connectées avec du très haut débit ? Est-ce l’annonce d’un nouveau mode de développement de produits et la fin du bon vieux produit en boîte développé en C / VB ? Est-ce l’avènement des applications en ligne avec de nouveaux modèles économiques, comme la location à l’usage et non plus l’achat d’un produit ? Personnellement, je crois en l’avenir du bureau virtuel riche, totalement personnalisable ou nous ne paierons qu’en fonction de ce que nous consommons. Paiement à la durée d’utilisation ? Paiement au volume de données traitées ? … tous les modèles sont permis ! Alors pour développer vos applications RIA / RDA, les logiciels de demain, je ne peux que vous conseiller d’utiliser Flex / Air l’une des meilleures technologies du moment ! Avec cet ouvrage découvrez la puissance et la richesse du langage et obtenez très rapidement des résultats impressionnants. Bonne lecture et bon développement RIA / RDA ! Cyril Reinhard Responsable du cursus Multimédia et Technologies de l’Information à l’EPITA
14
Introduction
C
ommençons par le commencement, dans cette introduction vous allez découvrir le fameux Web 2.0 et les solutions proposées par Adobe dans ce domaine pour satisfaire les utilisateurs.
Qu’est-ce qu’une RIA ? Datant de mars 2002, le terme RIA (Rich Internet Application) désigne des applications qui semblent exécutées localement alors qu’elles sont en fait des applications web.
Le concept Ce concept, développé par Macromedia (compagnie rachetée par Adobe 2005 et à l’origine du framework Flex), allie les avantages des applications traditionnelles et ceux des applications client-serveur comme on les retrouve habituellement sur l’Internet. On obtient ainsi des programmes livrés sur le Web mais qui possèdent significativement les mêmes caractéristiques que les applications que l’on installe sur un PC. c Fig. 1 : Le monde RIA
15
Introduction
Les Rich Internet Applications permettent d’effectuer de nombreux traitements côté client qui étaient normalement effectués côté serveur. Avant les RIAs, le navigateur Internet ne servait qu’à présenter les données issues des opérations effectuées sur le serveur : le client envoyait ses données au serveur qui calculait la réponse et la renvoyait au client qui l’affichait. Dorénavant, un certain nombre de ces calculs sont déportés chez le client qui effectue des opérations non nécessairement exécutées sur le serveur ; il économise ainsi des rafraîchissements du navigateur et des échanges de données qui sont coûteux en temps.
Avantage : RIA Les RIA présentent aussi des avantages certains par rapport aux applications lourdes installées sur les postes clients. En effet, il n’est pas nécessaire de les installer, car elles sont directement utilisables via le navigateur Internet. Ainsi, la distribution et les mises à jour sont effectuées automatiquement. Les RIA facilitent également la création d’applications multiplates-formes ; en développant avec Flex, vous n’aurez plus besoin de faire plusieurs versions de votre logiciel pour toucher les utilisateurs de différentes architectures ou systèmes d’exploitation, tous les ordinateurs équipés du Flash Player (près de 97 % des machines à l’heure actuelle) seront capables de lancer l’application sans surcoût en termes de développement. De plus, les utilisateurs sont rassurés car l’installation d’un programme collecté sur l’Internet est souvent synonyme d’invasion de spywares ou de virus. Avec l’avènement des applications riches, tout est contrôlé par le navigateur qui offre un cloisonnement par rapport au reste de la machine et prévient ainsi d’éventuels logiciels malveillants.
Récapitulatif Les avantages des RIA pour les développeurs sont les suivants : j j j j j j
16
un environnement efficace pour l’exécution du code, du contenu et des communications ; une intégration accrue dans un environnement commun pour le contenu, les communications et les interfaces homme-machine ; un modèle objet puissant et facilement extensible pour l’interactivité ; une réutilisation de composants facilitée qui permet des développements rapides et plus riches que ce que peut offrir le langage HTML par défaut ; la possibilité de réaliser des applications connectées et déconnectées ; une distribution facilitée en supprimant les besoins d’installation et de développements spécifiques aux différentes plates-formes visées.
Introduction
Et pour les utilisateurs, les avantages sont les suivants : j l’intégration harmonieuse de contenus riches (vidéo, audio, graphes) de haute fidélité qui présentent des données de façon précise, identique partout et très fidèle ; j un meilleur temps de réponse de l’application car on peut faire transiter des données sans besoin de rechargement et par conséquent présenter seulement une partie de ses données et en récupérer la suite en tâche de fond ; j une meilleure interactivité et des interfaces très réactives qui ne nécessitent plus ce fastidieux temps d’attente pendant le chargement et l’affichage d’une page ; j un sentiment de contrôle de la part de l’utilisateur dans le sens où les utilisateurs ont, par exemple dans le cadre d’une application de e-commerce, la possibilité de mieux visualiser les produits, de personnaliser leurs achats, de pouvoir revenir en arrière sans avoir l’impression de commander trois fois le même produit ou de repasser par la phase de paiement contre leur gré…, ce qui assure un taux de satisfaction plus élevé et un engagement plus grand de leur part. Alors aujourd’hui, pour bénéficier de tous les avantages que nous offrent les interfaces riches, il est possible de mettre en place des RIA de deux manières : j en utilisant les technologies web normalisées telles que l’ECMAScript, le DOM et le XHTML, et en suivant la méthode AJAX ; j en utilisant un framework de développement conçu pour les RIA tel que Flex d’Adobe, JavaFX de SUN, Silverlight de Microsoft ou XUL de Mozilla. La méthode AJAX présente l’avantage d’être compatible avec pratiquement tous les navigateurs sans recourir à l’installation d’un greffon supplémentaire. Cependant, elle requiert l’utilisation de technologies qui n’ont pas été prévues pour être manipulées de la sorte et ainsi le développement peut être fastidieux et le code dur à maintenir. Les frameworks de développement spécialement étudiés ont besoin par contre d’éléments extérieurs pour fonctionner ; il est nécessaire par exemple d’avoir installé le player Flash pour exécuter des applications Flex ou d’avoir le lanceur d’application XulRunner pour exécuter des applications XUL. Pensés pour la construction de RIA, ils fournissent des environnements de développement intégrés et des méthodes de développement qui permettent d’élaborer de manière propre et rapide des applications riches et complètes.
Quelques exemples Aujourd’hui, on retrouve déjà beaucoup de RIA sur l’Internet dont les plus connues sont : GMail de Google utilisant AJAX ou Google Analytics, Yahoo! Maps, Harley Davidson Customizer, Ebay San Dimas et Sony Phone Selector qui utilisent Flex, Joost réalisé avec XUL et Popfly qui utilise Silverlight.
17
Introduction
c Fig. 2 : Yahoo Mail
Yahoo! Mail, comme son concurrent GMail, est réalisé en AJAX : il propose de nombreuses fonctionnalités que des clients e-mails statiques sont incapables de fournir comme l’auto-complétion ou la mise à jour de la boite mail sans avoir à rafraichir.
c Fig. 3 : Youtube
18
Introduction
Youtube Remixer est un outil de montage de vidéo lié à la fameuse plate-forme multimédia ; il est réalisé en Flex et prouve l’intérêt de la technologie Flash lorsque l’on souhaite manipuler du contenu multimédia.
c Fig. 4 : Google Finance
Google utilise la technologie Flex pour certains de ses outils, notamment Google Finance et Google Analytics qui profitent de la puissance des graphiques Flex. Ceux-ci ont l’avantage d’être dynamiques (informations contextuelles lors du passage de la souris sur les graphes ou modification des courbes en temps réel).
c Fig. 5 : Ebay San Dimas
19
Introduction
Enfin, seule vraie démonstration de la plate-forme AIR, Ebay San Dimas propose d’utiliser Ebay directement sur votre ordinateur, sans avoir à passer par le navigateur.
Introduction à Flex
c Fig. 6 : Les solutions Adobe
Le terme Flex désigne à la fois le framework et le runtime d’application donnant la possibilité aux développeurs de construire des interfaces riches en tirant parti du plug-in Flash. Ces applications seront connectées et en utilisant le modèle de développement n-tiers, elles permettent d’associer aux interfaces utilisateurs plusieurs technologies côté serveur (ASP.NET, Java, PHP…) qui fournissent de l’information, soit via des webservices, soit en attaquant directement des bases de données, ou en utilisant des objets Java. Flex a plus de 4 ans, il est devenu un produit open-source depuis sa version 3 sortie début 2008. La prochaine version est attendue courant 2009.
Présentation de la technologie Techniquement, Adobe Flex regroupe les éléments suivants : j
j
j j
20
ActionScript 3.0 qui est un langage de script objet. Ce langage est la transposition pour Flex de la norme E4X (ECMAScript for XML).On peut l’apparenter au langage JavaScript dans le développement web classique. MXML, un langage basé sur la grammaire XMLqui permet de décrire des interfaces très interactives et de les mettre en forme. On peut l’apparenter au langage HTML dans le développement web classique. Un langage de style intégré qui reprend les spécifications de CSS 1 (Cascading Style Sheet). Une interface événementielle de manipulation de document basée sur la spécification 3 du DOM écrite par le W3C.
Introduction
Le langage MXML est conçu pour être très facilement appréhendable. Combinée à l’utilisation de FlexBuilder, l’écriture d’une interface en Flex ne requiert pas un apprentissage long et fastidieux car cet éditeur permet (grâce à la complétion automatique) d’écrire la plupart des balises à votre place. L’autre grosse brique dans la prise en main de Flex sera l’apprentissage du langage ActionScript. Les développeurs nantis de bases en programmation (de programmes compilés ou de scripts) ne seront pas déroutés outre mesure car c’est un langage objet très complet et les débutants seront fortement aidés dans leur apprentissage par le toujours fantastique FlexBuilder. De plus, si vous avez déjà eu l’occasion d’écrire du code JavaScript ainsi (une autre implémentation de la norme ECMAScript) ; vous n’aurez même pas à apprendre une nouvelle syntaxe.
Les concepts à appréhender Pour devenir un développeur Flex efficace, il vous faudra assimiler : j j j j j
Comment les applications Flex doivent être construites (et dans quels cas il n’est pas pertinent de choisir cette solution). Les relations entre les objets MXML et les objets ActionScript et comment utiliser chacun d’eux. Bien connaître les composants fournis par Flex, comment les manipuler et créer les vôtres. Les différents moyens d’interagir avec le serveur pour traiter les données. Ce qu’ implique, en termes de performance, le code que vous écrivez et les différents moyens d’améliorer votre application.
Un autre grand avantage de la technologie Flex est la communauté très importante qu’Adobe a déjà su développer autour de ce produit.De nombreux forums de discussions et de nombreuses listes de diffusion permettent d’être en relation avec des experts Flex présents dans le monde entier et, n’hésitons pas à nous en féliciter, beaucoup de ces experts sont originaires de France et parlent notre langue.
Un leader Aujourd’hui, sur le marché des RIA, Flex est la technologie la plus mûre (version 3) et à la plus grande pénétration dans le marché, notamment grâce à l’utilisation de la plate-forme Flash qui est très éprouvée et très répandue (environ 97 % des machines dans le monde sont pourvues du Flash Player et peuvent donc exécuter une application Flex immédiatement) ; elle l’est aussi grâce à son environnement de développement intégré,
21
Introduction
FlexBuilder, basé sur Eclipse (le célèbre EDI, Environnement de développement intégré, développé par l’Eclipse Foundation et initié par IBM). De plus, cette technologie est préposée à un bel avenir car, comme écrit précédemment, la prochaine version est d’ores et déjà prévue et beaucoup de développements sont en cours dans de multiples domaines : cela assure à ce framework une pérennité non négligeable si l’on souhaite s’investir dans cette technologie pour des développements aussi bien professionnels que personnels.
La licence Arrive la question de la licence d’utilisation. Très importante dans le choix d’une technologie pour une application, la licence d’utilisation de Flex l’est d’autant plus car elle conditionne non seulement le coût des outils nécessaires pour écrire le code, mais aussi les possibilités d’explorer les "entrailles" du framework et surtout les modalités de distribution. Originellement, Flex était distribué en étant protégé par une licence propriétaire, ce qui empêchait quiconque d’avoir accès aux sources des classes et des composants du framework ; mais depuis le 26 avril 2007, Adobe a annoncé son intention de modifier la licence de Flex et dorénavant la solution de développement sera disponible avec une licence d’utilisation dite "libre" (possibilité de visualiser les sources mais en plus de s’en servir, de les modifier et de les redistribuer) : la licence MPL. Ainsi, les curieux seront à même de fouiner dans le code source de Flex et éventuellement de le modifier à leur guise. Cependant, pour l’EDI, Flex Builder, reste "propriétaire" et bien qu’une version d’évaluation (limitée à 30 jours) de ce logiciel soit disponible sur le site d’Adobe, la version complète n’est disponible qu’à l’achat (environ 500 Q). Cet éditeur est de loin le plus abouti et cet investissement est donc pratiquement incontournable une fois la période d’évaluation expirée.
Introduction à AIR AIR, pour Adobe Integrated Runtime, est le pendant "bureau" et est déconnecté de Flex. La technologie AIR est un lanceur d’application multiplate-forme et multi-système d’opérations qui permet d’exécuter sur le poste client en local des programmes écrits dans les technologies Flash, Flex, HTML, etc. Ainsi, le passage de Flex à AIR permet sans grandes modifications de rendre des applications web disponibles hors ligne en les installant sur lePC.
22
Introduction
La première version stable de la technologie AIR (1.0) est sortie début 2008 et son évolution, tout comme sa pérennité, est fortement liée à celle de Flex. De nombreux groupes ont déjà parié sur cette technologie : AOL et eBay par exemple ont développé des applications AIR téléchargeables gratuitement sur le site d’Adobe.
23
1 1.1 Initiation à Flex Builder 3 ..............................
26
1.2 Créer sa première application ........................
34
1.3 Compiler une application Flex ........................
44
1.4 Check-list .................................................
45
Créer son premier projet avec Flex C
e chapitre d’initiation va vous permettre de vous familiariser avec le Framework et l’environnement de développement Flex. Nous y abordons l’installation et la manipulation des composants nécessaires à la création de notre premier projet.
1
Créer son premier projet avec Flex
1.1 Initiation à Flex Builder 3 Le premier chapitre vous a permis de comprendre les principes fondamentaux des RIA et de Flex en particulier. Il est maintenant temps de passer à la pratique et de créer une première application en Flex 3. C’est le but de ce chapitre. Avant de commencer, il faut au préalable installer les outils de développement nécessaires et comprendre leur fonctionnement de base. La première partie de ce chapitre sera donc entièrement consacrée à l’IDE d’Adobe : Flex Builder 3. Une fois votre poste de travail configuré correctement, vous entrerez dans le vif du sujet en créant votre premier projet. Un IDE est un programme regroupant la plupart du temps un traitement de texte et de nombreux outils afin de faciliter la programmation dans un langage donné. Flex Builder 3 est l’IDE de développement pour Flex 3 développé par Adobe. Il n’est cependant, du moins en théorie, pas indispensable au développement Flex puisque le SDK est disponible gratuitement sur le site d’Adobe. Il est donc possible de développer une application uniquement avec votre éditeur de texte favori, voire même avec Notepad. Le SDK permet alors de compiler les applications en ligne de commande. Mais ce procédé n’est clairement pas envisageable pour le développement d’applications de taille conséquente. De plus, les nombreuses fonctionnalités de Flex Builder 3 vous deviendront rapidement indispensables. L’IDE offre entre autres : j j j j j j
un compilateur intégré ; une gestion des versions ; un débogueur interactif ; un assistant de mise en page ; une complétion automatique et une détection d’erreurs dans le code ; une documentation complète.
Nous utiliserons donc cet IDE tout au long de cet ouvrage puisqu’il facilite grandement le développement Flex.
Flex Builder 3 et Eclipse Si vous vous intéressez un peu à la programmation, vous vous êtes peut-être aperçu que deux technologies sont particulièrement en vogue en ce moment. Il s’agit du Java et du .NET. Le Java est un langage orienté objet développé par SUN Microsystems au milieu des années 1980 et qui a la particularité d’être multiplateforme grâce à l’utilisation d’une
26
Initiation à Flex Builder 3
1
machine virtuelle. Il existe plusieurs IDE facilitant le développement Java comme Netbeans ou JBuilder par exemple. Mais le plus célèbre est sans aucun doute Eclipse. Eclipse est un IDE polyvalent et multiplateforme développé à l’origine par IBM. Il a, en outre, la particularité de ne pas être spécifique à un langage donné. Une des forces d’Eclipse vient de son architecture développée autour de la notion de plug-ins. Ainsi, de nombreux développeurs peuvent ajouter des fonctionnalités spécifiques ou bien encore apporter un support à de nouveaux langages de programmation. Pour finir, sachez qu’Eclipse est entièrement gratuit. Vous trouverez plus d’informations à son sujet sur www.eclipse.org. De son côté, Microsoft a introduit le framework .NET début 2000 ; il offre la particularité d’être supporté par de nombreux langages adaptés par Microsoft comme le VB.NET ou encore le C#. Microsoft a donc son propre IDE spécifique à son framework : il s’agit de Visual Studio. Adobe a fait le choix de se baser sur Eclipse pour développer son IDE, du fait de sa grande popularité auprès des développeurs et de sa capacité d’évolution grâce aux plug-ins. Ainsi, de nombreux développeurs sont déjà familiarisés avec l’environnement de développement Flex et le temps d’adaptation au développement de RIA sera d’autant plus court. Flex Builder 3 est disponible sous deux formes différentes car de nombreux développeurs ont déjà leur environnement Eclipse configurés à leur guise : j j
un plug-in ; un package comprenant Eclipse et le plug-in intégré.
Nous utiliserons le package complet pour l’installation de l’IDE dans la partie suivante. Enfin, sachez que Flex Builder (contrairement à Eclipse) est payant mais qu’une version d’évaluation de 30 jours est disponible. Nous allons utiliser la version 3 qui est la plus récente disponible au moment où nous écrivons ces lignes.
Installer Flex Builder 3 Commençons par l’installation de l’IDE. La première étape est le téléchargement. Rendez-vous sur le site d’Adobe à l’adresse suivante : http://www.adobe.com/fr/. 2 Dans la section Produits, sélectionnez Flex. Vous arrivez alors sur une page dédiée à la technologie Flex. Cliquez à présent sur le lien Tester Flex Builder 3. Comme 1
27
1
Créer son premier projet avec Flex
vous pouvez le constater, il est nécessaire de créer un compte Adobe pour accéder à la page de téléchargement : entrez une adresse e-mail valide puis cliquez sur Continuer.
c Fig. 1.1 : Formulaire de connexion 3
Une fois arrivé sur la page suivante, entrez les informations obligatoires signalées par un astérisque. Vous allez enfin pouvoir télécharger Flex Builder à la suite de votre inscription. Vous devriez arriver sur une page vous proposant plusieurs versions à télécharger : j j
une version standalone pour Mac ou Windows comprenant Eclipse et le plug-in Flex intégré ; une version plug-in pour Eclipse encore une fois pour Mac ou Windows.
Nous allons récupérer la version standalone qui contient tous les outils nécessaires au développement d’applications Flex.
c Fig. 1.2 : Téléchargez le standalone pour Mac ou Windows
28
Initiation à Flex Builder 3
4
1
Une fois le téléchargement terminé, lancez l’exécutable, cliquez sur Next et acceptez la licence.
c Fig. 1.3 : Contrat de licence Adobe 5
Choisissez ensuite le répertoire Files\Adobe\Flex Builder 3).
d’installation
(typiquement
C:\Program
c Fig. 1.4 : Répertoire d’installation 6
L’écran suivant va vous demander d’installer Flash Player 9 pour les navigateurs installés sur votre système (ici Internet Explorer et Firefox). Nous vous rappelons que Flash Player 9 est indispensable pour exécuter des applications Flex. Cliquez sur Next.
29
1
Créer son premier projet avec Flex
c Fig. 1.5 : Installation du Flash Player 7
Un résumé vous permet de vérifier les paramètres saisis avant l’installation effective des composants. Cliquez sur Next pour confirmer les paramètres d’installation.
c Fig. 1.6 : Résumé 8
30
Une fois l’installation Flex Builder 3 terminée, vous allez avoir le choix d’installer l’extension ColdFusion qui permet de faire le lien entre l’IDE et le middleware ColdFusion d’Adobe. Nous n’allons pas utiliser ce dernier dans cet ouvrage et il est donc inutile d’installer l’extension.
Initiation à Flex Builder 3
1
c Fig. 1.7 : Extension pour ColdFusion
Pour les utilisateurs de Windows Vista Il sera nécessaire de lancer Flex Builder 3 avec les droits administrateur au premier lancement de l’application. Dans le menu Démarrer, cliquez sur le raccourci Flex Builder 3 avec le bouton droit de la souris et sélectionnez Lancer en tant qu’administrateur dans le menu contextuel. c Fig. 1-8 : Lancer Flex Builder 3 pour la première fois sous Vista
31
1
Créer son premier projet avec Flex
Comprendre l’arborescence du dossier d’installation Maintenant que Flex Builder 3 est installé, il peut être utile de comprendre comment est structuré le kit de développement Flex. Ouvrez le répertoire d’installation. Comme vous pouvez le constater, celui-ci contient plusieurs sous-dossiers. Ces tableaux vont vous permettre de mieux comprendre leur utilité : Tableau 1.1 : Arborescence de Flex Builder 3 Répertoire
Description
Flex Builder 3
Dossier d’installation de l’IDE et des SDK
/configuration
Répertoire standard d’Eclipse contenant le fichier config.ini et les logs d’erreurs
/features
Répertoire standard d’Eclipse contenant le plug-in correspondant aux fonctionnalités de Flex Builder
/sdks
Contient le SDK
/jre
Contient le Java Runtime Environnement utilisé par défaut par l’IDE en mode Standalone
/Player
Répertoire d’installation des différents Player Flash (version standard et débogueur)
/plugins
Répertoire d’installation des plug-ins Eclipse utilisés par Flex Builder (rappelons qu’Eclipse est un IDE entièrement modulaire par le biais de plug-ins)
Le tableau suivant détaille l’arborescence des deux SDK installés par défaut. Tableau 1.2 : Arborescence du SDK Répertoire
Description
/bin
Contient les différents exécutables (Compilateur mxmlc, compc ou encore adl)
/frameworks
Contient les fichiers de configuration
/frameworks/libs
Contient les bibliothèques SWC utilisées pour compiler les applications
/frameworks/projects
Contient le code source du framework Flex
32
Initiation à Flex Builder 3
1
Tableau 1.2 : Arborescence du SDK /frameworks/themes
Contient les thèmes par défaut des différents composants Flex
/lib
Contient des fichiers jar
/runtimes
Contient les Players Flash et AIR
/samples
Contient les projets d’exemples accessibles depuis la page d’accueil Flex
Présentation de l’environnement de développement Vous avez normalement installé l’IDE d’Adobe et exploré son arborescence. Nous allons maintenant essayer de comprendre comment fonctionne le framework Flex. Il est grand temps de passer aux choses concrètes : démarrons Flex Builder 3. Au chargement, vous devriez voir apparaître l’écran suivant.
c Fig. 1.9 : Écran d’accueil de Flex Builder 3
33
1
Créer son premier projet avec Flex
Vous trouverez ici quelques tutoriels en anglais expliquant les concepts de base ainsi qu’un accès à l’aide de Flex Builder. Des exemples d’applications Flex sont également disponibles (Flex Component Explorer et Flex Style Explorer) permettant d’avoir un aperçu rapide et fonctionnel des différents composants et styles utilisables. Au fur et à mesure de votre progression dans cet ouvrage, vous allez probablement vouloir ouvrir les projets associés à ces exemples pour étudier leur code. Cela vous aidera à mieux comprendre les concepts étudiés en observant les résultats en situation réelle. Vous pouvez observer les différentes fenêtres et barres d’outils qui composent l’IDE (les utilisateurs d’Eclipse devraient vite retrouver leurs marques). D’autres fonctionnalités seront détaillées plus tard car elles ne sont accessibles que lorsqu’un projet est ouvert. La barre située en haut de l’IDE permet principalement d’accéder à des raccourcis : j j j j
créer un nouveau projet ; sauvegarder un projet ; lancer un projet ; déboguer un projet.
Toutes ces fonctionnalités sont cependant directement accessibles dans les différents menus de l’IDE.
c Fig. 1.10 : Barre d’outils Flex
Les vues de gauche permettent de gérer et d’explorer les différents projets créés dans Flex Builder (Navigator) et de parcourir l’arborescence des composants insérés dans une application (Outline). Enfin, sachez que l’interface est entièrement modulable et que vous pouvez placer les différents outils où bon vous semble, en fonction de vos préférences. Maintenant que vous avez un peu exploré l’interface, il est temps de créer votre premier projet Flex.
1.2 Créer sa première application Pour créer une application Flex, il faut tout d’abord créer un nouveau projet. Ainsi, Flex Builder va s’occuper de la création de l’arborescence et des fichiers nécessaires au déploiement de l’application.
34
Créer sa première application
1
Création d’un nouveau projet Commencez par créer un nouveau projet en suivant ces étapes : 1
Dans le menu, cliquez sur File/New/Flex Project. La boîte de dialogue suivante s’ouvrira : c Fig. 1.11 : Création d’un nouveau projet
Cette boîte de dialogue comporte deux champs : j j
2
le nom du projet (project name) la technologie serveur utilisée pour fournir des données à l’application. Entrez Mon premier projet Flex comme nom de projet et laissez None pour le type de serveur puis cliquez sur Next (voir fig. 1.12).
Cet écran va vous permettre de choisir le dossier de destination du projet. Par défaut, un projet est créé dans le workspace de l’IDE. Le workspace se situe par défaut dans My Documents/Flex Builder 3 pour cette version. Ainsi, par défaut, un nouveau projet sera créé dans My Documents/Flex Builder 3/nom_du_projet. Il est conseillé de garder les projets groupés dans le workspace mais ce n’est pas une obligation.
35
1
Créer son premier projet avec Flex
c Fig. 1.12 : Dossier de destination
Changer le chemin du workspace par défaut Il est possible de changer le répertoire par défaut du workspace, et des projets. Pour cela, cliquez dans le menu sur File puis sur Switch Workspace.
3
Cliquez sur Finish.
Flex Builder 3 devrait maintenant avoir créé l’arborescence du projet avec les fichiers nécessaires comme vous pouvez le constater dans la vue Navigator. Remarquez également qu’à la place de la page d’accueil Flex, l’IDE a ouvert le fichier MonProjet .mxml dans la vue centrale qui correspond à l’éditeur où vous écrirez le code ou encore où vous modifierez le design de l’application. Vous devriez donc avoir une fenêtre comme celle-ci : (voir fig. 1.13) Comme vous pouvez le constater, Flex Builder s’est chargé d’écrire un petit bout de code pour vous simplifier les choses, mais nous en reparlerons ultérieurement. Notez également la présence de deux boutons dans l’éditeur de code. Ils permettent de basculer entre les modes Source et Design (vous connaissez sûrement ce principe si vous utilisez Dreamweaver pour créer vos pages web). Vous vous trouvez normalement en mode Source. Nous détaillerons ces deux modes de travail complémentaires mais vous pouvez basculer en mode Design pour avoir un premier aperçu de votre nouvelle application si vous le souhaitez.
36
Créer sa première application
1
c Fig. 1.13 : Premier projet sous Flex Builder 3.
c Fig. 1.14 : Flex Builder en mode Design
37
1
Créer son premier projet avec Flex
Comprendre l’arborescence d’un projet Flex L’Assistant de création de projet de Flex Builder 3 a créé plusieurs éléments dans l’explorateur de projet (vue Navigator). Nous allons essayer de comprendre comment fonctionne l’arborescence d’un projet Flex. Tableau 1.3 : Arborescence d’un projet Flex Dossier/fichier
Description
/bin
C’est dans ce dossier que votre application est compilée au format .swf à chaque sauvegarde du projet. Les fichiers SWF sont déployés dans des pages HTML générées automatiquement.
/html-template
Contient des fichiers additionnels utilisés par certaines fonctionnalités de Flex comme le fichier de détection du Player Flash ou le Gestionnaire d’historique. Ces fichiers servent principalement à générer la page HTML dans laquelle l’application Flex au format .swf (flash) sera déployée.
MonProjet.mxml
Ce fichier (nommé par défaut lors de la création du projet) permet de décrire votre application. Il contient le tag qui correspond au composant principal.
.settings
Ce fichier caché dans Flex Builder contient les préférences du projet en cours.
Nous allons maintenant voir comment décrire une application Flex grâce au langage MXML.
MXML En Flex, deux langages sont utilisés pour écrire une application : j j
l’ActionScript 3 (détaillé dans le prochain chapitre) ; le MXML.
Le MXML est un langage basé sur le XML permettant de définir l’interface utilisateur d’une application et de définir des relations entre ses composants. Si vous avez déjà créé des sites web en HTML, alors vous ne devriez avoir aucun problème avec ce nouveau langage. Le principe est en effet très similaire : on place des composants sur une page sous forme de balises afin de définir une interface. Mais le MXML est un langage plus structuré. Il est également beaucoup plus riche et puissant grâce aux nombreux composants par défaut du framework Flex et à la facilité d’interaction entre eux. Enfin, le MXML permet de créer des composants personnalisés pour améliorer la réutilisabilité du code et mieux structurer une application.
38
Créer sa première application
1
Comme tout langage, le MXML doit respecter certaines règles simples que nous verrons au fur et à mesure. Nommage des fichiers MXML Les fichiers MXML doivent suivre les conventions suivantes : j
Le nom d’un fichier MXML doit commencer par un underscore (_) ou une lettre, ensuite un nom de fichier ne peut contenir que des lettres, des chiffres ou des underscores.
j
Les noms de fichiers ne doivent pas correspondre à une classe ActionScript existante, au nom ou à l’identifiant d’un composant et doivent être différents du mot "application".
j
Les fichiers MXML doivent porter l’extension .mxml.
Nous allons maintenant ajouter des composants à notre première application.
Mode Source Assurez-vous que le fichier MonProjet.mxml de votre projet est ouvert et que l’éditeur est en mode Source. Le fichier contient le code suivant par défaut :
La première ligne du fichier permet de spécifier la version du XML ainsi que le type d’encodage. Bien qu’optionnelles, il est néanmoins conseiller de remplir ces informations. Le type d’encodage peut varier selon les pays pour prendre en compte les caractères spécifiques à chaque langue, ici le format UFT-8 permet d’assurer une bonne compatibilité puisqu’il est indépendant du type de plate-forme ou de la langue. La balise est le nœud racine d’une application Flex définie dans l’espace de nom http://www.adobe.com/2006/mxml ; c’est aussi le conteneur principal. Un conteneur est un composant de l’interface utilisateur Flex permettant d’associer, de grouper et de définir la disposition d’autres composants Flex, y compris d’autres conteneurs imbriqués. Ainsi, tout composant d’une application doit être contenu entre les balises …. Ce principe est en fait très similaire aux balises d’une page web. Nous allons à présent ajouter quelques éléments à notre interface. Le but est de positionner : j un Panel avec un titre ;
39
1
Créer son premier projet avec Flex
j j j
un Label ; un TextInput ; un Button.
Procédez à présent comme suit : 1
Positionnez le curseur entre les balises … puis saisissez au clavier un chevron ouvrant : . Flex Builder a normalement ajouté les balises ouvrantes et fermantes correspondant au panel. Il est maintenant possible d’ajouter d’autres composants dans le Panel que vous venez de créer puisque ce composant est en réalité un conteneur.
1
Créer sa première application
5
Enfin, modifiez la propriété layout de la balise et remplacez absolute par vertical. Le layout permet de spécifier la disposition des composants au sein d’un conteneur mais nous verrons cela plus en détail dans le chapitre 3 Réaliser sa première interface.
Votre fichier MonProjet.mxml devrait maintenant contenir le code suivant :
Complétion Flex Vous pouvez utiliser la complétion à tout moment dans l’éditeur en appuyant sur [Ctrl]+[Barre}d'espace].
6
Ajoutons maintenant le Label. Le Label permet d’afficher de courts textes dans une application, comme un titre par exemple. Réitérez le même procédé que pour le Panel mais cette fois-ci, ajoutez une propriété text correspondant à la chaîne de caractères à afficher ("Hello World" par exemple). Pour finir, terminez cette balise par les caractères suivants : />.
Puisque le MXML est basé sur le XML, il est possible de définir des balises de deux manières : ; j (condensé des deux balises précédentes). j
Balises fermantes Il est souvent recommandé d’utiliser la seconde méthode pour les composants simples (Label, TextInput…) afin de rendre le code plus lisible.
Voici le résultat final :
41
1
Créer son premier projet avec Flex
Nous allons maintenant passer l’éditeur en mode Design afin d’avoir un premier aperçu de notre travail et d’ajouter les autres composants de manière visuelle. Cliquez sur le bouton Design dans le sélecteur de mode.
Mode Design Le mode Design peut s’avérer très utile pour placer des composants, avoir un aperçu global de l’application ou encore gérer les différents états (voir le chapitre 8, Personnaliser son application). Cette vue permet également de modifier les propriétés et le design des composants grâce au panneau de droite. Votre IDE devrait maintenant ressembler à l’écran suivant :
c Fig. 1.17 : Votre première application en mode Design
Vous pouvez cliquer sur les différents composants de votre application et modifier leurs propriétés. Vous pouvez ainsi sélectionner le Panel et modifier son titre qui est accessible dans le panneau des propriétés ou encore modifier la police de caractère du texte affiché ; choisissez Times New Roman dans l’onglet Style, et vous vous apercevrez que le changement de police s’est appliqué au titre du Panel ainsi qu’au Label car tout
42
Créer sa première application
1
composant prend par défaut les propriétés du composant parent. Ici, le Label est bien contenu dans le Panel, ce qui explique ce changement. c Fig. 1.18 : Modification du style en mode Design
Ajoutons maintenant les deux composants restants à notre application : j j
un TextInput ; un Button.
À cet effet, sélectionnez les composants dans la liste déroulante à gauche de l’éditeur et insérez-les grâce à un glisser-déposer sur le Panel. Pour terminer, remplacez le texte contenu dans le bouton par "Click Me" en modifiant sa propriété label. c Fig. 1.19 : Le résultat final en mode Design
Repassez à présent en mode Source. Flex Builder a bien ajouté les deux derniers composants dans le fichier mxml et modifié la propriété fontFamily du Panel. Voici le code final de ce premier projet :
43
1
Créer son premier projet avec Flex
1.3 Compiler une application Flex Notre premier projet est maintenant terminé et il est temps d’observer ce premier résultat dans un navigateur. À ce titre, il suffit simplement de cliquer sur la flèche verte de la barre d’outils. Flex Builder 3 se chargera alors de compiler votre projet et de le lancer dans votre navigateur par défaut.
c Fig. 1.20 : Compiler le projet
Du MXML au SWF Que s’est-il exactement passé quand vous avez appuyé sur le bouton Run ? En fait, un certain nombre d’étapes ont permis de créer un fichier SWF à partir de notre fichier MXML. La première étape consiste à transformer les balises MXML en une nouvelle classe ActionScript 3 (voir le chapitre suivant), car en réalité, tout ce qui est fait en MXML est faisable entièrement en ActionScript (mais cela peut vite devenir complexe et fastidieux). Ensuite, le compilateur crée du code qui instancie cette classe qui sera finalement compilé en fichier SWF (format standard du Flash Player). Grâce à l’environnement de développement Flex Builder 3, ce procédé s’est déroulé de manière transparente mais le SDK fourni offre, bien entendu, les outils de compilation (mxmlc). Il est possible de compiler les fichiers MXML en ligne de commande en appelant l’exécutable mxmlc.exe se trouvant dans le répertoire /sdk/bin du dossier d’installation de Flex Builder. Mxmlc −−show−actionscript−warnings=true MonProjet.mxml"
−−strict=true
−file−specs
"c:/…/
Le compilateur produit alors le fichier MonProjet.swf correspondant.
Fichiers générés Lors de la compilation, Flex Builder 3 a généré plusieurs fichiers dans le répertoire /bin de votre projet dont trois SWF qui correspondent aux versions suivantes de l’application : j j j
44
une version Standard pour la mise en production ; une version Debug ; une version Profile.
Check-list
1
Enfin, chacun de ces fichiers est encapsulé dans une page HTML séparée afin de les déployer dans un navigateur web. Les pages sont générées à partir du dossier html-template et permettent de vérifier la présence du Flash Player 9 dans le navigateur client et de charger le fichier SWF.
c Fig. 1.21 : Processus de compilation Flex
À propos du Profiler Le Profiler est une nouvelle fonctionnalité de Flex 3. Cet outil permet de visualiser le nombre d’instances et la taille en mémoire de tous les objets de votre application durant son exécution. Autant dire qu’il s’agit d’une mine d’informations pour toute personne souhaitant optimiser son code.
1.4 Check-list Dans ce premier chapitre, vous avez : a installé et pris en main Flex Builder 3 ; a créé une première application ; a appréhendé les bases du langage MXML ; a compilé et lancé une application Flex ; a étudié le mécanisme permettant de passer du MXML au SWF ; a travaillé en mode Source et Design. Le chapitre suivant est entièrement consacré au second langage utilisé dans le framework Flex : l’ActionScript 3.
45
2 2.1 Démarrer avec ActionScript dans Flex Builder .......
48
2.2 Les bases de la programmation .......................
55
2.3 La programmation orientée objet dans ActionScript ..
68
2.4 Déboguer de l’ActionScript 3.0 dans Flex Builder ..
77
2.5 Check-list .................................................
87
Découvrir l’ActionScript 3.0 S
i le MXML que vous venez de découvrir est un langage de description, ActionScript est pour sa part un langage de programmation qui vous permet d’utiliser au maximum les possibilités du Framework Flex. Vous découvrirez ici les bases de ce langage et son intégration dans Flex Builder.
2
Découvrir l’ActionScript 3.0
2.1 Démarrer avec ActionScript dans Flex Builder ActionScript est un langage de script, orienté objet, basé sur ECMAScript. Ce langage est un standard développé par l’ECMA, une organisation de standardisation très active dans le domaine de l’informatique. Le langage ECMAScript a été développé à partir des premières versions de JavaScript en 1997, et en est aujourd’hui à sa quatrième édition. ActionScript 3.0 est basé sur cette dernière édition et en est même une des implémentations les plus fidèles. ActionScript est utilisé dans les applications Adobe Flex ou Flash et apporte des possibilités étendues aux développeurs. Il permet de réaliser des applications complexes en laissant un accès de bas niveau aux données et aux objets. De nombreuses API permettent de gérer les événements, d’interagir avec du contenu Flash et bien d’autres fonctionnalités. Un raccourci rapide serait de dire qu’il représente la partie laissée aux programmeurs, le reste l’étant aux designers. Afin de pouvoir suivre les exemples qui illustreront notre découverte d’ActionScript, nous allons étudier dans un premier temps l’utilisation du code ActionScript dans une application Flex. L’IDE utilisé reste Flex Builder 3. Il permet d’accéder aux fonctions les plus simples comme les plus avancées du langage et guide l’utilisateur dans l’intégration avec la partie interface en MXML. Cette première partie n’est qu’une introduction et ne s’attardera pas sur les spécificités du langage qui sera décrit par la suite.
Créer l’application Flex Nous allons commencer par créer un projet qui nous servira à suivre les exemples de code en ActionScript 3. Nous allons donc lancer Flex Builder 3 et suivre la démarche détaillée dans le chapitre 1 sur la création d’un nouveau projet. Appelons le projet ActionScriptTest. L’objectif de notre première fonction en ActionScript sera tout simplement d’afficher dans notre application le message "Hello world!". Le champ de texte contenant le message sera décrit dans le MXML, mais le message à afficher sera donné par la fonction. Nous allons placer un champ de texte dans notre application. Ce champ sera non éditable pour bien montrer que son contenu est rempli de façon automatique. Nous l’appellerons textArea pour plus de simplicité. Voici son code :
Ce code est à insérer entre les balises et du fichier principal de l’application Flex : ActionScriptTest.mxml. Ce fichier aura alors cet aspect :
48
Démarrer avec ActionScript dans Flex Builder
2
Nous pouvons déjà exécuter notre application en cliquant avec le bouton droit de la souris sur le fichier MXML et sélectionner Run Application. Vous pourrez constater par vous-même que le champ de texte est vide. c Fig. 2.1 : L’application vide
Passons à présent à notre fonction ActionScript qui va nous permettre d’afficher notre message.
Le code ActionScript dans vos fichiers MXML Il existe deux façons d’organiser du code ActionScript dans une application Flex : à l’intérieur de vos fichiers MXML ou dans des fichiers séparés. La première, et la plus simple, consiste à insérer son code entre les balises et dans vos fichiers MXML. On place ces balises en haut de fichier, juste après la balise d’ouverture de l’application. Le résultat ressemble à cela :
49
2
Découvrir l’ActionScript 3.0
Vous pourrez noter que les commentaires en ActionScript se font grâce à un double slash (//) pour des commentaires sur une ligne. Le reste de la ligne est alors ignoré par le compilateur. Si les commentaires s’étendent sur plusieurs lignes, il faut débuter par un slash astérisque (/*) et terminer par un astérisque slash (*/). Cette façon de procéder est la même que pour le C++ et le Java. À l’intérieur de ces balises, nous allons déclarer une fonction giveHelloWorld qui renverra une chaîne de caractères contenant le message "Hello world!" à afficher : public function giveHelloWorld():String { return "Hello world!"; }
La syntaxe est très proche du Java. Observons quelques éléments de cette fonction : j j j j j j j
Le mot-clé public permet de rendre l’accès à la fonction possible en dehors du namespace. Le mot-clé function déclare une fonction. Ensuite vient le nom de la fonction, ici "giveHelloWorld". Les parenthèses permettent de déclarer la liste d’arguments. Il faut spécifier le type de retour de la fonction, ici on retourne une chaîne de caractères. Enfin vient le code de la fonction à proprement parler. On remarquera que les instructions se terminent par un point-virgule.
Notre fonction giveHelloWorld pourrait être utilisée directement pour, par exemple, donner une valeur à l’attribut text de notre composant TextArea. Mais nous pouvons également y faire appel dans une autre fonction. À présent, créons donc cette seconde fonction qui aura pour but de définir la valeur du texte contenu dans le TextArea à chaque fois qu’on y fera appel. Appelons cette fonction printHello : public function printHello():void { textAreaId.text = giveHelloWorld(); }
Cette fois-ci on ne renvoie rien, le type de retour est void. On remarque qu’on peut faire appel aux objets qui sont contenus dans le code MXML du moment que ceux-ci ont un
50
2
Démarrer avec ActionScript dans Flex Builder
identifiant, ici textAreaId. On peut alors faire appel à leurs attributs grâce au ".". La fonction printHello fait appel à giveHelloWorld pour affecter à l’attribut text de textAreaId la valeur de retour, en l’occurrence la chaîne "Hello world!". Enfin, nous devons faire appel à printHello durant l’exécution pour afficher notre texte. Nous allons le faire automatiquement au chargement de l’application. Pour cela, nous utiliserons l’attribut creationComplete de la balise en lui demandant d’exécuter la fonction printHello lorsque l’affichage est prêt :
On peut donc également faire appel à du code ActionScript à l’intérieur des balises. Il faut que les types de retour des fonctions correspondent à ceux des attributs. On aurait pu affecter la valeur text pour notre TextArea de cette manière :
Au final, notre fichier MXML ressemble à celui-ci :
Vous pouvez à présent lancer votre application et constater par vous-même que la zone de texte contient maintenant la chaîne "Hello world!" (voir fig. 2.2). Cette façon est la plus simple mais elle est loin d’être la plus élégante. De plus, elle ne permet pas d’utiliser le code déclaré dans un fichier MXML dans un autre. Aussi, nous utiliserons la seconde façon qui est plus recommandée pour nos exemples.
51
2
Découvrir l’ActionScript 3.0
c Fig. 2.2 : Hello world!
Le code ActionScript dans des fichiers séparés La seconde façon est de déclarer votre code ActionScript dans des fichiers séparés. Ceux-ci portent l’extension .as. Par convention, on les nomme du nom de la classe qu’ils contiennent. Même si cette façon de faire n’est pas obligatoire, elle est fortement recommandée par Adobe et permet de mieux se retrouver dans son code. Nous reviendrons sur la notion de classe un peu plus loin dans ce chapitre. Les fichiers ActionScript permettent de mieux concevoir votre application et de la découper en modules. Nous allons créer notre premier fichier ActionScript. À cet effet, commençons par créer un nouveau dossier dans notre application. Sélectionnez le projet puis allez dans le menu File/New/Folder. Nommez le dossier classes. Nous verrons par la suite que les dossiers sont également des packages. Sélectionnez ensuite le dossier nouvellement créé puis, allez toujours dans le menu File/New/ActionScript Class. Appelez ce fichier HelloWorld. On notera que par convention les packages ou dossiers ont une première lettre minuscule alors que les classes commencent par une majuscule. Vous obtiendrez au final un fichier HelloWorld.as dans le dossier classes qui ressemblera à celui-ci : package classes { public class HelloWorld { } }
Attardons-nous sur certains mots-clés :
52
Démarrer avec ActionScript dans Flex Builder
2
package classes signifie que le fichier fait partie du dossier classes. j le mot-clé public signifie que la classe est accessible partout en dehors du package. j class permet de définir la classe, il est suivi de son nom. j
Les termes que nous évoquons sembleront familiers à des utilisateurs de Java ou d’autres langages objet, mais si ce n’est pas votre cas, ne vous sentez pas perdu. Nous détaillerons ces concepts dans la suite du chapitre. Nous allons à présent retirer notre fonction giveHelloWorld du fichier MXML pour la placer dans la classe HelloWorld pour obtenir ceci : package classes { public class HelloWorld { public static function giveHelloWorld():String { return "Hello world!"; } } }
Sauvegardez vos fichiers HelloWorld.as et ActionScriptTest.mxml. Flex Builder vous préviendra alors d’une erreur dans ce dernier. Il ne trouve plus la fonction giveHelloWorld.
c Fig. 2.3 : Flex Builder ne trouve plus la fonction
53
2
Découvrir l’ActionScript 3.0
Flex Builder vous aidera souvent à utiliser votre code ActionScript grâce notamment à la complétion et aux imports automatiques. Nous allons utiliser cette dernière fonction pour résoudre notre problème et comprendre son origine.
Importer du code ActionScript dans un fichier MXML Vous allez maintenant supprimer l’appel à la fonction giveHelloWorld dans la fonction printHello. La fonction giveHelloWorld n’est plus définie dans notre fichier MXML mais dans le package classes. Il va donc falloir aller la chercher dans ce dernier. Tapez les premières lettres du mot classes et utilisez la complétion grâce à la combinaison [Ctrl]+[Barre}d'espace]. L’IDE vous proposera alors une liste déroulante contenant tous les éléments pouvant être utilisés. Continuez à taper et sélectionnez grâce aux flèches directionnelles le package classes puis validez avec la touche [Ä]. Tapez alors l’opérateur point de façon à avoir accès au contenu de ce package. Cette fois, la complétion vous proposera la classe contenue dans classes. Il s’agit de HelloWorld. Vous pouvez constater que lorsque vous validez le choix de cette classe, une ligne est ajoutée automatiquement par Flex Builder au début de votre code ActionScript : import classes.HelloWorld;
Cette ligne est un import. Elle permet d’utiliser le contenu déclaré en public dans la classe HelloWorld, du package classes. Vous pouvez alors continuer à utiliser la complétion pour retrouver notre fonction giveHelloWorld. Entrez l’opérateur point et vous aurez accès à la liste des fonctions de la classe HelloWorld. Celle-ci est plutôt réduite pour le moment. Validez de la même façon que précédemment et terminez par un point-virgule comme vous avez maintenant l’habitude de le faire. Votre code doit à présent ressembler à ceci :
54
Les bases de la programmation
2
À présent, vous savez comment utiliser du code ActionScript 3.0 dans vos fichiers MXML, et comment séparer les deux de façon plus élégante et organisée. Nous allons pouvoir approfondir les concepts entrevus dans cette première partie.
2.2 Les bases de la programmation Cette partie sera consacrée aux possibilités basiques offertes par ActionScript 3.0. Vous verrez comment ces dernières se rapprochent des fonctionnalités proposées par des langages comme le C++ mais surtout le Java.
Les packages et namespaces L’utilité des packages Les packages vont permettre d’organiser votre code à l’intérieur de votre application. On peut les assimiler à des dossiers et sous-dossiers à l’intérieur de votre application. Ils peuvent également être comparés aux bibliothèques du C ou C++. Les avantages de cette façon de procéder sont nombreux. On peut séparer différentes parties de code à l’intérieur du projet et ainsi obtenir une meilleure modularité. Les développeurs actifs sur le projet peuvent penser leur code et nommer leurs fonctions ou méthodes sans se soucier d’éventuels conflits de nom. Plus concrètement, on pourra avoir une méthode Toto dans un package FirstPackage et une méthode Toto différente de la première dans un autre package SecondPackage. Avant de commencer la réalisation de vos applications, il est utile de passer par une phase de conception en réfléchissant à l’organisation du projet. Vous pourrez par exemple regrouper les parties qui géreront les données dans un premier package, tandis que celles qui s’occuperont des événements se trouveront dans un second package. Ceux-ci pourront être subdivisés en sous-packages si vous jugez cette granularité nécessaire.
Déclaration de packages La déclaration d’appartenance à un package se fait simplement grâce au mot-clé package suivi de son nom. Si l’on se réfère à l’exemple précédent avec notre fichier HelloWorld .as, on obtient :
55
2
Découvrir l’ActionScript 3.0
package classes { public class HelloWorld { public static function giveHelloWorld():String { return "Hello world!"; } } }
Un package doit correspondre à un emplacement sur le système de fichier. Les fichiers contenus dans le package classes doivent donc se trouver dans un dossier du même nom. On pourrait également avoir un sous-package subPackage à l’intérieur. La déclaration se ferait alors ainsi : package classes.subPackage
L’arborescence serait par conséquent classes/subPackage. Cette arborescence nous amène à parler d’une notion très importante : le CLASSPATH. Celui-ci est une liste de chemins définis par l’utilisateur dans lequel le compilateur va aller chercher vos bibliothèques ou packages. Par défaut, le CLASSPATH inclut le répertoire de base du projet. Le compilateur trouvera donc le package classes.subPackage si les dossiers classes/subPackage sont dans le répertoire de base. Il est déconseillé de placer vos fichiers ActionScript directement dans ce répertoire. Il constitue le répertoire par défaut. Les packages sont conçus pour regrouper des classes. Cette notion de classe est propre à la programmation orientée objet sur laquelle nous reviendrons dans la suite de ce chapitre. Retenez pour l’instant que le nom du fichier ActionScript doit correspondre au nom de la classe qu’il contient, dans notre exemple HelloWorld. Cette classe doit être déclarée comme public afin qu’elle soit accessible à l’extérieur du package. Par défaut, la visibilité est internal : elle ne sera accessible qu’à l’intérieur du package. À l’intérieur de cette classe seront déclarées les fonctions ou variables (que nous appellerons par la suite méthodes et attributs). Pour que ces éléments soient accessibles en dehors du package, ils doivent être déclarés en public. D’autres options d’accessibilité seront explicitées par la suite. Par défaut, la visibilité est interne au package. Flex Builder vous guidera dans la création de vos packages en automatisant la plupart des déclarations et en vous avertissant si vos classes ne sont pas visibles à l’extérieur. Pour créer un package, il faut sélectionner dans l’arborescence de votre projet l’endroit où vous voulez le placer. Cliquez ensuite dans le menu sur File/New/Folder. Vous remarquerez à
56
Les bases de la programmation
2
nouveau la similitude entre les répertoires et les packages. Entrez alors un nom de package, par convention il commence par une minuscule. Vous pouvez à présent sélectionner ce nouveau package puis créer une classe en cliquant dans le menu sur File/New/ActionScript Class. Donnez-lui un nom, par convention il doit commencer par une majuscule, et assurez-vous que la visibilité sélectionnée est bien public et non internal. Validez et vous aurez alors une nouvelle classe dans votre package, qui sera utilisable dans votre application.
Utilisation de packages Nous allons à présent nous intéresser à l’utilisation de nos packages et de leur contenu. Si vous voulez utiliser la classe HelloWorld contenue dans le package classes, vous devez importer cette classe au début de votre code ActionScript. Cette opération se fait grâce au mot-clé import, soit de façon spécifique : import classes.HelloWorld;
Soit en important toutes les classes du package : import classes.*;
De façon générale, il vaut mieux éviter cette façon de procéder et recourir le plus possible aux imports spécifiques. Vous éviterez ainsi d’être confronté trop souvent à des conflits de nom. Vous pouvez alors faire appel aux méthodes contenues dans la classe HelloWorld à condition qu’elles soient déclarées en public. L’accès se fait grâce à l’opérateur point (.).
La notion de namespace Les namespaces sont des façons de contrôler la visibilité des éléments que vous déclarez. Nous avons déjà vu certains de ces éléments qui sont prédéfinis dans le langage ActionScript 3.0 : public et internal. Nous découvrirons par la suite private et protected. Si ceux-ci ne suffisent pas, vous êtes libre de déclarer vos propres namespaces pour des usages assez spécifiques. Une définition de méthode ou d’attribut se compose d’un identifiant et d’un namespace, même ci celui-ci peut être implicite (par défaut internal). Dans l’exemple suivant, myFunction est déclarée en internal :
57
2
Découvrir l’ActionScript 3.0
class MyClass { function myFunction():void { } }
Pour permettre l’accès à cette méthode, on peut préciser son namespace : public function myFunction():void { }
Pour déclarer un namespace, il suffit d’utiliser le mot-clé namespace, suivi de son nom : namespace myNamespace;
Vous pourrez alors l’utiliser comme public dans l’exemple précédent. Un namespace doit également contenir une valeur : l’URI (Uniform Resource Identifier). C’est un identifiant qui permet de s’assurer que la définition du namespace est unique. Cette valeur est définie lors de la création du namespace : namespace myNamespace = "http://www.adobe.com/flash";
Si vous ne spécifiez pas d’URI, le compilateur va créer pour vous un identifiant unique. Vous pouvez également appliquer aux namespaces que vous créez les contrôles d’accès prédéfinis. Par exemple, pour permettre l’accès à un namespace déclaré dans un package, vous allez lui appliquer le contrôle public : package myPackage { public namespace myNamespace; }
Pour appliquer les namespaces, c’est-à-dire placer des définitions dans ces derniers, il suffit de les utiliser comme les contrôles d’accès classiques lors des déclarations : namespace myNamespace; myNamespace function myFunction() { };
Vous ne pouvez appliquer qu’un seul namespace à la fois. En d’autres termes, vous ne pouvez pas cumuler myNamespace avec public ou internal par exemple. Vous pouvez faire référence à des fonctions déclarées dans des namespaces grâce au mot-clé use suivi du nom du namespace à utiliser. Vous avez alors accès aux éléments déclarés dans ce namespace. Pour utiliser myFunction déclarée dans myNamespace, on procédera ainsi :
58
2
Les bases de la programmation
use myNamespace; myFunction();
Mais cette façon peut poser de nombreux problèmes, notamment des conflits de noms si plusieurs anmespaces sont ouverts en même temps. Il n’existe en effet pas de moyen de fermer explicitement un namespace. On préférera donc utiliser les :: qui permettent de spécifier pour chaque appel un namespace : myNamespace::myFunction();
Vous avez à présent les connaissances de base concernant les namespaces. Les possibilités offertes sont très intéressantes et permettent par exemple l’implémentation de certains design patterns.
Les types de données et les variables Les types de données de base Les types de données sont des ensembles de valeurs. De base en ActionScript 3.0, on dispose des types primitifs suivants : Boolean (booléen), int (entier), Number (nombre), String (chaîne de caractères) et uint (entier non signé). Une valeur primitive est une valeur qui appartient à l’un de ces types. Il est recommandé de les utiliser plutôt que des valeurs complexes équivalentes car leur traitement est plus rapide et optimisé. Parmi les types complexes, nous pouvons citer les tableaux (Array), ou encore les dates (Date) .Toutes les valeurs qui ne sont pas de type primaire sont des valeurs complexes. Vos classes feront également partie de cette dernière catégorie. Le tableau suivant permet de visualiser les propriétés des types simples énoncés : Tableau 2.1 : Tableau des types de données primaires en ActionScript 3.0 Nom du type
Valeurs
Valeur par défaut
Note
Boolean
true ou false
false
int
Entre - 2 147 483 648 (-2^31) et 2 147 483 647 (2^31)
0
Stocké sous forme d’un entier de 32 bits. À préférer aux Numbers s’il n’y a pas de décimale.
Number
Entre Number.MAX_VALUE (1.79769313486231e+308) et Number.MIN_VALUE (4.940656458412467e-324)
NaN (Not a Number)
À utiliser pour les nombres décimaux ou les entiers qui dépassent les valeurs du type int.
59
2
Découvrir l’ActionScript 3.0
Tableau 2.1 : Tableau des types de données primaires en ActionScript 3.0 String
Une chaîne de caractères
uint
Entre 0 et 4 294 967 295 (2^32-1)
void
undefined
Null
null
null
Ne pas confondre null (absence de caractère) et la chaîne vide "". Pour les nombres entiers positifs
La valeur par défaut est la valeur d’une variable déclarée mais pas initialisée. Les types de données void et Null sont deux types particuliers : j
j
Le type void contient uniquement la valeur undefined. On peut uniquement associer cette valeur aux variables qui ne sont pas typées. void peut être utilisé en type de retour d’une fonction. Le type Null contient uniquement la valeur null. C’est la valeur par défaut du type String et de tous les types complexes. Si l’on essaie d’affecter null à toute variable d’un type primaire, elle sera convertie à la valeur par défaut du type.
Voyons à présent comment définir des variables en précisant leur type.
Déclaration de variables Les variables vous permettent de stocker des valeurs nécessaires à votre application. Pour déclarer une variable, vous devez utiliser le mot-clé var suivi du nom de la variable : var myVar;
Cela suffit à déclarer votre variable myVar et à l’utiliser. Mais vous ne pouvez l’utiliser tant que cette déclaration n’a pas été implémentée. Il est conseillé d’ajouter à votre déclaration le type de la variable afin d’éviter des problèmes dans la suite du code. Pour ce faire, il suffit d’ajouter le caractère : suivi du type. Vous pouvez également affecter une valeur lors de la création de la variable : var myVar:int = 42;
Si vous n’affectez pas de valeur à l’initialisation, la variable restera à la valeur par défaut de son type, ou à undefined si le type n’est pas précisé, jusqu’à une affectation.
60
Les bases de la programmation
2
Vous pouvez utiliser des virgules pour déclarer plusieurs variables sur une même ligne : var a:int = 42, b:String = "toto", c = 2.1;
Mais cette notation peut nuire à la compréhension de votre code. Un concept important, lorsqu’on parle de variables, est le concept de portée (scope en anglais). Une variable globale sera définie pour toutes les parties du code alors qu’une variable locale n’aura qu’une portée limitée. Pour déclarer une variable en globale, il faut la déclarer en dehors de toute fonction ou classe. Par contre, pour une variable locale, il suffit de la déclarer à l’intérieur d’une fonction. Les fonctions sont les plus petites portées pour les variables. Contrairement au C++ ou Java, il n’y a pas de portée limitée par des blocs de code.
Les opérateurs is et as L’opérateur is est un opérateur très pratique qui vous permettra de vérifier si une variable est d’un type donné. Son utilisation est très simple : var i:int = 42; if (i is int) // renverra true // code exécuté if (i is String) // renverra false // code non exécuté
L’opérateur as a un comportement et une utilisation similaires excepté qu’au lieu de renvoyer un booléen, il retourne la valeur de l’expression si le type est vérifié, null sinon. L’opérande de droite doit être un type. Reprenons l’exemple précédent avec as : var var res res
i:int = 42; res; = i as int; // res contiendra 42 = i as String // res contiendra null
Les conversions Il existe deux sortes de conversions de variables : j j
la conversion implicite ou coercition ; la conversion explicite ou cast.
Les conversions implicites se font à l’exécution de l’application : j
lors d’une affectation ;
61
2
Découvrir l’ActionScript 3.0
j j
lors du passage d’une valeur en argument d’une fonction ; lorsqu’une valeur est retournée par une fonction.
Dans l’exemple suivant, notre entier est converti implicitement en booléen : var i:int = 2; var bool:Boolean; bool = i; // bool contient true
Pour faire une conversion explicite ou un cast, il suffit d’entourer la variable avec des parenthèses et d’ajouter devant le nom du type qu’on veut obtenir : var i:int = 2; var bool:Boolean; bool = Boolean(i); // bool contient à nouveau true
Les conversions explicites permettent d’éviter certains messages d’erreur. Une conversion qui peut se révéler très utile est celle de valeurs numériques en chaînes de caractères et inversement : var n:Number = 3.14; var i:int = 2; var str:String; // Conversion de valeur numériques en chaines str = String(n); // str contient "3.14" str = String(i); // str contient "2" // Conversion de chaines en valeurs numériques str = "21"; i = int(str); // i contient la valeur 21 str = "37.42"; n = Number(str); // n contient la valeur 37.42
Nous étudierons d’autres possibilités de conversions dans la partie qui traite de la programmation objet. Les conversions de types complexes que vous aurez créées seront également examinées.
Les fonctions et opérateurs Les fonctions sont des blocs de code que vous pouvez définir et qui vous permettent de réaliser vos propres traitements sur des variables qui seront placées en paramètre. Souvent, vos fonctions seront déclarées à l’intérieur de classes. On les appellera alors des méthodes et leurs paramètres seront des arguments.
62
Les bases de la programmation
2
Déclaration de fonctions La déclaration d’une fonction se fait très simplement et dans l’ordre suivant : j j j j
au mot-clé function ; au nom de la fonction ; à la liste des paramètres (éventuellement vide) entre parenthèses ; au code de la fonction entre accolades.
Vous pouvez faire retourner à vos fonctions des valeurs d’un type spécifié. Il faut alors ajouter après la parenthèse fermante de la liste d’arguments, le caractère : suivi du nom du type retourné. Dans le code, vous devrez alors renvoyer à la fin de votre traitement une valeur du type demandé grâce au mot-clé return. Cet exemple montre une fonction basique qui va faire l’addition de deux entiers et renvoyer le résultat : function add(a:int, b:int):int { return a + b; // le code qui suit n’est plus exécuté }
Vous pouvez également imbriquer des fonctions les unes à l’intérieur des autres si vous le jugez nécessaire.
Les paramètres En ActionScript 3.0, tous les paramètres des fonctions sont passés par référence. C’est-à-dire qu’au lieu de faire une copie du paramètre et d’exécuter le code de la fonction sur cette copie, on travaille sur l’objet lui-même. Néanmoins, les paramètres de type primaire réagissent comme s’ils étaient passés par valeur. Pour illustrer cette propriété, modifions quelque peu notre fonction add : function add(a:int, b:int):int { ++a; ++b; return a + b; } var a:int = 2; var b:int = 3; var res:int; res = add(a, b); // res vaut 7 res = add(a, b); // res vaut encore 7 : a et b non modifiés
63
2
Découvrir l’ActionScript 3.0
ActionScript 3.0 permet de définir des valeurs par défaut pour les paramètres de vos fonctions. Tous les paramètres qui ont une valeur par défaut doivent être placés à la fin de la liste de paramètres. Ils sont alors considérés comme optionnels. S’ils ne sont pas définis lors de l’appel à la fonction, l’exécution se fera en utilisant leur valeur par défaut. Voici ce que donne notre fonction add avec une valeur par défaut pour un de ses paramètres : function add(a:int, b:int = 8):int { return a + b; } var a:int = 2; var res:int; res = add(a); // res vaut 10
Lorsque vous passez des paramètres à une fonction, vous pouvez utiliser l’objet arguments à l’intérieur de cette fonction. Cet objet est un tableau rempli automatiquement qui contient la liste des paramètres. Vous pouvez ainsi obtenir un argument en connaissant sa position : function listArg(a:int, b:int, c:int):int { return arguments[1]; // renvoie la valeur de b }
Deux propriétés intéressantes sont contenues dans arguments : length : donne la longueur du tableau, c’est-à-dire le nombre d’arguments ; j callee : fait référence à la fonction elle-même. j
Cette dernière propriété est très utile pour des fonctions récursives comme factorielles : function facto(i:int):int { if (i == 0) return 1; return i * arguments.callee(i - 1); }
Enfin, le paramètre ... permet de spécifier un tableau de paramètres de longueur indéterminée séparés par des virgules. Ce paramètre empêche l’utilisation de arguments dans la fonction mais reprend la propriété length. Il peut être utilisé en combinaison de paramètres explicités. Voici une fonction add plus évoluée faisant la somme de tous les paramètres :
64
Les bases de la programmation
2
function addAll(a:int, ... args):int { var res:int = a; for (var cpt:int = 0; i < args.length; ++i) res += args[cpt]; return res; }
Opérateurs courants ActionScript 3.0 fournit la plupart des opérateurs déjà implémentés dans d’autres langages. Ce tableau synthétise l’ensemble des opérateurs par ordre de priorité décroissante (de haut en bas) : Tableau 2.2 : Tableau des opérateurs en ActionScript 3.0 Catégorie
Opérateurs
Primaire
[] {x:y} () f(x) new x.y x[y] @ :: ..
Postfix
x++ x−−
Unaire
++x −−x + − ~ ! delete typeof void
Multiplicatif
* / %
Additif
+ −
Décalage de bits
> >>>
Relationnel
< > = as in instanceof is
Égalité
== != === !==
Et (bits)
&
Ou exclusif (bits)
^
Ou (bits)
|
Et logique
&&
Ou logique
||
Condition
? : (opérateur ternaire)
Affectation
= *= /= %= += −= = >>>= &= ^= |=
Virgule
,
65
2
Découvrir l’ActionScript 3.0
Nous avons déjà découvert certains d’entre eux, et d’autres paraissent évidents. Nous en verrons d’autres encore par la suite.
Les boucles et conditions Les boucles sont une des bases de la programmation. Leur fonctionnement est connu par tous les développeurs. Elles permettent d’exécuter des blocs de code tant qu’une condition est vérifiée. Adobe recommande de placer le code entre accolades. Cela est obligatoire lorsque la portion est constituée de plusieurs lignes mais optionnel lorsqu’elle ne contient qu’une seule ligne. Voici les boucles qu’il est possible d’utiliser en ActionScript 3.0 ; nous les illustrons par des exemples.
La boucle for Elle permet d’itérer tant qu’une valeur n’atteint pas une certaine condition. Il faut initialiser la valeur, définir un cas d’arrêt et incrémenter la variable : var i:int; for (i = 0; i < 5; ++i) // code à exécuter
La boucle for in Elle permet d’itérer sur les indices d’un tableau ou les propriétés d’un objet. Dans ce dernier cas, la variable contiendra le nom de la propriété courante. var tab:Array = ["a", "b", "c"]; for (var i:int in tab) // i contient l’indice de l’élément dans le tableau et non sa valeur
La boucle for each in Cette boucle se rapproche de la précédente puisqu’elle parcourt également un tableau, une collection ou les propriétés d’un objet. Mais cette fois, la variable contiendra la valeur de l’élément courant. var tab:Array = ["a", "b", "c"]; for each (var i:String in tab) // i la valeur de l’élément courant
66
Les bases de la programmation
2
La boucle while Avec la boucle while, il ne faut pas oublier de préciser dans le code à exécuter l’incrémentation de la variable. Il est donc plus facile de partir sur une boucle infinie avec un while qu’avec un for. var i:int = 0; while (i < 5) { // code à exécuter ++i; // incrémentation obligatoire }
La boucle do while Pour terminer avec les boucles, voici une variante de while. La différence est que le code est exécuté au moins une fois puisque la condition est vérifiée à la sortie. var i:int = 0; do { // code à exécuter ++i; // incrémentation obligatoire } while (i < 5);
Passons à présent aux conditions.
Les conditions if else et if else if On peut choisir d’exécuter ou non une série d’instructions grâce à une condition. Comme pour les boucles, Adobe recommande d’utiliser des accolades pour entourer le code à exécuter. Mais si c’est une obligation pour des instructions sur plusieurs lignes, ce n’est qu’un conseil pour du code sur une ligne. L’utilisation des conditions est très simple : if (i < 10) { // code exécuté si i < 10 } else { // code sinon }
Retenons que le else est optionnel. On pourrait se contenter du if s’il n’y avait rien à exécuter en cas d’échec du test. Si d’autres conditions sont à vérifier, on peut ajouter des tests : if (i < 10) { // code exécuté si i < 10 } else if (i < 20) {
67
2
Découvrir l’ActionScript 3.0
// code exécuté si 10 < i < 20 } else { // code exécuté sinon }
La condition switch Cette condition remplit le même rôle qu’une suite de if else if mais rend le code plus lisible. Un switch évalue une expression et utilise le résultat pour choisir quelles instructions exécuter. var i:int = 1; switch (i) { case 0: // code break; case 1: // code executé break; default: // code si aucune condition n’est vérifiée }
Maintenant que vous avez découvert les bases du langage ActionScript 3.0, passons à un de ses aspects les plus intéressants : son orientation objet.
2.3 La programmation orientée objet dans ActionScript Ce chapitre n’a pas pour but d’être un cours exhaustif sur la programmation orientée objet. Nous rappellerons ses concepts de base et l’implémentation qui en est faite dans ActionScript 3.0. Si vous êtes développeur web et déjà familier avec la programmation objet, vous n’aurez certainement pas besoin de la première partie de cette description. Dans ce cas, nous vous conseillons de passer directement à l’implémentation.
Les avantages de la programmation orientée objet La programmation orientée objet est une méthode ou paradigme de programmation qui apporte une nouvelle façon de concevoir des applications comparativement aux langages impératifs comme le C. Les langages objets les plus connus sont le C++, le Java et le C#. Le paradigme objet consiste à définir et assembler des briques logicielles appelées objets pour concevoir ses applications. Cette méthode de programmation apporte une façon totalement différente de penser son code. Son utilisation permet d’obtenir, entre autres,
68
La programmation orientée objet dans ActionScript
2
une bien meilleure modularité et donc des applications plus facilement maintenables. Elles doivent être découpées en modules de taille raisonnable qui auront chacun des fonctionnalités précises. Ces modules ont des propriétés qui leur sont propres, et des interfaces qui permettent d’interagir avec eux. Les objets sont des ensembles de propriétés qui leur sont propres et qu’on appelle attributs, et de méthodes qui définissent leurs comportements. Les définitions de la structure des objets sont contenues dans des classes qui sont en quelque sorte leur patron. Lorsqu’un objet est créé à partir d’une classe, on parle d’instanciation. Les attributs et méthodes peuvent être cachés afin d’assurer uniquement un fonctionnement interne à l’objet : c’est l’encapsulation. Un objet a un type donné mais peut également appartenir à plus d’un type : c’est ce qu’on appelle le polymorphisme. Il est souvent réalisé grâce à l’héritage qui permet de spécialiser un objet. Cette notion primordiale sera expliquée plus loin. ActionScript 3.0 est un langage complètement objet, c’est-à-dire que toutes les variables que vous pourrez manipuler sont des objets. Observons à présent comment les concepts que nous venons d’énoncer sont implémentés.
Les classes La définition d’une classe se fait grâce au mot-clé class dans un fichier "as" du nom de la classe. Par convention, le nom d’une classe commence par une majuscule. Dans l’exemple suivant, on définit une classe MyClass dans le package myPackage : package myPackage { public class MyClass { } }
public permet d’accéder à la classe depuis toute votre application. C’est en général le comportement qu’on souhaite. À la place de public, on aurait pu utiliser un des attributs
d’encapsulation suivants : dynamic : permet d’ajouter des propriétés à la classe durant l’exécution. final : la classe ne doit pas être héritée par une autre classe. j internal : c’est le comportement par défaut, la classe est visible dans le package. j j
À l’intérieur des accolades qui suivent le nom de la classe, on place la définition des attributs et des méthodes.
69
2
Découvrir l’ActionScript 3.0
Les attributs Pour tout ce qui se trouve à l’intérieur d’une classe, on retrouve des propriétés d’encapsulation : public : les éléments déclarés ainsi seront visibles partout dans le code. j private : limite la visibilité de l’élément à l’intérieur de la classe. j protected : permet l’accès à l’élément par les classes héritées (nous verrons par la j
j
suite la notion d’héritage). internal : protection par défaut, qui donne la visibilité à tout le package.
Ces protections sont donc valables aussi bien pour les attributs que les méthodes. Les attributs sont des variables attachées aux instances des classes, c’est-à-dire aux objets créés à partir des définitions des classes. Chaque fois qu’on instancie une classe, on a donc un nouvel objet avec toutes les variables qui le constituent. Prenons par exemple une définition de classe avec quelques attributs : package myPackage { public class MyClass { public var var1:int = 1; private var var2:int = 2; protected var var3:int = 3; internal var var4:int = 4; public const const1:int = 0; } }
Le seul attribut qui sera accessible à l’extérieur de notre classe ou package est celui déclaré en public : var1. Mais on aura également accès à une constante : const1. La valeur d’une constante, déclarée à l’aide du mot-clé const, est définie lors de la création de l’objet et ne peut être modifiée au contraire d’un attribut déclaré avec var. Voici comment accéder aux attributs précédents dans du code mxml :
Il nous faut donner quelques explications sur ce code. Au lancement de l’application, on instancie un objet objectTest qui est de type MyClass. Il est déclaré en public afin d’être accessible dans tout le code. On se sert du label objectValue pour afficher la valeur de la variable var1. Celle-ci est modifiée à l’intérieur de la fonction addVar. On remarque qu’on accède aux attributs grâce à l’opérateur . lorsque c’est possible. On pourrait également se servir des opérateurs [] qui s’utilisent ainsi : objectTest["var1"] += 1;
Nous avons vu pour l’instant que les attributs d’une classe dépendent de ses instanciations. Mais le mot-clé static permet de faire appel à une propriété en passant par la classe et non par une instance de la classe. Pour illustrer ce propos, remplaçons notre déclaration de la variable var1 dans MyClass : public var var1:int = 1;
devient alors : public static var var1:int = 1;
On accède aux variables statiques par le nom de la classe et non par un objet de son type. Notre fonction addVar devient par exemple :
71
2
Découvrir l’ActionScript 3.0
public function addVar():void { MyClass.var1 += 1; objectValue.text = String(MyClass.var1); }
Passons à présent aux méthodes.
Les méthodes Les méthodes sont déclarées à l’intérieur des classes grâce au mot-clé function. Elles respectent les principes que nous avons vus lors de l’étude des fonctions. Les protections sont les mêmes que pour les attributs, à savoir public, private, protected et internal. Le mot-clé static peut, lui aussi, être utilisé pour définir des méthodes statiques qui ne dépendront pas des instances de la classe. Les méthodes qui ne sont pas déclarées en statique effectuent des traitements liés au contenu de l’objet à partir duquel elles sont appelées. Il existe certaines méthodes spécifiques comme le constructeur. Celui-ci est appelé implicitement à chaque fois qu’on instancie un objet. Mais il peut également être explicité. Il s’agit d’une méthode portant le même nom que la classe. Elle est obligatoirement déclarée en public et le mot-clé est d’ailleurs optionnel. Vous pouvez, grâce à ce constructeur, initialiser des variables ; par exemple : package myPackage { public class MyClass { public var var1:int; public function MyClass():void { var1 = 0; } } }
Notre constructeur MyClass initialise la variable var1 à 0. Cette opération sera faite chaque fois qu’on instanciera un nouvel objet de type MyClass. Afin de respecter les principes de la programmation objet, on utilise également des getters et setters qui permettent d’accéder aux attributs ou de les modifier. On déclare nos attributs en private ou en protected pour les faire hériter. Pour notre classe MyClass, cela donne :
72
La programmation orientée objet dans ActionScript
2
package myPackage { public class MyClass { private var var1:int; public function get publicVariable():int { return var1; } public function set publicVariable(value:int):void { var1 = value; } } }
Plutôt que d’accéder directement à var1, on passera par publicVariable pour obtenir sa valeur et pour lui affecter une nouvelle valeur : objectTest.publicVariable += 1;
Les interfaces Les interfaces sont des collections de déclarations de méthodes qui permettent à des objets indépendants de communiquer entre eux. Le principe repose sur la différence entre une déclaration, qui contient toutes les informations nécessaires à l’appel de la méthode (type des variables, valeur de retour…), et son implémentation qui peut être différente. La déclaration d’une interface est très simple, grâce au mot-clé interface. Flex Builder nous guide également pour cette étape. Dans votre projet de test, cliquez avec le bouton droit de la souris sur votre package myPackage (créez-le au besoin). Choisissez alors new et ActionScript Interface. Une boîte de dialogue vous demandera alors le nom de votre interface. Appelons-la MyInterface (par convention les noms des interfaces commencent par une majuscule comme les classes). Déclarons à présent une fonction addVar qui prend un entier en argument et renvoie void à l’intérieur de cette interface. Nous obtenons le résultat suivant : package myPackage { public interface MyInterface {
73
2
Découvrir l’ActionScript 3.0
function addVar(toAdd:int):void; } }
L’interface contient uniquement les déclarations. Pour utiliser cette interface, il suffit de spécifier à une classe qu’elle l’implémente grâce au mot-clé implements et d’implémenter chaque méthode à l’intérieur de la classe. Vous devez respecter plusieurs points pour les méthodes implémentées : j j j j
déclarer avec l’attribut public ; utiliser le même nom que la méthode de l’interface ; avoir le même nombre de paramètres et les mêmes types ; avoir le même type de retour.
Nous allons faire implémenter l’interface MyInterface à notre classe MyClass : package myPackage { public class MyClass implements MyInterface { private var var1:int; public function addVar(toAdd:int):void { var1 += toAdd; } } }
Chaque classe qui implémentera notre interface pourra avoir sa propre version de la fonction addVar. On peut faire implémenter plusieurs interfaces à une classe en les ajoutant à la suite, séparées par des virgules, lors de la déclaration de la classe. Notez que si vous avez l’intention d’implémenter des interfaces à la création de votre classe, vous pouvez le spécifier à l’intérieur de Flex Builder qui vous préparera les déclarations. Il ne restera alors plus qu’à entrer le code.
L’héritage Il s’agit d’une notion fondamentale en programmation orientée objet. Elle permet de réutiliser du code, d’organiser son application mais aussi de profiter de propriétés comme le polymorphisme.
74
La programmation orientée objet dans ActionScript
2
Pour illustrer cette partie, nous allons nous servir d’un exemple concret : des formes géométriques. Nous aurons une classe de base, Shape, dont les classes Circle et Square hériteront. Les cercles et les carrés sont bien des formes mais ont des propriétés différentes. Nous allons commencer par créer la classe Shape dans notre package myPackage. Dans cette classe, créons une méthode area qui renvoie l’aire d’une forme géométrique. Puisque Shape est une forme quelconque, renvoyons une valeur quelconque : package myPackage { public class Shape { public function area():Number { return NaN; } } }
Déclarons à présent une classe Circle. Flex Builder nous aide également à déclarer des classes héritées : lorsque vous avez entré le nom de la classe, ne validez pas immédiatement. En face de Superclass, vous avez un bouton Browse. Cliquez dessus et sélectionnez la classe mère de votre nouvelle classe. En l’occurrence, il s’agit de Shape située dans le package myPackage. Lorsque vous validerez la création de Circle, votre classe sera tout de suite héritée. À l’intérieur de cette nouvelle classe, nous allons déclarer une variable radius en private qui sera le rayon de notre cercle. Puis, nous allons surcharger la méthode area. La surcharge est le fait de redéfinir une méthode de la classe mère. Grâce au mot-clé override, cette méthode sera appelée en priorité par rapport à celle de la classe Shape. Le code de notre fonction sera propre à la classe Circle : package myPackage { public class Circle extends Shape { private var radius:Number = 1; override public function area():Number { return Math.PI * (radius * radius); } } }
75
2
Découvrir l’ActionScript 3.0
Vous noterez l’utilisation du mot-clé extends pour spécifier de quelle classe dérive Circle. Vous ne pouvez hériter que d’une seule classe au contraire d’un langage comme le C++, par exemple, qui permet l’héritage multiple. Enfin, procédons de même pour notre classe Square dont le code est le suivant : package myPackage { public class Square extends Shape { private var side:Number = 1; override public function area():Number { return side * side; } } }
Les seuls éléments qui peuvent être redéfinis grâce à override sont les méthodes (getters et setters inclus). Les attributs (var ou const) sont seulement hérités. La visibilité des méthodes dans la classe mère doit être, soit public, soit protected, en aucun cas private (visibilité limitée à la classe elle-même). Vos méthodes héritées doivent avoir le même nom, le même nombre et type d’arguments et le même type de retour. Grâce au polymorphisme, vous pouvez déclarer des objets Circle ou Square qui seront aussi reconnus en tant que forme : public var forme:Shape = new Circle;
L’utilité de ce principe apparaît clairement si l’on déclare une fonction qui prend en paramètre une forme et renvoie son aire : public function getArea(forme:Shape):Number { return forme.area(); }
On pourra passer à cette fonction aussi bien des objets de type Circle que de type Square. Vous vous êtes maintenant familiarisé avec les principes de base de l’ActionScript 3.0. Nous allons nous lancer dans le développement à proprement parler.
76
Déboguer de l’ActionScript 3.0 dans Flex Builder
2
2.4 Déboguer de l’ActionScript 3.0 dans Flex Builder Au fur et à mesure de votre apprentissage de Flex, les applications que vous développerez atteindront une taille conséquente et différents bugs viendront inévitablement perturber le bon déroulement de vos projets. Nous allons tout d’abord réaliser une petite application Flex utilisant les notions ActionScript acquises dans ce chapitre puis nous utiliserons la perspective Debug de Flex Builder 3 pour corriger d’éventuelles erreurs.
Création d’une application Flex utilisant ActionScript Nous allons créer une deuxième application Flex dans le but de montrer l’utilisation du débogueur Flex. Cette application stockera une liste d’utilisateurs et la comparera aux informations saisies par l’utilisateur dans un champ texte. La vérification s’effectuera par une méthode action script appelée lorsqu’un clic sur un bouton sera détecté. Pour cela, créez un nouveau projet et nommez-le exemple_debug. Puis, respectez les étapes suivantes : Ajoutez une VBox avec la propriété horizontalAlign sur "center" et centrez-la au milieu de l’application (horizontalCenter="0" verticalCenter="0"). 2 Dans celle-ci, ajoutez un Label avec les propriétés id="infoLbl" et text="Entrez un login". 3 Ajoutez ensuite un TextInput que nous nommerons loginTxtIn. 4 Enfin, ajoutez un Button avec les propriétés id="validateBtn" et label="valider" 1
Le code de cette application devrait donc pour l’instant être le suivant :
Elle ne sert pour l’instant pas encore à grand-chose mais nous allons rajouter un petit bout de code ActionScript dans un instant. Mais avant cela, assurons-nous que l’application compile en la lançant dans le mode Debug.
77
2
Découvrir l’ActionScript 3.0
Le mode Debug Le mode Debug de Flex va permettre d’étudier et de contrôler l’application que vous venez de réaliser au cours de son exécution. À cet effet, il faut lancer l’application non plus avec le bouton Run comme auparavant mais avec le bouton Debug situé juste à sa gauche. À première vue, vous ne verrez rien de bien différent par rapport au mode normal. Cliquez avec le bouton droit de la souris, et un menu Debugger apparaît dans le menu contextuel. c Fig. 2.4 : Menu contextuel du Debugger dans le navigateur
Si vous cliquez dessus, une fenêtre apparaîtra pour vous permettre de choisir la machine sur laquelle se trouve l’instance de Flex Builder qui a lancé l’application. Normalement, vous devriez laisser Localhost puisque vous avez lancé le projet à partir de votre propre ordinateur. c Fig. 2.5 : Choix de l’instance du Debugger
78
Déboguer de l’ActionScript 3.0 dans Flex Builder
2
Ajouter un point d’arrêt Nous allons maintenant ajouter un peu d’ActionScript dans l’application afin de vérifier si le texte saisi correspond à des données que nous stockerons dans un tableau. Il faut ajouter une balise de au-dessus de la VBox et procéder de la manière suivante : 1
Déclarez une variable nommé nameList de type Array et initialisez-la avec les données suivantes : ["Joe", "William", "Jack", "Averell"] Initialisation d’un tableau
Il existe plusieurs méthodes pour initialiser un tableau : j
Par le constructeur Array : var nameList:Array = new Array("Joe", "William", "Jack", "Averell") ;
j j
De manière Litteral : var nameList:Array = ["Joe", "William", "Jack", "Averell"] ; En créant un tableau vide et en ajoutant les données une à une : var nameList:Array = new Array(); nameList.push("Joe")…
2
Créez une fonction checkName prenant en paramètre une chaîne de caractères. Cette méthode va vous permettre de parcourir un à un les éléments du tableau afin de vérifier si la chaîne passée en paramètre est bien présente dans celui-ci. La fonction renverra donc un booléen :
public function checkName(name:String):Boolean { for each (var item :String in nameList) { if (name == item) return true; } return false; } 3
Créez une seconde fonction que nous appellerons validate et qui ne renverra pas de valeur car elle affichera simplement un message en fonction du résultat de l’appel à la fonction précédente :
public function validate():void { var name : String = loginTxtIn.text; var test : Boolean = checkName(name); if (test)
79
2
Découvrir l’ActionScript 3.0
Alert.show("Bienvenue " + name + " , vous êtes bien sur la liste!"); else Alert.show("Désolé " + name + " mais vous n’êtes pas sur la liste..."); } 4
Puis ajoutez le code suivant dans la balise Button : click=’validate()’
Voici le code final du projet :
80
Déboguer de l’ActionScript 3.0 dans Flex Builder
2
Nous avons entré notre code ActionScript et il nous reste à tester notre application. Entrez Luke et cliquez sur le bouton Valider. c Fig. 2.6 : Le nom saisi est incorrect.
Testons maintenant notre application en entrant Jack: c Fig. 2.7 : Jack est bien reconnu.
Remarquez tout de même que le test échoue en entrant jack en minuscule car la comparaison de chaînes est sensible à la casse. Ajoutons maintenant un point d’arrêt (ou breakpoint en anglais) sur la fonction validate. À cet effet, double-cliquez dans la bordure de l’éditeur de texte au niveau de la déclaration de la méthode, ou bien cliquez avec le bouton droit de la souris et sélectionnez Toggle Breakpoint dans le menu contextuel. Un point bleu devrait alors apparaître. c Fig. 2.8 : Point d’arrêt sur la méthode validate
Relancez l’application en mode Debug, entrez à nouveau jack en minuscule et constatez le comportement de Flex Builder lorsque vous cliquez sur le bouton Valider.
81
2
Découvrir l’ActionScript 3.0
Une fenêtre apparaît alors pour que Flex Builder ouvre la perspective Debug. Cliquez sur Yes. c Fig. 2.9 : Fenêtre de confirmation
Comme vous pouvez le constater, deux nouveaux panneaux sont apparus dans l’éditeur.
c Fig. 2.10 : Pperspective Debug de Flex Builder 3
Nous allons maintenant exécuter notre programme en mode Pas à pas et nous en profiterons pour expliquer le fonctionnement des deux panneaux. Quelques détails sur l’ajout de points d’arrêt Il n’est possible de placer des points d’arrêt que sur les lignes du programme qui contiennent du code ActionScript, c’est-à-dire : j j
dans les fichiers ActionScript (extension .as) ou encore entre des balises ; dans des balises MXML gérant des événements : . SUITE
82
Déboguer de l’ActionScript 3.0 dans Flex Builder
2
Si le point d’arrêt que vous avez placé ne respecte pas ces conditions, Flex Builder va automatiquement parcourir les dix lignes suivantes pour essayer de trouver un emplacement adéquat. Si tel est le cas, le point d’arrêt sera automatiquement déplacé sur ce dernier à l’exécution du programme. Dans le cas contraire, le point d’arrêt sera tout simplement ignoré.
Le pas à pas Le mode Pas à pas permet de contrôler l’exécution d’un programme, instruction par instruction Flex Builder propose plusieurs modes qui sont accessibles dans la barre du panneau Debug ou directement depuis le menu Run de l’éditeur. Voici donc une description des commandes les plus courantes : j
j j j j j
Resume ([F8]): permet de reprendre l’exécution du programme après que celui-ci ait stoppé sur un point d’arrêt. L’exécution continue normalement ou bien jusqu’au prochain point d’arrêt s’il en existe. Suspend : permet de stopper temporairement l’exécution d’un programme. Terminate : quitte la session de débogage en cours. Step Into ([F5]) : entre dans la fonction appelée. Step Over ([F6]) : exécute la ligne courante puis passe à la suivante mais sans entrer en mode Pas à pas dans une fonction appelée. Step Return ([F7]) : continue l’exécution du programme jusqu’à la sortie de la fonction en cours ou jusqu’au prochain point d’arrêt.
Reprenons l’exécution de notre application là où elle en était. Nous avions placé un point d’arrêt sur la méthode validate(). Utilisez la fonction Step Into jusqu’à l’appel à la fonction checkName. Si vous effectuez encore un Step Into, vous entrerez dans cette fonction. En revanche, un Step Over exécutera tout de même la fonction mais l’éditeur vous emmènera directement à la ligne suivante sans entrer dans le corps de checkName. Une fois dans la fonction checkName, vous devriez exécuter la boucle étape par étape à moins que vous ne décidiez de faire un Step Return pour retourner à la suite de la fonction Validate.
Afficher le contenu d’une variable Le deuxième onglet, qui est apparu avec la perspective Debug, permet d’inspecter les objets présents dans l’application au cours de son exécution. Flex Builder offre plusieurs manières d’inspecter les variables d’une application ou d’une méthode en cours d’exécution.
83
2
Découvrir l’ActionScript 3.0
La première méthode est très pratique puisqu’il suffit de passer le curseur de la souris sur n’importe quelle variable pour afficher sa valeur. Comme un exemple vaut mieux qu’un long discours, mettons cela en pratique. Enlevez le point d’arrêt de la fonction validate et placez-en un sur la fonction checkName. Lancez l’application en mode Debug, saisissez jack en minuscule et cliquez sur Valider. Dès que Flex Builder se sera arrêté sur la méthode checkName, nous utiliserons le mode Pas à pas (Step Into) pour afficher le contenu de la variable Item à chaque itération : passez la souris sur la variable aux différentes étapes pour afficher sa valeur. c Fig. 2.11 : Affichage du contenu de la variable Item
Remarquez également que le panneau Variables est mis à jour à chaque instruction : il affiche le contenu des variables en cours d’accès.
c Fig. 2.12 : Panneau Variables
Ce nouveau panneau permet également de rechercher une variable (ce qui devient vite indispensable dans des applications de grande taille). Appuyez en premier lieu sur la croix à droite de la variable this (qui représente l’application) pour bien vous rendre compte de toutes les variables contenues dans votre programme. Nous allons maintenant effectuer une recherche, et il vous suffit d’appuyer sur [Ctrl]+[F]. Nous souhaitons afficher l’adresse de notre tableau contenant la liste de noms. Il suffit de taper le nom de la variable dans le champ de saisie (ici nameList) mais il est également possible d’utiliser les caractères spéciaux ? (remplacement d’exactement un caractère) et * (0 ou n caractères) pour faciliter la recherche. Nous aurions très bien pu entrer n?meL ou *eList et nous aurions obtenu le même résultat.
84
Déboguer de l’ActionScript 3.0 dans Flex Builder
2
c Fig. 2.13 : Recherche d’une variable
Une fois la variable trouvée, sélectionnez-la et cliquez sur OK ; le panneau Variables se placera au niveau du résultat. Ici, nous affichons le contenu du tableau nameList, où nous retrouvons bien les valeurs d’initialisation.
c Fig. 2.14 : Résultat de la recherche
La fonction trace La fonction trace est une des fonctions les plus pratiques en ActionScript puisqu’elle permet d’afficher sur la fenêtre Output de l’IDE des messages ou des variables lorsque l’application est lancée en mode Debug. Cette fonction est un complément indispensable et très simple pour afficher des variables ou s’assurer qu’un bout de code a bien été exécuté, sans avoir recours au mode Pas à pas.
85
2
Découvrir l’ActionScript 3.0
Cependant, cette méthode souffre de quelques défauts puisque les messages ne sont affichables que dans l’IDE ; de plus, l’affichage des objets de types complexes est plutôt limité puisque trace ne retourne pas un descriptif complet des propriétés accessibles. Pour utiliser cette méthode, rien de plus simple. Il suffit d’appeler trace avec une chaîne ou une variable en paramètre. Par exemple, si nous reprenons l’exemple en cours : public function checkName(name:String):Boolean { for each (var item :String in nameList) { trace(item) if (name == item) return true; } return false;
À chaque itération, le nom contenu dans la variable item sera affiché.
Corriger les erreurs Pour finir, nous pourrions modifier le code pour que la comparaison de chaîne ne soit plus sensible à la casse. Il suffit d’appeler la méthode toLowerCase() sur chaque chaîne comparée : public function checkName(name:String):Boolean { for each (var item :String in nameList) { if (name.toLowerCase() == item.toLowerCase()) return true; } return false; }
Et voici le résultat : c Fig. 2.15 : La comparaison n’est plus sensible à la casse.
86
Check-list
2
2.5 Check-list Au cours de ce chapitre, vous avez :
a découvert les bases du langage ActionScript 3.0 ; a étudié les possibilités avancées du langage ; a intégré du code ActionScript à votre application Flex ; a étudié l’organisation correcte de votre code ; a débogué votre code ActionScript dans Flex Builder. Dans le prochain chapitre, vous aurez l’occasion de découvrir des aspects plus graphiques de Flex puisqu’il sera consacré à l’interface.
87
3 3.1 Les composants MXML .................................
90
3.2 Les conteneurs d’agencement .........................
96
3.3 Mise en forme de l’interface ..........................
108
3.4 Les contrôles simples ....................................
113
3.5 Mise en pratique : une interface d’annuaire .........
120
3.6 Check-list .................................................
124
Réaliser sa première interface T
oute application repose sur une interface utilisateur, et la force de l’IDE Adobe Flex Builder 3 est de rendre cette couche de présentation la plus facile possible pour les développeurs. Ce chapitre détaille la manière de réaliser une interface avec les composants mis à disposition par Flex.
3
Réaliser sa première interface
3.1 Les composants MXML Les composants sont à la base du framework Flex, il est indispensable de comprendre leur fonctionnement et leurs différentes utilisations. Nous verrons ensuite comment tirer partie au maximum des composants MXML.
Définition d’un composant Flex est un environnement de développement qui repose principalement sur des composants. Plusieurs familles de composants complémentaires permettent au développeur de créer non seulement une interface complexe mais également de la lier à des données structurées. Ces composants sont des classes ActionScript instanciables avec de nombreuses caractéristiques que nous détaillerons tout au long de ce chapitre et des suivants. Flex met à disposition des composants visuels appelés des contrôles (les Labels, les Buttons ou les Charts) ainsi que des composants non visuels permettant de développer le côté logique de l’application (HTTServiceRequest pour récupérer des données externes au projet, ou Timer pour contrôler l’interaction dans le temps de l’application). Ce chapitre va se consacrer uniquement au premier type de composant. Les composants sont des objets à la fois génériques et flexibles qui doivent adapter leur apparence aux besoins de l’application et réagir spécifiquement aux interactions de l’utilisateur. Ces composants se prennent rapidement en main car ils partagent un grand nombre de propriétés et de méthodes. Les principales caractéristiques des composants concernent : j j j j
les événements ; le style ; la taille ; la position.
Tous ces composants sont instanciables via des tags MXML ou via une classe ActionScript et leur API (Application Programming Interface) est également accessible des deux manières. De nombreux composants sont fournis par Flex pour répondre aux besoins les plus courants, mais pour des cas plus spécifiques à votre application le chapitre 8 vous explique comment créer vos propres composants ou étendre les propriétés d’autres composants.
90
Les composants MXML
3
Travailler avec les contrôles Flex Les contrôles sont les composants visuels issus de Flex. La diversité de ces composants et leur nombre font la richesse du framework Flex. Travailler avec ces contrôles nécessitera probablement d’utiliser de l’ActionScript dans votre application. Le point clé est de comprendre comment manipuler un contrôle donné. Pour manipuler un composant en ActionScript, on définit généralement la propriété id du composant dans la balise MXLM. Par exemple, le code suivant attribue l’identifiant monBouton à la propriété id :
Vous pouvez spécifier l’affichage de votre texte en utilisant des propriétés de style sur le contrôle comme color ou fontSize. Vous pouvez également afficher du texte formaté en HTML grâce à la propriété htmlText, et ainsi utiliser les tags courants du langage HTML comme
ou . L’exemple suivant montre un texte formaté en HMTL avec des options de style provenant du contrôle :
bleu de taille 12 gras
Ce texte est de taille 10 en noir et en italique. ]]>
Voici le résultat à l’écran : c Fig. 3.23 : Texte formaté dans Flex
118
Les contrôles simples
3
Vous remarquerez que le style provenant du htmlText écrase les styles définis auparavant : la couleur noire vient de la balise HTML tandis que la couleur bleue vient des propriétés du contrôle Text.
Écrire du texte De la même manière que pour afficher du texte, on va distinguer les contrôles qui permettent de saisir du texte sur une seule ligne, le TextInput, des contrôles multilignes comme le TextArea et le RichTextEditor. Les contrôles TextInput et TextArea s’utilisent avec une simple balise MXML et les attributs text et htmlText permettent de mettre une valeur par défaut comme le montre l’exemple suivant :
Pour récupérer la valeur de ce contrôle, il vous suffit de lire la valeur contenue dans la propriété text. Lorsque vous permettez à l’utilisateur de saisir du texte, vous voulez généralement lui permettre de formater un tant soit peu son texte, comme on le ferait dans un éditeur de texte comme Word. Flex possède un contrôle très complet afin de formater son texte au format HTML en WYSIWYG. Le contrôle RichTextEditor est composé d’un Panel avec deux éléments fils : j j
un TextArea permettant à l’utilisateur de saisir son texte ; une barre d’outils contenant diverses fonctionnalités classiques de mise en page (le choix de la police, la taille ou la couleur). c Fig. 3.24 : Le contrôle RichTextEditor
119
3
Réaliser sa première interface
Nous vous donnons le code pour obtenir cet exemple. La valeur du texte est liée en ActionScript pour plus de commodité. Vous en apprendrez davantage sur cette liaison dans les prochains chapitres.
3.5 Mise en pratique : une interface d’annuaire Avant de clôturer ce chapitre, nous allons prendre pas à pas un exemple complet intégrant les points importants que vous venez d’apprendre. Nous allons réaliser une interface d’une application classique, à savoir : un annuaire pour gérer vos contacts.
c Fig. 3.25 : L’interface que nous allons créer
120
Mise en pratique : une interface d’annuaire
3
Mettre en place les conteneurs Vous allez commencer par créer un nouveau projet que vous nommerez annuaire. Ouvrez le fichier annuaire.mxml ; vous êtes fin prêt pour attaquer l’interface. Redimensionnez la taille du conteneur Application pour former un rectangle de 650 × 400 pixels et définissez le type de layout en vertical au lieu d’absolute. Déposez en premier une HDividedBox occupant tout l’espace disponible (les propriétés width et height doivent être à 100 %). Déposez consécutivement deux Panel dans la HDividedBox. Les Panel ont une taille par défaut qu’il faut changer. Mettez leur hauteur à 100 %. Nous voulons que le Panel de gauche soit moins large, précisez ainsi une largeur de 50 %. Le second Panel doit prendre tout l’espace restant, sa largeur est donc logiquement de 100 %. Ajoutez un titre aux Panel grâce à la propriété title. Ajoutez maintenant dans chaque Panel un ControlBar et vous devriez avoir le résultat suivant :
c Fig. 3.26 : Mise en place des conteneurs
Ajouter les contrôles simples en mode Design Déposez un Button dans le premier ControlBar, et trois Button dans le second. Regardez le résultat afin de connaître les textes des boutons. Il faut maintenant placer correctement les boutons. Sélectionnez le ControlBar de gauche et dans le panel Common, attribuez la valeur right à la propriété Horizontal align. Dans le ControlBar de droite, placez le conteneur Spacer entre les deux premiers boutons et attribuez-lui une largeur de 100 % pour qu’il occupe tout l’espace disponible de ControlBar. Ainsi, les deux derniers boutons sont déplacés complètement à droite tandis que le premier reste à gauche.
121
3
Réaliser sa première interface
c Fig. 3.27 : Placement des boutons
Nous allons maintenant compléter le Panel de gauche. Commencez par définir le layout du Panel en vertical. Placez ensuite une HBox avec une largeur de 100 % puis en dessous de celle-ci, ajoutez une DataGrid qui prend tout l’espace disponible. Passez en mode Source et retrouvez l’endroit où la DataGrid est définie. Modifiez le code pour supprimer la colonne supplémentaire et renommez les titres des colonnes. Votre code devrait ressembler à celui-ci :
Vous remarquerez que nous avons modifié les valeurs des propriétés dataField des colonnes. C’est pour pouvoir lier la DataGrid avec des données. Nous ne détaillerons ce concept que dans les prochains chapitres, mais vous pouvez rajouter le code suivant dans le tag de la DataGrid pour rajouter des valeurs dans la grille.
122
3
Mise en pratique : une interface d’annuaire
Chaque propriété des tags est alors liée à la colonne dont lui correspond la propriété dataField. Tant que vous êtes en mode Source, recherchez plus haut la définition du tag HBox et ajoutez un tag TextInput et un tag Image. Trouvez sur Internet une image loupe pour représenter la recherche et utilisez l’URL de cette image comme valeur de la propriété source du tag. Le code devrait ressembler à ceci :
Bien sûr, cette image n’a aucune raison d’être chargée à l’exécution et devrait être importée lors de la compilation. Dans cette optique, copiez cette image dans le dossier images que vous aurez créé à la racine de votre application. Ensuite, importez cette image en spécifiant le chemin vers l’image :
Repassez en mode Design ; vous remarquerez que les composants sont collés au bord intérieur du Panel. Pour rajouter une marge, sélectionnez la vue Alphabetical View de l’onglet Flex Properties et descendez dans la liste jusqu’aux propriétés paddingBottom, paddingLeft, etc. Précisez une valeur de 5 pixels aux quatre marges et vous devriez maintenant avoir quelque chose comme ceci dans votre navigateur, après avoir compilé votre application : c Fig. 3.28 : Interface du Panel de gauche
123
3
Réaliser sa première interface
Il ne nous reste plus que le Panel de droite à compléter. Sélectionnez des contrôles Label et positionnez-les dans le Panel en mode Design pour profiter des guides qui apparaissent pour aligner et répartir les contrôles. Le layout absolute permet de placer vos contrôles comme bon vous semble. Vous pouvez vous amuser à lier les Labels avec la liste des contacts (bien que ce ne soit pas l’objectif de ce chapitre) en mettant, par exemple, pour le prénom :
Il faut maintenant rajouter l’image de votre contact dans votre dossier images. Rajoutez un contrôle Image et spécifiez le chemin de l’image dans la source. Si vous voulez lier l’image aux noms dans la liste, ne mettez pas la directive @Embed pour pouvoir changer dynamiquement la source de l’image. Rajoutez également une contrainte de 20 pixels sur la marge de droite afin que la photo ne disparaisse pas lorsque l’utilisateur redimensionnera la liste.
c Fig. 3.29 : L’interface que nous avons créée
Rajoutez au-dessus de la HDividedBox un Label en gras et avec une taille de 18 pixels afin d’intituler votre première interface : mon Annuaire !
3.6 Check-list Dans ce chapitre, nous avons vu :
a ce qu’était un composant dans Flex ;
124
Check-list
3
a les principaux conteneurs et leur utilisation ; a le positionnement et le redimensionnement d’un contrôle ; a l’utilisation de quelques contrôles simples ; a la gestion des images dans Flex. Le chapitre suivant est consacré à la gestion des événements dans Flex.
125
4 4.1 Introduction aux événements ...........................
128
4.2 Utiliser les événements ..................................
129
4.3 Les événements clavier .................................
133
4.4 Créer ses propres événements ........................
137
4.5 Mise en pratique : un convertisseur de devises .....
138
4.6 Check-list .................................................
143
Gérer les événements C
e chapitre présente les principes qui régissent le modèle événementiel de Flex. Nous allons ainsi voir comment réagir aux actions de l’utilisateur, et comment les traiter en prenant en compte leur nature (événements liés au clavier, à la souris, etc.).
4
Gérer les événements
4.1 Introduction aux événements Pour un développeur web, la programmation événementielle peut se révéler quelque peu déstabilisante ; néanmoins, une fois que vous y aurez goûté, vous ne pourrez plus vous en passer ! Un événement permet au développeur de savoir ce qui se passe dans son application et de réagir en conséquence, chaque événement pouvant être récupéré et traité pour fournir une réponse adéquate. Avec Flex, toute interaction peut générer un événement, qu’il s’agisse d’un simple clic ou d’une action plus complexe. Mais les événements peuvent aussi être déclenchés sans aucune interaction, quand l’apparence ou l’état d’un composant est modifié. Avant de passer à la pratique, il va falloir s’initier à un peu de théorie : nous allons donc vous expliquer le flux des événements puis détailler les principaux objets utilisés par Flex pour gérer ces derniers. Nous pourrons ensuite passer sereinement à la pratique.
Comprendre le flux des événements Lorsque Flash déclenche un événement, l’objet correspondant Event effectue un aller-retour entre l’objet émetteur et l’objet récepteur. Le flux des événements se décompose en trois phases : j
j
j
La phase de "capture" : dans cette phase, le lecteur Flash parcourt tous les nœuds de l’application pour voir si l’un d’eux attend l’événement envoyé, et si c’est le cas, l’action associée à cet événement est lancée. La phase de "ciblage" : cette phase concerne simplement le nœud émetteur. Flash initialise l’objet Event, cherche si une fonction est associée à cet événement (on parle de listener) et la déclenche le cas échéant. La phase de "bouillonnement" : cette étape au nom assez étonnant désigne le moment où Flash remonte l’intégralité des nœuds de l’application et déclenche les listeners associés à l’événement.
À propos de l’objet Event Nous avons précédemment évoqué l’objet Event. Il s’agit à présent de décrire sa structure et son fonctionnement pour mieux comprendre les subtilités du modèle événementiel. On parle d’objet Event mais il s’agit plus précisément de la classe flash.events.Event d’ActionScript, classe qui contient de nombreuses propriétés qui définissent l’événement déclenché. On ne crée pas un Event, il est créé implicitement par l’application lors de son déclenchement. Cependant, une fois l’objet instancié, nous pouvons le récupérer pour
128
Utiliser les événements
4
obtenir des informations sur l’origine et la nature de l’événement. Pour pouvoir récupérer un Event, il suffit de le passer en paramètre de notre listener, et lorsque celui-ci sera déclenché, on pourra accéder au paramètre et donc à l’Event.
La classe EventDispatcher Voici un nom un peu barbare mais qui désigne l’une des classes de base de Flex. En effet, la majorité des éléments qui constituent une interface Flex héritent de cette classe qui est la clé de voûte du modèle événementiel. De manière concrète, cela signifie que tous ces éléments peuvent utiliser la méthode addEventListener() qui permet d’écouter un événement en particulier afin d’y associer une réaction particulière. Il ne s’agit pas de la seule méthode de la classe EventDispatcher ; elle permet aussi, via la méthode dispatchEvent(), de déclencher un événement personnalisé. On peut également mentionner la méthode hasEventListener() qui permet de vérifier si un listener est présent sur l’objet pour un événement en particulier. Enfin, la méthode willTrigger() parcourt toute la hiérarchie des composants de notre interface pour vérifier la présence d’un listener.
4.2 Utiliser les événements La mise en place d’un événement s’effectue en deux étapes. Dans un premier temps, il s’agit de déclarer une fonction : on parle de listener, qui déclenche une réaction. Cette fonction utilise souvent l’objet Event (mentionné précédemment) pour accéder aux propriétés qui définissent l’événement. Dans un second temps, il s’agit de lier notre listener à un objet, en spécifiant le type d’événement attendu (un clic de souris par exemple). Pour accomplir cette étape, nous disposons de deux méthodes : utiliser du code inline directement dans l’interface en MXML, ou bien lier l’événement dans le code. Pour illustrer ces mécanismes, nous allons commencer par déclarer une fonction que nous utiliserons comme listener :
Cette fonction est volontairement très simple. Nous aurons l’occasion de voir un exemple un peu plus complexe dans la mise en pratique à la fin de ce chapitre. Cette fonction utilise la classe Alert de Flex qui permet, via la méthode show(), de déclencher un pop-up très utile pour déboguer une application.
Utiliser les événements inline Nous allons commencer par le plus simple. En effet, cette méthode permet d’utiliser un grand nombre d’événements en ajoutant une simple propriété à l’un des objets de votre interface MXML. Concrètement, si l’on veut exécuter la fonction précédemment déclarée lorsque l’on clique sur un bouton, il suffit d’ajouter l’attribut click à la balise de la manière suivante :
Vous pouvez admirer le résultat. c Fig. 4.1 : Notre premier événement
Cette fonctionnalité permet de mettre en œuvre des événements de manière simple et rapide ; vous serez amené à l’utiliser régulièrement lors de vos conceptions d’interfaces Flex. Notez que vous n’êtes pas limité au simple clic, car de nombreux autres types d’événements peuvent être déclenchés de la même manière. Nous tâcherons d’énumérer les principaux types ultérieurement.
Utiliser les événements dans le code À présent, nous allons voir comment associer un listener à un composant côté ActionScript. Si cette méthode n’est pas fondamentalement plus compliquée à mettre en place, elle requiert une certaine connaissance des différents types d’événements.
130
Utiliser les événements
4
Voyons donc comment associer la fonction myListener au bouton caractérisé par l’id myButton. Comme nous l’avons vu précédemment, vous pouvez déclarer le bouton côté MXML, ou bien côté ActionScript. Le code que nous allons voir ne changera pas : myButton.addEventListener(MouseEvent.CLICK, myListener);
Nous obtenons le même résultat qu’avec la méthode inline. Tâchons cependant d’expliciter cet extrait de code : le composant myButton dispose de la méthode addEventListener qui permet de lui signifier qu’il doit réagir à un événement particulier. Cette méthode prend deux arguments, le type d’événement attendu, ici un clic de souris, et la méthode à associer à cet événement, ici myListener, notre listener déclaré précédemment.
Manipuler l’objet Event À présent, vous êtes capable de déclencher un événement. Il pourrait être intéressant d’avoir accès aux propriétés de l’événement dans notre méthode listener. Même si cela ne vous paraît pas évident à première vue, vous serez certainement ravi de connaître l’origine ou le type de l’événement traité. Nous allons commencer avec un exemple pratique simple. Imaginons que nous voulions effectuer un débogage rapide de notre application, en l’occurrence nous aimerions savoir quel type d’événement a été déclenché dans notre application. Il suffit de reprendre notre fonction myListener déclarée plus haut et la modifier de la manière suivante : function myListener(event:Event):void { Alert.show("Evénement "+event.type+" déclenché"); }
Et voilà le travail. c Fig. 4.2 : Type d’événement
131
4
Gérer les événements
Si vous avez encore du mal à comprendre l’utilité de cette fonctionnalité, nous allons voir une autre propriété intéressante de l’objet Event. L’attribut currentTarget désigne le composant cible, autrement dit le composant à l’origine de l’événement. Un attribut hautement intéressant, donc, dans la mesure où il permet d’accéder aux propriétés du composant source. En gardant le même bouton que dans nos exemples d’utilisation d’événements, nous pouvons illustrer l’utilité de cette fonctionnalité : function myListener(event:Event):void { Alert.show("Bouton ’"+event.currentTarget.Label+"’ cliqué"); }
Nous obtenons alors le résultat suivant : c Fig. 4.3 : Accéder à un attribut
Notez que si en général la déclaration de l’événement comme un simple Event suffit, il arrive que vous ayez besoin d’accéder à des propriétés spécifiques à un type d’événement, par exemple un KeyboardEvent : il suffit alors de déclarer notre objet comme KeyboardEvent au lieu d’Event pour résoudre ce problème. Type non reconnu Il arrive que l’inclusion de la classe de l’événement soit nécessaire pour déclarer cet événement. Pensez donc à l’importer dans votre ActionScript.
Les événements à connaître Vous savez désormais comment utiliser les événements, et comment manipuler l’objet Event, mais encore faut-il connaître les différents événements et leur cas d’utilisation dans votre future application. Nous avons déjà vu comment réagir à un clic de souris ; beaucoup d’autres événements existent et certains sont indispensables. Vous devez les connaître.
132
4
Les événements clavier
Voici donc une liste d’événements génériques que vous serez amené à utiliser dès votre première application : Tableau 4.1 : Les événements à connaître Attribut
Description
creationComplete
Voici un événement des plus sympathiques pour gérer votre initialisation. Il est déclenché lorsqu’un composant et tous ses fils sont créés : on peut alors initialiser les valeurs de certaines variables ou composants.
Error
L’une des méthodes permettant de rattraper et de traiter les erreurs est de récupérer et de traiter cet événement.
Scroll
Cet événement est déclenché à chaque fois que l’utilisateur défile avec sa souris dans son application : il peut se révéler utile dans un tableau bien fourni.
Change
C’est un événement au nom plutôt évocateur. Il est déclenché dès qu’un composant subit une modification, et il se révèle très utile lors de l’utilisation d’une ComboBox ou d’un composant personnalisé.
4.3 Les événements clavier Il existe un point important, à savoir distinguer les RIA du reste des applications web : il s’agit de la possibilité d’utiliser le clavier pour interagir avec l’interface. Flex soumet donc à cet impératif en proposant, dans le cadre de son système événementiel, une gestion simple et complète des raccourcis clavier. Nous nous efforcerons de vous présenter cette fonctionnalité tout au long de cette partie.
Gérer les événements clavier Nous allons voir dans un premier temps comment réagir aux frappes du clavier, sans distinguer une touche en particulier. À cet effet, Flex propose deux types d’événements, l’un correspond au moment où l’utilisateur appuie sur une touche, l’autre au moment ou il la relâche. Ces événements sont appelés KeyboardEvent.KEY_DOWN et KeyboardEvent .KEY_UP, et ils sont tous les deux déclenchés à chaque fois que l’utilisateur appuie sur une touche de son clavier. Notez cependant que les listeners doivent être attachés à un composant dit actif, par exemple s’il s’agit d’un TextInput, le focus doit y être présent.
133
4
Gérer les événements
Priorité des événements Le composant est toujours actif dans votre interface. Si vous attachez vos listeners à ce composant, ils seront donc pris en compte quel que soit le focus dans l’application.
Nous allons voir un exemple concret de l’utilisation de ces deux événements. Commençons par déclarer un TexInput et un Label :
Puis une fonction qui va nous servir de listener : private function autoFill():void { my_label.text = my_input.text; }
Il ne nous reste plus qu’à relier le tout. Voyons d’abord comment le réaliser de manière programmatique : my_input.addEventListener(KeyboardEvent.KEY_UP, autoFill);
Vous pouvez aussi, bien entendu, utiliser la méthode inline, plus simple à mettre en place :
Dans tous les cas, le résultat sera le suivant : c Fig. 4.4 : Utilisation des événements clavier
Notez que les équivalents à KeyboardEvent.KEY_UP et KeyboardEvent.KEY_DOWN sont bien logiquement les attributs keyUp et keyDown en MXML.
134
Les événements clavier
4
Récupérer les codes clavier Maintenant que vous savez comment réagir à un événement clavier, il pourrait être intéressant de récupérer le code de la touche pressée pour réagir de manière différente en fonction de la touche appuyée. Flex vous permet de réaliser ce genre de manipulation en utilisant le keyCode (spécifique à la touche pressée) ou le charCode (spécifique au caractère correspondant, suivant le code ASCII, numérotation standard utilisée dans l’informatique pour représenter les caractères alphanumériques). Pour récupérer ces valeurs, il suffit de passer à nouveau par l’objet Event, véritable boîte à outils du modèle événementiel. En partant de l’exemple précédent, nous allons simplement modifier la fonction autoFill (notre listener), afin qu’elle ne réagisse plus qu’à un caractère : private function autoFill(event:KeyboardEvent) { if (event.charCode == 97) my_label.text = my_input.text; }
Désormais, notre texte ne sera recopié dans le Label uniquement si l’on appuie sur la touche [a], 97 correspondant à la lettre a en ASCII. Récupérer un code clavier Peu de gens connaissent bien les codes clavier, il existe cependant une façon relativement simple de les récupérer. Il suffit d’afficher votre code via un Alert.show() ou dans un label, et vous pourrez alors connaître rapidement le code de la touche que vous souhaitez utiliser.
Il existe cependant quelques exceptions à ce système de code clavier ; en effet, les touches [Maj], [Alt] et [Ctrl] disposent chacune d’un attribut particulier dans l’objet KeyboardEvent pour vérifier si l’utilisateur a appuyé sur l’une de ces touches. Voici un nouvel exemple montrant comment détecter une combinaison de touches, en l’occurrence les touches [Ctrl]+[A] : private function autoFill(event:KeyboardEvent):void { if (event.ctrlKey){ if (event.charCode == 97) my_label.text = my_input.text; } }
135
4
Gérer les événements
Une fois votre application lancée, appuyez simultanément sur [Ctrl]+[A] : c Fig. 4.5 : Combinaison de touches
Tout le texte contenu dans notre TextInput est reporté dans le Label.
Les événements clavier-souris Nous allons terminer ce tour d’horizon des événements clavier en voyant comment combiner le clavier et la souris dans les interactions avec notre interface. Lors d’un clic de souris, Flex déclenche un événement de type MouseEvent. Cet objet dispose de plusieurs propriétés permettant de vérifier si une touche a été pressée : Tableau 4.2 : Vérifier si une touche est pressée Attribut
Description
altKey
Si la touche [Alt] est pressée, la valeur de cette propriété est true.
ctrlKey
Si la touche [Ctrl] est pressée, la valeur de cette propriété est true.
shiftKey
Si la touche [Maj] est pressée, la valeur de cette propriété est true.
Voyons à présent comment utiliser cette fonctionnalité. On reprend le même listener que précédemment, mais à un détail près : il s’agit cette fois de l’attacher à un clic de bouton au lieu d’un pressage de touche :
La fonction modifiée donnera ceci : private function autoFill(event:MouseEvent) { if (event.ctrlKey) my_label.text = my_input.text; }
136
Créer ses propres événements
4
Nous commençons par écrire dans notre TextInput, puis, à l’aide d’un petit [Ctrl] clic, voici le résultat : c Fig. 4.6 : Ctrl+clic
Ceci conclut notre partie sur les événements clavier. Bien entendu, vous aurez souvent l’occasion d’utiliser ces fonctionnalités dans vos applications car c’est ce qui fait la différence entre une RIA et une autre application web.
4.4 Créer ses propres événements Nous allons, à présent, voir comment déclencher les événements manuellement. Dans certains cas, vous pouvez avoir envie de faire réagir votre application de manière personnalisée pour déclencher une réaction particulière.
La méthode dispatchEvent() Pour déclencher vous-même un événement, il suffit d’utiliser dispatchEvent(). Cette méthode s’utilise de la manière suivante : myObject.dispatchEvent(myEvent:Event);
Cette fonction retourne un booléen. Avant de pouvoir envoyer un événement, il faut cependant l’instancier ; on va donc créer un nouvel objet Event : myEvent:Event = new Event(Event.CHANGE); myInput.dispatchEvent(myEvent);
On choisit d’utiliser l’événement CHANGE, qui correspond à la méthode onChange() telle que nous l’avons évoquée précédemment, puis on le déclenche en utilisant la fonction dispatchEvent().
137
4
Gérer les événements
Déclencher un événement en MXML Voyons à présent comment déclencher un événement en MXML, en reprenant l’exemple appliqué précédemment en ActionScript :
Il suffit d’utiliser la méthode dispatchEvent directement dans la propriété click de notre bouton. Lorsque vous cliquerez sur ce dernier, l’événement CHANGE sera directement déclenché sur le TextInput. Notez que si aucun listener n’attend l’événement déclenché, il ne va rien se produire. Typiquement, on devra dans notre cas déclarer un listener change sur notre TextInput pour obtenir une réaction.
Personnaliser votre événement Maintenant que vous savez comment créer et envoyer un événement manuellement, il pourrait être judicieux de le personnaliser. Dans un premier temps, nous allons voir comment modifier ses propriétés. Prenons par exemple un événement de type clic de souris : nous avons vu que pour gérer le clavier et la souris simultanément, nous pouvions utiliser la propriété ctrlKey pour vérifier que l’utilisateur appuie simultanément sur la touche [Ctrl]. Voici comment utiliser cette propriété dans votre événement : var myEvent:MouseEvent = new MouseEvent(MouseEvent.CLICK,false,false); myEvent.shiftKey = true; myButton.dispatchEvent(myEvent);
Notez que si vous désirez ajouter une propriété personnalisée à votre événement, vous devrez créer une classe dérivée de la classe Event, mais nous verrons plus tard comment créer des classes dérivées.
4.5 Mise en pratique : un convertisseur de devises Vous avez compris le fonctionnement du système événementiel dans Flex. Il est grand temps de passer à la pratique. Nous allons réaliser ensemble une petite application de convertisseur en dollars, ce qui nous permettra de voir quelques exemples d’événements sur une véritable application.
138
Mise en pratique : un convertisseur de devises
4
Mise en place du projet Si vous avez lu attentivement les parties précédentes, cette étape ne devrait pas vous poser de problème. Créez donc un nouveau projet appelé USDConvert puis ouvrez le fichier USDConvert.mxml, vous devriez voir ceci :
L’interface Il s’agit, à ce stade, de mettre en place l’interface de notre application. Commencez par passer en mode Design, car il est plus facile de construire l’interface de cette manière. Tout d’abord, ajoutez un Panel, puis initialisez ses propriétés de la manière suivante : j j j j j
Title : Mon petit convertisseur ; Width : 500 ; Height : 200 ; X : 20 ; Y : 20.
Puis ajoutez un TextInput, deux Labels et un Button, organisés de la manière suivante : c Fig. 4.7 : Mise en forme de l’interface
Sélectionnez le premier Label et entrez Prix en euros, puis sélectionnez le TextInput et affectez priceInput à son id et 20 à la propriété fontSize afin d’améliorer la lisibilité de notre résultat.
139
4
Gérer les événements
Sélectionnez maintenant le bouton et affectez convertBtn à la propriété id et Convertir en dollars à la propriété label. Même manipulation avec le dernier Label, effacez tout d’abord le texte du Label, puis affectez resultText à la propriété id. Passez en mode Source. Le code de votre application devrait normalement ressembler à ceci :
Mettre en place la logique métier À présent, il s’agit d’ajouter un peu de code à notre interface. Nous allons donc réaliser la logique de l’application. Dans la mesure où il s’agit d’une application simple, vous pouvez directement ajouter le code dans le fichier USDConvert.mxml. Commencez par ajouter une balise dans votre fichier, créez une fonction priceCopy puis créez une fonction priceConvert. La première se contentera de recopier le montant entré par l’utilisateur, la seconde assurera la conversion de notre montant en euros vers des dollars lorsque l’utilisateur clique sur le bouton.
Comme vous le voyez, ce code est assez simple. Quelques petites remarques cependant sont à retenir. La fonction parseInt permet de transformer une String en int afin de pouvoir manipuler le montant en euros. L’affichage du résultat dans le Label est prévu à cet effet ; nous gardons le montant en euros récupéré dans la fonction priceCopy, nous enrichissons quelque peu la phrase du résultat et nous ajoutons le résultat en dollars. Notons que le taux de change a été rentré en dur. Nous pourrions bien sûr imaginer le récupérer à partir d’un Service Web, mais cela fera l’objet d’un exemple plus loin dans cet ouvrage.
Associer la logique à l’interface avec MXML Voici la partie la plus facile. Il s’agit juste d’affecter notre TextInput et notre Label résultat de la manière suivante :
Le TextInput réagira donc à la frappe du clavier et le bouton à un clic. Au final, votre code devrait ressembler à ceci :
141
4
Gérer les événements
Nous vous donnons le résultat en image : c Fig. 4.8 : L’application finale
Associer la logique à l’interface avec ActionScript Cette partie est un peu plus difficile mais ne présente rien d’insurmontable. Nous allons simplement relier nos listeners à nos composants côté ActionScript. Nous commençons par créer une nouvelle fonction appelée initEvents qui va se charger d’initialiser la liaison au démarrage de l’application : public function initEvents():void { priceInput.addEventListener(KeyboardEvent.KEY_UP, priceCopy); convertBtn.addEventListener(MouseEvent.CLICK, priceConvert); }
Pour que cette initialisation fonctionne, nous devons à présent utiliser la propriété creationComplete de la balise :
Et voilà le travail.
142
Check-list
4
4.6 Check-list Dans ce chapitre, nous avons vu :
a comment appréhender le fonctionnement des événements en Flex , a comment utiliser les événements en ligne et dans le code ActionScript , a comment utiliser les événements clavier, souris et clavier/souris ; a comment apprendre à déclencher les événements soi-même ; a comment utiliser les événements dans une véritable application ; Le chapitre suivant est consacré à la gestion des données dans Flex.
143
5 5.1 Définir un data model ..................................
146
5.2 Lier des données ........................................
156
5.3 Valider des données ....................................
161
5.4 Formater les données ...................................
168
5.5 Travailler avec XML .....................................
171
5.6 Check-list .................................................
175
Gérer les données A
ujourd’hui, la gestion des données est un domaine clé pour le développement Web. Ce chapitre vous permet de découvrir la gestion des données au sein de Flex. Vous y apprenez ainsi à organiser, traiter et présenter les données avec cette technologie.
5
Gérer les données
5.1 Définir un data model Afin d’apporter un plus à vos applications riches, il peut s’avérer utile de pouvoir manipuler des données pour les afficher, les modifier ou les transmettre à d’autres applications. Flex permet une manipulation avancée des données qu’il est utile de connaître pour vous faciliter certaines tâches. La gestion des données ne sert pas qu’à récupérer des informations distantes ou à les envoyer vers un serveur. On peut également manipuler des données internes à son application pour les sauvegarder, les afficher ou simplement les utiliser. Cette partie vous montrera comment définir des data models qui sont en quelque sorte les patrons qui guident le stockage des données. Ces modèles de données sont la partie Modèle de l’architecture MVC (Modèle Vue Contrôleur).
Création d’un formulaire Ce chapitre ne traitera pas des données distantes mais uniquement de la manipulation de données internes à notre application. Nous allons donc commencer par créer un squelette basique qui nous fournira des données à récupérer. Un moyen simple d’obtenir des informations saisies par l’utilisateur est un formulaire. C’est l’occasion de développer l’utilisation d’un conteneur très pratique : le conteneur Form. Grâce aux balises , vous pourrez utiliser des propriétés qui vous simplifieront la tâche au quotidien : j j j j j
organisation des composants en les alignant à gauche ; accès à un bouton de soumission du formulaire ; définition de champs obligatoires ; validation de vos données ; génération de messages d’erreur.
À l’intérieur du conteneur, vous pourrez utiliser certaines balises dont voici les propriétés et les utilisations basiques : j
: permet d’afficher des titres pour des groupes d’items. C’est un
élément optionnel. : ce sont les champs du formulaire mais également des conteneurs. Leur titre est la valeur de l’attribut label. L’attribut direction permet de spécifier la disposition des boîtes de texte ou des boîtes de sélection qui seront contenues par les FormItems (par défaut : verticale). La disposition des éléments du formulaire est gérée par la balise principale mais certains de ses attributs permettent de jouer avec des paramètres comme les j
146
Définir un data model
5
espacements. Un autre attribut intéressant est le defaultButton qui permet de spécifier le bouton qui validera le formulaire par défaut. Notre formulaire sera une sorte de bulletin d’inscription. Il contiendra : j j j j j j j
le statut ; un nom ; un prénom ; une date de naissance ; un numéro de téléphone ; une adresse e-mail ; un code postal.
Nous ajouterons à la suite un bouton print qui fera appel à une méthode printUser. Cette méthode affichera pour l’instant une alerte toute simple. En déclarant print comme bouton par défaut du formulaire, vous pourrez constater qu’il est appelé lorsqu’on appuie sur la touche [Ä] à partir de n’importe quel champ. Voici le code de notre application Inscription :
Mr Mme Mlle
147
5
Gérer les données
Nous vous donnons le résultat en image : c Fig. 5.1 : Notre formulaire
Nous avons la base de notre application ; intéressons-nous à présent aux modèles de données.
148
Définir un data model
5
La balise Les data models sont des objets ActionScript. Le moyen le plus simple de créer un data model est d’utiliser la balise en MXML. Nous verrons par la suite que ce n’est pas la méthode la plus conseillée pour des applications gérant beaucoup de données. Elle peut néanmoins se révéler utile pour de petites applications et le stockage de données simples. La façon la plus simple de procéder est de déclarer votre modèle dans le fichier MXML de votre application. Il suffit pour cela d’ouvrir une balise et de lui donner un id. Cette balise contient une arborescence XML et contiendra donc obligatoirement un nœud racine. À l’intérieur de celui-ci, vous trouverez les nœuds fils qui décriront votre modèle. Pour notre utilisateur, nous pouvons définir le modèle suivant à l’intérieur de notre application :
Vous remarquerez bien sûr que ce modèle ne contient aucune donnée. Pour l’instant, tous les champs ont la valeur nulle. Nous allons donc remplir notre modèle afin qu’il contienne des données statiques prêtes à être utilisées :
Mr
Edouard Ruiz
10/05/1984 0654321098 [email protected]
149
5
Gérer les données
94130
Afin de vérifier que ces données sont bien prises en compte, modifions la fonction printUser afin d’afficher le contenu du modèle. Vous accédez aux fils du nœud racine grâce à des . : public function printUser():void { var message:String = ""; message += usermodel.title + " "; message += usermodel.name.first + " "; message += usermodel.name.last + "\r"; message += usermodel.birthday + "\r"; message += usermodel.phone + "\r"; message += usermodel.email + "\r"; message += usermodel.zipcode; Alert.show(message, "Nouvel utilisateur !"); }
Vous pouvez à présent lancer l’application et constater par vous-même que les données du modèle s’affichent bien lorsqu’on appuie sur le bouton. Si vous voulez qu’un champ contienne une chaîne vide, il faut le lui spécifier grâce à des accolades : {""}
Les accolades permettent la liaison des données (le binding) : nous y reviendrons ultérieurement. Nous allons pour l’instant l’utiliser afin d’afficher des données dynamiques, saisies par l’utilisateur. Pour ce faire, nous modifions notre modèle afin de remplacer les chaînes de caractères par des liaisons vers les champs de texte de notre formulaire. Ces liaisons se font simplement en plaçant entre accolades l’id de l’élément et l’attribut qui contient la valeur à utiliser (vous pouvez utiliser la complétion de Flex Builder pour accéder aux éléments) :
{title.value}
{firstname.text} {lastname.text}
{birthday.text}
150
Définir un data model
5
{phone.text} {email.text} {zipcode.text}
Maintenant, votre application affichera le contenu des champs du formulaire : c Fig. 5.2 : Affichage du contenu du formulaire
Stockage des modèles dans des fichiers externes Vous pouvez également définir vos modèles dans des fichiers externes, ce qui facilite leur réutilisation. Il suffit de placer le contenu des balises Model dans un fichier XML valide (commençant par la balise par exemple). Ce fichier XML est situé côté serveur et non côté client. Vous devez ensuite utiliser l’attribut source de la balise Model pour lui spécifier l’emplacement du fichier (chemin relatif ou URL). Dans notre cas, pour un modèle contenu dans un fichier User.xml au même niveau que l’application, on obtiendrait le data model : . Bien évidemment, le patron contenu dans le fichier XML peut contenir aussi bien des données statiques que des liaisons vers des champs.
La balise À la place de la balise , vous pouvez utiliser dans notre code MXML. La seule différence avec la précédente, c’est qu’elle permet d’accéder aux fonctions avancées qui gèrent le XML dans ActionScript 3. Celles-ci suivent les spécifications d’ECMAScript pour XML (E4X). Pour s’assurer du respect de ce format, il suffit de définir l’attribut format à e4x.
151
5
Gérer les données
Voici le modèle précédent avec la balise :
{title.value}
{firstname.text} {lastname.text}
{birthday.text} {phone.text} {email.text} {zipcode.text}
Le comportement est le même. Stockage des modèles dans des fichiers externes Les similitudes entre les deux balises ne s’arrêtent pas là puisque permet également de spécifier un attribut source qui rend possible le stockage des modèles dans des fichiers externes.
Les modèles basés sur du script Les modèles peuvent aussi être intégrés en tant que variable à l’intérieur des balises . Cette méthode n’apporte rien de plus que les balises Model et XML et est même plus contraignante puisqu’elle ne permet pas la liaison des données avec les accolades. Pour permettre la liaison des données, il faudrait ajouter une fonction permettant d’écouter les changements sur les boîtes de texte du formulaire. À chaque modification, elle mettrait à jour le modèle que nous allons créer. La liaison des données n’étant pas l’objet de cette partie et la méthode des modèles dans du script n’étant pas conseillée, nous allons nous contenter de données statiques. Il suffit de créer une variable de type Object à l’intérieur de vos balises et d’intégrer entre accolades votre modèle : public var usermodel:Object = { title:"Mr", name: {
152
Définir un data model
5
first:"Edouard", last:"Ruiz" }, birthday:"10/05/1984", phone:"0654321098", email:"[email protected]", zipcode:"94130" }
Passons à présent à la méthode que nous vous recommandons d’utiliser pour vos modèles.
Les modèles basés sur des classes ActionScript Cette dernière méthode est celle que vous devrez choisir si vous comptez manipuler des données complexes et éventuellement leur faire subir des traitements. Elle permet également le typage des propriétés des modèles. Jusqu’à présent, les champs n’étaient que des chaînes de caractères. Vous allez pouvoir à présent spécifier pour chacun d’eux un type de donnée spécifique. Commencez par créer un package model puis une nouvelle classe UserModel à l’intérieur de celui-ci. Dans cette classe, mettez en public toutes les propriétés de l’utilisateur. Afin de montrer l’utilité des modèles déclarés dans des classes, créez une méthode getResume qui va servir à afficher les coordonnées de l’utilisateur. Choisissez également des types différents pour vos propriétés. Voici la classe UserModel : package model { [Bindable] public class { public var public var public var public var public var public var public var
UserModel title:String = "Mr"; firstname:String; lastname:String; birthday:Date; phone:String; email:String; zipcode:uint;
public function getResume():String { return title + " " + firstname + " " + lastname + "\r" + birthday.toDateString() + "\r" + phone + "\r" + email + "\r" + zipcode; } } }
153
5
Gérer les données
Vous noterez l’utilisation d’une métadonnée [Bindable]. Elle permet la liaison des données sur toutes les propriétés public de la classe. Pour des propriétés private ou protected, il faudrait ajouter la métadonnée à chaque fois, ce qui rendrait notre exemple un peu plus lourd. Retournez sur votre fichier MXML. Commençons par créer le modèle. Déclarez dans la balise , le namespace model (ou tout autre nom) :
Toutes les classes du package model seront accessible grâce à ce namespace. La création du data model se fait très simplement dans votre code MXML :
UserModel est le nom de votre classe (la complétion de Flex Builder sera encore utile).
À partir de là, vous pouvez accéder à votre modèle grâce à son identifiant dans le code de votre application. Modifiez la fonction printUser afin qu’elle fasse appel à la méthode getResume de votre objet usermodel. Utilisez ensuite l’attribut change de vos boîtes de dialogue afin de modifier la valeur des propriétés lorsqu’elles sont saisies. Voici le résultat :
Mr Mme Mlle
Vous remarquerez le typage de birthday ou zipcode tandis que les autres propriétés restent en chaînes de caractères. Nous allons à présent étudier un autre aspect de la manipulation des données en Flex : la liaison des données.
155
5
Gérer les données
5.2 Lier des données Le data binding, ou liaison de données, permet d’automatiser le passage de données entre des parties de votre application. Cette propriété est très utile lorsque vous avez besoin, par exemple, de faire évoluer un élément en fonction de données saisies ou reçues : un graphique qui va se mettre à jour, un texte qui se modifie…
Les accolades en MXML Vous avez déjà eu un aperçu de la liaison de données en utilisant les accolades. C’est le moyen le plus simple d’utiliser la liaison de données. Commençons par un petit exemple. Créez une application contenant un formulaire avec un unique champ de texte qui servira à entrer un nom. À la suite de ce formulaire, créez un label :
Pour utiliser la syntaxe des accolades, il suffit de placer entre elles la source de données et d’affecter le tout en tant que valeur d’une propriété qui sera la destination. Notre label res devient donc :
Le texte de ce dernier évoluera automatiquement en fonction des données saisies dans le champ de texte. Vous pouvez constater le fonctionnement par vous-même : c Fig. 5.3 : Le texte s’affiche au fur et à mesure de la frappe.
Mais les possibilités des accolades sont bien plus évoluées.
156
Lier des données
5
Utiliser du code ActionScript dans les accolades Il est possible, en effet, de faire appel à du code ActionScript à l’intérieur des accolades. Il suffit juste que l’expression renvoie une valeur. On peut citer comme possibilités des expressions conditionnelles, des concaténations de chaînes, des calculs ou encore des fonctions. Intégrons-les dans un nouvel exemple toujours basé sur un formulaire et une phrase qui évoluera en fonction de la saisie. Cette fois, vous allez effectuer la liaison des données dans un data model et vous afficherez le contenu de ce modèle. Il représentera une personne avec son titre, son nom et son âge. Dans le formulaire, un RadioButton permettra de sélectionner le titre, et les autres champs seront des boîtes de texte. Voici le code de l’application :
{man.selected ? "Mr" : "Mme"} {"De " + lastname.text} {int(age.text) / 2}
Vous avez ainsi une expression conditionnelle pour le titre, une concaténation pour le nom et un calcul pour l’âge.
157
5
Gérer les données
Nous vous donnons le résultat en image : c Fig. 5.4 : Plusieurs types de liaison de données
La balise en MXML Au lieu d’utiliser les accolades, vous pouvez également faire appel à la balise en MXML. Cette façon de faire est un moyen de respecter l’architecture MVC puisqu’elle sépare totalement la vue du modèle tandis que la balise est le contrôleur. L’utilisation de cette balise est très simple. Il suffit de lui spécifier un attribut source d’où proviennent les données, et un attribut destination qui sera mis à jour. Pour exemple, reprenez l’application des accolades. Nous allons cette fois utiliser la balise Binding pour mettre à jour le label :
Vous constaterez que le résultat est le même qu’avec les accolades : c Fig. 5.5 : La liaison de données avec la balise Binding
158
Lier des données
5
Vous pouvez également utiliser du code ActionScript, comme on l’a vu précédemment à l’intérieur de la balise source :
ou avec des accolades :
et :
Mais la balise Binding a d’autres atouts.
Plusieurs sources ou plusieurs destinations Que ce soit avec les accolades ou avec la balise , vous pouvez lier une même source de données à plusieurs destinations. La première méthode se fait intuitivement tandis que la seconde nécessite plusieurs balises Binding. Dans l’exemple précédent, ajoutez un label res2 et une seconde balise :
Vous observerez que les deux labels évoluent en même temps : c Fig. 5.6 : Plusieurs destinations
Mais il n’y a seulement qu’avec la balise Binding que vous pourrez lier plusieurs sources de données à une même destination. Il faudra encore utiliser plusieurs de ces balises et leur spécifier cette fois des sources différentes. La destination contiendra la valeur de la dernière source mise à jour. Ajoutez un champ qui représentera le prénom de votre formulaire. Supprimez le label res2 et modifiez votre seconde balise Binding en lui affectant res.text en destination tandis que la source sera l’attribut text du champ firstName. Voici le corps de votre application une fois modifiée :
159
5
Gérer les données
En remplissant alternativement les deux champs du formulaire, vous observerez que seul le dernier champ renseigné reste affiché dans votre label : c Fig. 5.7 : Deux sources pour une même destination
Lier des données en ActionScript Enfin, une dernière méthode permet de réaliser la liaison de données. Il suffit d’utiliser la classe mx.binding.utils.BindingUtils et sa méthode statique bindProperty. Il faut lui préciser l’identifiant et l’attribut concernés de la destination et de la source. Reprenons l’application précédente. Supprimez les balises Binding et remplacez-les par des balises de script. À l’intérieur de ces dernières, créez une fonction initializeHandler qui fera appel à la méthode bindProperty lors du lancement de l’application. N’oubliez pas de préciser son appel dans l’attribut initialize de la balise Application. Voici le résultat :
Vous connaissez à présent les bases de la liaison de données en Flex.
160
Valider des données
5
5.3 Valider des données Les données saisies par l’utilisateur peuvent parfois être incorrectes. Il faut de temps à autre guider l’utilisateur pour qu’il entre des données correctement formatées ou correspondant à ce qu’on attend de lui. La validation des données est essentielle côté serveur, mais Flex fournit également des éléments qui permettent une première étape de validation côté client : les validators. Dans cette partie, nous allons découvrir les possibilités offertes par ces éléments et commencer à les utiliser.
Les validateurs prédéfinis Flex fournit à l’utilisateur des validateurs prédéfinis qui permettent de vérifier que les entrées respectent certains critères. Vous pouvez, par exemple, valider un numéro de téléphone ou de carte de crédit, un code postal ou plus simplement une chaîne de caractères. Voici les validateurs prédéfinis et les données qu’ils valident : j j j j j j j j j j
CreditCardValidator : les numéros de carte de crédit ; CurrencyValidator : les sommes d’argent ; DateValidator : les dates ; EmailValidator : les e-mails ; NumberValidator : les nombres ; PhoneNumberValidator : les numéros de téléphone ; RegExpValidator : les expressions régulières ; SocialSecurityValidator : les numéros de sécurité sociale ; StringValidator : les chaînes de caractères selon des critères ; ZipCodeValidator : les codes postaux.
Pour utiliser un validateur en MXML, il faut utiliser la balise avec le nom du validateur spécifique que vous voulez utiliser à la place de Validator. Vous devez également spécifier les attributs source et property qui contiennent respectivement l’objet, lié grâce aux accolades, et son attribut à valider. Validons de cette façon un champ de texte servant à entrer un numéro de téléphone :
161
5
Gérer les données
Lancez l’application et essayez de tromper le validateur. Ne tapez rien pour commencer mais sélectionnez la seconde boîte de texte. La première qui sert à entrer le numéro de téléphone s’entoure de rouge et un message apparaît vous signalant le problème lorsque vous laissez votre curseur dessus :
c Fig. 5.8 : Un premier message d’erreur
Entrez alors un numéro de moins de dix chiffres et changez à nouveau le focus. Un nouveau message apparaît :
c Fig. 5.9 : Le second message d’erreur
À partir du moment où votre numéro fait dix chiffres, il est validé :
c Fig. 5.10 : Le champ est validé !
En ActionScript, la validation est tout aussi simple. Vous devez créer votre validateur dans une variable et associer les attributs source et property lorsque la création du composant d’entrée est terminée :
162
Valider des données
5
Le résultat est le même que précédemment.
Utiliser des validateurs dans un formulaire Nous allons utiliser quelques-uns des validateurs prédéfinis pour valider un formulaire d’enregistrement comme nous en avons vu au début de ce chapitre. Dans une nouvelle application, créez un formulaire contenant les champs : prénom, anniversaire, numéro de téléphone, adresse e-mail et code postal. Ajoutez un bouton à la fin qui servira à valider ce formulaire. Mais, ce bouton ne sera activé qu’une fois tous les champs valides. Créez ensuite les validateurs associés aux champs. À l’intérieur de balises de script, créez une variable booléenne formIsValid initialisée à false qui servira à définir l’état du bouton. Permettez qu’elle puisse être liée à une destination grâce à [Bindable]. Créez ensuite une méthode validateForm qui servira à valider le contenu du formulaire. Vous ferez appel à cette méthode à chaque fois qu’un changement sera détecté dans un des champs du formulaire à l’aide de l’attribut change des champs de texte. Cette façon de faire permet de guider plus facilement l’utilisateur en lui précisant au fur et à mesure de la frappe si son entrée est valide. Voici le code de notre application :
164
Valider des données
5
Notre exemple valide les champs dans l’ordre de remplissage s’ils contiennent quelque chose. Nous nous servons pour cela de la méthode validate des validateurs. Cette méthode permet d’activer la vérification dans du code ActionScript et renvoie un ValidationResultEvent qui sert à déterminer le résultat de la validation. Tant que tous les champs ne sont pas remplis et valides, l’utilisateur ne peut pas envoyer le formulaire :
c Fig. 5.11 : Formulaire en cours de remplissage
165
5
Gérer les données
Dès que toutes les conditions sont respectées, on peut soumettre le formulaire :
c Fig. 5.12 : Formulaire valide
Personnalisation de la validation L’utilisation des validateurs est donc assez basique. Il existe néanmoins de nombreuses possibilités d’extension si vous voulez personnaliser votre application. Vous pouvez ainsi personnaliser les messages d’erreur des validateurs prédéfinis. À cet effet, il suffit de modifier certains attributs. Pour remplacer le message d’erreur d’un PhoneNumberValidator lorsque le numéro entré n’a pas atteint le nombre de chiffres requis, il faudra définir une nouvelle chaîne à l’attribut wrongLengthError :
Plus avancé : vous pouvez créer vos propres validateurs en faisant hériter une classe ActionScript de la classe mx.validators.Validator, ou étendre les possibilités des validateurs prédéfinis en faisant hériter de la classe appropriée. Nous allons définir un nouveau validateur qui va vérifier qu’une chaîne de caractères est bien composée d’au moins deux mots qui seront le nom et le prénom. Appelons ce composant FullNameValidator. Créez une classe ActionScript de ce nom dans un package components et faites-la dériver de la classe Validator en n’oubliant pas de générer le constructeur. À l’intérieur de cette classe, vous devrez redéfinir la méthode doValidation qui prend en argument l’objet à valider et renvoie un tableau contenant les erreurs de validation. À l’intérieur de cette fonction se trouve le code qui valide votre objet. Voici la classe FullNameValidator : package components { import mx.validators.Validator;
166
Valider des données
5
import mx.validators.ValidationResult; public class CompleteNameValidator extends Validator { private var results:Array; public function CompleteNameValidator() { super(); } override protected function doValidation(value:Object):Array { results = []; results = super.doValidation(value); if (results.length > 0) return results; var baseString:String = String(value); var fullName:Array = baseString.split(’ ’); if (fullName.length < 2) { results.push(new ValidationResult(true, null, "notFullName", "Vous devez entrer un nom et prénom.")); return results; } return results; } } }
La méthode ValidationResult permet de définir une erreur lors de la validation en spécifiant le message d’erreur. On retourne enfin le tableau qui est vide si l’objet est validé ou contient des erreurs, dans le cas contraire. Vous pouvez à présent utiliser ce composant dans une application en définissant le namespace correspondant :
Le résultat est similaire aux autres validateurs :
167
5
Gérer les données
c Fig. 5.13 : Champ invalide
c Fig. 5.14 : Champ validé
Vous êtes à présent armé pour intégrer la validation de données dans vos applications.
5.4 Formater les données Il peut arriver que vous souhaitiez afficher de façon standard des données saisies par l’utilisateur. Flex fournit pour cela des outils : les Formatters. Ces éléments déclenchent la mise en forme des données avant qu’elles ne soient affichées. Nous allons découvrir dans ce chapitre l’utilisation de ces formateurs.
Utiliser les formateurs de base Comme pour les validateurs, Flex fournit des éléments qui permettent de gérer des types de données courants. Voici la liste des formateurs et les données correspondantes : j j j j j
CurrencyFormatter : des sommes d’argent ; DateFormatter : les dates ; NumberFormatter : les nombres ; PhoneFormatter : les numéros de téléphone ; ZipCodeFormatter : les codes postaux.
Toutes ces classes dérivent de mx.formatters.Formatter. Il est, bien entendu, possible d’étendre cette classe afin de définir vos propres formateurs. Mais intéressons-nous tout d’abord aux formateurs prédéfinis. Prenons comme exemple le CurrencyFormatter. Il faut le déclarer dans le code MXML avec la balise puis appeler sa méthode format à l’intérieur des accolades pour réaliser la liaison des données. Elle prend en argument la valeur à
168
Formater les données
5
formater. L’entrée utilisateur se fera grâce à un champ de texte et vous afficherez le résultat dans un Label.
De nombreux paramètres permettent de configurer votre CurrencyFormatter. Leur nom est assez explicite : ici, notre entrée numérique sera convertie avec une précision de deux chiffres après la virgule et arrondie au plus près, et le symbole de monnaie sera placé à droite. Voici le résultat : c Fig. 5.15 : Un nombre formaté en euros
Récupérer les erreurs de formatage En cas d’erreur lors de la saisie utilisateur, lorsque la chaîne est impossible à formater, une erreur est produite par le formateur. La raison de cette erreur est contenue dans l’attribut error. Afin d’observer ce message d’erreur, ajoutez à votre exemple une fonction printError qui affichera une alerte le contenant :
Cette fonction sera appelée par un bouton situé dans le panel :
Le message d’erreur, si l’on entre des lettres au lieu de chiffres, est "Invalid value" : c Fig. 5.16 : Le message d’erreur
Un autre message d’erreur est disponible pour le CurrencyFormatter : "Invalid format" si l’un des attributs du formateur contient une valeur invalide. Les messages d’erreur peuvent être plus ou moins explicites, aussi il peut parfois être utile de définir vos propres fonctions d’erreur.
Formater à l’intérieur d’une liste de données Le formatage peut également servir à mettre en forme une liste de données. Nous allons créer une liste de dates que nous remplirons grâce à un champ de texte. Cette liste sera mise en forme grâce à un itemRenderer et un DateFormatter. Voici l’exemple :
170
Travailler avec XML
5
Et son rendu : c Fig. 5.17 : Une liste de dates formatée
Pour simplifier l’exemple, il n’y a pas de validation de la saisie utilisateur : la chaîne à saisir l’est sous forme américaine, autrement dit MM/JJ/AAAA. À vous de réfléchir sur l’ajout d’une fonctionnalité pour valider une date formatée à la française par rapport à ce que vous avez déjà vu. Passons à présent à la manipulation de données en XML.
5.5 Travailler avec XML Aujourd’hui, XML est un langage qu’il est essentiel de savoir manipuler. Il est en effet présent partout et permet à la fois le stockage de données et la transmission d’informations au travers de Services Web par exemple. Comme nous l’avons déjà signalé, ActionScript 3 fournit aux développeurs des outils basés sur ECMAScript for XML (E4X) qui permettent le traitement simple et puissant de données XML. Nous allons nous intéresser d’un peu plus près à la manipulation de données en XML.
Accéder aux éléments Vous pouvez déclarer des variables contenant des données XML en ActionScript. En effet, XML est un type de données natif. Créons par exemple une liste d’utilisateurs avec un nom et prénom, un âge et une adresse e-mail. Notre liste contient deux nœuds :
171
5
Gérer les données
[Bindable] private var userList:XML =
Edouard Ruiz
23 [email protected]
Vianney Baron
21 [email protected]
Vous allez ensuite accéder aux nœuds et aux attributs de votre liste d’utilisateurs. Si vous avez l’habitude du XML, vous ne serez pas surpris par l’accès aux nœuds qui se fait grâce à l’opérateur point (.) : userList.user vous donnera accès à la liste des nœuds user. Si vous voulez accéder à un nœud particulier, vous pouvez utiliser la notation des tableaux c’est-à-dire avec des crochets ([]) : userList.user[0].age, par exemple, vous donnera accès au contenu du nœud age de l’utilisateur ayant l’indice 0 dans le tableau des utilisateurs, autrement dit, le premier. Vous pouvez également vouloir accéder à un nœud en fonction d’un de ses attributs. Pour cela, il faut préfixer le nom de l’attribut par un @ : userList.user.(@id == 2).name .firstname qui vous donnera le prénom de l’utilisateur ayant comme identifiant la valeur 2. Voici le résultat de nos requêtes dans des labels :
Vous pouvez constater la cohérence du résultat :
172
Travailler avec XML
5
c Fig. 5.18 : Accès aux données XML
On peut également effectuer des requêtes plus complexes : userList.user.(age > 22).name.firstname vous donnera les prénoms des utilisateurs dont l’âge est strictement supérieur à 22.
Modifier les données Si vous pouvez accéder aux nœuds de votre objet XML grâce au point et à l’arobase, il est également possible de les modifier avec les mêmes opérateurs. Il suffit d’affecter un nouveau résultat à un élément auquel on accède. Conservez la variable userList définie dans l’exemple précédent mais remplacez les labels par ce formulaire :
173
5
Gérer les données
Les champs de texte mettront à jour l’utilisateur en position 0 dans la liste userList. Bien entendu, il pourrait être intéressant d’utiliser une DataGrid, par exemple, pour naviguer dans cette liste et ainsi pouvoir modifier tout son contenu. Remplacez donc le champ de texte all par une DataGrid :
Remplacez aussi l’indice 0 qui vous permettait d’accéder au premier élément de la liste d’utilisateurs par list.selectedIndex qui vous donne la position courante dans la liste. Vous pouvez à présent naviguer dans la grille et modifier l’élément :
174
Check-list
5
c Fig. 5.19 : Modification des données
Créer ou assembler des objets XML Vous pouvez également créer des objets XML et les ajouter ou les insérer dans une liste déjà existante. Les méthodes prependChild et appendChild permettent respectivement d’ajouter avant ou après une liste de propriétés : userList.prependChild(xmlUserVar) ou userList.appendChild(xmlUserVar) ajouteront à la liste d’utilisateurs une variable xmlUserVar de type XML contenant un schéma d’utilisateur correct. Si vous souhaitez ajouter un élément à l’intérieur d’une liste par rapport à l’élément courant, il faudra utiliser les méthodes insertChildBefore ou insertChildAfter. Celles-ci prennent en argument l’élément par rapport auquel on se positionne ainsi que l’élément à ajouter, tous deux de type XML. Enfin, la suppression se fait grâce à la méthode delete. Ainsi, l’appel à delete(userList .user[0]) supprimera le premier nœud de la liste d’utilisateurs. Vous êtes prêt à présent pour stocker, afficher ou manipuler des données en Flex.
5.6 Check-list Dans ce chapitre, nous avons vu :
a comment définir des modèles de données ; a comment découvrir la liaison de données ; a comment utiliser des méthodes de validation ; a comment mettre en forme des données ; a comment utiliser XML. Le prochain chapitre sera consacré à l’amélioration et à l’enrichissement de votre interface.
175
6 6.1 Les contrôles avancés ..................................
178
6.2 Créer ses propres composants ........................
182
6.3 Mise en pratique : une interface maître-détail .......
190
6.4 Check-list .................................................
201
Aller vers une interface riche F
lex permet aux développeurs d’interfaces d’utiliser de nombreux composants comme cela a été vu dans les précédents chapitres. Certains de ces composants permettent d’afficher de manière « ordonnée » les données que vous souhaitez présenter à vos utilisateurs. Aussi, vous bénéficiez d’importantes possibilités pour créer vous-même vos composants, afin de personnaliser votre application jusque dans les moindres détails ou de la découper en différents modules.
6
Aller vers une interface riche
6.1 Les contrôles avancés Dans Flex, les contrôles qui sont considérés comme contrôles avancés sont ceux dirigés par les données qu’ils sont chargés d’afficher. Ainsi, nous retrouvons dans ces contrôles avancés les Tree, les List et les HorizontalList, les ComboBox et les DataGrid. Ces composants qui sont tous hérités de la classe ListBase ont peu ou prou le même mode de fonctionnement et permettent de présenter des données organisées à l’utilisateur.
Les List, les HorizontalList et les ComboBox Ces trois composants sont des listes avec des positionnements d’éléments différents. La balise dispose les éléments de façon verticale avec une barre de défilement latérale, la balise dispose les différents items horizontalement et crée une liste déroulante.
c Fig. 6.1 : Exemple de List
c Fig. 6.2 : Exemple de HorizontalList.
Ces contrôles ont de multiples propriétés pour positionner les items et paramétrer leur apparence qu’il vous sera facile de découvrir grâce au Flex Builder et sa complétion automatique. Nous ne nous attarderons donc pas sur cet aspect de l’utilisation des composants avancés mais nous allons étudier leur utilisation fonctionnelle.
Remplir une List Le remplissage des List et HorizontalList se fait en utilisant la propriété dataProvider. Aussi, le moyen le plus simple est de spécifier des balises comme balises filles de . En effet, Flex interprète une succession de balises comme un tableau :
Nevers Château-Chinon Cosne-sur-Loire
178
Les contrôles avancés
6
L’indexation des éléments d’une liste se fait à partir de 0, ainsi dans notre exemple "Nevers" aura l’index 0 et "Cosne-sur-Loire" l’index 2.
La propriété selectedItem Les listes sont pourvues de multiples méthodes et propriétés qui aident à leur manipulation. La plus couramment utilisée est selectedItem. Cette propriété est une copie de l’objet sélectionné dans la liste. Ainsi, des opérations peuvent être effectuées en fonction du choix de l’utilisateur :
c Fig. 6.3 : Exemple de List utilisée avec l’attribut selectedItem
Remplir la liste avec des images Il peut aussi être pertinent de faire des listes d’images. Pour cela, on suit le même principe que pour une liste comme expliqué précédemment, mais il faut préciser un "moteur de rendu", ou itemRenderer, spécifique au type de données que l’on veut présenter à l’utilisateur :
179
6
Aller vers une interface riche
c Fig. 6.4 : Ainsi, nous avons simplement Exemple de liste d’images créé un ArrayCollection (dans le code ActionScript) contenant les chemins vers les images voulues, et nous avons fourni ce tableau comme source de notre HorizontalList. Cependant, nous avons précisé un itemRenderer qui est présent dans les bibliothèques de Flex.
Les DataGrid Ce composant fonctionne sur le même principe que les trois types de liste étudiés précédemment en affichant plusieurs champs sur une seule ligne. Ainsi, la collection de données n’est pas seulement composée d’éléments mis bout à bout mais également de colonnes pour former une matrice. Cette possibilité d’avoir plusieurs colonnes permet d’afficher plusieurs informations (vous en verrez une application dans l’exemple pratique à la fin de ce chapitre), et permet en outre à l’utilisateur de trier la liste comme il l’entend en cliquant simplement sur les intitulés de colonnes. Le remplissage de ce type de contrôle se fait grâce à des ArrayCollection et les différents types de champs font les différentes colonnes. Vous découvrirez à la fin de ce chapitre comment utiliser les DataGrid dans un exemple pratique.
180
Les contrôles avancés
6
Les Tree Encore un type de liste différent qui permet d’afficher des données hiérarchisées. Les Tree permettent par exemple de présenter une arborescence de système de fichiers comme le fait l’explorateur Windows. c Fig. 6.5 : Exemple de composant Tree
Bien sûr, du fait de la hiérarchisation des données, le remplissage d’un Tree ne se fait pas à partir de simples Array ou ArrayCollection, mais nécessite l’utilisation des XML, et des XMLList. Possibilité de remplissage Il est possible de remplir un Tree en utilisant des ArrayCollection, sachant que les enfants sont contenus dans des objets appelés children.
Voici un exemple de remplissage d’un Tree avec un XMLList :
181
6
Aller vers une interface riche
6.2 Créer ses propres composants L’une des grandes forces de Flex est de permettre aux développeurs de créer leurs propres composants à partir des composants déjà existants. Ainsi, il est possible de spécialiser un composant existant pour le rendre intégrable directement dans beaucoup d’applications types. La création de composants Flex est très aisée. Un composant personnalisé se stocke sous forme de fichier MXML ou ActionScript dans le répertoire components de votre projet Flex. Si ce répertoire n’existe pas encore, il est temps de le créer : cliquez avec le bouton droit de la souris sur le projet Flex puis sur New, Folder et appelez-le components. Choix du dossier pour placer ses composants Nous vous indiquons ici de placer vos nouveaux composants dans le dossier components. Ce nom de dossier n’est qu’une indication pour vous aider à vous y retrouver dans l’arborescence de votre projet Flex. Vous pouvez, si vous le désirez, appeler ce dossier autrement ou même placer les nouveaux composants créés à la racine du projet. En revanche, vous devrez modifier le chemin au moment de la déclaration du namespace.
Un nouveau conteneur racine pour les composants MXML Tout d’abord dans le menu de Flex Builder cliquez sur File puis sur New et MXML components. c Fig. 6.6 : La fenêtre du Flex Builder pour la création des composants MXML
182
Créer ses propres composants
6
Vous remarquez alors qu’il vous est demandé de choisir le dossier dans lequel le composant va être placé. Sélectionnez donc le dossier components et indiquez un nom pour votre composant. Surtout, indiquez à partir de quel composant Flex vous voulez démarrer. Choix du composant de base Si vous choisissez Box comme composant de base, vous aurez beaucoup de possibilités mais le travail d’affinement sera long. Aussi, nous vous conseillons de cibler au mieux le composant de base pour vous faciliter le travail dans le cas de création d’un composant spécifique.
Si vous avez choisi Form comme composant de base et que vous appelez votre composant mon_composant, Flex Builder vous ouvre le fichier : mon_composant.mxml
À ce moment, il est judicieux de noter que le nœud racine du fichier n’est pas un nœud mx:Application mais un nœud mx:Form et aurait été un nœud mx:Canvas si vous aviez sélectionné Canvas comme composant de base. Aussi, comme les fichiers MXML doivent avoir comme racine un conteneur, vous comprenez qu’il faut baser vos composants sur des conteneurs de navigation ou de layout. Dorénavant, vous pouvez, comme vous en avez l’habitude, modifier le fichier MXML en mode Source ou en mode Design et ainsi personnaliser votre composant. Si vous voulez réaliser un formulaire type pour que vos utilisateurs s’enregistrent sur l’application, il est intéressant de modifier le composant Form pour qu’il soit composé de base des champs login, password et d’un bouton validation. Grâce au mode Design, vous ajoutez donc ces champs et le bouton et vous obtenez dans la source : login_form.mxml
183
6
Aller vers une interface riche
Vous allez pouvoir ensuite en une seule ligne ajouter ce nouveau composant dans vos applications Flex. c Fig. 6.7 : Le composant créé pour l’enregistrement des utilisateurs
Utilisons nos nouveaux composants Un nouveau namespace Maintenant que notre composant personnalisé est créé et se trouve dans le dossier components, il est plus qu’intéressant de savoir comment l’appeler et l’utiliser dans le reste de l’application. c Fig. 6.8 : Le nouveau composant est visible dans l’arborescence du projet Flex
184
Créer ses propres composants
6
Dans un premier temps, il vous faut comprendre que l’appel de ce nouveau composant va nécessiter la création d’un nouvel espace de noms, ou namespace. Tous les composants fournis par Flex s’appellent dans le namespace mx. Or, notre composant n’est pas fourni par Flex. Nous allons donc devoir lui créer un namespace pour ne pas risquer de collisions et pour séparer ce que l’on crée de ce qui existe déjà. Aussi, l’utilisation d’un nouveau namespace permet de définir un nom simple pour faire référence à un chemin d’arborescence. Pour déclarer un nouveau namespace, et lui affecter un chemin dans l’arborescence, il suffit de faire comme dans l’exemple suivant en utilisant la syntaxe xmlns:mon_namespace :
Vous remarquez que dans l’exemple précédent deux namespaces sont déclarés : j j
mx, qui pointe à tous les composants fournis avec Flex et référencés dans le fichier sur lequel pointe l’adresse Internet. mcmp, qui fait référence à tous les composants se trouvant dans le dossier components. Ne faire référence qu’à un seul composant du dossier
Il est tout à fait possible de ne faire pointer un namespace que sur un seul composant du dossier. Pour cela, il faut remplacer : components.* par components.mon_composant.
Dorénavant, lorsque vous ouvrirez une balise MXML en indiquant le namespace mcmp, Flex Builder vous proposera en complétion automatique tous les composants auxquels fait référence mcmp. c Fig. 6.9 : Exemple de complétion automatique pour le nouveau namespace
185
6
Aller vers une interface riche
Un simple ajout de balise Maintenant que le nouveau namespace est créé, l’ajout de votre nouveau composant dans l’application Flex se fait en utilisant la même méthode que celle appliquée depuis le début avec les composants traditionnels : un simple ajout de balise dans le code MXML. Bien entendu, il faut utiliser le namespace déclaré à la place de mx. Par exemple, vous avez créé le composant Form_login que vous voulez intégrer dans votre application :
L’insertion de votre nouveau composant Form_login dans un Panel s’est faite simplement et votre application Flex utilise dorénavant un composant réalisé par vos soins.
Définir les nouvelles propriétés et les nouvelles méthodes pour un composant En MXML Le langage MXML permet l’utilisation des balises , et définies pour des propriétés de type chaîne de caractères, booléen et nombre. Le nom de la propriété est alors l’id précisé dans la balise. Il est possible de définir une valeur par défaut pour les propriétés que vous insérez dans vos composants en renseignant le corps des balises de propriétés : Valeur par défaut
Cette valeur par défaut peut être soit une valeur statique comme dans l’exemple précédent, soit un URL si on définit celle-ci dans la propriété source ou bien une donnée liée :
15 {numJours * 24}
Vous pouvez utiliser la méthode ainsi définie dans votre application Flex :
À l’exécution, vous allez voir que lorsque adviendra un changement dans le TextArea mta, le TextArea ta1 se remplira de la valeur : "Le nombre indiqué dans la propriété maPropriete est : 4".
188
Créer ses propres composants
6
c Fig. 6.10 : Exemple avec les TextArea dont celui que nous avons créé
La création de composants en ActionScript Nous avons vu comment créer de nouveaux composants grâce au langage MXML. Nous allons maintenant étudier comment faire la même chose en ActionScript. Les composants ainsi créés peuvent être référencés dans vos applications Flex par des tags MXML. Ils peuvent contenir des éléments graphiques, définir leur propre logique de travail (procédures, fonctions, événements… qui permettent au composant de calculer ou d’agir sur le reste de l’application) ou compléter des composants Flex déjà existants. Voici par exemple le code d’un bouton personnalisé hérité du contrôle Button de Flex : class components.MonButton extends mx.controls.Button { function MonButton() { // Le code de la fonction super() ; // Appel au constructeur du composant parent } // La suite du code }
Il ne reste plus qu’à enregistrer ce bout de code dans le fichier mon_button.as dans le dossier components (comme pour les composants créés en MXML). Ensuite, l’utilisation de ce nouveau composant se fera comme pour les composants MXML : j j
déclaration d’un namespace ; utilisation d’une balise MXML pour insérer le composant dans l’application Flex en cours de création.
ActionScript vs MXML pour la création de nouveaux composants En ActionScript, vous aurez la possibilité de créer des composants visuels comme des boutons, des conteneurs… mais aussi des composants non visuels qui seront plus efficaces au lancement de l’application.
189
6
Aller vers une interface riche
Alors qu’en MXML, on se cantonne seulement au "visuel" du nouveau composant, l’ActionScript permet d’écrire, ou de modifier des comportements procéduraux, événementiels ou fonctionnels. Remarquez que souvent le plus pratique est de mêler les deux techniques, MXML pour le design avec de l’ActionScript pour le fonctionnel.
Pourquoi créer ses propres composants ? La création d’un nouveau composant permet, outre la personnalisation de composants existants afin de les spécialiser pour votre application, de rendre vos applications Flex plus modulaires. Vous découvrirez que la découpe d’une grosse application en de multiples composants rend sa maintenance plus efficace. Ainsi, vous pourrez faire évoluer différemment les divers modules de votre programme et travailler à plusieurs de façon indépendante. Aussi, avec le temps vous allez créer des composants de plus en plus génériques qui seront réutilisables dans vos différentes applications. Ne pas réinventer la roue est un principe fondamental dans n’importe quel développement de logiciel mais en plus de cela, en cas de bug ou de faille de sécurité, l’utilisation de composants génériques permet des corrections aisées et rapides à déployer. Ainsi, la création de composants personnalisés n’est pas seulement utile pour créer de nouveaux composants révolutionnaires mais cette fonctionnalité doit être détournée pour modulariser vos applications Flex.
6.3 Mise en pratique : une interface maître-détail Maintenant que vous savez comment utiliser de façon avancée les composants Flex et notamment leur création, il est temps de mettre en pratique ces connaissances en programmant une interface maître-détail. Nous verrons comment découper une application Flex en plusieurs modules, et comment les utiliser en les faisant interagir.
Qu’est-ce qu’une interface maître-détail ? Principe récurrent dans la création d’interfaces d’applications, les interfaces "maître-détail" permettent de zoomer sur un objet sélectionné dans une liste. La partie "maître" affiche une collection d’objets et la partie "détail" permet d’implémenter un zoom sur les objets de la collection qui affiche des détails sur l’objet sélectionné dans la première. Ainsi, lorsque l’utilisateur modifie sa sélection dans la partie maître, la partie détail est mise à jour afin d’inspecter le nouvel objet sélectionné.
190
Mise en pratique : une interface maître-détail
6
L’inspecteur d’objet (partie détail) n’affiche rien quand l’utilisateur n’a sélectionné aucun ou plusieurs éléments de la collection. Affichage de plusieurs éléments Dans certaines implémentations de l’interface maître-détail, l’inspecteur d’objet permet d’afficher plusieurs objets en cas de sélection multiple. De même, souvent les détails sont éditables mais vous conviendrez aisément que les changements nécessaires sont maintenant à votre portée sans besoin de description dans cette courte mise en pratique.
Mise en place du projet Rien de nouveau dans notre cas : nous allons créer un nouveau projet que nous nommerons MasterDetail dans la suite de l’explication. Créez aussi tout de suite le dossier components qui, comme vous le savez maintenant, servira à stocker les différents modules. Vous retrouvez l’arborescence qui vous est maintenant familière : c Fig. 6.11 : Arborescence du projet MasterDetail
Et le fichier MasterDetail.mxml qui ne contient pour le moment que les déclarations XML de base :
Le découpage du projet Ce mini-projet sera découpé en deux modules principaux. Un module maître qui contiendra l’interface maître et un module détail qui contiendra l’interface… détail. Le développement se fera de façon séparée et nous allons voir à la fin comment les assembler et les faire interagir. Ces deux modules seront des modules MXML qui incluront le code métier nécessaire à leur fonctionnement.
191
6
Aller vers une interface riche
Pour une organisation plus propre, chaque module sera placé dans un dossier spécifique afin de séparer les fichiers nécessaires au fonctionnement de chacun. c Fig. 6.12 : La nouvelle arborescence du projet avec séparation des modules
Le module maître Pour la création du module maître, nous allons partir sur le composant Box que nous allons modifier afin de pouvoir insérer un DataGrid que nous allons remplir avec les données de la collection. Vous obtenez ainsi le fichier master.mxml dans le dossier components\master\ qui s’articule avec comme nœud racine :
Paramétrage du DataGrid La collection utilisée pour l’exemple est une liste d’enregistrements de personnes qui contient le nom, le prénom, et un identifiant. Exemple : 1 Dupont Etienne. Nous avons besoin de trois colonnes pour afficher ces différents champs. Tout d’abord, insérez en mode Design un DataGrid dans votre module. L’ajout de colonnes dans un DataGrid se fait grâce à la balise qui est un conteneur pour les trois éléments . De plus, modifiez la propriété headerText des trois colonnes afin de leur donner des noms significatifs :
192
Mise en pratique : une interface maître-détail
6
Notez que nous donnons à notre DataGrid l’id masterList pour nous permettre de pouvoir l’appeler plus tard et y insérer les données de la collection.
Stockage de la collection Pour cet exemple, nous allons stocker les éléments de la collection (la liste de personnes) dans un model Flex qui sera enregistré dans le fichier collection.xml dans le dossier components car ce fichier sera utilisé aussi par le composant Detail. Ce modèle comporte pour chaque enregistrement user plusieurs champs : id pour l’identifiant, lastname et firstname (pour le nom et le prénom), birthday (pour la date de naissance), ainsi que phone, email et zipcode pour respectivement le numéro de téléphone, l’adresse e-mail et le code postal de chaque personne enregistrée. Pour plus de renseignements sur le stockage et le chargement des données en Flex, veuillez-vous reporter au chapitre Gérer les données. Vous devriez obtenir le fichier collection.xml sur le même type que celui-ci :
1 Edouard Ruiz 10/05/1984 0654321098 [email protected] 94130
2 Vianney Baron 14/07/1985 0658982345 [email protected] 75017
3 Jessy Bernal
193
6
Aller vers une interface riche
23/01/1985 0698235455 [email protected] 94800
Il nous reste à indiquer au composant que nous utilisons ce modèle ainsi que l’endroit où celui-ci est stocké en insérant la balise :
Remplissage du DataGrid avec les données de la sélection Afin de remplir le DataGrid, nous allons lier les données du modèle avec la propriété dataProvider de notre DataGrid qui porte l’identifiant masterList :
Il va falloir indiquer aux colonnes quels champs du modèle afficher. Pour cela, nous allons nous servir de la propriété dataField de la balise :
En faisant appel à ce nouveau module dans le fichier MasterDetail.mxml, nous obtenons le résultat escompté :
194
6
Mise en pratique : une interface maître-détail
c Fig. 6.13 : L’interface Master du projet après remplissage du DataGrid
Élaboration du code métier Notre liste maîtresse est en place et il est dorénavant nécessaire de doter notre module du code permettant à l’interface détail d’afficher tous les renseignements concernant l’objet sélectionné. ActionScript est un langage objet. Nous allons donc écrire une classe qui va permettre de transférer les informations de l’élément sélectionné. Cet objet sera récupéré dans l’interface détail afin de remplir les champs utiles.
La classe User Stockées dans le fichier User.as lui-même placé dans le dossier components afin de la rendre facilement accessible aux deux modules, cette classe contient les sept propriétés qui vont contenir toutes les informations qui caractérisent un utilisateur, ainsi que les getters et setters. Elle fait partie du package components : Package components { Public class User { private var id : int; private var firstName : String; private var lastName : String; private var birthDay : String; private var email : String; private var phone : String; private var zipCode : String; public function User(id:int, firstName:String, lastName:String, birthDay:String, email:String,phone:String,zipCode:String) : void { this.setId(id); this.setFirstName(firstName); this.setLastName(lastName); this.setBirthDay(birthDay);
195
6
Aller vers une interface riche
this.setEmail(email); this.setPhone(phone); this.setZipCode(zipCode); } /* Getters et setters normaux dont voici deux exemples. */ public function setEmail(value:String) : void { this.email = value; } public function getPhone() : String { return this.phone; } ..} }
Cette classe sera instanciée lors d’un événement click sur un élément de la collection, et cet objet sera alors transmis à l’interface détail.
La fonction getUser() Vous l’avez sûrement déjà compris, il est maintenant nécessaire d’ajouter quelques petits bouts de code dans le fichier master.mxml. Pour gagner en simplicité, nous laisserons le code ActionScript dans le fichier MXML, entre les balises : et . Dans un premier temps, importez la classe User nouvellement créée dans le package components afin de pouvoir l’utiliser : import components.User;
Ensuite, le principe de la fonction getUser() va être de récupérer l’index de l’item sélectionné (grâce à la méthode getItemIndex() du ArrayCollection que vous allez très vite découvrir) puis de récupérer l’objet correspondant à cet index avec la méthode getItemAt() afin de pouvoir en extraire les différents champs. Afin de pouvoir récupérer un objet correspondant à la ligne sélectionnée, nous allons devoir insérer une nouvelle étape dans la construction du DataGrid. Au lieu de le remplir directement à partir du Model, nous allons "binder" tout d’abord le Model col dans une collection (ArrayCollection) puis nous allons ensuite remplir la liste à partir du ArrayCollection. Pour cela, il va falloir modifier la balise et en rajouter une nouvelle :
196
6
Mise en pratique : une interface maître-détail
/* …Début du fichier… */
/* …Fin du fichier… */
Insertion d’une nouvelle propriété dans le DataGrid Vous remarquerez que nous avons ajouté une nouvelle propriété dans la balise afin d’interdire les sélections multiples.
La fonction getUser() est très simple grâce aux multiples méthodes fournies par Flex : public function getUser() : User { /* Déclaration de la variable currentId qui contient l’index de */ /* la ligne sélectionnée */ var currentId : int = arrayUser.getItemIndex(masterList.selectedItem); /* currentItem contient l’objet du ArrayCollection correspondant */ /* à la ligne sélectionnée */ var currentItem : Object = arrayUser.getItemAt(currentId); /* Instanciation de la classe User, le constructeur de la */ /* classe permet de remplir toutes les propriétés de l’objet */ var user : User = new User(int(currentItem.id), currentItem.firstname, currentItem.lastname, currentItem.birthday, currentItem.email, currentItem.phone, currentItem.zipcode) ; return user; }
Cette fonction sera appelée par la classe MasterDetail (la classe principale de notre mini-projet) au moment où nous assemblerons les différentes parties du projet.
Le module détail Pour le module détail, il faut partir comme pour le module maître. À savoir, nous allons partir du composant Flex et nous allons y ajouter les éléments dont nous avons besoin. Vous devez donc obtenir le fichier detail.mxml dans le dossier components\detail\ de votre projet Flex.
197
6
Aller vers une interface riche
L’affichage des renseignements dans la partie détail de votre interface maître-détail se fera grâce à un formulaire et à des champs TextInput. Par un glisser-déposer en mode Design, ou en tapant vous-même le code, vous devriez obtenir :
Faites bien attention à fournir à chaque balise une propriété id qui vous permettra par la suite de remplir les champs grâce à une fonction ActionScript. c Fig. 6.14 : Le module détail en mode Design dans le Flex Builder
198
Mise en pratique : une interface maître-détail
6
Le code ActionScript n’est pas non plus très dur. Il se compose d’une seule fonction applyChange() et de l’import de la classe User. Cette fonction prend en paramètre un objet de type User et remplit ensuite tous les champs TextInput en renseignant la propriété text de chacun :
Lors de l’appel à cette fonction, les champs se rempliront avec les données contenues dans l’objet user.
L’assemblage des deux modules C’est certainement la partie la plus simple. Nous retournons à présent dans le fichier MasterDetail.mxml, que nous n’avons pas beaucoup modifié depuis le départ. Dans un premier temps, vous allez devoir déclarer deux namespaces (un par module) :
Et ensuite, vous insérez la balise correspondante à chaque module dans le corps du fichier :
199
6
Aller vers une interface riche
Vous avez sans doute noté que nous avons identifié chaque module en leur fournissant une propriété id. Ainsi, nous allons pouvoir faire appel à masterInterface.getUser() et fournir le résultat de cette dernière à la méthode detailInterface.applyChange() : private function transfertUser() : void { detailInterface.applyChange(masterInterface.getUser()); }
Cette nouvelle fonction, transfertUser(), va être appelée du déclenchement de l’événement click de l’élément afin de mettre à jour les champs de la partie détail. Après avoir rajouté pour des raisons esthétiques un conteneur VBox et un trait HRule, vous obtiendrez un fichier MasterDetail.mxml ressemblant au suivant :
Nous avons pour ainsi dire créé une interface maître-détail fonctionnelle qui est, rappelons-le, présente dans un très grand nombre de développements en informatique.
200
Check-list
6
c Fig. 6.15 : L’interface maître-détail sans aucun élément sélectionné
c Fig. 6.16 : L’interface maître-détail affichant les informations de l’élément sélectionné
6.4 Check-list Dans ce chapitre, nous avons vu :
a quels étaient les composants avancés de Flex ; a comment se servir sommairement de ces composants ; a comment créer nos propres composants ; a la modularisation d’une application ; a les interfaces maître-détail. Le prochain chapitre va vous initier à la navigation dans les applications Flex en utilisant les conteneurs avancés.
201
7 7.1 Introduction à la navigation ...........................
204
7.2 Manipuler une ViewStack ..............................
204
7.3 Les contrôles TabNavigator et Accordion ............
215
7.4 Mise en pratique : mon CV en ligne .................
218
7.5 Check-list .................................................
225
Naviguer dans son application C
e chapitre est dédié à la navigation au sein d’une application riche. Les conteneurs de navigations fournis par le framework Flex permettent d’enrichir vos interfaces et de mettre en œuvre des scénarios en fonction des choix de l’utilisateur.
7
Naviguer dans son application
7.1 Introduction à la navigation Vous devriez maintenant avoir un bon aperçu des composants et conteneurs du framework Flex. Cependant, nous n’avons pas encore abordé le problème de la navigation au sein d’une application. En effet, contrairement à un site web standard, une application Flex n’est pas divisée en pages dynamiques distinctes. Le principe se rapproche nettement plus d’une application de bureau classique où tous les composants sont associés à une fenêtre. En MXML, c’est la balise qui représente le conteneur parent et nous y avons jusqu’à présent ajouté des composants toujours affichés. Nous allons aborder dans ce chapitre les composants permettant de fournir un système de navigation afin de guider les utilisateurs dans nos applications. Ce type de composants est très souvent utilisé pour réaliser des processus de validation multi-étapes (panier d’achat ou remplissage de plusieurs formulaires) et permettent d’alléger un écran trop chargé en le décomposant en plusieurs sous-catégories. De manière générale, les conteneurs de navigation permettent de contrôler les actions de l’utilisateur en affichant ou en masquant certains composants de manière à ce qu’un seul et unique conteneur enfant ne soit visible. Vous pouvez d’ores et déjà avoir un aperçu des huit composants de navigation que nous détaillerons dans ce chapitre. Les composants sont accessibles dans Flex Builder 3 dans la catégorie Navigator. c Fig. 7.1 : Composants de navigation du framework Flex
7.2 Manipuler une ViewStack Nous allons utiliser notre premier composant de navigation : le conteneur ViewStack est l’élément le plus simple et le plus générique.
Introduction au composant ViewStack Le composant ViewStack est au cœur du système de navigation dans Flex puisque tous les autres conteneurs de la catégorie en dérivent ou implémentent des méthodes ou propriétés similaires. Comme nous l’avons mentionné plus haut, une ViewStack est un
204
Manipuler une ViewStack
7
conteneur : elle peut donc contenir d’autres objets avec comme particularité de devoir obligatoirement être aussi des conteneurs. Dans le cas contraire, une erreur se produirait à l’exécution du programme. Le diagramme suivant va vous permettre de mieux comprendre le lien entre ces différents contrôles de navigation :
c Fig. 7.2 : Diagramme de classe des contrôles de navigation
En fait, une ViewStack fonctionne de la manière suivante. Le composant stocke en interne une collection de conteneurs enfants qui sont empilés les uns sur les autres (stacked en anglais). La particularité de ce composant est qu’un seul et unique conteneur enfant ne peut être visible à la fois. Il faut ensuite utiliser du code ActionScript (en utilisant les
205
7
Naviguer dans son application
méthodes et propriétés du composant) ou d’autres composants afin de choisir quel conteneur devra être affiché par la ViewStack. L’image suivante schématise des conteneurs encapsulés dans une ViewStack : c Fig. 7.3 : Schéma du fonctionnement d’une ViewStack
Notez également que ce composant adopte certaines propriétés par défaut : j j j
Taille par défaut : une ViewStack adopte la largeur et la hauteur du conteneur affiché par défaut. Redimensionnement : une ViewStack ne change pas de taille lorsque le conteneur actif change, il faut pour cela utiliser la propriété resizeToContent. Positionnement des conteneurs enfants : les conteneurs enfants sont positionnés par défaut dans le coin supérieur gauche de la ViewStack. Si l’un des conteneurs enfants est plus grand que la ViewStack, alors il sera tronqué.
Ajouter une ViewStack dans une application Nous allons maintenant utiliser un composant ViewStack pour stocker plusieurs autres conteneurs de type HBox par exemple. Comme vous vous en doutez, la balise est utilisée pour déclarer ce type de composant : nous la nommerons "myVs". Nous allons placer trois HBox que nous remplirons avec un Label permettant de reconnaître le composant visible. Nous allons également fixer une largeur et une hauteur
206
Manipuler une ViewStack
7
communes à l’exception du dernier élément qui sera plus large de 200 pixels. Nous ajouterons enfin un Spacer puis un second Label pour bien montrer le comportement par défaut d’une ViewStack lorsque le conteneur enfant nécessite une taille supérieure.
Essayez à présent d’ajouter un composant classique dans la ViewStack comme un simple Label par exemple. L’application compile correctement, mais une erreur se produit à l’exécution car le Player ne peut pas forcer un composant de type en conteneur. c Fig. 7.4 : Une ViewStack n’accepte que des conteneurs comme composant enfant.
207
7
Naviguer dans son application
Normalement, votre ViewStack devrait ressembler à ceci :
c Fig. 7.5 : Premier exemple du composant ViewStack
Nous vous l’accordons, pour l’instant, cela n’est guère pratique car nous ne pouvons pas choisir le composant de type HBox à afficher puisque le conteneur ViewStack n’implémente pas de mécanisme de navigation par défaut. Nous allons arranger tout cela en créant une fonction ActionScript qui changera le composant à afficher. Cette fonction utilisera les propriétés des ViewStack. Les plus importantes pour manipuler ce type de composant sont les suivantes : Tableau 7.1 : Propriétés essentielles de ViewStack Propriété
Utilisation
SelectedIndex
Cette propriété donne l’indice du composant actuellement actif (c’est-à-dire visible) s’il y a des conteneurs enfants dans la ViewStack. Les indices des conteneurs commencent à 0 comme tous les tableaux en Flex, et s’il n’y a pas de composant, alors cette propriété a comme valeur -1. Il est également possible d’utiliser cette propriété dans la balise MXML de la ViewStack pour choisir le composant qui sera affiché par défaut de la manière suivante : .
SelectedChild
Cette propriété a un fonctionnement similaire à SelectedIndex ; cependant, c’est ici l’ensemble du composant enfant qui est utilisé au lieu de son indice.
numChildren
Correspond au nombre de composants enfants contenu dans une ViewStack.
Nous allons maintenant ajouter une HBox au-dessus de notre composant ViewStack auquel nous ajouterons un label qui affichera les détails du composant grâce au binding (liaison avec les données) de Flex et une ComboBox que nous nommerons cb_switch et qui sera initialisé avec un tableau de chaînes allant de 1 à 3. Enfin, la méthode ActionScript
208
Manipuler une ViewStack
7
permettant de changer le conteneur sera appelée sur l’événement change de la ComboBox. Voici donc le code à ajouter au-dessus de notre ViewStack :
1 2 3
Relancez l’application puis sélectionnez le conteneur 3 grâce à la liste déroulante. Un ascenseur s’affiche en bas du conteneur car nous lui avons assigné une taille plus large que le composant par défaut (indice 0) qui est le conteneur hb1.
c Fig. 7.6 : Le conteneur 3 est tronqué.
Pour changer ce comportement et redimensionner la ViewStack à chaque changement de conteneur, il suffit d’activer la propriété resizeToContent de la manière suivante :
209
7
Naviguer dans son application
Vous devriez maintenant avoir le conteneur 3 affiché en entier :
c Fig. 7.7 : Le conteneur 3 est affiché en entier.
Manipuler une ViewStack avec les contrôles de type navigation bar Comme vous venez de le constater, une ViewStack seule n’est pas très pratique à utiliser pour une navigation aisée au sein d’une application. En effet, des composants dérivant de cette classe ou implémentant les mêmes propriétés et méthodes lui sont souvent préférés tels que les composants TabNavigator et Accordion que nous aborderons prochainement. Si vous regardez plus attentivement la liste des composant classés dans la catégorie Navigator ou encore le diagramme de classe au début de ce chapitre, vous remarquerez plusieurs composants héritant de la classe NavBar. Nous allons voir les quatre composants suivants en détail : ButtonBar ; ToggleButtonBar ; j LinkBar ; j TabBar. j j
Si ces composants sont classés dans la catégorie Navigator, c’est parce qu’ils permettent tous d’implémenter directement un système de navigation pour le composant ViewStack en spécifiant simplement le dataProvider adéquat (ici le nom de la ViewStack).
Les contrôles ButtonBar et ToggleButtonBar Les contrôles ButtonBar et ToggleButtonBar représentent des groupes de boutons ordonnancés de manière horizontale ou verticale et ayant une apparence commune. La
210
Manipuler une ViewStack
7
principale différence entre ces deux composants vient de leur comportement lorsque l’utilisateur clique sur un bouton du contrôle. Sur un composant ButtonBar, le bouton change d’apparence lors d’un clic puis il reprend son état normal. Le composant ToggleButtonBar, quant à lui, ne revient pas à son apparence initiale et garde l’apparence d’un bouton enfoncé même si l’utilisateur relâche le bouton. Cela permet d’informer l’utilisateur de manière visuelle quel conteneur est actif, lorsque la ToggleButtonBar est utilisée avec un composant ViewStack. Voici à quoi ressemblent visuellement ces deux composants : c Fig. 7.8 : Une ButtonBar
Et voici le code associé :
c Fig. 7.9 : Une ToggleButtonBar
Le code à nouveau est le suivant :
Comme vous pouvez le voir sur l’image précédente, la seule différence notable vient du fait que le composant ToggleButtonBar garde le bouton sélectionné sur l’état enfoncé. Si vous cliquez de nouveau dessus, le bouton reste toujours sélectionné. Pour l’éviter, vous devez modifier la propriété toggleOnClick qui est à false par défaut. Dans ces deux exemples, une valeur a été affectée à la propriété dataProvider ; nous avons passé en paramètre le nom du composant ViewStack que nous avions précédemment déclaré. Les deux composants ont alors créé un bouton pour chaque sous-conteneur de la ViewStack, et leur propriété label a servi pour le texte de chaque bouton. Vous pouvez maintenant utiliser les barres de contrôle pour naviguer très simplement dans votre application. Cependant, les dataProvider des composants ButtonBar ne sont pas limités à la ViewStack ; il est ainsi possible de déclarer ses propres dataProvider en utilisant des tableaux de chaînes ou des tableaux d’objet. Dans ce dernier cas, le composant recherche trois propriétés pour définir les boutons : j j
label : le nom qui sera affiché sur le bouton ; icon : une image à éventuellement inclure avant le label ;
211
7
Naviguer dans son application
j
toolTip : affiche une description au passage de la souris.
Voici donc un petit exemple MXML avec un tableau d’objets décrit de manière statique :
$" + e.hitData.item.Sales + ""; }
Les légendes Vous avez également la possibilité d’ajouter des légendes à vos graphiques. Vous utiliserez à cet effet le composant et vous le lierez au graphique souhaité en indiquant l’identifiant du graphique à l’attribut dataProvider du composant. Le contrôle va chercher les informations dans le graphique pour coller automatiquement les bonnes couleurs aux légendes. Pour que ce contrôle fonctionne, il faut nommer les séries du graphique à légender en utilisant l’attribut displayName. Si vous ne le faites pas, rien ne s’affichera dans la légende. L’exemple suivant montre chaque série avec la propriété displayName qui se lie au label des légendes :
import mx.collections.ArrayCollection; [Bindable] public var expenses:Array = [ {Person: "Pierre", Sport: 6, Reading:1, Tv:4},
317
11
Présenter les données graphiquement
{Person: "Marie", Sport: 2, Reading:6, Tv:3}, ];
Vous obtenez le résultat suivant : c Fig. 11.18 : Le composant Legend
Vous pouvez disposer les éléments de la légende horizontalement en utilisant l’attribut direction avec la valeur horizontal. Modifiez le layout de l’application pour qu’il soit non plus horizontal mais vertical et vous aurez alors ceci : c Fig. 11.19 : La légende horizontalement
318
Interaction avec les graphiques
11
Animer un graphique Supposons que vous vouliez comparer les données de deux sources différentes. Avec Flex, vous pouvez créer des transitions animées d’un graphique à l’autre. Vous verrez que cet effet spectaculaire n’est pas difficile à mettre en place. Pour assimiler ce concept, nous allons prendre un exemple. Nous allons comparer les ventes et les invendus de livres de deux libraires selon les catégories des livres. Commençons par créer un nouveau projet et deux sources de données, une pour chaque boutique. Voici un exemple de ce que vous pouvez écrire : [Bindable] private var {bookCat: {bookCat: {bookCat: {bookCat: [Bindable] private var {bookCat: {bookCat: {bookCat: {bookCat:
bookStats1:Array = [ "Science-fiction", Sales: 250, NoSales:46}, "Drame", Sales: 234, NoSales:56}, "Classique", Sales: 89, NoSales:156}, "Enfant", Sales: 109, NoSales:56} ]; bookStats2:Array = [ "Science-fiction", Sales: 246, NoSales:15}, "Drame", Sales: 52, NoSales:250}, "Classique", Sales: 189, NoSales:56}, "Enfant", Sales: 39, NoSales:15} ];
Ajoutez maintenant un ColumnChart, associez le dataProvider de la première librairie et ajoutez deux séries pour avoir une colonne représentant les ventes et une autre pour les invendus. Vous devriez avoir le code suivant :
Nous voulons maintenant animer notre graphique. Nous avons trois transitions possibles : j
SeriesInterpolate ;
319
11
Présenter les données graphiquement
SeriesSlide ; j SeriesZoom. j
Nous allons commencer par la transition SeriesInterpolate, qui est la plus simple à faire. Juste au-dessus du tag du graphique, rajoutez le tag de la transition, avec un identifiant et une durée de transition, comme le montre le code suivant :
Il faut maintenant lier cette transition aux séries via l’attribut showDataEffect. Les tags des deux séries doivent ressembler à ceci :
Pour que la transition ait lieu, il faut que le dataProvider du graphique change. Nous allons donc rajouter deux RadioButton qui sélectionneront l’une au l’autre des sources de données. Rajoutez finalement le code suivant :
C’est tout ce qu’il y a à faire. Vous pouvez lancer l’application, et vous devriez avoir le résultat suivant :
c Fig. 11.20 : Le graphe s’anime lorsqu’on change de boutique
320
11
Mise en pratique : un module de statistiques
Quand vous sélectionnez un ou l’autre des RadioButton, la source de données du graphique change, provoquant une transition. Le fond du graphique se redimensionne pour coller aux nouvelles valeurs et les colonnes s’animent pour correspondre aux nouvelles valeurs. Pour les deux autres types de transition, il faut opérer de façon légèrement différente car nous aurons besoin de deux effets : un effet pour faire glisser les colonnes dans un sens et un autre effet pour les faire glisser dans l’autre sens. Remplacez le tag SeriesInterpolate par deux tags SeriesSlide comme ceci :
Vous remarquerez que vous devez spécifier en plus cette fois la direction de l’effet : up ou down. L’un permet de faire croître les colonnes tandis que l’autre les fait s’effondrer. Remplacez dans les séries les valeurs des attributs showDataEffect par chartSlideIn et rajoutez à chacun l’attribut hideDataEffect avec la valeur du second effet : chartSlideOut. Vous aurez le code suivant :
Vous n’avez rien d’autre à modifier. Lancez l’application et admirez le résultat : les colonnes existantes disparaissent et les nouvelles augmentent. Pour tester l’effet de zoom des SeriesZoom, remplacez le nom des éléments SeriesSlide par SeriesZoom et supprimez les attributs direction. Toutes les autres fonctionnalités sont identiques ; vous pouvez lancer l’application et voir l’effet de zoom et de dézoom. Comme vous avez pu le constater, créer des effets pour animer des graphiques dans Flex n’est pas compliqué et le résultat est toujours spectaculaire.
11.5 Mise en pratique : un module de statistiques Nous allons réaliser une petite application qui permettra à un libraire de visualiser la croissance des ventes de livres dans ses différentes boutiques ainsi que la répartition des
321
11
Présenter les données graphiquement
catégories d’ouvrages vendus. Nous allons rester simple pour l’exemple et supposer que le libraire n’a que deux boutiques. La première étape, vous la connaissez maintenant, c’est de créer un nouveau projet Flex. Libre à vous de trouver un nom et un emplacement pour ce petit projet. Nous allons commencer par définir les sources de données qu’il faudra présenter graphiquement. Nous utiliserons pour cela deux fichiers XML, un pour chaque boutique. Nous resterons sur des fichiers statiques car c’est plus rapide. Créez un fichier statistiques_paris.xml dans le dossier bin. Nous devons placer ce fichier dans le dossier bin car lorsque vous lancerez l’application, Flex cherchera le fichier dans le répertoire local, autrement dit, le répertoire où se trouve l’application compilée. Votre fichier XML doit avoir la structure suivante :
01/01/2007 34
Science-fiction 55
Complétez ce fichier en rajoutant des données. À cet effet, rajoutez des éléments record avec leur descendance en modifiant les valeurs des éléments enfants. Créez ensuite un second fichier que vous nommerez statistiques_lyon.xml et qui comportera le même schéma mais avec des données différentes. Format des dates Flex s’attend à lire des dates au format américain, qui est différent du format français. Vos dates doivent respecter le format suivant : MM/JJ/AAAA.
Nous allons maintenant entamer le code de notre application. Nous allons dans un premier temps placer les différents éléments. Utilisez judicieusement les conteneurs et positionnez les différents contrôles pour aboutir au résultat suivant dans Flex Builder :
322
11
Mise en pratique : un module de statistiques
c Fig. 11.21 : Le design de l’application dans Flex Builder
Vérifions maintenant que vous avez un code similaire à celui-ci :
Veillez à nommer à l’identique les identifiants des contrôles qui en possèdent. Assurez-vous également que l’un des deux RadioButton ait l’attribut selected à true et qu’ils aient tous les deux un attribut value. Nous allons maintenant lier les données du fichier XML aux graphiques. Nous allons utiliser un HTTPService. Rajoutez le tag suivant dans votre application :
323
11
Présenter les données graphiquement
Rappelez-vous, l’événement result signifie que la méthode setCharts sera appelée à chaque fois que l’on aura fait une requête avec httpService. Nous allons d’ailleurs tout de suite préciser quand nous voulons faire cette requête : la première fois lorsque l’application est lancée, puis à chaque fois que l’on sélectionne une boutique. Rajoutez l’attribut creationComplete au tag Application et l’attribut click aux tags RadioButton avec comme valeur l’appel à la fonction getStats :
…
Voyons maintenant le code des deux fonctions que nous venons de citer. Créez un tag Script et copiez les deux fonctions suivantes :
[Bindable] public var SalesStats:Object; [Bindable] public var CategoryStats:Object; public function setCharts():void { SalesStats = httpService.lastResult.stats.salesstats.stat; CategoryStats = httpService.lastResult.stats.categorystats.stat; } public function getStats():void { httpService.url = "statistiques_"+bookShop.selectedValue+".xml"; httpService.send(); }
La fonction getStats permet de spécifier quel fichier XML nous voulons récupérer en fonction du RadioButton sélectionné. C’est pour cette raison que l’un des deux RadioButton doit être sélectionné dès le lancement de l’application car cette fonction est appelée en tout premier lieu. La fonction setCharts permet de récupérer les données de la requête et de la mettre dans deux variables SalesStats et CategoryStats. Ces deux variables vont être bien entendu les dataProvider de nos deux graphiques. Occupons-nous de notre camembert en premier et de sa légende :
324
11
Mise en pratique : un module de statistiques
Attaquons-nous maintenant à notre AreaChart. Commençons par définir les axes :
Vous remarquerez tout d’abord l’utilisation du tag LinearAxis pour l’axe vertical. Cet usage permet juste de spécifier nous-même l’intervalle de l’axe et d’avoir un axe un peu moins chargé. Vous remarquerez ensuite l’utilisation du tag DateTimeAxis pour l’axe horizontal. Flex va nous faciliter grandement la tâche car ce tag va trier lui-même les données et les placer chronologiquement. Il va également se charger de calculer l’intervalle idéal pour afficher les dates en abscisse. Ainsi, il choisira un affichage par jour, par mois ou par année selon l’étendue des données. Nous allons maintenant nous occuper de la série en la personnalisant quelque peu. Nous allons choisir les couleurs de la courbe et de la surface en dessous de la courbe :
...
325
11
Présenter les données graphiquement
L’application est fonctionnelle. Vous pouvez d’ores et déjà la lancer et vérifier que vous obtenez le résultat suivant :
c Fig. 11.22 : L’application dans votre navigateur Internet
Nous allons rajouter encore quelques petites choses. Tout d’abord, animons ces deux graphes lorsque nous changeons de boutique. Ajoutez à cet effet un tag SeriesInterpolate ainsi que des attributs showDataEffect aux séries des graphiques :
...
...
Modifions également l’affichage des dates qui ne sont pas très esthétiques. Nous allons dans cette optique dire au graphique que nous voulons utiliser notre propre méthode pour afficher la date :
Nous codons finalement notre fonction d’affichage. Rajoutez à présent dans la balise Script le code suivant :
326
Check-list
11
import mx.formatters.DateFormatter; public function dateTimeAxisLabel(cat:Object, pcat:Object, ax:Object):String { var dateFormat:DateFormatter = new mx.formatters.DateFormatter(); dateFormat.formatString = "MMMMMMMMMM DD, YYYY"; return dateFormat.format(cat); }
Nous avons maintenant fini. Voici à quoi ressemble notre application :
c Fig. 11.23 : Amélioration de l’affichage des dates sur l’axe horizontal
Vous maîtrisez maintenant les bases des graphiques dans Flex. Si vous voulez poursuivre l’exercice, utilisez les autres sortes de graphiques tout en gardant les mêmes données.
11.6 Check-list Dans ce chapitre, nous avons vu :
a comment différencier les types de graphiques ; a comment utiliser un composant de Flex Charting ; a comment rendre un graphique interactif ; a comment animer un graphique. Le prochain chapitre abordera le développement d’applications lourdes riches en utilisant la technologie AIR.
327
12 12.1 Passer de Flex à AIR ....................................
330
12.2 Utiliser HTML ............................................
337
12.3 Gérer des fichiers .......................................
344
12.4 Utiliser SQLite ...........................................
352
12.5 Personnaliser ses fenêtres ..............................
357
12.6 Check-list .................................................
361
Utiliser AIR
P
oussée par le succès de Flex, Adobe lance AIR, une nouvelle plateforme basée sur Flex, qui pourrait révolutionner le développement d’applications de bureau. Elle leur apporte ainsi les bénéfices de Flex que vous avez pu découvrir jusqu’à présent en adaptant la technologie aux développement hors du Web. Découvrons à présent quelques points forts de AIR.
12
Utiliser AIR
12.1 Passer de Flex à AIR AIR (pour Adobe Integrated Runtime), anciennement Apollo, est une plate-forme de développement créée par Adobe pour étendre vos RIA à votre Bureau. Cette plate-forme est basée sur les mêmes langages que Flex, à savoir MXML et ActionScript mais également HTML/CSS, AJAX, Flash ou PDF. AIR intègre également une base de données SQLite. Pour faire tourner les applications créées avec le framework AIR, vous aurez besoin du runtime, ou moteur d’exécution. À l’heure actuelle, celui-ci est encore en version bêta mais permet déjà d’exploiter les possibilités de AIR. Les applications que vous pouvez créer sont variées : widgets divers, magasins virtuels, gestionnaires d’album photo ou de documents, éditeur de texte, lecteur multimédia… La partie AIR du laboratoire Adobe propose une galerie contenant de nombreux exemples de ce qu’il est possible de réaliser. Les avantages de cette technologie sont nombreux. Vous bénéficierez d’une gestion du mode Connecté ou Déconnecté très simplement. Vos applications seront portables puisqu’il suffit d’installer le moteur d’exécution pour les lancer (actuellement ce moteur est disponible pour Mac OS et Microsoft Windows). Vous pourrez accéder aux fichiers de votre ordinateur contrairement aux applications Flex. Enfin, vous retrouverez leur style qui est assez design et dans l’air du temps.
Les outils pour utiliser et développer une application AIR La première chose à installer pour utiliser les applications AIR est le moteur d’exécution. Vous le trouverez (en version bêta pour le moment) à cette adresse : http://labs.adobe.com/ downloads/air.html. Il vous permettra d’exécuter les applications dont l’extension est par défaut .air. Une fois le téléchargement terminé, vous pourrez vous lancer dans l’installation guidée : c Fig. 12.1 : Validation de la licence
330
Passer de Flex à AIR
12
c Fig. 12.2 : Installation en cours
c Fig. 12.3 : Fin de l’installation
En moins de trente secondes, vous aurez la possibilité de lancer des applications AIR. Pour le développement à proprement parler, il existe deux méthodes : Flex Builder 3, qui intègre les possibilités du framework AIR, ou le SDK AIR qui installera les binaires nécessaires à la compilation de vos fichiers de code. Il est en effet possible d’éditer vos fichiers avec un éditeur de texte classique et de les compiler en ligne de commande. Comme Flex Builder 3 vous est familier et que son utilisation est beaucoup plus conviviale que la seconde méthode, nous allons uniquement détailler la création de projets AIR avec le logiciel d’Adobe. Flex Builder et AIR Seule la version 3 de Flex Builder permet de créer des projets AIR. Les projets Apollo créés avec Flex Builder 2.0.1 ne sont pas compatibles avec la nouvelle version du framework.
Un projet AIR dans Flex Builder 3 Flex Builder permet de gérer les projets AIR aussi bien que les projets Flex. Vous serez ainsi guidé dans votre développement grâce aux aides, à la complétion et aux diverses
331
12
Utiliser AIR
assistances qui sont fournies à l’utilisateur. Vous pourrez également déboguer comme vous avez appris à le faire précédemment ou utiliser l’éditeur visuel pour embellir votre application. La création d’un projet AIR n’est pas très éloignée de celle d’un projet Flex. 1
Dans le menu, cliquez sur File, New et enfin AIR Project. Vous vous retrouverez face aux fenêtres classiques de création de projet où vous pourrez entrer le nom du projet, AIRTest en l’occurrence : c Fig. 12.4 : Le nom du projet
Et son workspace : c Fig. 12.5 : Le workspace
332
12
Passer de Flex à AIR
2
Continuez ensuite en validant l’étape suivante et vous arriverez sur un écran spécifique à AIR où vous pourrez renseigner des propriétés propres à votre projet :
c Fig. 12.6 : Les propriétés de votre projet 3
Validez la création du projet en cliquant sur Finish afin de valider vos choix. Votre projet est à présent créé et vous pouvez d’ores et déjà le lancer ou le déboguer en utilisant les mêmes boutons qu’avec des projets Flex. Cette fois, votre navigateur ne sera pas utilisé mais une nouvelle fenêtre apparaîtra : c Fig. 12.7 : Application de base
333
12
Utiliser AIR
Dans l’onglet Navigator, vous pouvez observer l’arborescence suivante : c Fig. 12.8 : Arborescence de base d’un projet AIR
Les fichiers qui nous intéressent ici sont les suivants : j j
AIRTest.mxml : c’est le fichier principal de l’application, celui qui sera défini comme fichier d’application par défaut. AIRTest-app.xml : ce fichier XML est inclus dans toutes les applications AIR. Il définit des propriétés de base telles que le nom de l’application, son appID et des caractéristiques liées à la fenêtre. Vous avez pu renseigner certaines de ces propriétés lors de la création du projet.
Observons plus en détail les caractéristiques de notre projet.
Les caractéristiques d’un projet AIR Les fichiers MXML des projets AIR ressemblent à ceux des projets Flex. Néanmoins, ils utilisent de temps à autre des éléments particuliers propres aux applications de bureau. Ainsi, le conteneur de base de votre application sera un . Ce conteneur permet d’avoir un contrôle plus ou moins avancé sur la fenêtre de votre application afin de pouvoir la réduire, l’agrandir, etc. À l’intérieur de ce conteneur, vous pourrez aussi bien déclarer du code ActionScript que faire appel à un fichier externe, ou tout simplement utiliser d’autres objets MXML. Le fichier AIRTest-app.xml, particulier à un projet AIR, est le fichier de description de l’application. Ce fichier, généré par Flex Builder lors de la création du projet, contient les propriétés basiques comme son nom, sa version, un copyright… Ces données serviront à informer l’utilisateur lorsqu’il voudra lancer l’application. Lorsqu’il est créé, le fichier de description contient des commentaires qui vous guident dans son édition. Observons l’architecture du fichier de description de notre projet sans ces commentaires :
334
Passer de Flex à AIR
12
AIR Test
A test project 2007 [SWF reference is generated]
Les balises utilisées sont assez explicites et permettront d’afficher des informations à l’installation par exemple. permet de définir le fichier qui sera chargé en premier par l’application (SWF ou HTML). Laissez la valeur par défaut. L’attribut systemChrome défini à none permettra d’utiliser la gestion des fenêtres d’AIR et d’activer la transparence en définissant transparent à true. Vous pouvez également jouer avec height et width qui sont la hauteur et la largeur par défaut de la fenêtre. Voici votre fenêtre, une fois les modifications effectuées : c Fig. 12.9 : L’application avec la gestion des fenêtres d’AIR
Aux balises déjà présentes, vous pouvez rajouter qui contiendra des balises , , ou . Ces images serviront de miniatures à votre application. permettra de définir des types de fichiers qui seront ajoutés au système lors de l’installation. Le fichier de description de l’application est conservé dans les applications AIR (portant l’extension .air) que vous pourrez trouver et lancer.
335
12
Utiliser AIR
Créer un package AIR La création d’un package AIR permet de diffuser votre application. Le package généré sert à l’installer sur un système disposant du moteur d’exécution. Par défaut, l’installation propose des options comme la création d’un raccourci ou le chemin d’installation et elle est, dans la plupart des cas, suffisante. Dans Flex Builder, la création d’un package se fait très simplement en cliquant dans le menu sur Project puis Export AIR Package…. Vous accédez ainsi à l’écran suivant :
c Fig. 12.10 : Écran de génération de package
Sélectionnez alors le projet AIRTest, l’application principale ; laissez désactivée la possibilité de déboguer puis cochez les fichiers que vous voulez inclure dans le package. Le fichier de description et le SWF sont obligatoires. Validez enfin en cliquant sur Finish et votre package AIRTest.air sera généré. Vous pouvez dès à présent le tester. Double-cliquez sur le fichier qui est apparu dans le navigateur de Flex Builder ou dans votre explorateur de fichiers. Une fenêtre d’installation va apparaître : c Fig. 12.11 : Confirmation de l’installation
336
Utiliser HTML
12
Ignorez les messages d’avertissement et continuez. Vous pourrez alors définir les options d’installation : c Fig. 12.12 : Options d’installation
Une fois l’installation effectuée, vous retrouverez votre application dans votre liste de programmes installés. Vous n’avez donc pas à vous soucier de la phase d’installation pour diffuser votre création ! Les messages avant l’installation Les messages qui vous avertissent, au début de l’installation, de l’authenticité du diffuseur et des risques de sécurité encourus sont dus à la non-signature du paquet. AIR étant en version bêta, il est pour l’instant impossible de signer ses packages. Nous ne savons pour l’instant rien sur la possibilité de le faire et nous devons attendre la sortie de la version finale.
Passons à présent au détail des possibilités proposées par AIR.
12.2 Utiliser HTML Une des possibilités offertes par AIR est d’interpréter du code HTML complexe dans des fichiers SWF. Par complexe, il faut comprendre que les balises HTML classiques sont gérées mais également le code JavaScript, les images et les feuilles de style CSS.
La classe HTMLControl La classe HTMLControl est celle qui prend en charge la gestion du contenu HTML. Elle est basée sur le WebKit, une bibliothèque de fonctions issue du moteur de rendu KHTML
337
12
Utiliser AIR
utilisée dans l’application Konqueror du projet KDE. Ce WebKit était au départ réservé au navigateur de Mac OS X, Safari. Il est à présent utilisé dans de nombreux projets dont celui qui nous intéresse ici : AIR. Vous ne pouvez pas ajouter un HTMLControl directement dans un conteneur. Il faut l’ajouter en tant que fils d’un UIComponent ou d’un objet qui hérite de cette classe. Créez donc une nouvelle application AIRHTMLTest dans votre projet AIRTest. Notez au passage la création automatique d’un nouveau fichier de description AIRHTMLTest-app.xml dans lequel vous allez ajouter les attributs width (800) et height (600) à la balise rootContent. Dans cette application, ajoutez un UIComponent avec l’id componentContainer en mode Design et modifiez-le pour qu’il occupe l’intégralité de votre fenêtre. En mode Source, déclarez un HTMLControl avec l’id htmlControl et instanciez un nouvel objet de ce type dans une fonction initApp. Définissez ensuite les propriétés width et height de htmlControl à 800 et 600. Enfin, ajoutez ce dernier au componentContainer précédemment déclaré en appelant sa méthode addChild. Vous pouvez à présent passer à l’affichage de pages HTML. Le rendu apparaîtra dans votre application. Le chargement d’URL se fait grâce à la méthode load de votre HTMLControl. Elle prend en argument une URLRequest qu’il faut donc préalablement créer. Voici à quoi devrait ressembler votre code pour afficher la page principale de Google :
En lançant l’application, vous devriez obtenir le résultat suivant :
338
Utiliser HTML
12
c Fig. 12.13 : Une page HTML dans votre application AIR
Vous pouvez utiliser d’autres URL que celles de Google pour tester votre application. Vous pouvez notamment essayer des adresses URL sécurisées (https://) ou naviguer dans votre système de fichiers avec file:///c:/ par exemple. app−resource et app−storage sont des chemins prédéfinis qui vous permettent d’accéder au chemin de base de l’application et à son chemin de stockage. Enfin, vous pouvez afficher un document PDF si vous disposez du plug-in Acrobat Reader 8.1 en utilisant un URL pointant vers un PDF. Vérifier que l’utilisateur peut ouvrir un document PDF Pour vérifier que l’utilisateur peut ouvrir un document PDF et ainsi éviter de nombreux désagréments, vous pouvez tester si la propriété statique pdfCapability de la classe HTMLControl est égale à la constante PDFCapability.STATUS_OK.
339
12
Utiliser AIR
Vous pourriez également vouloir afficher une chaîne de caractères contenant du code HTML. Pour cela, il faudra utiliser la méthode loadString en lui plaçant la chaîne en argument : htmlControl.loadString("AIR affiche du HTML !"); c Fig. 12.14 : Votre chaîne HTML
Observons maintenant les possibilités avancées de la classe HTMLControl.
Les possibilités avancées L’historique HTMLControl conserve un historique des pages visitées. Il est donc très simple de naviguer dans l’historique. Vous devrez utiliser les méthodes historyBack et historyForward afin de respectivement revenir en arrière ou avancer dans l’historique. historyLength vous
donnera, comme son nom l’indique, la longueur de l’historique tandis que historyPostion sera la position courante. Il est également possible d’accéder à une position donnée de l’historique en la passant en argument de la méthode historyAt.
Nous allons mettre en application ces possibilités en améliorant notre navigateur. Ajoutez au-dessus du componentContainer une VBox contenant deux boutons : back et forward. Pour chacun d’eux, définissez la propriété click respectivement à htmlControl .historyBack() et htmlControl.historyForward() :
Vous pouvez à présent naviguer dans votre historique :
340
Utiliser HTML
12
c Fig. 12.15 : Navigation dans l’historique
Accéder à des variables contenues dans vos pages Il est possible d’accéder à des variables ou des fonctions déclarées dans du code JavaScript de vos pages HTML. Les éléments HTML sont également accessibles grâce à leur attribut id. Dans l’application AIRHTMLTest, déclarez une variable de type XML contenant du code HTML valide : private var html:String = "" + "" + "" + "Coucou !
" + "" + "”;
Chargez-la dans htmlControl et déclarez ensuite trois labels lbl1, lbl2 et lbl3 qui serviront à afficher l’objet appelé variable, le résultat de fonction et le contenu de toto. Pour changer le texte de ces labels, créez une fonction aff :
341
12
Utiliser AIR
private function aff(e:Event):void { lbl1.text = "variable : " + htmlControl.window.variable; lbl2.text = "fonction : " + htmlControl.window.fonction(); lbl3.text = "idHTML : " + ➥ htmlControl.window.document.getElementById("idHTML").innerHTML; }
L’accès se fait à travers l’objet window du HMTLControl. La variable se récupère grâce à son nom, et l’appel à la fonction se fait comme un appel classique. Pour accéder aux éléments HTML, il faut par contre utiliser l’objet document et sa méthode getElementById. Son contenu se trouve dans la propriété innerHTML. L’événement COMPLETE du HTMLControl Vous ne pourrez pas accéder aux variables avant le chargement complet de la page. Aussi, il faut lui ajouter un EventListener qui fera appel à la fonction aff lorsqu’il enverra l’événement COMPLETE : htmlControl.addEventListener(Event.COMPLETE, aff);. HTMLControl envoie d’autres événements comme uncaughtJavaScriptException si une exception Java n’est pas contrôlée dans la page.
Vous pouvez également modifier les variables auxquelles vous avez accès en leur affectant des valeurs. Le bouton suivant vous permettra de changer le texte contenu dans le paragraphe idHTML :
Voici l’affichage, une fois le bouton cliqué :
c Fig. 12.16 : Modifier les variables
342
12
Utiliser HTML
HTMLControl dans le composant HTML Vous avez sûrement remarqué que lorsque vous redimensionnez la fenêtre de votre application, la taille de votre HTMLControl n’évoluait pas. Pour résoudre ce problème et compléter notre navigateur, nous allons faire appel au composant MXML HTML. Celui-ci contient un objet HTMLControl. Dans une nouvelle application AIRBrowser dont vous fixerez la taille à 1 024 en largeur et 768 en hauteur, créez une VBox contenant les boutons back et forward, une boîte de texte adress qui servira à entrer l’adresse, et un bouton go de validation. Ajoutez ensuite le composant HTML mainPage avec la balise en vous assurant que l’attribut layout de votre WindowedApplication a la valeur vertical. Faites ensuite appel aux méthodes de mainPage.htmlControl pour naviguer dans l’historique. Pour charger une page, vous pourriez bien entendu appliquer ce que nous avons vu jusqu’à présent, mais l’opération en sera simplifiée en passant une chaîne de caractères à la propriété location du composant HTML. Le code d’un navigateur entièrement fonctionnel se réduit à ceci :
c Fig. 12.17 : Votre navigateur AIR
C’est à vous de jouer à présent pour ajouter vos propres fonctionnalités.
12.3 Gérer des fichiers Si, en Flex, il est impossible d’accéder au système de fichiers, principalement pour des raisons de sécurité, il en va autrement pour AIR qui se destine aux applications de bureau. Nous allons voir dans ce chapitre comment sont permises les opérations sur les fichiers et les dossiers.
Les classes pour gérer les fichiers Description des classes AIR fournit aux développeurs plusieurs classes pour gérer les fichiers : j
j j
File : c’est l’objet de base qui représente un chemin vers un fichier ou un dossier. Il sert à initialiser l’interaction avec celui-ci mais aussi à le déplacer, le copier ou le supprimer. FileMode : cette classe définit les constantes qui servent lors de l’ouverture d’un fichier pour déterminer les droits qu’on a sur celui-ci (lecture, écriture, etc.). FileStream : cette classe permet quant à elle d’ouvrir les fichiers afin de les lire ou d’écrire.
Les méthodes proposées par File et FileStream peuvent être synchrones, c’est-à-dire qu’elles vont bloquer l’exécution de votre application pendant leur exécution, ou asynchrones et s’exécuter dans ce cas, en arrière-plan. Nous pouvons alors connaître leur état de retour grâce à des événements.
Les chemins Les deux propriétés de la classe File qui permettent de définir le chemin du fichier ou dossier pointé sont les suivantes :
344
Gérer des fichiers
j
j
12
nativePath : c’est le chemin spécifique à la plate-forme. Sous Windows, ce sera par
exemple c:\\directory\file.txt alors que sous Mac OS, nous utiliserons /directory/file .txt. url : c’est le chemin du fichier. Il utilise des schémas comme file (file://c/directory/ file.txt) ou app−ressource et app−storage déjà rencontré dans la partie précédente.
Pour faire pointer une variable de type File, vous pouvez donc vous contenter de modifier l’une de ces propriétés : var fileVar:File = new File(); fileVar.nativePath = "C:\\";
Cette propriété est équivalente à : var fileVar:File = new File(); fileVar.url = "file://c/";
Les backslashs dans les chemins Veillez à bien doubler les caractères \ dans vos chemins pour définir la propriété nativePath sinon vous risquez d’obtenir des erreurs de chaînes de caractères.
Il existe bien d’autres façons de faire pointer des objets File vers des chemins. Vous pouvez notamment partir des propriétés de File qui pointent vers des répertoires standard : userDirectory : c’est le répertoire utilisateur, sous Vista : C:\Users\userName. j documentsDirectory : c’est le répertoire Mes Documents, sous Vista : j
j j j
C:\Users\userName\Documents. desktopDirectory : le Bureau de l’utilisateur, sous Vista : C:\Users\userName\Desktop. applicationResourceDirectory : le répertoire dans lequel s’exécute l’application. applicationStorageDirectory : le répertoire de stockage de l’application.
À partir d’un de ces répertoires ou tout simplement à partir d’un objet File qui pointe vers un répertoire, vous pouvez utiliser la méthode resolve qui prend en argument une chaîne de caractères. Cette méthode vous donnera, à partir du chemin courant, le chemin complet qui mène au fichier ou répertoire décrit par la chaîne. Voici un petit exemple à partir du fileVar déclaré plus haut :
345
12
Utiliser AIR
fileVar.resolve("fichier.xml").nativePath; // C:\fichier.xml File.documentsDirectory.resolve("fichier.html").nativePath; // ➥ C:\Users\userName\Documents\fichier.html
Les chemins relatifs La chaîne que vous placez en argument peut très bien être un chemin relatif du type ..\fichier.txt ou tout simplement .. pour accéder à un répertoire.
Les boîtes de sélection Enfin, vous pouvez utiliser les boîtes de sélection de répertoires et de fichiers fournies par AIR. Pour les répertoires, il faudra utiliser la méthode browseForDirectory d’un objet File. Le code suivant affichera le chemin du dossier sélectionné dans le Label :
Voici la boîte de sélection : (voir fig. 12.18) D’autres boîtes de sélection sont disponibles pour les fichiers browseForOpen, browseForSave et browseForMultiple qui servent respectivement à choisir un fichier à ouvrir, un fichier à sauvegarder ou plusieurs fichiers. On peut également leur donner des filtres sous forme d’un tableau de FileFilter en second argument. Ces filtres permettent de n’afficher que les fichiers les respectant. Ils se déclarent et s’utilisent ainsi : var filtre:FileFilter = new FileFilter("Desc", "*.ext1;*.ext2"); fileVar.browseForOpen("Sélectionnez un fichier", [filtre]);
346
Gérer des fichiers
12
c Fig. 12.18 : Une boîte de sélection de dossier
Quelques informations Outre nativePath et url, les objets de type File disposent de propriétés intéressantes qu’il est préférable de connaître avant de les manipuler :
j
creationDate : la date de création du fichier (il faut que le fichier ou dossier existe). exists : est à true si le fichier ou dossier existe, à false sinon. extension : donne l’extension du fichier sans le .. icon : renvoie un objet contenant l’icône du fichier. isDirectory : est à true si le chemin est un répertoire, à false sinon. modificationDate : donne la date de dernière modification. name : donne le nom du fichier ou du dossier (sans le chemin). parent : donne le répertoire parent du chemin (est à null si le chemin est à la
j
racine). size : donne la taille du fichier en octets.
j j j j j j j
Nous allons à présent nous intéresser à la manipulation des répertoires.
Manipuler des répertoires Nous allons décrire les diverses méthodes proposées par File pour la gestion des répertoires. Commençons par la création. Elle se fait grâce à la méthode createDirectory :
347
12
Utiliser AIR
var path:File = File.applicationResourceDirectory.resolve("test"); path.createDirectory();
Nous vous conseillons de créer vos répertoires ou fichiers à partir du répertoire de l’application afin d’observer les résultats directement dans l’explorateur de Flex Builder. Ce code crée un dossier test dans le répertoire bin de votre projet (si vous avez conservé bin comme répertoire de compilation). Si le dossier existe déjà, rien ne se passe. Par défaut, tous les répertoires décrits par le chemin sont créés. Vous pouvez ainsi obtenir l’arborescence test/rep1/rep2/rep3 en une seule fois. File permet également la création de dossiers temporaires grâce à createTempDirectory.
Ceux-ci seront créés dans le dossier temporaire de Windows (C:\Users\userName\AppData\Local\Temp sous Vista) avec un nom aléatoire terminé par .tmp. Attention, ces répertoires ne sont pas supprimés à la fermeture de l’application. Vous pouvez lister le contenu d’un répertoire grâce aux méthodes listDirectory et listDirectoryAsync qui est la version asynchrone de la première. Elles retournent un tableau d’objets File pointant sur les éléments du répertoire : var content:Array = File.applicationResourceDirectory.listDirectory();
La suppression de répertoires se fait en appelant les méthodes deleteDirectory ou deleteDirectoryAsync. Elles prennent en argument un booléen optionnel qui, lorsqu’il est à true, permet la suppression de répertoires non vides. Par défaut, ils ne sont pas supprimés. var path:File = File.applicationResourceDirectory.resolve("test"); path.deleteDirectory(true);
Vous pouvez envoyer vos répertoires vers la corbeille au lieu de les supprimer définitivement. Dans ce cas-la, utilisez plutôt les méthodes moveToTrash ou moveToTrashAsync. Enfin, le déplacement ou la copie de répertoires se fait avec moveTo et moveToAsync ou copyTo et copyToAsync. Elles prennent en argument la destination et un argument booléen qui, lorsqu’il est à true, permet le remplacement de répertoires existants à l’emplacement spécifié. var orig:File = File.applicationResourceDirectory.resolve("orig"); var dest:File = File.applicationResourceDirectory.resolve("dest"); orig.moveTo(dest, true);
Nous allons maintenant passer aux fichiers.
348
12
Gérer des fichiers
Gérer les fichiers Manipuler les fichiers Les méthodes de la classe File qui permettent de manipuler les fichiers sont similaires à celles qui gèrent les répertoires. Elles s’appellent à partir d’un objet File dont le chemin est défini. Pour déplacer ou copier des fichiers, vous disposez également de moveTo et moveToAsync ou copyTo et copyToAsync qui prennent en premier argument la destination et en second, un booléen qui indique si la destination doit être écrasée. Utilisez les événements en ajoutant un EventListener pour détecter si votre opération de copie ou de déplacement s’est bien déroulée. L’événement IOErrorEvent.IO_ERROR est ainsi déclenché si une telle opération échoue. Dans le cas contraire, c’est l’événement Event.COMPLETE qui vous servira. Pour supprimer, il faut par contre faire appel aux méthodes deleteFile ou deleteFileAsync. De même que pour les dossiers, il est possible d’envoyer des fichiers vers la corbeille en utilisant moveToTrash et sa version asynchrone moveToTrashAsync. Enfin, il est aussi possible de créer des fichiers temporaires avec la méthode statique createTempFile de la classe File. Elle renvoie un objet File qu’il convient de stocker pour garder le chemin du fichier temporaire. Le fichier n’est pas supprimé à la sortie de l’application.
Lire et écrire des fichiers Pour lire et écrire dans des fichiers, il faut utiliser la classe FileStream. Celle-ci permet l’ouverture des fichiers dans différents modes à partir des chemins définis dans les objets de type File. Afin d’observer leur fonctionnement, nous allons réaliser une nouvelle application dont le but sera de charger ou sauvegarder du texte que l’utilisateur entrera. Commencez donc une nouvelle application et insérez-y une TextArea textTotSave et deux boutons save et load qui feront appel aux méthodes loadFile et saveFile que nous allons définir. Dans du code ActionScript, déclarez deux variables de type File et un FileStream : private var fileSave:File = new File(); private var fileLoad:File = new File(); private var fileStream:FileStream;
Puis la fonction loadFile : private function loadFile():void {
349
12
Utiliser AIR
fileLoad.addEventListener(Event.SELECT, loadText); fileLoad.browseForOpen("Fichier à charger"); }
Cette fonction fait appel à une boîte de sélection pour choisir le fichier à charger et stocker son chemin dans fileLoad. Vous ajoutez un eventListener qui appellera la fonction loadText lors de la sélection d’un fichier : private function loadText(event:Event):void { fileStream = new FileStream(); fileStream.addEventListener(IOErrorEvent.IO_ERROR, printMessage); fileStream.addEventListener(Event.COMPLETE, writeText); fileStream.openAsync(fileLoad, FileMode.READ); }
Dans cette méthode, vous créez un nouveau FileStream qui vous servira à lire le contenu du fichier sélectionné. Ajoutez deux eventListener. Le premier écoute le signal IOErrorEvent.IO_ERROR qui est déclenché lorsqu’une erreur se produit et appelle la fonction suivante : private function printMessage(event:Event):void { Alert.show("Opération interrompue !"); }
Le second réagit lorsque le fileStream sera complètement rempli et appellera alors writeText que nous définirons plus loin. La méthode openAsync est la version asynchrone de open. Elles permettent l’ouverture des fichiers définis par un objet de type File placé en premier argument. Le second argument est le mode d’ouverture du fichier. Ces modes sont définis dans la classe FileMode : j j j j
READ : le fichier est ouvert en lecture seulement. WRITE : le fichier est ouvert en écriture, si le fichier n’existe pas il est créé à
l’ouverture, sinon tout est écrasé. APPEND : le fichier est créé s’il n’existe pas, et dans le cas contraire, l’écriture se fait à la suite. UPDATE : le fichier est également créé s’il n’existe pas, il est ouvert en lecture et écriture et seuls les endroits où l’on écrit sont modifiés.
350
Gérer des fichiers
12
Dans le cas présent, nous ouvrons donc le fichier en lecture seule pour pouvoir l’afficher dans la fonction writeText : private function writeText(event:Event):void { textToSave.text = fileStream.readUTFBytes(fileStream.bytesAvailable); fileStream.close(); }
Elle écrit dans textToSave en récupérant le contenu du flux grâce à la méthode readUTFBytes qui prend en argument le nombre d’octets à lire (ici la taille totale de fileStream). De nombreuses autres méthodes sont disponibles pour lire le contenu des flux en fonction de ce qu’ils contiennent et en fonction de l’encodage. Il est important de fermer le flux en utilisant la méthode close, sans quoi le fichier pourra être indisponible pour les autres programmes. Le bouton save fera, quant à lui, appel à la fonction saveFile : private function saveFile():void { fileSave.addEventListener(Event.SELECT, saveText); fileSave.browseForSave("Fichier à sauvegarder"); }
Elle ouvre une boîte de sélection de fichier pour laisser à l’utilisateur le choix de la sauvegarde. Quand le fichier est sélectionné, la méthode saveText réalise la copie : private function saveText(event:Event):void { fileStream = new FileStream(); fileStream.addEventListener(IOErrorEvent.IO_ERROR, printMessage); fileStream.openAsync(fileSave, FileMode.WRITE); fileStream.writeUTFBytes(textToSave.text); fileStream.close(); }
Nous instancions un nouveau flux puis nous ouvrons le fichier en mode Écriture. Il ne reste alors plus qu’à faire appel à la méthode writeUTFBytes en lui donnant la chaîne de caractères à écrire. Comme pour la lecture, il existe plusieurs méthodes en fonction de ce qu’on veut écrire. N’oubliez pas la fermeture du flux à la fin. Voici donc en quelques lignes un simple éditeur de texte :
351
12
Utiliser AIR
c Fig. 12.19 : Votre éditeur de texte
Passons maintenant à la base SQLite.
12.4 Utiliser SQLite AIR offre la possibilité d’utiliser une base SQLite locale. Le runtime contient en effet un moteur de base de données. Cette base de données locale sera stockée sur l’ordinateur exécutant l’application et pourra servir à la persistance des données de n’importe quel type. Les opérations SQL habituelles sont alors autorisées. Nous allons découvrir dans cette partie comment se servir de cette nouvelle fonctionnalité.
Se connecter à une base La connexion à une base de données est la première opération à réaliser pour accéder à cette possibilité avancée de AIR. Pour pouvoir se connecter, il faut commencer par instancier un objet de type SQLConnection. Utilisez ensuite la méthode open de cet objet. Elle prend en paramètre un objet de type File qui contient le chemin de votre base sur le disque. Vous pouvez également préciser à l’aide d’un booléen si la base doit être créée en cas de non-existence (c’est le cas par défaut). Si vous ne spécifiez aucun argument à la méthode open, la base sera uniquement stockée en mémoire et perdue à la sortie de l’application. La connexion à une base de données est une opération asynchrone. Il vous faudra donc utiliser des événements pour vérifier l’état de la connexion. L’application suivante réalise
352
12
Utiliser SQLite
une connexion à la base de données user.db qui sera créée et stockée dans le répertoire de stockage de l’application. Deux méthodes sont appelées en cas de succès ou d’échec de la connexion :
Les événements SQLErrorEvent.ERROR et SQLEvent.OPEN sont déclenchés respectivement si la connexion échoue ou si elle est ouverte. Voici l’application au démarrage, une fois la connexion ouverte : (voir fig 12.20) Vous pouvez fermer une connexion manuellement grâce à la méthode close. Néanmoins, cela peut s’avérer superflu dans le sens où le runtime ferme toutes les connexions ouvertes lorsque l’application s’arrête. En général, la méthode à suivre est d’ouvrir toutes les connexions nécessaires au lancement de l’application.
353
12
Utiliser AIR
c Fig. 12.20 : Connexion réussie
Créer des tables Votre base est à présent créée mais ne contient aucune donnée. Il va falloir créer des tables afin d’organiser le contenu que vous allez vouloir insérer. Ces tables sont en quelque sorte des schémas qui architecturent les données à l’intérieur de votre base. La création de tables se fait en exécutant une requête SQL comme toute autre opération sur votre base de données. Il faudra donc être un peu familier avec ce langage. Néanmoins, les opérations basiques se font sans trop de difficultés. Intéressons-nous donc d’abord à la création de ces requêtes. Il faut pour cela utiliser un objet SQLStatement. Définissez ensuite la propriété sqlConnection à la connexion que vous avez ouverte préalablement. Écrivez ensuite votre requête dans une chaîne de caractères et associez cette chaîne à la propriété text de votre objet SQLStatement. Vous pouvez ajouter des eventListener pour vérifier l’exécution de vos requêtes. Si vous avez besoin de paramètres, définissez-les dans la propriété parameters qui est un tableau. Enfin, l’exécution se lance avec la méthode execute. Pour créer une table names dans la base user.db précédemment utilisée, il faudra ajouter à la méthode connectionSucceed le code suivant : var statement:SQLStatement = new SQLStatement(); statement.sqlConnection = conn; statement.text = "CREATE TABLE IF NOT EXISTS name(" + "userId INTEGER PRIMARY KEY AUTOINCREMENT, " +
354
12
Utiliser SQLite
"firstName TEXT, lastName TEXT, " + "email TEXT)"; statement.execute();
La table créée contient une clé primaire auto-incrémentée à chaque insertion dans la table, et des champs firstName, lastName et email. Le fait d’exécuter la requête dans connectionSucceed vous permet de vous assurer que la connexion est ouverte. C’est à vous de jouer à présent pour compléter la base en fonction de vos besoins.
Manipuler des données En plus de cette opération de création de tables, vous aurez besoin des opérations d’insertion, de suppression ou parfois de mise à jour. Ces requêtes se réalisent de la même manière que la précédente.
L’insertion Pour l’insertion, il faut utiliser une requête INSERT en spécifiant les champs et leur valeur. Pour ajouter une valeur à la table names, ajoutez un eventListener à la requête permettant la création de la table. Lorsque celle-ci enverra l’événement SQLEvent.RESULT, vous ferez appel à la méthode addElement : private function addElement(event:Event):void { var statement:SQLStatement = new SQLStatement(); statement.sqlConnection = conn; statement.text = "INSERT INTO names(firstname, lastname, email) " + "VALUES (’Toto’, ’Tata’, ’[email protected]’)"; statement.execute(); }
Vous pouvez également ajouter un eventListener pour agir en cas d’erreur, auquel cas il faudra récupérer l’événement SQLErrorEvent.ERROR.
La sélection Pour récupérer des éléments de votre table, il faut utiliser SELECT. Cette méthode va récupérer tous les éléments de votre table names : private function getElement(event:Event):void { statement = new SQLStatement(); statement.addEventListener(SQLEvent.RESULT, getSucceed);
355
12
Utiliser AIR
statement.sqlConnection = conn; statement.text = "SELECT firstName, lastName, email " + "FROM names"; statement.execute(); }
Déclarez au préalable un SQLStatement en global afin d’y accéder dans la méthode getSucceed qui traitera les résultats. Notez que vous pouvez limiter le nombre de résultats de votre requête en spécifiant un argument entier à execute. Pour récupérer la suite des résultats s’il en existe plus que la valeur à spécifier, il faudra faire appel à la méthode next en lui spécifiant une valeur entière. private function getSucceed(event:SQLEvent):void { var result:SQLResult = statement.getResult(); var str:String = ""; for (var i:int = 0; i < result.data.length; ++i) { str += result.data[i]["firstName"] + " " + result.data[i]["lastName"] + " " + result.data[i]["email"] + "\n"; } Alert.show(str); }
La méthode getSucceed appelée lorsque le SELECT réussit, affiche tous les résultats. Vous devrez passer par un objet de type SQLResult qui contiendra vos données. Vous passez ensuite par la méthode getResult de votre requête pour récupérer cet objet.
La mise à jour et la suppression La mise à jour d’éléments présents dans vos tables se fait grâce à un UPDATE tandis que la suppression se fait avec un DELETE. Voici deux exemples de ces requêtes : statement.text = "UPDATE names " + "SET firstName = ’Nono’ " + "WHERE firstName = ’Toto’";
Et : statement.text = "DELETE FROM names " + "WHERE firstName = ’Nono’";
La première va remplacer la chaîne Toto par Nono lorsqu’elle sera trouvée tandis que l’autre va supprimer les rangs dont le champ firstName est égal à la chaîne Nono.
356
12
Personnaliser ses fenêtres
Vous connaissez à présent les fondements de l’utilisation des bases SQL locales dans AIR. Pour plus de détails sur la syntaxe particulière de ce langage, nous vous renvoyons à des documentations spécialisées sur le sujet.
12.5 Personnaliser ses fenêtres AIR, comme Flex, permet aux développeurs un grand contrôle sur l’apparence de ses applications. Celles du premier s’exécutant sur le Bureau de l’utilisateur plutôt que dans un navigateur, il est possible de configurer l’apparence des fenêtres et leur comportement.
Les types de fenêtres Trois propriétés permettent de définir le type de vos fenêtres : type : définit un type de fenêtre (Normal, Utility ou Lightweight). systemChrome : permet de manipuler la fenêtre (standard ou none). j transparent : active ou non la transparence (true ou false). j alpha: à utiliser directement dans la balise du composant WindowedApplication ; j j
cette propriété permet de régler la transparence de votre fenêtre. Dans les types, Normal donne une fenêtre qui utilise les propriétés du système et ses contrôles de fenêtre et elle apparaît dans la barre des tâches. Utility est une version simplifiée disposant de moins de contrôles. Enfin, Lightweight ne dispose pas de contrôle de fenêtre et n’apparaît pas dans la barre des tâches. Ce paramètre se configure à la création d’une nouvelle fenêtre dans du script : public function createNativeWindow():void { var options:NativeWindowInitOptions = new NativeWindowInitOptions(); options.transparent = false; options.systemChrome = NativeWindowSystemChrome.STANDARD; options.type = NativeWindowType.UTILITY; var newWindow:NativeWindow = new NativeWindow(true, options); newWindow.title = "Nouvelle fenêtre"; newWindow.width = 320; newWindow.height = 240; }
Cette fonction crée une nouvelle fenêtre de type Utility, avec un systemChrome standard et sans activer la transparence. Tous ces paramètres se placent en second argument du constructeur NativeWindow. Le premier sert à spécifier si la fenêtre sera directement
357
12
Utiliser AIR
visible. Vous pouvez bien entendu créer votre fenêtre sans la rendre visible tout de suite et le faire le moment venu grâce à la propriété booléenne visible. Vous pouvez spécifier le gestionnaire de fenêtre, c’est-à-dire ce qui va gérer les contrôles du type agrandir, réduire ou fermer. Cette propriété se règle grâce à l’attribut systemChrome de la balise rootContent dans le fichier de description de l’application. Par défaut, une application est créée avec cet attribut à standard, et la fenêtre de votre application utilise alors les contrôles de fenêtre de votre système : c Fig. 12.21 : Une fenêtre basique
Lorsque vous spécifiez que systemChrome doit être à none, il faut alors proposer à la fenêtre un contrôleur. Par défaut, les fenêtres de AIR, à savoir les WindowedApplication, disposent de leur propre contrôleur : c Fig. 12.22 : Une fenêtre avec le contrôleur de AIR
358
Personnaliser ses fenêtres
12
Vous pouvez également activer la transparence pour vos fenêtres. Pour cela, il faut spécifier que l’attribut transparent est à la valeur true. Attention cependant, ce choix n’est disponible que lorsque systemChrome est à none. Voici le résultat après avoir modifié seulement ces deux attributs : c Fig. 12.23 : Une fenêtre avec la transparence activée
Le résultat n’est pas entièrement transparent. Cet effet est seulement activé mais l’image de fond de l’application reste affichée. Pour obtenir une entière transparence, passez par un style dans votre code MXML :
WindowedApplication { background-image:""; background-color:""; }
Voici le résultat : (voir fig. 12.24) À vous de choisir quelle apparence est la plus appropriée pour votre application. Faites néanmoins attention à ne pas perdre vos fenêtres entièrement transparentes.
359
12
Utiliser AIR
c Fig. 12.24 : Une fenêtre transparente et cela se voit !
Gérer les événements des fenêtres Pour réagir à des actions sur une fenêtre, il est possible d’utiliser les événements qu’elle déclenche. Il faut à ce titre ajouter un eventListener à la fenêtre. Pour récupérer la fenêtre principale, procédez comme suit : public function init():void{ var appWindow:NativeWindow = this.stage.window; appWindow.visible = true; }
Cette méthode vous donnera dans la variable appWindow la fenêtre principale. Ajoutez alors votre eventListener comme vous avez maintenant l’habitude de le faire. Les événements à écouter sont les suivants : j j j j j
Event.ACTIVATE ; Event.DEACTIVATE ; Event.CLOSING ; Event.CLOSE ; Event.FOCUS_IN ;
360
Check-list
j j j j j j j
12
Event.FOCUS_OUT ; NativeWindowBoundsEvent.MOVING ; NativeWindowBoundsEvent.MOVE ; NativeWindowBoundsEvent.RESIZING ; NativeWindowBoundsEvent.RESIZE ; NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING ; NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGE.
Tous ces événements permettent d’agir lorsque la fenêtre est déplacée, redimensionnée, ou encore lorsque son focus change. Il reste encore de nombreuses possibilités à découvrir comme le drag-and-drop, la gestion du mode Connecté ou Déconnecté et l’interaction avec d’autres applications. AIR offre de nouvelles possibilités de développement et il ne faut pas oublier que la révision actuelle est une version bêta dont les fonctionnalités sont encore bridées ou non implémentées.
12.6 Check-list Dans ce chapitre, nous avons vu :
a la nouvelle solution d’Adobe pour étendre vos applications riches à votre Bureau ; a comment distribuer vos créations ; a les possibilités de gestion du HTML ; a comment réaliser un navigateur ; a comment manipuler des fichiers et des répertoires sur votre ordinateur ; a comment utiliser la base de données locale SQLite ; a comment personnaliser vos fenêtres. Le prochain chapitre vous fera découvrir des fonctionnalités avancées de Flex.
361
13 13.1 Cairngorm ...............................................
364
13.2 Tests unitaires ............................................
372
13.3 Flex Data Services ......................................
383
13.4 Obtenir de l’aide .......................................
384
13.5 Check-list .................................................
387
Aller plus loin
F
lex n’a plus de secret pour vous à présent, il est donc temps de s’intéresser aux outils et méthodes qui vont vous permettre d’enrichir vos applications et d’accélérer vos développements. Dans ce chapitre nous allons évoquer plusieurs Framework visant à vous simplifier la tâche lors de la mise en place d’une application de grande envergure.
13
Aller plus loin
13.1 Cairngorm À présent que vous maîtrisez les concepts de Flex, vous commencez à réaliser des applications d’une certaine taille. La question de l’architecture va alors se poser : en effet, si une simple arborescence de fichiers avec une séparation de la logique (fichiers ActionScript) et de la présentation (fichiers MXML) paraît suffisante, elle sera rapidement dépassée ! Heureusement, même si Flex ne propose pas de solution embarquée pour ce problème, il existe un framework qui comble admirablement ce vide : Cairngorm. Il le fait si bien que la société à l’origine du projet, iteration::two, a été rachetée par Macromedia en 2006, et le framework fait aujourd’hui partie de la Adobe Engagement Platform.
Le motif de conception modèle vue contrôleur Pour décrire Cairngorm, il faut commencer par une définition de l’architecture modèle vue contrôleur. En effet, c’est sur ce motif de conception que le framework se base et vous devrez bien le connaître pour utiliser intelligemment Cairngorm dans votre application. L’architecture MVC (modèle vue contrôleur) est donc un motif de conception (on parle aussi de design pattern). Son principe est de séparer les données, les traitements et la présentation, ce qui donne trois parties fondamentales dans l’application finale, le modèle, la vue et le contrôleur : Tableau 13.1 : L’architecture MVC Entité
Rôle
Modèle
Le modèle prend en charge la partie "données" de l’application. Cela signifie qu’il englobe la partie récupération des données, mais aussi leur manipulation et leur traitement ; c’est donc le modèle qui prend en charge tous les traitements métier de votre application.
Vue
La vue correspond à l’interface de votre application : typiquement, votre modèle enverra les données brutes à la vue adaptée qui les organisera pour la présentation. Dans un framework comme Ruby On Rails ou Symfony, la vue sera réalisée en HTML. La vue n’effectue cependant aucun traitement, il s’agit simplement d’afficher les données du modèle et de permettre à l’utilisateur d’interagir avec elles.
Contrôleur
Le contrôleur est chargé de faire la liaison entre le modèle et la vue ; il gère donc les événements associés aux interactions de l’utilisateur sur l’interface et les répercute sur le modèle. De la même manière, il renvoie la vue correspondante aux données que l’application souhaite afficher.
364
Cairngorm
13
À présent que nous avons décrit les différents composants de ce motif de conception, voici un petit diagramme expliquant comment ces acteurs interagissent : c Fig. 13.1 : L’architecture MVC
Tâchons de développer sur le cycle de fonctionnement de MVC : j j j j j
L’utilisateur effectue une action (il clique sur un bouton par exemple). Le contrôleur réagit à l’événement, généralement via un listener. Le contrôleur accède au modèle, et déclenche les éventuelles modifications concernant les données. Une vue adaptée utilise le modèle pour modifier l’interface utilisateur. L’interface se met à nouveau en attente d’une nouvelle action.
Si vous avez compris les tenants et aboutissants de l’architecture MVC ainsi que les concepts inhérents à Flex, vous devriez à présent réaliser qu’ils sont faits pour s’entendre. Sinon ne vous inquiétez pas, les prochains paragraphes vont vous éclairer.
L’architecture MVC selon Cairngorm Cairngorm est donc basé sur l’architecture MVC : il a donc pour objectif de faciliter la communication entre le client et le serveur et de garder une séparation. La vue dans Cairngorm est chargée d’envoyer les événements en rapport avec les actions de l’utilisateur ; elle peut aussi être utilisée en liant des données du modèle à ses composants (par exemple grâce au dataProvider). Le modèle est symbolisé par le singleton ModelLocator, qui est utilisé par la vue pour récupérer les données. Ces dernières sont représentées par des Value Objects (VO) ou bien directement par des attributs du ModelLocator.
365
13
Aller plus loin
Cairngorm ne dispose que d’un seul contrôleur, ce qui respecte les normes de MVC 2. Il est chargé de récupérer tous les événements provenant de la vue et de les redistribuer dans les classes chargées de l’intermédiaire avec la partie métier (elles sont appelées classes Command). La classe Command concernée peut alors, selon les besoins, modifier le modèle ou initier une communication avec un serveur distant.
Utiliser Cairngorm dans votre application Cairngorm est disponible sous forme de fichier .swc, et est très simple à utiliser dans votre application. Rendez-vous sur le site Open Source d’Adobe pour télécharger la version binaire. Une fois sur la page dédiée à Cairngorm : http://opensource.adobe.com/wiki/ display/cairngorm/Cairngorm, cliquez sur Download, vous êtes alors redirigé vers la page suivante :
c Fig. 13.2 : Téléchargement de Cairngorm
Un simple clic sur le bouton gauche de la souris sur le lien Cairngorm 2.2.1 Binary suffit pour récupérer l’archive. Maintenant, il faut extraire le contenu de l’archive, de
366
Cairngorm
13
préférence à l’emplacement prévu pour les librairies Flex. Il s’agit simplement d’un répertoire bin contenant le fichier Cairngorm.swc, la version binaire de Cairngorm. Si vous souhaitez utiliser ce binaire dans l’une de vos applications, il n’y a rien de plus simple. Une fois dans Flex Builder, accédez aux propriétés du projet :
c Fig. 13.3 : Propriétés du projet
Puis dans Flex Build Path, rendez-vous dans l’onglet Library Path et cliquez sur le bouton Add SWC... : (voir fig. 13.4) Récupérez le fichier Cairngorm.swc à l’endroit où vous l’avez extrait. Notez que Cairngorm ne se résume pas à un simple binaire, loin de là. En effet, il s’agit d’une solution architecturale, donc vous aurez à faire le plus gros du travail pour adapter votre application. Mais nous allons tenter de clarifier le tout en passant par la mise en pratique.
367
13
Aller plus loin
c Fig. 13.4 : Add SWC
Mise en pratique Mettre en place une application basée sur Cairngorm en partant de rien risquerait de nous prendre trop de temps. Nous allons donc partir d’un exemple concret qui a fait ses preuves depuis un bon moment.
Initialisation Il s’agit d’une petite application de login développée par Alex Uhlmann, l’un des membres de l’équipe Flex au sein d’Adobe. Vous pouvez la récupérer à cette adresse : http://www.alex-uhlmann.de/flash/adobe/blog/cairngormlogin/CairngormLogin.html. Cliquez avec le bouton droit de la souris, puis avec le bouton gauche sur View Source : (voir fig. 13.5)
368
Cairngorm
13
c Fig. 13.5 : Source du projet
Vous noterez le lien en bas à gauche de l’écran Download source : c’est via ce lien que vous pourrez récupérer les sources du projet. Une fois l’archive téléchargée, décompressez son contenu dans un répertoire approprié. 1
Il est temps de créer le projet. Dans Flex Builder, créez donc un nouveau projet nommé CairngormLogin. Une fois le projet créé, commencez par ajouter Cairngorm.swc comme indiqué précédemment.
2
Ensuite, importez les sources téléchargées dans le projet. Cliquez avec le bouton droit de la souris sur le projet, puis avec le bouton gauche, sur Import, puis dans General choisissez File System :
369
13
Aller plus loin
c Fig. 13.6 : Importer les fichiers
3
À présent, récupérez le dossier dans lequel vous avez extrait les sources téléchargées, puis sélectionnez l’ensemble des fichiers : c Fig. 13.7 : Sélectionner les fichiers
4
Lorsque vous cliquerez avec le bouton gauche de la souris sur le bouton Finish, Flex Builder va vous demander si vous souhaitez écraser les sources actuelles. Acceptez en cliquant avec le bouton gauche de la souris sur le bouton Yes.
370
13
Cairngorm
Description des sources Si vous regardez dans le répertoire ajouté à votre projet, vous devriez voir ceci : c Fig. 13.8 : Arborescence du projet
Ce petit tableau devrait vous aider à comprendre cette arborescence : Tableau 13.2 : L’organisation de Cairngorm Dossier
Description
Business
Ce dossier contient la logique nécessaire à l’accès aux données sur un serveur.
Commands
Nous trouvons ici les commandes, à savoir des classes chargées de réagir à un événement précis.
Control
C’est ici que l’on trouve le contrôleur de l’application.
Model
Le modèle de notre application.
View
La vue de notre application.
VO
Stocke les Value Objects, objets métier chargés de représenter les différentes entités présentes dans l’application.
371
13
Aller plus loin
Nous allons maintenant examiner de plus près les fichiers qui constituent cette application : j
CairngormLogin.mxml est le fichier principal de l’application. Il contient une certaine quantité de code, cependant le plus important est l’extrait suivant :
Comme vous pouvez le constater, il s’agit d’un appel à la vue, au composant LoginPanel plus précisément. j
j j
j
j
LoginPanel.mxml est situé dans le dossier view, ici nous constatons que lorsque l’on clique sur le bouton, la méthode loginUser() est appelée ; cette méthode se contente de stocker les informations Username et Password dans un Value Object (VO) et de l’envoyer via un LoginEvent qui sera récupéré par le contrôleur. LoginEvent.mxml, nous voici à présent dans le dossier control : cette classe a pour seul but d’envoyer l’événement au contrôleur de l’application. LoginControl.mxml est le contrôleur frontal. Si vous avez compris le modèle MVC, vous savez qu’il s’agit de la classe chargée de récupérer les événements et de déclencher la réponse appropriée. Il effectue cette tâche grâce à la méthode addCommand(). LoginCommand.as est situé dans le dossier commands. Chaque commande doit implémenter la fonction execute() ; son but dans cet exemple est d’accéder au serveur pour vérifier les informations entrées. Cependant, vous devez encore passer par la classe Delegate chargée d’accéder au serveur. LoginDelegate.as, que vous trouverez dans le répertoire business, est chargé de la "plomberie" qui accède au serveur. Pour cette démonstration, il ne fait que déclencher un petit temps d’attente.
Vous avez vu, grâce à cet exemple, comment s’organise une application basée sur Cairngorm. Si vous pensez que votre application s’adapte à ce concept, n’hésitez pas à l’utiliser, car il vous aidera à garder un code clair et organisé tout au long du développement.
13.2 Tests unitaires Même si la notion de tests reste assez peu répandue dans le monde du développement web, elle tend à se démocratiser, notamment grâce à des frameworks comme Ruby On Rails ou Symfony.
372
Tests unitaires
13
Nous allons tâcher d’expliquer le concept de tests unitaires afin de comprendre leur utilité dans le cadre d’une application Flex. Nous introduirons ensuite le framework de tests unitaires développé pour Flex : FlexUnit. Cette introduction sera suivie d’une mise en pratique dans le cadre d’une application.
Le principe des tests unitaires Tout le monde comprend facilement l’intérêt de tester une application, cependant la majorité des développeurs ont pris l’habitude de réaliser des batteries de tests généraux une fois l’application terminée. Cette pratique soulève des inconvénients, car si l’un des tests échoue, trouver la cause de cet échec peut parfois se révéler pénible, surtout lorsque l’on travaille sur une application d’envergure. Afin de remédier à ce problème, le principe de test unitaire a été inventé. Il s’agit en fait d’une pratique qui consiste à tester séparément chaque partie d’une application, afin de vérifier qu’elles fonctionnent toutes correctement. Une partie est le plus petit morceau possible d’une application pouvant être testé ; cette définition peut vous sembler vague mais le concept vous paraîtra limpide lorsque nous passerons à la pratique. Les intérêts de cette pratique sont multiples. Tout d’abord du point de vue de la maintenance : en effet, comme chaque segment de notre application est indépendant et testé de manière autonome, vous pourrez facilement modifier une classe ou une fonction et vous assurer que le morceau d’application concerné fonctionne encore. Le test unitaire permet aussi de réduire, voire de faire disparaître, le besoin de tests d’intégration lors de la phase finale de développement ; dans la mesure où chaque morceau de l’application a été testé, leur réunion ne pose en général pas de problème. Enfin, le test unitaire fournit une véritable documentation de l’application : en parcourant rapidement les différents tests, vous comprendrez l’utilité d’un morceau de code. Si les tests ont été bien pensés, toutes les fonctionnalités de l’application devraient apparaître de manière évidente. Ce type de documentation possède l’avantage de toujours être à jour, dans la mesure où la réussite des tests en dépend, contrairement à la documentation classique qui doit être mise à jour continuellement pour correspondre à la réalité. Une fois que vous maîtriserez la pratique des tests unitaires, vous pourrez étudier des pratiques attenantes, tel le développement piloté par les tests, qui consiste à écrire les tests pour ensuite développer le module qui les passera avec succès. Ce concept fait partie intégrante de la méthode agile appelée eXtreme Programming (XP), qui devient de plus en plus populaire dans le développement web, tant elle réduit le temps de développement d’applications évoluées.
373
13
Aller plus loin
FlexUnit Avec la démocratisation de la pratique des tests unitaires, est apparu le besoin d’outils permettant d’automatiser ce processus. Les développeurs en langage Java qui lisent ces lignes connaissent peut-être JUnit, une librairie de tests unitaires facile à intégrer et disposant d’une interface permettant de voir en détail le résultat des batteries de tests. Partant de cet exemple, un groupe de développeurs a lancé un projet équivalent mais conçu pour fonctionner avec Flex : FlexUnit (logique, n’est-ce pas ?). Ce framework est en fait une librairie ActionScript 3.0 qui propose toutes les fonctionnalités d’un JUnit avec en prime une interface de présentation des tests en… Flex bien sûr ! Cette particularité vous permet d’intégrer l’interface de présentation directement dans votre application, facilitant ainsi l’accès aux résultats de vos batteries de tests. Nous allons à présent récupérer l’archive contenant tout le nécessaire pour utiliser FlexUnit. Tout comme Cairngorm, FlexUnit est maintenant disponible sur le site Open Source d’Adobe à l’adresse http://opensource.adobe.com/wiki/display/flexunit/FlexUnit. Une fois sur la page dédiée au projet, téléchargez l’archive en cliquant sur le lien suivant :
c Fig. 13.9 : Téléchargement de FlexUnit
Ensuite, ouvrez l’archive. Nous allons examiner son contenu et vous devriez voir en principe l’arborescence suivante :
374
Tests unitaires
13
c Fig. 13.10 : L’archive
Nous avons donc trois répertoires distincts, mais deux seulement vont retenir notre attention. Le premier, bin, contient la librairie FlexUnit sous forme binaire : c’est un fichier SWC qu’il suffira d’ajouter à notre projet pour pouvoir profiter des fonctionnalités du framework. Le second dossier, asdocs, contient la documentation, et nous allons examiner son contenu. Commencez par extraire le contenu de l’archive dans le dossier de votre choix (un dossier dédié aux librairies Flex serait l’idéal), naviguez ensuite dans le dossier asdocs, et vous devriez voir les fichiers suivants : c Fig. 13.11 : La documentation
375
13
Aller plus loin
Ouvrez le fichier index.html : vous accédez alors au sommaire de la documentation, qui est une documentation d’API standard. Essayons de la décrire pour ceux d’entre vous qui consultent pour la première fois ce type de documentation :
c Fig. 13.12 : Index de la documentation
La documentation s’ouvre sur la liste des packages qui constituent la librairie FlexUnit. Cliquez à présent sur le package flexunit.framework : (voir fig. 13.13) Vous voyez maintenant les différentes interfaces et classes qui constituent le package. Chacun de ces éléments est détaillé de la manière suivante : (voir fig. 13.14)
376
Tests unitaires
13
c Fig. 13.13 : Détails du framework
c Fig. 13.14 : Détails d’une classe
377
13
Aller plus loin
Ici, vous voyez donc l’ensemble des méthodes disponibles pour la classe concernée avec leurs signatures ainsi qu’une description de leur utilité. Notez que si vous désirez accéder directement à une méthode, il vous suffit de consulter l’index :
c Fig. 13.15 : Index de la documentation
Vous avez ici accès à tous les packages, classes, méthodes et attributs de la librairie FlexUnit.
Mise en pratique Nous allons à présent passer à la pratique. Voyons comment mettre en place cet outil de tests dans une application, puis nous verrons l’utilisation des tests et enfin le fonctionnement de l’interface d’affichage des résultats.
378
13
Tests unitaires
Mise en place du projet Commencez par créer un projet appelé USDConvert. Vous êtes capable à présent de créer un projet Flex les yeux fermés. Un petit détail cependant : cette fois, nous souhaitons lui adjoindre la librairie FlexUnit. Lors de la création du projet, arrivé à la dernière étape, rendez-vous dans l’onglet Library path, cliquez avec le bouton droit de la souris sur le bouton Add SWC…. Une fenêtre va alors s’ouvrir ; sélectionnez le fichier flexunit.swc et appuyez sur OK. Ouvrez à présent le fichier USDConvert.mxml, vous devriez voir ceci :
À présent, pour pouvoir utiliser les composants de la librairie, il faut ajouter son préfixe dans la balise Application de la manière suivante :
Le but de notre application va être d’écrire une classe ActionScript qui effectue la conversion de dollars en euros et vice versa.
Initiation de FlexUnit Pour commencer, il va falloir mettre en place le TestRunner, qui est l’entité chargée d’effectuer les tests et d’afficher leurs résultats. Commencez donc par ajouter le composant suivant :
Compilez votre application, et vous devriez obtenir le résultat suivant : (voir fig. 13.6) Le résultat est tout à fait sympathique. Bien sûr, pour le moment, votre application ne fait rien, mais vous pouvez déjà observer le TestRunner qui se compose d’une barre de progression, d’une grille affichant les tests et d’une barre de recherche. Pour faire fonctionner l’ensemble, il va cependant falloir ajouter un peu de "plomberie", sous forme de code ActionScript 3. Ce code peut être placé directement dans le MXML via une balise Script ou bien dans un fichier .as séparé selon votre préférence.
379
13
Aller plus loin
c Fig. 13.16 : Le TestRunner
D’abord, vous devez déclarer une fonction chargée de créer les tests : private function createSuite():TestSuite { var ts:TestSuite = new TestSuite(); ts.addTest( CashConverterTest.suite() ); return ts }
Dans un premier temps, vous allez créer une nouvelle batterie de tests, une TestSuite, puis vous lui ajouterez des tests en utilisant la méthode addTest() ; CashConverterTest correspond à la classe de test que nous allons créer, elle porte ce nom car elle a pour but de tester la classe CashConverter que nous allons également créer. Vous allez ensuite utiliser la fonction onCreationComplete() pour initialiser et lancer les tests : private function onCreationComplete(){ testRunner.test = createSuite(); testRunner.startTest(); }
Enfin, n’oubliez pas d’ajouter la ligne suivante au début de votre code ActionScript : import flexunit.framework.TestSuite;
Création des classes ActionScript Vous démarrez avec la classe CashConverter qui va renfermer la logique de notre application (une logique assez simple, rassurez-vous). Créez donc cette classe dans votre projet :
380
Tests unitaires
13
package { public class CashConverter { public static function toDollar(euros:int):int { return euros * 1.38; } public static function toEuro(dollars:int):int { return dollars / 1.38; } } }
Cette classe se compose de deux fonctions : l’une effectue la conversion en dollars, l’autre en euros. Il ne reste plus qu’à la tester. À cet effet, nous allons créer la classe CashConverterTest qui va s’en charger : package { import flexunit.framework.TestCase; import flexunit.framework.TestSuite; public class CashConverterTest extends TestCase { public function CashConverterTest( methodName:String ) { super( methodName ); } public static function suite():TestSuite { var ts:TestSuite = new TestSuite(); ts.addTest( new CashConverterTest( "testToDollar" ) ); ts.addTest( new CashConverterTest( "testToEuro" ) ); return ts; } /** * Ensures the Euro to Dollar conversion works as expected. */ public function testToDollar():void { var Euro:int = 100;
381
13
Aller plus loin
var Dollar:int = CashConverter.toDollar( Euro ); assertTrue( "Egal à 138 dollars", Dollar == 138 ); } /** * Ensures the Dollar to Euro conversion works as expected. */ public function testToEuro():void { var Dollar:int = 138; var Euro:int = CashConverter.toEuro( Dollar ); assertTrue( "Egal à 100 euros", Euro == 100 ); } } }
Il n’y a là rien de bien de sorcier : les fonctions testToDollar() et testToEuro() sont chargées de tester les fonctions de la classe CashConverter, et la fonction suite() met en place la batterie de tests. Le point le plus important est l’utilisation de la fonction assertTrue() : cette fonction, spécifique à FlexUnit, vérifie l’égalité proposée, mais vous pouvez également utiliser assertFalse(), assertNull(), etc. L’ensemble des fonctions proposées est disponible dans la documentation de la classe Assert.
Le résultat Vous pouvez à présent lancer votre application et admirer le résultat :
c Fig. 13.17 : Le résultat des tests
Comme vous le constatez, les tests sont passés sans difficultés. Notez que si un test venait à échouer, les raisons de cet échec seraient affichées sur chaque tests.
382
LiveCycle Data Services et BlazeDS
13
13.3 LiveCycle Data Services et BlazeDS Avant de parler du système de gestion de données proposé par Adobe pour Flex, une petite mise au point s’impose : vous n’aurez sans doute jamais besoin de cette solution, visant particulièrement un public de professionnels. De plus, sa mise en place contraignante et son prix élevé (plus de 10 000 Q) en font un produit réservé aux applications les plus évoluées. Notez cependant qu’une version Open source est disponible sous le nom de BlazeDS. BlazeDs est en réalité un sous ensemble (un peu moins complet) de LiveCycle DataServices et propose notamment les fonctionnalités les plus pertinentes telles que le remoting ou encore le datapush. BlazeDs est disponible sur le site Open Source d’adobe au même titre que Cairngorm et FlexUnit : http://opensource.adobe.com/wiki/display/ blazeds/BlazeDS. Au cours des prochains paragraphes, nous allons évoquer les trois composants qui forment Data Services, à savoir RPC (Remote Procedure Call), Data Management Service (disponible seulement avec LiveCycle DataServices) et Messaging Service. Chacun de ces éléments propose des fonctionnalités complémentaires visant à rendre une application Flex plus puissante, plus rapide ou simplement à en simplifier le développement.
Remote Procedure Call Les RPC sont utilisés pour accéder à des données distantes il s’agit en fait de créer un composant ActionScript chargé d’appeler un service distant et de récupérer les données envoyées par ce service. Grâce à ce composant, l’application peut exécuter des requêtes asynchrones et récupérer les données directement prêtes à être traitées. Les RPC disponibles sont les suivantes : j j j
HTTP URL, représenté par le composant HTTPService, qui utilise les méthodes POST et GET. Service web, représenté par le composant WebService, qui est compatible avec le protocole SOAP. Objet Java, représenté par le composant RemoteObject, qui permet d’accéder directement à un objet sur le serveur.
Si HTTPService et WebService sont des composants disponibles directement dans Flex, l’utilisation de LiveCycle Data Services vous donne accès à un grand nombre de fonctionnalités indispensables pour une entreprise, telles que la configuration de proxy, l’identification, la gestion d’une liste noire ou encore la gestion centralisée des RPC.
383
13
Aller plus loin
Le composant RemoteObject n’est quant à lui disponible qu’avec LCDS et BlazeDS : il permet de mapper les classes ActionScript en calquant directement les classes métier Java situées sur le serveur. Au lieu de passer par un service web, l’application accède directement aux objets sur le serveur grâce à un fichier de configuration chargé de renseigner le mapping.
Data Management Cet artefact propose un grand nombre de fonctionnalités permettant d’enrichir la gestion des données dans votre application Flex. Vous pouvez ainsi gérer la synchronisation de données, la pagination automatique et bien d’autres options qui feront rentrer votre application dans une nouvelle dimension. Le service permet enfin de gérer les données complexes, liées par des relations 1-n ou n-n (si cela ne vous dit rien, n’ayez crainte, il s’agit de concepts évolués pour l’architecture de bases de données).
Messaging Le service appelé Messaging repose sur les RPC et le Data Management pour offrir un système d’envoi de messages en temps réel, suivant les principes d’un chat. Via un composant MXML, l’application se charge de traiter, de véhiculer et de recevoir les messages. Le client de messagerie est compatible avec d’autres technologies, comme par exemple Java et son JMS (Java Message Service).
13.4 Obtenir de l’aide Il vous sera indispensable de compulser les différentes sources d’aides et de tutoriels dédiés à Flex 2 lors de vos nombreux développements. Pour vous faciliter la tâche, nous allons à présent établir une liste des sites les plus complets : vous pourrez les consulter si vous ne trouvez pas la solution à l’un de vos problèmes dans cet ouvrage.
L’aide officielle À l’instant où nous écrivons ces lignes, l’aide officielle de Flex n’est disponible que dans la langue de Shakespeare. Autant dire que si vous ne comprenez rien à l’anglais, vous risquez d’avoir du mal à trouver des sources d’aide satisfaisantes. Évoquons rapidement l’aide officielle. Elle est disponible au sein du Flex Builder bien sûr, mais également sur Internet via le site d’Adobe.
384
Obtenir de l’aide
13
c Fig. 13.18 : L’aide de Flex Builder
c Fig. 13.19 : L’aide en ligne
385
13
Aller plus loin
Dans l’ensemble, cette aide est assez complète, les tutoriels se révèlent notamment très utiles pour un débutant.
Le forum Adobe Flex Flex, comme tous les produits Adobe, dispose de son forum sur le site d’Adobe. Rendez-vous à l’adresse http://www.adobe.fr/, et dans l’onglet Communautés sélectionnez Forums. La liste suivante apparaît :
c Fig. 13.20 : Les forums de produits
Sélectionnez Flex. Vous accédez alors à l’espace dédié à Flex et à ses produits dérivés :
386
Check-list
13
c Fig. 13.21 : Les forums Flex
Comme vous le remarquerez, il existe un forum dédié à chaque aspect de la suite Flex. Mais encore une fois, ces forums sont réservés aux anglophones. N’hésitez surtout pas à poser toutes les questions qui vous tourmentent : les réponses sont en général rapides et de qualité, dans la mesure où la question n’est pas trop rebattue, cela dit.
13.5 Check-list Dans cet ultime chapitre, nous avons vu : a comment appréhender le concept de modèle MVC ; a les principes régissant le fonctionnement de Cairngorm ; a quand et comment utiliser le framework de tests unitaires FlexUnit ; a les fonctionnalités proposées par la solution LiveCycle Data Services ES ; a où trouver de l’aide en cas de souci. Les annexes vous proposent à présent une webographie ainsi qu’une série de conseils à compulser consciencieusement.
387
14 14.1 Webographie ...........................................
390
14.2 Antisèches ...............................................
392
14.3 Glossaire .................................................
405
Annexes
C
es annexes proposent une liste de sites web dédiés à la technologie Flex. Vous trouverez toutes les réponses à vos questions en parcourant cette Webographie. Le reste du chapitre est consacré aux antisèches, qui vous permettront, en cas de trou de mémoire, de rapidement vous remémorez un détail de fonctionnement de Flex. Enfin le glossaire fournit une définition pour chaque terme technique utilisé dans cet ouvrage.
14
Annexes
14.1 Webographie Il est probable qu’une fois les bases de Flex maîtrisées, vous allez vouloir en savoir plus. Afin de faciliter votre démarche, voici une liste des sites indispensables pour tout Flexeur.
Sources officielles Tout d’abord, voici tous les sites officiels en rapport avec le framework Flex ; vous trouverez ici les sections intéressantes du site Adobe, ainsi que les sites des outils évoqués dans cet ouvrage.
Adobe http://www.adobe.com/fr/
Le site officiel d’Adobe, dans sa version française. C’est toujours pratique de l’avoir sous la main si vous utilisez un des produits Adobe. http://www.adobe.com/fr/products/flex/
La partie du site dédiée à Flex : vous y trouverez les dernières informations concernant Flex et ses produits dérivés. http://www.adobe.com/support/documentation/en/flex/
Documentation en ligne de Flex. En plus d’être consultable partout, elle est richement commentée par les utilisateurs et les développeurs, ce qui devrait vous aider à répondre aux problèmes courants. http://www.adobe.com/devnet/flex/
Voici le Developer Center : il contient tous les articles récemment écrits sur Flex, un bon nombre de tutoriels et d’exemples ainsi qu’une liste impressionnante de composants développés par des utilisateurs. Une véritable mine d’informations. http://www.adobe.com/cfusion/webforums/forum/index.cfm?forumid=60
Le forum officiel dédié à Flex et ses produits dérivés : vous y trouverez bon nombre de solutions à des problèmes courants. Vous pouvez également poser des questions si vous avez épuisé toutes les sources d’aide.
390
Webographie
14
Adobe Labs http://labs.adobe.com/
Le laboratoire Adobe fourmille de produits dans leur phase de développement, notamment le Flex Builder 3. Si vous êtes un peu curieux, n’hésitez pas à naviguer sur le site : vous trouverez sans doute d’excellents outils que personne n’utilise pour le moment. http://labs.adobe.com/technologies/air/
Voici la page dédiée à AIR sur le laboratoire. Vous trouverez donc toutes les innovations qui feront le futur de cette technologie. http://labs.adobe.com/technologies/flex/
Voici la page dédiée à Flex sur le laboratoire. Vous trouverez donc toutes les innovations qui feront le futur de ce framework. http://labs.adobe.com/wiki/index.php/Cairngorm
Cette partie du site est dédiée à Cairngorm : c’est la source officielle d’informations concernant le framework. À suivre donc avec attention si vous utilisez cette solution.
FlexUnit http://code.google.com/p/as3flexunitlib/
Le site officiel du framework FlexUnit. Il s’agit en fait du groupe Google associé au projet ; il est à visiter régulièrement pour être au courant des dernières mises à jour.
Communauté http://flex.org/
Un site anglophone au contenu impressionnant, qui nous tient au courant de l’actualité des différentes communautés Flex, et qui propose des centaines d’exemples et de tutoriels réalisés par les Flexeurs du monde entier. http://www.cflex.net/
Un autre site particulièrement bien documenté et qui a la particularité de proposer un ensemble de conseils triés par niveau. Du débutant à l’expert. http://flexbox.mrinalwadhwa.com/
FlexBox est un concept intéressant. Il s’agit d’une application Flex présentant sous forme de bibliothèque un très grand nombre de composants développés par la communauté Flex.
391
14
Annexes
Flex en France http://www.fdeshayes.net/
Le blog référence dans le monde des RIA en France. Vous y trouverez des informations régulièrement mises à jour sur Flex, AIR et toutes les autres technologies révolutionnaires dans le domaine du Web. http://flex.mediabox.fr/
Seul forum français disponible à l’heure actuelle. Il est hébergé par une société spécialisée dans la formation sur les produits Flex. Vous y trouverez donc une aide fiable en cas de problèmes. http://fr.wikipedia.org/wiki/Adobe_Flex
Vous connaissez certainement Wikipédia, la plus grande encyclopédie disponible en ligne. Voici donc la page française dédiée à Flex. Elle n’est pas très fournie pour le moment, mais ne la perdez pas de vue car il est probable que la situation évolue rapidement.
14.2 Antisèches Voici quelques rappels de ce que vous avez appris dans ce livre. Pensez à y jeter un œil en cas de doute.
Les composants Voici tout d’abord un petit résumé des composants à connaître ; ils sont triés par famille. Le but n’est pas d’établir une liste exhaustive des composants proposés par Flex 2, mais simplement de vous donner des pistes si jamais vous aviez un doute quant au composant à utiliser.
Les contrôles : mx.controls Boutons Button
392
Antisèches
14
c Fig. 14.1 : Exemple de bouton
Bouton
LinkButton
c Fig. 14.2 : Exemple de lien
Lien
PopUpMenuButton
Bouton déroulant c Fig. 14.3 : Exemple de bouton déroulant
RadioButton
c Fig. 14.4 : Exemple de bouton radio
393
14
Annexes
Bouton radio
Contrôles textuels Label
c Fig. 14.5 : Exemple de label
Label
RichTextEditor
Éditeur de texte c Fig. 14.6 : Exemple d’éditeur de texte
Text
394
Antisèches
14
c Fig. 14.7 : Exemple de texte
Texte
TextArea
Zone de texte c Fig. 14.8 : Exemple de zone de texte
TextInput
Champ de saisie c Fig. 14.9 : Champ de saisie
Les autres Image
Image c Fig. 14.10 : Exemple d’image
395
14
Annexes
DateChooser
Calendrier c Fig. 14.11 : Exemple de calendrier
Les conteneurs : mx.containers Les boîtes HBox
Boîte horizontale c Fig. 14.12 : Exemple de boîte horizontale
VBox
396
Antisèches
14
Boîte verticale c Fig. 14.13 : Exemple de boîte verticale
Panel
Panneau c Fig. 14.14 : Exemple de panneau
Form
Formulaire
c Fig. 14.15 : Exemple de formulaire
397
14
Annexes
La navigation Accordion
Accordéon c Fig. 14.16 : Exemple d’accordéon
TabBar
Dossiers Factures Contacts
Barre de navigation c Fig. 14.17 : Exemple de barre de navigation
ViewStack
398
Antisèches
14
Pile d’écrans Le composant ViewStack se contente d’empiler les pages qu’il comporte. Il est utilisé de concert avec un autre composant de navigation pour permettre de parcourir ses différents écrans.
Les RPC : mx.rpc HTTPService Déclaration
Utilisation
WebService
Les graphiques : mx.charts Nous allons nous contenter de présenter les graphiques les plus utilisés.
PieChart
399
14
Annexes
Le camembert c Fig. 14.18 : Le camembert
LineChart
Les courbes c Fig. 14.19 : Les courbes
400
Antisèches
14
ColumnChart
Les bâtons c Fig. 14.20 : Les bâtons
Les validateurs : mx.validators Nombre
Chaîne de caractères
Date
401
14
Annexes
Adresse e-mail
Numéro de téléphone
Les propriétés Voici une petite liste des propriétés à connaître absolument. Elles sont souvent communes à plusieurs composants, et vous n’aurez de cesse de les utiliser dans vos développements.
Les basiques j j j j
id : l’identifiant du composant, essentiel pour pouvoir faire référence au composant dans l’application. label : le texte qui habille le composant, généralement un bouton ou bien un mx:Label. text : similaire au label mais utilisé pour les entrées de texte, typiquement mx:TextInput. dataProvider : utilisé pour peupler un tableau, une grille, un arbre, etc.
Taille et position x, y : la position du composant, renseignée en pixels. j width, height : la taille du composant, renseignée en pixels ou en pourcentage, en j
fonction de la taille du composant père.
Styles Les styles sont les mêmes que vous utilisez déjà dans vos feuilles de style CSS. Notez que vous pouvez parfaitement les utiliser directement dans le composant sous forme de propriétés, mais nous vous conseillons vivement de déclarer des feuilles de style à part pour améliorer la lisibilité de votre code et l’homogénéité de votre interface.
Événements j j
click : déclenché par un clic sur le bouton gauche de la souris. change : déclenché dès que le composant subit une modification.
402
Antisèches
j j j
14
keyUp, keyDown : déclenchés respectivement lorsque l’on appuie et lorsque l’on
relâche une touche du clavier. focusIn, focusOut : déclenchés respectivement lorsque l’on entre dans un champ de saisie et lorsque l’on en sort. creationComplete : déclenché lorsque le composant est créé, ce qui est indispensable pour effectuer diverses initialisations.
Utiliser ActionScript Voici les deux méthodes pour utiliser ActionScript.
Dans le code MXML Un petit exemple de fichier MXML :
Dans un fichier séparé À présent, un appel à un fichier ActionScript :
AIR Voici ce que vous devez retenir à propos de AIR.
Manipuler les fichiers Vous créez le fichier :
403
14
Annexes
var file:File = File.documentsDirectory; file = file.resolve("Tests/test.txt");
Vous l’ouvrez : var stream:FileStream = new FileStream( ); stream.open(file, FileMode.WRITE);
Vous écrivez : stream.writeUTFBytes("Bonjour");
Et vous fermez : stream.close();
Utiliser HTML Pour appeler une page HTML dans votre application Apollo, rien de plus simple ; vous n’avez qu’à ajouter :
Et voilà.
Personnaliser la fenêtre Dans le fichier application.xml, ajoutez : main.swf
Puis dans votre application :
Et vous obtenez une fenêtre transparente du plus bel effet.
404
Glossaire
14
14.3 Glossaire ActionScript Le langage de programmation derrière la technologie Flash, aujourd’hui disponible dans sa version 3.0. Il se rapproche des langages de script orientés objet tels que JavaScript et se base sur la norme E4X (ECMAScript for XML). Classe Spécifique aux langages objet, il s’agit de la structure qui sert de moule pour créer des objets. Client Dans le monde du Web, le terme client désigne en général le navigateur Internet de l’utilisateur. Ce terme vaut pour une application riche (RIA ou RDA) et l’on parle également de client léger pour une interface web et de client lourd pour une interface sur le Bureau. Composant Il s’agit des briques de base du framework Flex, chacune étant en réalité un objet ActionScript utilisable clé en main par le développeur. Conteneur Ce terme désigne les composants Flex chargés de la mise en place de l’interface, ces composants contiennent généralement d’autres composants, d’où leur nom. Contrôle Les contrôles quant à eux sont les composants Flex avec lesquels l’utilisateur interagit, comme par exemple un bouton. CSS, Cascading Style Sheet C’est un langage déclaratif basé sur XML et permettant de définir la disposition et l’apparence des balises HTML, ou, dans le cas de Flex, des composants dans l’interface. Déboguer Le principe de débogage est simple, il s’agit d’effectuer des tests afin de débusquer, puis de corriger, les bugs d’une application. Espace de noms (voir : Namespace)
405
14
Annexes
E4X ECMAScript for XML est la norme sur laquelle repose le langage ActionScript 3.0. Il s’agit de la même norme que le langage JavaScript avec une gestion native du format XML (parcours et modification de la structure d’un document XML) ce qui facilite la gestion de la communication entre Flex et le serveur. Événement Lorsque l’utilisateur navigue sur un site web ou une application Flex, il effectue des actions qui sont répercutées grâce aux événements afin d’être traités. Un clic de souris ou une frappe de clavier déclenchent un événement. Flash Player Plugin développé par Adobe qui peut être installé sur tous les navigateurs du marché, il permet d’exécuter des applications Flash au sein du navigateur et donc doit être nécessairement installé par l’utilisateur pour exécuter une application Flex. Ce plugin est installé sur plus de 97% des machines connectées à Internet. Fonction Ensemble de commandes visant à être répétées et qu’on a donc regroupées sous un seul nom. Lors de l’appel, des paramètres peuvent être adjoints pour enrichir la fonction. Firefox Navigateur web Open Source, développé par la fondation Mozilla, il est aujourd’hui l’un des principaux acteurs du marché. Il s’affirme comme étant le seul concurrent sérieux d’Internet Explorer. Framework C’est un ensemble de bibliothèques et d’outils, capable d’interagir pour assurer le développement rapide d’applications. Il peut être logiciel, comme Flex, ou architectural, comme Cairngorm. HTML, Hypertext Markup Language C’est le langage utilisé pour créer les pages qui constituent un site web. Il est basé sur XML et utilise des balises qui sont interprétées graphiquement par le navigateur web. Internet Explorer Navigateur web développé par Windows, il est aujourd’hui leader dans la mesure où il est utilisé par la moitié des ordinateurs dans le monde. Sa suprématie est cependant remise en question avec la croissance de produits Open Source comme Firefox.
406
Glossaire
14
JavaScript Langage de script interprété par les navigateurs web, il permet d’ajouter une logique basique aux pages statiques HTML. Il est cependant critiqué, notamment à cause des variations d’interprétation selon les navigateurs. Méthode Fonction attachée à un objet particulier. Elle est définie dans une classe. MVC, Modèle Vue Contrôleur C’est une méthode de conception architecturale qui consiste à séparer l’affichage des données dans une application, le contrôleur agit comme intermédiaire. MXML Bien qu’aucune terminaison exacte n’ait été fournie, on pourrait l’appeler Macromedia eXtensible Markup Language dans la mesure où il a été créé par Macromedia dans le cadre du framework Flex. Il s’apparente à HTML mais propose plus de fonctionnalités. Namespace, Espace de noms Il s’agit d’un ensemble d’objets apparentés regroupés de manière à simplifier la compréhension d’une application. Objet Entité composée de variables et de méthodes, il s’agit du concept de base dans le cadre d’un langage objet. Package Structure regroupant plusieurs objets ou méthodes sous une forme modulaire et réutilisable. RIA, Rich Internet Application Ce nouveau terme à la mode désigne les nouveaux sites web qui tendent à se rapprocher des applications de bureau dans leurs fonctionnalités. RPC, Remote Procedure Call Protocole regroupant les services permettant d’appeler des procédures sur un ordinateur distant. Serveur Machine chargée d’effectuer des opérations répondant aux requêtes des clients connectés.
407
14
Annexes
Serveur web Serveur particulier dédié au traitement des requêtes HTTP et à l’affichage de sites web. Service web Plus généralement appelé Web Service, il s’agit d’un utilitaire chargé de répondre à des requêtes prédéfinies. Il peut s’agir d’une simple opération ou bien d’une réponse plus évoluée comme la météo. SOAP, Simple Object Access Protocol C’est un protocole de RPC basé sur XML, il est utilisé dans un grand nombre d’échanges sur Internet. SWF, Small Web Format Format de fichiers graphique vectoriel développé par Adobe. Il s’agit du format binaire permettant au Player Flash du navigateur d’exécuter l’animation ou l’application. C’est le format de sortie d’une application Flex une fois la compilation réussie. URL, Uniform Resource Locator Chaîne textuelle représentant l’adresse d’un fichier sur le Web. Validateur Contrôles Flex chargés de s’assurer de la validité des informations entrées par l’utilisateur dans une forme. Ils peuvent vérifier qu’il s’agit bien d’un nombre, d’un e-mail ou encore d’un numéro de téléphone. XML, eXtensible Markup Language Langage informatique générique basé sur un ensemble de balises enchevêtrées. Il est à la base d’un grand nombre de langages actuels, notamment HTML et MXML.
408
INDEX
A Accolades en MXML, 156 Accordion, 215, 398 ActionScript, 48, 189, 405 ActionScript 3.0, 20 Adobe Integrated Runtime (AIR), 22, 32, 330 AIR, 22, 330 AIR Debug launcher, 32 Apollo, 330 package, 336 AltKey, 136 Amazon, 291 AMF3, 290 AnimateProperty, 229 Apollo, 330 Application, 99 ApplicationControlBar, 102 Arborescence du SDK, 32 Flex Builder 3, 32 projet Flex, 38 Architecture, 364 AreaChart, 306 As, 61 Attributs, 70 Axes, 312
B Balises fermantes, 41 BarChart, 307 Binding, 156 Blur, 229 Boolean, 59 Booléen, 59 Breakpoint, 81
410
Bubble Chart, 308 Button, 392 ButtonBar, 210
C Cairngorm, 364 Canvas, 97, 107 Cascading Style Sheet (CSS), 242, 405 Chaîne de caractères, 59 Change, 133 Chargement dynamique, 270 des données XML, 270 Chemins relatifs, 346 Classes, 69, 405 Clavier, 135 codes, 135 événements, 133 Client, 405 Codes clavier, 135 ColdFusion, 30, 290 ColumnChart, 307, 401 ComboBox, 178 Command, 366 Compiler, 44 Complétion Flex, 41 Comportement, 228 Composant, 90, 405 Conteneur, 96, 405 d’agencement, 96 Contenu d’une variable, 83 Contraintes, 112 ControlBar, 101 Contrôles, 405 avancés, 178 Image, 115 Contrôleur, 364 Conversion du texte en nombre, 231
INDEX
Convertisseur de devises, 138 CreationComplete, 133 CSS, 242, 405 CtrlKey, 136 CurrencyFormatter, 168
D Data binding, 156 Data Management, 384 Data model, 146 Data models, 146 DataGrid, 180 DataTips, 315 DateChooser, 396 DateFormatter, 168 Dates, 59 DateTimeAxis, 325 Déboguer, 405 Deep Linking, 256 Design Pattern, 364 Devises, 138 DispatchEvent, 137 Dissolve, 229 DividedBox, 103 Do while, 67 Document PDF, 339 Données formater, 168 récupération, 270 valider, 161 Drag and Drop, 252 Drag initiator, 252 Drag proxy, 252 Drag source, 252 DragEvent, 256 DragManager, 256 DragSource, 256
Drop target, 252 Drop-in, 246 Duration, 235
E Ebay San Dimas, 17 Eclipse, 26 ECMAScript, 48 Effet, 229, 234 EmailValidator, 402 Encodage des bundles, 264 End, 233 Entier, 59 non signé, 59 Error, 133 Espace de noms, 184, 407 Événements, 128, 228, 406 clavier, 133 clavier-souris, 136 Event, 128 EventDispatcher, 129 EXtensible Markup Language (XML), 408 Extreme programming, 373
F Fade, 229 Fault, 287 FaultEvent, 285 File, 346 Firefox, 406 Flash, 273 Flex Builder 3, 26 arborescence, 32 installer, 27
411
INDEX
Flex Builder et AIR, 331 Flex Charting, 304 Flex Data Services, 383 FlexPrintJob, 260 FlexUnit, 373-374, 391 Fonction, 406 For, 66 For each in, 66 For in, 66 Form, 397 Formater les données, 168 Formulaire, 146 validateur, 163 Forum, 386 Adobe Flex, 386 Framework, 406
G GetChildAt, 92 GetChildByName, 92 Glow, 229 Graphiques, 315 Grid, 104
H Harley Davidson Customizer, 17 Hbox, 97, 396 HDividedBox, 103 Héritage, 74 Historique, 256 HorizontalAxis, 313 HorizontalList, 178 HTML, 406 HTMLControl, 337 HTTPService, 274, 279, 383, 399
412
Hypertext Markup Language (HTML), 406
I Id, 91 IDE, 26 If else, 67 Image, 395 Importation d’images à l’exécution, 115 Imprimer, 260 Inclusion, 270 Inline, 130, 244, 246 Int, 59 Interfaces, 73 Internationalisation, 263 Internet Explorer, 406 Iris, 230 Is, 61 Item Editor, 244 Item Renderer, 244
J Java Runtime Environnement, 32 JavaScript, 407 Joost, 17
L Label, 394 Layout, 99 Légende, 317 Licence, 22 LineChart, 308, 400 LinkBar, 212
INDEX
LinkButton, 393 List, 178 Listener, 129 LiveDragging, 104 Load, 287
M Maître-détail, 190 Messaging, 384 Méthode, 72, 186, 407 drop-in, 245 Mode Debug, 78 Design, 42 Source, 39 Model, 149 Modèle, 364 stockage des modèles, 151 Modèle Vue Contrôleur (MVC), 146, 158, 364, 407 ModelLocator, 365 Module de statistiques, 321 Move, 230 MVC, 146, 158, 364, 407 selon Cairngorm, 365 Mx Binding, 158 Script, 188 XML, 151 MXML, 20-21, 38, 407 accolades, 156
N Namespace, 55, 184, 407 Navigateur Firefox, 406
Navigator, 36 Nombre, 59 Not a Number, 59 Null, 60 Number, 59, 231 NumberFormatter, 168 NumberValidator, 401 NumChildrend, 208 NumericStepper, 246
O Objet, 407 programmation orientée objet, 68 Opérateurs courants, 65
P Package, 55, 407 AIR, 336 Panel, 99, 397 Pause, 230 PDF, 339 PhoneFormatter, 168 PhoneNumberValidator, 402 PieChart, 304-305, 399 Play, 233 Player Flash et la sécurité, 273 PlotChart, 308 Point d’arrêt, 79, 81 ajout, 82 Popfly, 17 PrintJob, 260 Profiler, 45 Programmation orientée objet, 68 Propriétés, 186
413
INDEX
R RadioButton, 393 Récupération de données, 270 Remote Procedure Call, 383, 407 RemoteObject, 290, 383 Resize, 230 ResourceManager, 263 Result, 287 ResultFormat, 279 Resume, 83 Rich Internet Application (RIA), 15, 26, 407 avantages, 16 RichTextEditor, 394 Rotate, 230 RPC, 383, 407
S Sandbox, 273 Scroll, 133 SDK, 26 arborescence, 32 Sécurité du Player Flash, 115 SelectedChild, 208 SelectedIndex, 208 SelectedItem, 179 SerieInterpolate, 319 Séries, 310 Serveur, 407 web, 408 Service Oriented Architecture (SOA), 285 Services web, 286, 408 web et HTTPService, 289 ShiftKey, 136 ShowTarget, 237
414
Simple Object Access Protocol (SOAP), 286, 408 Small Web Format, 408 SOAP, 286, 408 Sony Phone Selector, 17 SoundEffect, 230 Spacer, 102 SQLConnection, 352 SQLite, 352 SQLStatement, 354 StartDelay, 235 Statistiques, 321 Step Into, 83 Step Over, 83 Step Return, 83 Stockage des modèles, 151 String, 60 StringValidator, 401 Style, 242-243 StyleManager, 243 Suspend, 83 SWF, 44, 408 Switch, 68
T TabBar, 214, 398 Tableaux, 59 TabNavigator, 215 Terminate, 83 TestRunner, 379 Tests unitaires, 372-373 TestSuite, 380 Text, 394 Text Controls, 117 TextArea, 395 TextInput, 395 This, 92
INDEX
Tile, 106 ToggleButtonBar, 210 Trace, 85 Transitions, 238, 241 Tree, 181 Triggers, 228
U UIComponent, 338 Uint, 60 Undefined, 60 Uniform Resource Locator (URL), 408 URL, 408 URLKit, 260 Use-network, 116
V Validateur, 401, 408 dans un formulaire, 163 prédéfinis, 161 Validators, 401 Valider des données, 161 Value Objects, 365 Variable, 83 VBox, 97, 396 VDividedBox, 103 View states, 238 ViewStack, 204, 398
Void, 60 Vue, 364
W WebService, 383, 399 While, 67 WipeDown, 230 WipeLeft, 230 WipeRight, 230 WipeUp, 230 Workspace, 35 Wsdl, 287
X XML, 408 chargement dynamique, 270 Mx, 151
Y Yahoo ! Maps, 17
Z ZipCodeFormatter, 168 Zoom, 230
415
Composé en France par Jouve 11, bd de Sébastopol - 75001 Paris