Vous êtes sur la page 1sur 416

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 Support technique :
20-22, rue des Petits-Hôtels Également disponible sur www.microapp.com
75010 PARIS http://www.microapp.com
Tél. : 01 53 34 20 20
Fax : 01 53 34 20 00

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 1678
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.
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 gras : menu, commande, boîte de dialogue, bouton, onglet.
j italique : zone de texte, liste déroulante, case à cocher, bouton radio.
j Police bâton : instruction, listing, texte à saisir.
j ➥ : 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 Créer son premier projet avec Flex 25

1.1 Initiation à Flex Builder 3 ................................................... 26


Flex Builder 3 et Eclipse ...................................................... 26
Installer Flex Builder 3 ........................................................ 27
Comprendre l’arborescence du dossier d’installation .................. 32
Présentation de l’environnement de développement ................... 33
1.2 Créer sa première application ............................................ 34
Création d’un nouveau projet ............................................... 35
Comprendre l’arborescence d’un projet Flex ............................ 38
MXML ............................................................................ 38
Mode Source .................................................................. 39
Mode Design .................................................................. 42
1.3 Compiler une application Flex ............................................ 44
Du MXML au SWF ............................................................ 44
Fichiers générés ................................................................ 44
1.4 Check-list ....................................................................... 45

2 Découvrir l’ActionScript 3.0 47

2.1 Démarrer avec ActionScript dans Flex Builder ....................... 48


Créer l’application Flex ...................................................... 48
Le code ActionScript dans vos fichiers MXML ........................... 49
Le code ActionScript dans des fichiers séparés ......................... 52
Importer du code ActionScript dans un fichier MXML .................. 54
2.2 Les bases de la programmation .......................................... 55
Les packages et namespaces ............................................... 55
Les types de données et les variables ...................................... 59
Les fonctions et opérateurs ................................................... 62
Les boucles et conditions ..................................................... 66
2.3 La programmation orientée objet dans ActionScript ................ 68
Les avantages de la programmation orientée objet .................... 68
Les classes ...................................................................... 69
Les interfaces ................................................................... 73
L’héritage ........................................................................ 74
2.4 Déboguer de l’ActionScript 3.0 dans Flex Builder .................. 77
Création d’une application Flex utilisant ActionScript .................. 77
Le mode Debug ................................................................ 78
Ajouter un point d’arrêt ....................................................... 79
Le pas à pas .................................................................... 83
Afficher le contenu d’une variable .......................................... 83
Sommaire

La fonction trace ............................................................... 85


Corriger les erreurs ............................................................ 86
2.5 Check-list ....................................................................... 87

3 Réaliser sa première interface 89

3.1 Les composants MXML ...................................................... 90


Définition d’un composant ................................................... 90
Travailler avec les contrôles Flex ............................................ 91
Différencier les composants ................................................. 93
Utiliser un composant en MXML et en ActionScript ..................... 94
3.2 Les conteneurs d’agencement ............................................. 96
Comprendre l’utilité des conteneurs ....................................... 96
Maîtriser les conteneurs primordiaux : HBox et VBox .................. 97
Reconnaître les cadres d’utilisation des autres conteneurs
d’agencement .................................................................. 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 ....................................................... 113
Utiliser Flex Component Explorer pour appréhender
les contrôles simples ........................................................ 113
Afficher des images ......................................................... 114
Utiliser les Text Controls ..................................................... 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

4 Gérer les événements 127

4.1 Introduction aux événements ............................................ 128


Comprendre le flux des événements ..................................... 128
À propos de l’objet Event .................................................. 128
La classe EventDispatcher .................................................. 129
4.2 Utiliser les événements .................................................... 129
Utiliser les événements inline .............................................. 130
Utiliser les événements dans le code ..................................... 130
Manipuler l’objet Event ..................................................... 131
Les événements à connaître ............................................... 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
4.4 Créer ses propres événements .......................................... 137
La méthode dispatchEvent() ................................................ 137
Déclencher un événement en MXML ..................................... 138
Personnaliser votre événement ............................................ 138
4.5 Mise en pratique : un convertisseur de devises ..................... 138
Mise en place du projet .................................................... 139
L’interface ..................................................................... 139
Mettre en place la logique métier ........................................ 140
Associer la logique à l’interface avec MXML .......................... 141
Associer la logique à l’interface avec ActionScript ................... 142
4.6 Check-list ..................................................................... 143

5 Gérer les données 145

5.1 Définir un data model ..................................................... 146


Création d’un formulaire ................................................... 146
La balise <mx:Model> ...................................................... 149
La balise <mx:XML> ......................................................... 151
Les modèles basés sur du script ........................................... 152
Les modèles basés sur des classes ActionScript ....................... 153
5.2 Lier des données ............................................................ 156
Les accolades en MXML ................................................... 156
Utiliser du code ActionScript dans les accolades ..................... 157
La balise <mx:Binding> en MXML ....................................... 158
Plusieurs sources ou plusieurs destinations .............................. 159
Lier des données en ActionScript ......................................... 160
5.3 Valider des données ....................................................... 161
Les validateurs prédéfinis ................................................... 161
Utiliser des validateurs dans un formulaire .............................. 163
Personnalisation de la validation ......................................... 166
5.4 Formater les données ...................................................... 168
Utiliser les formateurs de base ............................................ 168
Récupérer les erreurs de formatage ...................................... 169
Formater à l’intérieur d’une liste de données ........................... 170
5.5 Travailler avec XML ........................................................ 171
Accéder aux éléments ...................................................... 171
Modifier les données ....................................................... 173
Créer ou assembler des objets XML ..................................... 175
5.6 Check-list ..................................................................... 175
Sommaire

6 Aller vers une interface riche 177

6.1 Les contrôles avancés ..................................................... 178


Les List, les HorizontalList et les ComboBox ............................ 178
Les DataGrid ................................................................. 180
Les Tree ........................................................................ 181
6.2 Créer ses propres composants .......................................... 182
Un nouveau conteneur racine pour les composants MXML ......... 182
Utilisons nos nouveaux composants ..................................... 184
La création de composants en ActionScript ............................ 189
ActionScript vs MXML pour la création de nouveaux composants . 189
Pourquoi créer ses propres composants ? .............................. 190
6.3 Mise en pratique : une interface maître-détail ...................... 190
Qu’est-ce qu’une interface maître-détail ? .............................. 190
Mise en place du projet .................................................... 191
Le découpage du projet .................................................... 191
Le module maître ............................................................. 192
Le module détail ............................................................. 197
L’assemblage des deux modules ......................................... 199
6.4 Check-list ..................................................................... 201

7 Naviguer dans son application 203

7.1 Introduction à la navigation ............................................. 204


7.2 Manipuler une ViewStack ................................................ 204
Introduction au composant ViewStack .................................. 204
Ajouter une ViewStack dans une application .......................... 206
Manipuler une ViewStack ................................................. 210
Dimension des conteneurs enfants ....................................... 214
7.3 Les contrôles TabNavigator et Accordion ............................ 215
Le composant TabNavigator .............................................. 215
Le composant Accordion ................................................... 216
Navigation au clavier ...................................................... 217
Ajouter des boutons pour faciliter la navigation ....................... 218
7.4 Mise en pratique : mon CV en ligne ................................... 218
Création du projet ........................................................... 219
Ajout d’un composant de navigation .................................... 221
Ajout des informations ...................................................... 221
Mise en forme et design .................................................... 222
Résultat final .................................................................. 222
7.5 Check-list ..................................................................... 225
Sommaire

8 Personnaliser son application 227

8.1 Utiliser les comportements ............................................... 228


Comment fonctionnent les comportements ? ........................... 228
Les effets disponibles dans Flex ........................................... 229
Appliquer les comportements aux composants ........................ 230
8.2 Ajouter des effets ........................................................... 234
Retarder le lancement d’un effet .......................................... 234
Combiner plusieurs effets .................................................. 234
Créer son propre effet d’apparition ...................................... 236
8.3 ViewStates et transitions .................................................. 238
Mettre en œuvre les ViewStates .......................................... 238
Appliquer des transitions ................................................... 241
8.4 Styliser l’interface .......................................................... 242
La balise <mx:Style> ........................................................ 243
Les classes de style .......................................................... 243
Le StyleManager ............................................................. 243
Le style inline .................................................................. 244
8.5 Item renderers et editors ................................................. 244
Utiliser des renderers et des editors en méthode drop-in ............. 245
La méthode inline ............................................................ 246
Quels sont les composants Flex qui peuvent servir de renderer ou
d’editor ? ...................................................................... 247
Utiliser des items renderers et editors complexes ...................... 248
8.6 Check-list ..................................................................... 249

9 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) ............................ 256
Pour quoi faire ? ............................................................. 256
Comment ça marche ? ..................................................... 257
Concrètement ? .............................................................. 257
9.3 Impression .................................................................... 260
9.4 Internationalisation ........................................................ 263
Faire une application localisée pas à pas .............................. 263
Mettre autre chose que des objets string dans les ressources ....... 266
Charger les fichiers de langue à l’exécution ........................... 267
9.5 Check-list ..................................................................... 267
Sommaire

10 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 ................................................................. 274
Récupération de données via une requête http ........................ 275
Utiliser le binding ............................................................ 280
Récupérer les résultats de manière événementielle .................... 281
Gérer les erreurs ............................................................. 283
10.3 Services web ................................................................ 285
Utiliser des services web de type SOAP ................................ 286
Appeler des méthodes distantes .......................................... 287
Passer des arguments aux méthodes de services web ............... 287
Différence d’utilisation entre service web et HTTPService ........... 289
10.4 RemoteObject ............................................................... 290
10.5 Mise en pratique : une application avec Amazon ................. 291
10.6 Check-list ..................................................................... 301

11 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 ..................................... 305
Le PieChart .................................................................... 305
L’AreaChart ................................................................... 306
Le ColumnChart et le BarChart ........................................... 307
Le LineChart ................................................................... 308
Le BubbleChart et le PlotChart ............................................ 308
11.3 Mettre en forme les graphiques ......................................... 309
Les données ................................................................... 309
Les séries ...................................................................... 310
Les axes ........................................................................ 312
11.4 Interaction avec les graphiques ......................................... 315
Les bulles d’information ..................................................... 315
Les légendes .................................................................. 317
Animer un graphique ....................................................... 319
11.5 Mise en pratique : un module de statistiques ........................ 321
11.6 Check-list ..................................................................... 327
Sommaire

12 Utiliser AIR 329

12.1 Passer de Flex à AIR ....................................................... 330


Les outils pour utiliser et développer une application AIR ............ 330
Un projet AIR dans Flex Builder 3 ........................................ 331
Les caractéristiques d’un projet AIR ...................................... 334
Créer un package AIR ...................................................... 336
12.2 Utiliser HTML ................................................................ 337
La classe HTMLControl ..................................................... 337
Les possibilités avancées ................................................... 340
HTMLControl dans le composant HTML ................................ 343
12.3 Gérer des fichiers .......................................................... 344
Les classes pour gérer les fichiers ......................................... 344
Manipuler des répertoires ................................................. 347
Gérer les fichiers ............................................................. 349
12.4 Utiliser SQLite ............................................................... 352
Se connecter à une base ................................................... 352
Créer des tables ............................................................. 354
Manipuler des données .................................................... 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

13 Aller plus loin 363

13.1 Cairngorm ................................................................... 364


Le motif de conception modèle vue contrôleur ......................... 364
L’architecture MVC selon Cairngorm .................................... 365
Utiliser Cairngorm dans votre application .............................. 366
Mise en pratique ............................................................ 368
13.2 Tests unitaires ................................................................ 372
Le principe des tests unitaires .............................................. 373
FlexUnit ........................................................................ 374
Mise en pratique ............................................................ 378
13.3 LiveCycle Data Services et BlazeDS ................................... 383
Remote Procedure Call ..................................................... 383
Data Management .......................................................... 384
Messaging .................................................................... 384
13.4 Obtenir de l’aide ........................................................... 384
L’aide officielle ............................................................... 384
Sommaire

Le forum Adobe Flex ........................................................ 386


13.5 Check-list ..................................................................... 387

14 Annexes 389

14.1 Webographie ............................................................... 390


Sources officielles ............................................................ 390
Communauté ................................................................. 391
Flex en France ................................................................ 392
14.2 Antisèches .................................................................... 392
Les composants .............................................................. 392
Les propriétés ................................................................. 402
Utiliser ActionScript .......................................................... 403
AIR .............................................................................. 403
14.3 Glossaire ..................................................................... 405

15 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 un environnement efficace pour l’exécution du code, du contenu et des
communications ;
j une intégration accrue dans un environnement commun pour le contenu, les
communications et les interfaces homme-machine ;
j un modèle objet puissant et facilement extensible pour l’interactivité ;
j 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 ;
j la possibilité de réaliser des applications connectées et déconnectées ;
j une distribution facilitée en supprimant les besoins d’installation et de
développements spécifiques aux différentes plates-formes visées.

16
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 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.
j 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.
j Un langage de style intégré qui reprend les spécifications de CSS 1 (Cascading Style
Sheet).
j Une interface événementielle de manipulation de document basée sur la
spécification 3 du DOM écrite par le W3C.

20
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 Comment les applications Flex doivent être construites (et dans quels cas il n’est pas
pertinent de choisir cette solution).
j Les relations entre les objets MXML et les objets ActionScript et comment utiliser
chacun d’eux.
j Bien connaître les composants fournis par Flex, comment les manipuler et créer les
vôtres.
j Les différents moyens d’interagir avec le serveur pour traiter les données.
j 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 un compilateur intégré ;
j une gestion des versions ;
j un débogueur interactif ;
j un assistant de mise en page ;
j une complétion automatique et une détection d’erreurs dans le code ;
j 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 un plug-in ;
j 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.
1 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

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 une version standalone pour Mac ou Windows comprenant Eclipse et le plug-in
Flex intégré ;
j 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 1

4 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 d’installation (typiquement C:\Program


Files\Adobe\Flex Builder 3).

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 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.

30
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 créer un nouveau projet ;
j sauvegarder un projet ;
j lancer un projet ;
j 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 le nom du projet (project name)
j la technologie serveur utilisée pour fournir des données à l’application.
2 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 <mx:Application> 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 l’ActionScript 3 (détaillé dans le prochain chapitre) ;
j 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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">

</mx:Application>

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 <mx:Application> 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 <mx:Application>…</mx:Application>. Ce principe est en fait très similaire aux
balises <html> </html> 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 un Label ;
j un TextInput ;
j un Button.

Procédez à présent comme suit :


1 Positionnez le curseur entre les balises <mx:Application>…</mx:Application> puis
saisissez au clavier un chevron ouvrant : <. La complétion de l’IDE s’active
automatiquement et vous propose une liste de balises disponibles.

c Fig. 1.15 :
Complétion automatique
dans Flex Builder 3

2 Saisissez à présent directement Panel puis tapez sur [Ä]. Nous allons maintenant lui
ajouter quelques propriétés.
3. Placez-vous dans la balise <mx:Panel> et appuyez sur la touche [T] ; là encore, la
complétion s’active. Nous voulons associer un titre à notre composant. Tapez title
ou sélectionnez cette propriété dans la liste déroulante qui vient d’apparaitre. Enfin,
saisissez un titre qui apparaîtra en haut de ce composant ("Un panneau Flex" par
exemple).

c Fig. 1.16 :
Complétion sur les
propriétés d’un
composant

4 Pour finir, entrez un chevron fermant >. 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.

40
Créer sa première application 1

5 Enfin, modifiez la propriété layout de la balise <mx:Application> 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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical">
<mx:Panel title="Un panneau Flex">

</mx:Panel>
</mx:Application>

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 <balise> </balise> ;
j <balise/> (condensé des deux balises précédentes).

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 :


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical">
<mx:Panel title="Un panneau Flex">

41
1 Créer son premier projet avec Flex

<mx:Label text="Hello World"/>


</mx:Panel>
</mx:Application>

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 un TextInput ;
j 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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical">
<mx:Panel title="Un panneau Flex"
fontFamily="Times New Roman">
<mx:Label text="Hello World" />
<mx:TextInput/>
<mx:Button label="Click Me"/>
</mx:Panel>
</mx:Application>

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 −−strict=true −file−specs "c:/…/
MonProjet.mxml"
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 une version Standard pour la mise en production ;
j une version Debug ;
j une version Profile.

44
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 :
<mx:TextArea id="textArea" editable="false"/>

Ce code est à insérer entre les balises <mx:application> et </mx:application> du fichier


principal de l’application Flex : ActionScriptTest.mxml. Ce fichier aura alors cet aspect :

48
Démarrer avec ActionScript dans Flex Builder 2

<?xml version="1.0" encoding="utf-8"?>


<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
➥ layout="absolute">
<mx:TextArea id="textArea" editable="false"/>
</mx:Application>

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 <mx:Script>
et </mx:Script> 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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
➥ layout="absolute">
<mx:Script>
<![CDATA[
// code ActionScript 3.O
]]>
</mx:Script>
<mx:TextArea id="textAreaId" editable="false"/>

49
2 Découvrir l’ActionScript 3.0

</mx:Application>

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 Le mot-clé public permet de rendre l’accès à la fonction possible en dehors du
namespace.
j Le mot-clé function déclare une fonction.
j Ensuite vient le nom de la fonction, ici "giveHelloWorld".
j Les parenthèses permettent de déclarer la liste d’arguments.
j Il faut spécifier le type de retour de la fonction, ici on retourne une chaîne de
caractères.
j Enfin vient le code de la fonction à proprement parler.
j 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
Démarrer avec ActionScript dans Flex Builder 2

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 <mx:Application> en lui demandant
d’exécuter la fonction printHello lorsque l’affichage est prêt :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
➥ layout="absolute" creationComplete="printHello()">

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 :
<mx:TextArea id="textAreaId" editable="false" text="giveHelloWorld()"/>

Au final, notre fichier MXML ressemble à celui-ci :


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" creationComplete="printHello()">
<mx:Script>
<![CDATA[
public function giveHelloWorld():String
{
return "Hello world!";
}

public function printHello():void


{
textAreaId.text = giveHelloWorld();
}
]]>
</mx:Script>
<mx:TextArea id="textAreaId" editable="false"/>
</mx:Application>

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

j 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.

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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" creationComplete="printHello()">
<mx:Script>
<![CDATA[
import classes.HelloWorld;
public function printHello():void
{
textAreaId.text = classes.HelloWorld.giveHelloWorld();
}
]]>

54
Les bases de la programmation 2

</mx:Script>
<mx:TextArea id="textAreaId" editable="false"/>
</mx:Application>

À 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
Les bases de la programmation 2

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 Note


défaut

Boolean true ou false false

int Entre 0 Stocké sous forme d’un entier


- 2 147 483 648 (-2^31) et de 32 bits. À préférer aux
2 147 483 647 (2^31) Numbers s’il n’y a pas de
décimale.

Number Entre Number.MAX_VALUE NaN (Not a À utiliser pour les nombres


(1.79769313486231e+308) Number) décimaux ou les entiers qui
et Number.MIN_VALUE dépassent les valeurs du type
(4.940656458412467e-324) 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 null Ne pas confondre null


(absence de caractère) et la
chaîne vide "".

uint Entre 0 et 4 294 967 295 Pour les nombres entiers


(2^32-1) positifs

void undefined

Null null

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 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.
j 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 i:int = 42;
var res;
res = i as int; // res contiendra 42
res = i as String // res contiendra null

Les conversions
Il existe deux sortes de conversions de variables :
j la conversion implicite ou coercition ;
j 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 lors du passage d’une valeur en argument d’une fonction ;


j 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 au mot-clé function ;
j au nom de la fonction ;
j à la liste des paramètres (éventuellement vide) entre parenthèses ;
j 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 :


j length : donne la longueur du tableau, c’est-à-dire le nombre d’arguments ;
j callee : fait référence à la fonction elle-même.

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 :
j dynamic : permet d’ajouter des propriétés à la classe durant l’exécution.
j 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.

À 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 :
j 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
suite la notion d’héritage).
j 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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns="*" layout="vertical" creationComplete = "initApp()" >

<mx:Script>
<![CDATA[

70
La programmation orientée objet dans ActionScript 2

import myPackage.MyClass;

public var objectTest:MyClass = new MyClass;

public function initApp():void


{
objectValue.text = String(objectTest.var1);
}

public function addVar():void


{
objectTest.var1 += 1;
objectValue.text = String(objectTest.var1);
}
]]>
</mx:Script>

<mx:Button click="addVar()" label="Click me"/>


<mx:Label id="objectValue"/>
</mx:Application>

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 déclarer avec l’attribut public ;
j utiliser le même nom que la méthode de l’interface ;
j avoir le même nombre de paramètres et les mêmes types ;
j 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 :
1 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"

Le code de cette application devrait donc pour l’instant être le suivant :


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">
<mx:VBox horizontalAlign="center" verticalAlign="middle"
horizontalCenter="0" verticalCenter="0">
<mx:Label id="infoLbl" text="Entrez un login" />
<mx:TextInput id="loginTxtIn"/>
<mx:Button id="validateBtn" label="valider" />
</mx:VBox>
</mx:Application>

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 <mx:Script> 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 De manière Litteral : var nameList:Array = ["Joe", "William", "Jack", "Averell"] ;
j 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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
public var nameList:Array = ["Joe","William",
"Jack","Averell"];

public function checkName(name:String):Boolean


{
for each (var item :String in nameList)
{
if (name == item)
return true;
}
return false;
}

public function validate():void


{
var name : String = loginTxtIn.text;
var test : Boolean = checkName(name);
if (test)
Alert.show("Bienvenue " + name + " , vous êtes
bien sur la liste!");
else
Alert.show("Désolé " + name + " mais vous
n’êtes pas sur la liste...");
}

]]>
</mx:Script>
<mx:VBox horizontalAlign="center" verticalAlign="middle"
horizontalCenter="0" verticalCenter="0">
<mx:Label id="infoLbl" text="Entrez un login" />
<mx:TextInput id="loginTxtIn"/>

80
Déboguer de l’ActionScript 3.0 dans Flex Builder 2

<mx:Button id="validateBtn" label="valider"


click=’validate()’ />
</mx:VBox>
</mx:Application>

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 dans les fichiers ActionScript (extension .as) ou encore entre des balises <mxScript>
</mx:Script> ;
j dans des balises MXML gérant des événements : <mx:Button id="validateBtn" label="valider"
click=’validate()’ />.
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 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.
j Suspend : permet de stopper temporairement l’exécution d’un programme.
j Terminate : quitte la session de débogage en cours.
j Step Into ([F5]) : entre dans la fonction appelée.
j Step Over ([F6]) : exécute la ligne courante puis passe à la suivante mais sans entrer
en mode Pas à pas dans une fonction appelée.
j 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 les événements ;
j le style ;
j la taille ;
j 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 :
<mx :Button id="monBouton" label="Cliquer ici” />

Cette propriété optionnelle est utile lorsque vous voulez accéder aux événements ou
propriétés du composant en ActionScript. Techniquement, cette propriété indique au
compilateur MXML de générer une variable publique nommée monButton qui fera
référence à l’instance de ce bouton précisément. Vous pourrez dès alors accéder à ce
composant depuis du code ActionScript et modifier ses propriétés ou appeler ses
méthodes. La variable sera disponible depuis n’importe quelle classe ou bloc
d’ActionScript.
Par exemple, le bloc d’ActionScript suivant permet de changer le texte du bouton en
modifiant sa propriété label lorsque l’on clique dessus.
<mx:Button id="monButon" label="Cliquer ici" click="setLabel();" />
<mx:Script><![CDATA[
function setLabel():void {
myButton.label = "Merci d’avoir cliqué";
}
]]></mx:Script>

Vous pouvez attribuer la propriété id d’un composant directement dans le code MXML
ou alors via l’interface design grâce au panel Common de l’onglet Flex Properties situé
par défaut en haut à droite.

Unicité de la propriété id

Pour tout contrôle MXML possédant une propriété id, il existe une variable publique représentant le
contrôle. Si vous spécifiez deux contrôles avec le même id, l’une des variables sera écrasée et vous ne
pourrez plus différencier les deux objets ; il est donc nécessaire que la valeur de cette propriété soit
toujours unique dans tout le document. Cela veut aussi dire que l’instance du composant sera accessible
dans toute votre application (dans une fonction, une classe externe, un fichier ActionScript importé ou
dans un script inline).

91
3 Réaliser sa première interface

Si vous ne spécifiez pas la propriété id de votre composant, vous pouvez tout de même
y accéder via les méthodes du contrôle parent, c’est-à-dire le contrôle qui l’enveloppe,
généralement un conteneur. Les méthodes en question sont les méthodes getChildAt() et
getChildByName().
Vous pouvez également manipuler l’objet courant ou le document imbriqué courant en
utilisant le mot-clé this, suivi de l’opérateur point (.). Cela revient au même que
d’utiliser la valeur de l’id en ActionScript. Dans l’exemple précédent, il revient au même
d’utiliser this.label ou myButton.label.
Enfin, vous pouvez avoir une référence sur le composant en utiliser le mot-clé this suivi
de la chaîne de caractères représentant son identifiant (la valeur de la propriété id en
somme) entre crochets. L’exemple suivant est une application complète utilisant ce
procédé et qui change la taille de la police du texte de chaque bouton lorsque l’on clique
dessus.
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script><![CDATA[
public function changeBtn(s:String):void {
s = "btn" + s;
this[s].setStyle("fontSize","18");
}
]]></mx:Script>
<mx:Button id="btn1" click="changeBtn(’2’)" label="Change l’autre" />
<mx:Button id="btn2" click="changeBtn(’1’)" label="Change l’autre" />
</mx:Application>

Quand utiliser la technique this["id"]

Cette dernière technique est particulièrement intéressante lorsque l’on travaille avec les contrôles de
type Repeater ou lorsque vous créez des objets en ActionScript dont vous ne connaissez pas
l’identifiant.

Lorsque vous êtes en mode Design, vous pouvez modifier un certain nombre de propriétés
sur le contrôle sélectionné. Certaines propriétés sont communes à de nombreux
composants comme la taille ou la position, et d’autres propriétés sont spécifiques à
chaque contrôle. Ces informations spécifiques se trouvent dans le volet Common (le
premier volet) du panneau Flex Properties. L’image suivante montre les propriétés
spécifiques au composant DateChooser qui affiche un calendrier pour sélectionner des
dates.

92
Les composants MXML 3

c Fig. 3.1 :
Panneau des propriétés
d’un contrôle

Différencier les composants


Flex dispose d’une liste de composants complète afin de créer des interfaces utilisateurs
riches. En mode Design, vous disposez dans Flex Builder d’un panneau nommé
Components (en bas à gauche par défaut) qui contient l’intégralité des composants mis
à votre disposition. L’image suivante retrace l’arborescence que vous pouvez voir dans ce
panneau.

c Fig. 3.2 : Les différents types de contrôles Flex

Les composants Controls sont les composants typiques de l’interface utilisateur tels que
les Button, les TextArea ou les ComboBox. On distingue deux types de contrôles : les
contrôles Basic et les Data provider. Le second type de contrôles regroupe les
composants qui nécessitent des données structurées afin de les afficher comme le
DataGrid par exemple qui affiche une liste de données dans un tableau. Nous ne verrons
dans ce chapitre que les contrôles basiques.

93
3 Réaliser sa première interface

Les composants de type Layout et Navigator font partie de la catégorie des conteneurs :
c’est-à-dire qu’ils servent à accueillir des contrôles, soit pour les agencer de diverses
manières pour les conteneurs de type Layout, soit pour gérer leur affichage en fonction de
la navigation pour les conteneurs de type Navigator.
Les composants de type Adobe AIR sont réservés aux applications de bureau pour avoir
des interactions avec le système de fichier de l’ordinateur sur lequel est lancée
l’application. Par exemple, un explorateur de fichier ou une boîte de dialogue pour
sélectionner un fichier. Ce type de composant n’est pas envisageable pour une application
Flex destinée à être publiée sur Internet car le lecteur Flash dans un navigateur ne peut
pas avoir accès aux informations contenues sur votre ordinateur (par mesure de sécurité).
Si vous disposez du plug-in Chart, vous disposez d’une catégorie supplémentaire de
contrôles permettant d’afficher des graphes. Vous aurez plus de détails sur l’utilisation de
ces contrôles dans le chapitre dédié aux graphes.

Utiliser un composant en MXML et en ActionScript


Chaque composant Flex possède une API MXML et une API ActionScript homologues.
Les attributs disponibles dans un tag MXML correspondent aux propriétés, événements,
styles et comportements de la classe ActionScript. Vous pouvez utiliser les deux API
selon vos préférences mais le choix se portera essentiellement sur les cas d’utilisation du
composant. Les composants statiques verront leurs propriétés définies dans le tag MXML,
a contrario, les composants dynamiques (qui verront leurs propriétés modifiées durant
l’exécution du programme) seront modifiés dans un contexte ActionScript.

Ce que l’on ne peut pas faire en MXML

Deux parties de l’API des composants ne sont pas exposées dans l’API MXML : les propriétés en lecture
seule ainsi que les méthodes. Il est alors nécessaire de passer par l’API ActionScript.

Lorsque vous attribuez des propriétés à un contrôle en MXML, vous avez deux
alternatives : passer directement par l’édition du code MXML en s’aidant de la
complétion automatique ou renseigner les champs adéquats dans l’interface design. Le
panel Flex Properties est à votre disposition pour modifier les paramètres principaux de
votre contrôle ou l’intégralité des propriétés et événements en passant par la Category
View (voir fig. 3.3).
Nous allons maintenant prendre un exemple simple et comparer les deux approches
MXML et ActionScript. Nous allons créer une interface avec un bouton et une zone de
texte dont le message change lorsque l’on clique sur le bouton.

94
Les composants MXML 3

c Fig. 3.3 : Les modes Standard View et Category View de l’onglet Flex Properties

Le tableau suivant détaille l’utilisation de MXML et d’ActionScript pour configurer vos


composants :

Tableau 3.1 : Syntaxe de modification d’un composant en MXML ou en ActionScript

Version MXML Version ActionScript

Propriété en <mx:Panel id="panel1" panel1.title = "titre";


lecture/écriture title="Titre" visible="true" /> panel1.visible = "true";

Propriété en lecture Impossible d’accéder à une propriété var myClass:String=mp1


seule en lecture seule via un attribut MXML. .className;

Méthode Les méthodes ne sont pas accessibles myList


directement dans un tag MXML. .sortItemsBy("price", "DESC");

95
3 Réaliser sa première interface

Tableau 3.1 : Syntaxe de modification d’un composant en MXML ou en ActionScript

Evénement <mx:Accordion private function changeHandler


change="changeHandler(event);" / (event:Flash.events
> .MouseEvent):void {...}

Style <mx:Panel paddingTop="12" Pour modifier le style : panel1


paddingBottom="12" /> .setStyle("paddingTop", 12); Pour
récupérer la valeur du style :
var currentPaddingTop:Number
= panel1.getStyle("paddingTop");

Comportement <mx:WipeUp id="wipeIn" btn


duration="1000"/> .setStyle(’showEffect’, wipeIn);
<mx:Button id="btn"
showEffect="{wipeIn}"

3.2 Les conteneurs d’agencement


Les conteneurs permettent de structurer hiérarchiquement la mise en forme de
l’application. On emploiera plus généralement le terme anglais "layout" pour parler de la
mise en page. Les conteneurs (le terme anglophone étant "container") servent à contrôler
la position et la taille des différents composants qu’ils contiennent, ainsi que la navigation
dans l’application. Il existe deux types de conteneurs dans Flex : les conteneurs
d’agencement et les conteneurs de navigation. Nous aborderons dans ce chapitre le
premier type de conteneur.

Comprendre l’utilité des conteneurs


Un conteneur représente une surface rectangulaire de l’application Flex. À l’intérieur
d’un conteneur, vous pouvez ajouter des composants ou d’autres conteneurs qui
s’afficheront à l’intérieur. Les composants sont appelés les enfants du conteneur.
Nous avons déjà utilisé un conteneur jusqu’à présent sans le savoir : le conteneur
Application, qui représente l’intégralité de la zone Flash de l’application Flex et qui
contient tous les autres composants.
Les conteneurs possèdent de nombreuses règles prédéfinies, notamment sur la taille et la
position des composants enfants. La partie design de l’application en sera grandement
simplifiée. Bien entendu, ces règles sont flexibles et peuvent être modifiées simplement.

96
Les conteneurs d’agencement 3

Ces règles prédéfinies possèdent deux avantages : le premier est de permettre au


développeur de se concentrer sur les fonctionnalités métier de son application et non sur
les problématiques de mise en place d’une interface. Le second est de pouvoir miser sur
la connaissance de ce type d’interface de la part des utilisateurs finaux. Les RIAs utilisent
généralement les mêmes types de conteneurs pour naviguer dans l’application. De ce fait,
l’utilisateur ne se soucie plus de savoir comment marche cette application et peut
directement focaliser son attention sur le contenu.

Le conteneur Canvas

Si vous désirez avoir un très grand contrôle sur l’affichage des composants dans un conteneur, vous
pouvez utiliser le conteneur Canvas qui ne possède aucune information par défaut sur le positionnement
et la taille des composants enfants.

Maîtriser les conteneurs primordiaux : HBox et VBox


Bien que vous puissiez créer une application en utilisant qu’un seul conteneur, les RIAs
sont généralement dotées de plusieurs conteneurs. Les deux conteneurs les plus simples
à utiliser et les plus récurrents sont les conteneurs HBox et VBox, qui permettent
respectivement d’afficher les composants enfants sur une ligne et une colonne. Ces deux
conteneurs sont des raccourcis d’utilisation du conteneur Box qui est strictement
équivalent aux deux autres conteneurs cités, sauf que l’on précise alors la valeur de
l’attribut direction.
L’exemple suivant présente une interface avec trois conteneurs de mise en forme,
organisée de deux manières différentes afin de bien de cerner leur application. Pour
réaliser cette interface, créez un nouveau projet Flex nommé test−HBox et ouvrez le
fichier main.mxml en mode Design.
1 Sélectionnez le composant HBox qui se trouve dans le nœud Layout de l’explorateur
de composants. Faites un glisser-déposer sur l’éditeur. L’IDE vous demande la taille
du composant : précisez 50 %. Un rectangle noir apparaît dans l’éditeur.
2 Sélectionnez le composant VBox et posez-le dans la HBox. Précisez une largeur de
50 % et laissez la valeur par défaut de la hauteur. Répétez l’opération, vous
remarquerez que la seconde VBox se place à droite de la première. C’est le résultat
attendu, vu qu’une HBox place ses contrôles enfants horizontalement.
3 Sélectionnez ensuite des composants et placez-les dans les VBox nouvellement
créées. L’exemple ci-après est composé pour la balise VBox de droite d’un composant
Panel avec un titre et dans la balise VBox de gauche de plusieurs boutons. Vous
remarquerez que les éléments sont placés verticalement cette fois-ci.

97
3 Réaliser sa première interface

Vous devriez obtenir le résultat suivant :


c Fig. 3.4 :
Exemple d’utilisation de
conteneur VBox

Passez maintenant en mode Source, et analysez le code. Les boutons et les checkbox se
trouvent imbriqués dans chacune des deux balises VBox qui sont toutes les deux incluses
dans la HBox. Afin de bien comprendre l’intérêt de ces conteneurs, supposons que nous
voulions présenter les boutons dans le sens opposé : les boutons doivent être maintenant
alignés, et les deux séries de composants doivent se retrouver l’une en dessous de l’autre.
Il suffit d’intervertir les types de conteneurs que nous avons utilisés. Voici à quoi
ressemble alors le code de l’application en mode Source :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:VBox width="50%">
<mx:HBox width="50%" height="100%">
<mx:Panel width="250" height="200"
layout="absolute" title="Panel de haut">
</mx:Panel>
</mx:HBox>
<mx:HBox width="50%" height="100%">
<mx:Button label="bouton 1" />
<mx:Button label="bouton 2" />
<mx:Button label="bouton 3" />
</mx:HBox>
</mx:VBox>
</mx:Application>

Seules les balises VBox changent par rapport à l’exemple précédent et deviennent des HBox
ainsi que la balise HBox qui devient une balise VBox. Et voici le nouveau résultat en mode
Design : (voir fig. 3.5)

98
Les conteneurs d’agencement 3

c Fig. 3.5 :
Exemple d’utilisation du
conteneur HBox

Utilisez l’attribut layout du conteneur Application

Si vous supprimez la balise VBox qui encadre les deux HBox de l’exemple précédent, vous ne
remarquerez aucun changement visuel. En effet, le conteneur Application agit par défaut comme une
VBox. Cela vient de l’attribut layout qui, par défaut, a la valeur vertical. Cet attribut peut avoir la
valeur horizontal pour agir comme une HBox. Nous verrons plus loin que l’attribut peut aussi avoir la
valeur absolute.

Reconnaître les cadres d’utilisation des autres conteneurs


d’agencement
Flex contient une dizaine de conteneurs d’agencement. Il est important de connaître ces
conteneurs qui répondent généralement à tous vos besoins d’agencement dans vos
applications Flex. Nous allons voir maintenant en détail tous ces conteneurs, à l’exception
du conteneur Form qui fera l’objet d’une attention plus détaillée dans le chapitre Aller
vers une interface riche.

Le Panel
Le conteneur de mise en forme Panel inclut une barre de titre avec un titre et un message
de status, une bordure et une zone de contenu pour y insérer les autres composants. Les
Panel servent à séparer le contenu de l’application en modules. Vous pouvez placer
plusieurs Panel sur une même page contenant un formulaire, une liste de produits et des
graphes (voir fig. 3.6).

99
3 Réaliser sa première interface

c Fig. 3.6 :
Exemple d’utilisation
d’un conteneur Panel

Le conteneur Panel possède une propriété layout, comme de nombreux conteneurs, qui
permet de disposer les éléments de trois manières différentes : vertical (par défaut),
horizontal et absolute. La disposition absolute permet de spécifier l’emplacement de
chaque enfant en spécifiant leur coordonnées x et y alors que les deux autres modes
utilisent des règles prédéfinies de positionnement horizontal et vertical. Vous pouvez
modifier ce paramètre directement dans le code MXML ou, si vous préférez l’interface
design, ces informations se situent dans le panel Layout de l’onglet Flex Properties situé
en bas à droite par défaut.
c Fig. 3.7 :
Modifier la direction en mode Design

Voici le code d’une application Flex présentant un conteneur Panel avec un formulaire.
L’attribut title permet de donner un titre au module graphique, un procédé standard des
GUI d’application lourde.

100
Les conteneurs d’agencement 3

<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Panel id="myPanel" title="Mon application">
<mx:Form width="300">
<mx:FormHeading label="Information de paiement"/>
<!-- Elements du formulaire -->
</mx:Form>
</mx:Panel>
</mx:Application>

Le ControlBar
Le conteneur ControlBar s’utilise avec un Panel ou un TitleWindow pour contenir des
composants qui pourront être partagés par les autres composants enfants du conteneur
Panel ou TitleWindow. Pour une application de catalogue de produit, le ControlBar peut
contenir les contrôles Flex pour spécifier la quantité désirée et ajouter le produit au panier
comme le montre l’exemple ci-après.
c Fig. 3.8 :
Exemple d’utilisation du
conteneur ControlBar

Pour créer un conteneur ControlBar, il faut ajouter un tag <mx:ControlBar> comme


dernier enfant du tag <mx:Panel>, comme le montre le code de l’exemple suivant :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Panel title="Exemple de ControlBar">
<mx:HBox width="100%" height="100%">
<!-- Area for your catalog. -->
</mx:HBox>
<mx:ControlBar>
<mx:Label text="Quantité"/>

101
3 Réaliser sa première interface

<mx:NumericStepper/>
<!-- Utiliser un spacer pour pousser le bouton à droite. -->
<mx:Spacer width="100%"/>
<mx:Button label="Ajouter au panier"/>
</mx:ControlBar>
</mx:Panel>
</mx:Application>

Par ailleurs, l’exemple utilise le contrôle Spacer pour faciliter l’agencement de


l’interface.

Utiliser le contrôle Spacer

Spacer est un contrôle invisible qui sert à positionner précisément des éléments au sein de conteneurs
positionnés automatiquement. Dans cet exemple, le contrôle Spacer est le seul composant basé sur un
pourcentage du conteneur ControlBar. Flex dimensionne le contrôle Spacer de façon à ce qu’il occupe
tout l’espace disponible dans le conteneur, autrement dit l’espace qui n’est pas nécessaire pour d’autres
composants. Flex repousse ainsi le contrôle Button vers le bord droit du conteneur.

L’ApplicationControlBar
Le contrôle ApplicationControlBar permet de contenir des composants fournissant des
commandes de navigation et d’application. L’ApplicationControlBar est une sous-classe
de ControlBar, néanmoins, le style du composant est bien différent. Ce conteneur
contient généralement un contrôle MenuBar afin de recréer un menu horizontal en haut de
l’application, ce qui est une disposition classique des éléments de contrôles dans une
application lourde.

c Fig. 3.9 : Exemple d’utilisation du conteneur ApplicationControlBar

Typiquement, le conteneur ApplicationControlBar est placé en haut de l’application et


reste ancré grâce à la propriété dock mise à true. Cette propriété redimensionne
également le conteneur en adaptant sa largeur à la largeur de l’application ; et lorsque
l’utilisateur fait défiler le contenu de l’application, ce conteneur ne sera pas affecté par le
défilement et restera en haut de la zone visible. Si cette propriété est à false, le conteneur
aura le même comportement que les autres conteneurs d’agencement. La propriété par
défaut est false.

102
Les conteneurs d’agencement 3

Vous pouvez voir un exemple d’utilisation de ce conteneur dans l’exercice


d’application à la fin de ce chapitre.

La HDividedBox et la VDividedBox
Les DividedBox sont des conteneurs semblables aux conteneurs Box dans la mesure où ils
disposent leur enfants de la même manière. La différence est que ce composant place
automatiquement un séparateur entre chaque composant enfant. Ce séparateur permet de
redimensionner la surface des conteneurs allouée à chaque enfant grâce à la souris. Tout
comme les Box, la propriété direction peut avoir la valeur horizontal ou vertical, la
HDividedBox et la VDividedBox sont des conteneurs DividedBox avec la propriété
direction spécifiée respectivement à horizontal et vertical.

c Fig. 3.10 : Exemple d’utilisation des conteneurs HDividedBox et VDividedDox

Dans cet exemple, le conteneur principal est une HDividedBox. Le séparateur horizontal
marque la séparation entre l’arborescence du TreeControl et la VDividedBox. Celle-ci
contient un contrôle Panel (en haut) et un contrôle TextArea (en bas). Le séparateur
vertical marque la séparation entre les deux contrôles.
Pour que les séparateurs fonctionnent, il faut que les composants enfants des DividedBox
soient redimensionnables. Pour cela, il faut donc s’assurer que les composants enfants ont
des tailles relatives (la hauteur et la largeur doivent être spécifiées en pourcentage) et non
absolues (en les spécifiant en pixels). Vous pouvez agrandir les composants contenus dans
ces conteneurs jusqu’à une taille maximale et les réduire jusqu’à une taille minimale. Ces
contraintes doivent être précisées en attribuant des valeurs aux propriétés maxWidth et
maxHeight ainsi que minWidth et minHeight.

103
3 Réaliser sa première interface

Utilisez le liveDragging

Lorsque l’utilisateur redimensionne un conteneur, l’apparence de l’application ne s’effectue qu’au


moment où il lâche le bouton de la souris. En affectant la valeur true à la propriété liveDragging, les
modifications se feront en même temps que les mouvements de la souris. Cependant, dans certains cas,
cette option peut conduire à des baisses de performance.

Le Grid
Le conteneur Grid permet d’agencer les composants dans un tableau dont le nombre de
cellules est variable, à la manière d’un tableau HTML. Pour ceux qui ne sont pas
familiers avec ce type d’objet, voici un schéma décomposant les différents éléments que
l’on retrouve dans un tableau et que nous allons utiliser pour décrire l’utilisation du
composant Grid.

c Fig. 3.11 : Schéma d’un conteneur Grid avec trois lignes et trois colonnes

Pour utiliser un tel composant, il faut respecter les étapes suivantes :


1 Définissez le conteneur d’agencement avec la balise <mx:Grid> qui peut contenir
autant de balises <mx:GridRow> que vous souhaitez.
2 Ajoutez des balises <mx:GridRow> qui représenteront chacune une ligne de votre
tableau. Cette balise doit être incluse dans une balise <mx:Grid> et peut contenir
autant de <mx:GridItem> que souhaité.
3 Ajoutez des balises <mx:GridItem> qui représenteront chacune une cellule de votre
ligne. Cette balise doit être incluse dans une balise <mx:GridRow>.

104
Les conteneurs d’agencement 3

4 Ajoutez un seul contrôle dans la cellule définie par la balise <mx:GridItem>. Si vous
voulez mettre plusieurs contrôles dans une même cellule, placez un conteneur
d’agencement dans la cellule du tableau et rajoutez les contrôles dans le conteneur.
Vous n’êtes pas obligé de définir le même nombre de cellules sur chaque ligne.
Cependant, chaque cellule définie fera la même taille que les autres cellules placées dans
la même colonne.
De la même manière que les tableaux HTML, le contrôle GridItem possède deux
propriétés rowSpan et colSpan permettant de créer des cellules occupant plusieurs
colonnes ou plusieurs lignes. Fusionner plusieurs cellules ensemble n’agrandit pas
forcément le composant enfant de la cellule. Il faut spécifier une taille relativement à la
cellule.
L’exemple suivant montre une utilisation complète du conteneur Grid. L’image de
gauche est le résultat dans le navigateur de l’utilisateur. Elle représente le conteneur Grid
en superposition. Le bouton 4 occupe deux cellules horizontalement tandis que le
bouton 5 occupe deux cellules verticalement.
c Fig. 3.12 :
Utilisation d’un
conteneur Grid avec des
cellules fusionnées

<mx:Grid>

<!-- Définition de la première ligne -->


<mx:GridRow>
<!-- Définition de la première cellule -->
<mx:GridItem>
<mx:Button label="1" />
</mx:GridItem>
<mx:GridItem>
<mx:Button label="2" />
</mx:GridItem>
<mx:GridItem>
<mx:Button label="3" />
</mx:GridItem>
</mx:GridRow>

<!-- Définition de la deuxième ligne -->


<mx:GridRow>
<!-- Fusion des colonnes 1 et 2 -->
<mx:GridItem colSpan="2">

105
3 Réaliser sa première interface

<mx:Button label="4" width="100%"/>


</mx:GridItem>
<!-- Fusion des lignes 1 et 2 -->
<mx:GridItem rowSpan="2">
<mx:Button label="5" height="100%"/>
</mx:GridItem>
</mx:GridRow>

<!-- Définition de la troisième ligne -->


<mx:GridRow>
<mx:GridItem>
<mx:Button label="6"/>
</mx:GridItem>
<mx:GridItem>
<!-- Cellule vide -->
</mx:GridItem>
</mx:GridRow>

</mx:Grid>

Le Tile
Le conteneur Tile agence ses enfants sur plusieurs lignes ou colonnes automatiquement.
Le conteneur s’occupe d’ajouter de nouvelles lignes ou colonnes si cela est nécessaire. La
propriété direction détermine l’agencement horizontal (par défaut) ou vertical des
contrôles enfants. Concrètement, si vous définissez 16 enfants dans un conteneur Tile,
vous verrez se former une grille de 4 lignes par 4 colonnes. Si vous définissez 13 enfants,
Flex créera toujours une grille de 4 par 4 cellules mais les 3 dernières cellules de la
dernière ligne resteront vides.
c Fig. 3.13 :
Exemple d’utilisation du
conteneur Tile dans les
deux directions

106
Les conteneurs d’agencement 3

Les cellules d’un conteneur Tile sont toutes identiques, contrairement au conteneur Grid.
La taille d’une cellule sera déterminée par la cellule nécessitant le plus d’espace pour
afficher intégralement son composant enfant. Pour spécifier une taille arbitraire, vous
disposez des propriétés tileHeight et tileWidth. Flex dimensionne automatiquement les
contrôles enfants du conteneur Tile. Si vous définissez vous-même la taille des cellules
et que l’un des composants enfants possède une taille supérieure aux cellules, ce
composant sera alors coupé.
Le code MXML suivant décrit l’utilisation du conteneur Tile :
<mx:Tile direction="horizontal">
<mx:Button label="1" height="50" width="75"/>
<mx:Button label="2" height="50" width="75"/>
<mx:Button label="3" height="50" width="75"/>
<mx:Button label="4" height="50" width="75"/>
<mx:Button label="5" height="50" width="75"/>
</mx:Tile>

Vous remarquerez que les cellules ne sont pas explicitement décrites dans le code. Si vous
spécifiez une taille relative aux composants enfants, sachez que le composant parent sur
lequel sera calculée la taille n’est pas l’objet Tile directement mais la cellule du Tile
contenant votre contrôle.

Le Canvas
Le conteneur Canvas définit une surface rectangulaire dans laquelle vous pouvez placer
des contrôles. Contrairement aux autres conteneurs, Flex n’agence pas automatiquement
les contrôles enfants du Canvas. Vous devez spécifier la position des enfants en utilisant
une position absolue ou basée sur des contraintes. Pour utiliser la position absolue,
spécifiez les propriétés x et y de chaque composant. Pour utiliser la position basée sur des
contraintes, spécifiez la taille des ancres et leur côté. Pour une information détaillée sur
le positionnement, regardez la section sur la mise en forme de l’interface.
L’exemple suivant montre une utilisation simple de ce conteneur en plaçant un conteneur
Box dans le conteneur Canvas en utilisant à la fois une position absolue et les contraintes.
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Canvas width="150" height="150" backgroundColor="#FFFFFF">
<mx:Box id="hBox2" xmlns:mx="http://www.adobe.com/2006/mxml"
left="30"
right="30" y="50" height="50" backgroundColor="blue">
</mx:Box>
</mx:Canvas>

107
3 Réaliser sa première interface

</mx:Application>

Le code MXML précédent produit le résultat ci-après dans votre navigateur. La zone
blanche représente le Canvas et le rectangle à l’intérieur représente la Box.

3.3 Mise en forme de l’interface


Vous savez désormais placer vos éléments les uns par rapport aux autres dans le Canvas
de votre application Flex. Nous allons maintenant détailler les techniques pour arranger
ces éléments en ajustant leur taille et leur position. Bien que l’un des atouts de Flex soit
de pouvoir créer une interface organisée rapidement, vous aurez au final besoin de ces
propriétés.

Comprendre le redimensionnent d’un composant


Flex dispose de plusieurs techniques pour décider de la taille d’un contrôle ou d’un
conteneur :
j La taille par défaut : Flex détermine automatiquement les tailles des contrôles.
C’est ce qui se produit si vous ne renseignez pas les propriétés de hauteur ou de
largeur de votre contrôle.
j La taille absolue : vous précisez la largeur et la hauteur en pixels du contrôle grâce
aux propriétés width et height. Les valeurs de ces propriétés sont des nombres
uniquement, il n’y a pas de mesure associée (px, em) comme c’est le cas en HTML.
j La taille relative : vous définissez une taille du contrôle par rapport à celle de son
conteneur parent avec une valeur en pourcentage (vous devez rajouter le caractère %
après la valeur pour que Flex différencie votre intention de mettre une taille relative
et non une taille absolue).
j La taille par contrainte : vous ne précisez pas directement les propriétés width et
height de votre contrôle mais vous spécifiez la position des côtés du contrôle par
rapport au conteneur parent. Nous détaillerons cette méthode prochainement.

Lorsque vous ajoutez un nouveau conteneur dans votre application via l’interface de
design, Flex vous demande la taille de votre conteneur. Vous pouvez renseigner ses
propriétés width et height à ce moment-là ou ultérieurement dans l’interface, grâce au
panneau Layout de l’interface de design (situé en bas à droite par défaut). Vous pouvez
également passer directement par l’édition du code MXML si vous êtes à l’aise avec le
code MXML.

108
Mise en forme de l’interface 3

c Fig. 3.14 :
Modifier la taille en mode Design

L’exemple suivant illustre l’utilisation de ces différents types de taille dans une petite
application Flex.

c Fig. 3.15 : Les différents types de taille d’un contrôle

Vous remarquerez que la taille par défaut d’un conteneur s’adapte en fonction des
composants fils qu’il contient. Néanmoins, en taille relative et absolue, Flex ne tient pas
compte des éléments fils contenus par le Panel.
Essayez de reproduire visuellement cet écran, et comparez votre code à celui de
l’exemple :
<?xml version="1.0"?>

109
3 Réaliser sa première interface

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="horizontal">
<mx:Panel layout="vertical" title="Taille par défaut"
horizontalAlign="center">
<mx:DateChooser showToday="true"/>
<mx:CheckBox label="activer parametre 1"/>
<mx:CheckBox label="activer paramètre 2"/>
<mx:Button label="Appliquer"/>
</mx:Panel>
<mx:Panel width="100%" height="100%" layout="absolute"
title="Taille absolue">
<mx:Button label="Button"/>
</mx:Panel>
<mx:Panel width="250" height="200" layout="horizontal"
title="taille relative">
<mx:Button label="Button"/>
</mx:Panel>
</mx:Application>

Le contrôle, en taille absolue, s’adapte à son conteneur parent. Ici, il s’agit du conteneur
parent des trois Panel et du conteneur principal Application. Comme nous ne lui avons
pas spécifié de taille, il prend tout l’espace possible dans le navigateur Internet. Ainsi,
lorsque nous redimensionnons la fenêtre, nous pouvons constater que la taille du Panel
du milieu varie.

c Fig. 3.16 : Comportement de la taille par rapport au navigateur

110
Mise en forme de l’interface 3

Flex s’arrange pour que le Panel central, le seul en taille absolue, occupe 100 % de
l’espace disponible sachant que les deux autres Panel ont une taille fixe. La taille
minimale du Panel central sera la taille limite permettant d’afficher ses contrôles fils. Si
l’on continue à réduire la fenêtre, l’application sera alors rognée sur les côtés et des barres
de défilement surgiront.

Comprendre le positionnement absolu et les contraintes


Lorsque vos conteneurs ont la propriété layout définie à vertical ou horizontal, vous
ne gérez pas la position des contrôles enfants. Cependant, vous pouvez spécifier la valeur
absolute à cette propriété. Dès lors, vous pouvez positionner les contrôles comme bon
vous semble. Le positionnement absolu ne concerne que trois types de conteneurs, à
savoir : les conteneurs Application, Canvas et Panel.
Les propriétés x et y permettent de positionner l’élément concerné par rapport au coin
haut gauche du conteneur parent. Si vous ne renseignez pas de valeur, l’élément sera
placé aux coordonnées (0;0) autrement dit, dans le coin. En positionnement absolu, vous
avez le contrôle total de la mise en forme, ce qui permet par exemple de superposer des
composants. L’exemple suivant utilise ce procédé pour placer deux balises HBox
superposées avec un fond coloré dans un Canvas :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
backgroundGradientColors="[#FFFFFF, #FFFFFF]">
<mx:Canvas width="100" height="100" backgroundColor="yellow">
<mx:VBox width="80" height="80" x="20" y="20"
backgroundColor="green ">
</mx:VBox>
<mx:VBox width="50" height="50" x="0" y="50"
backgroundColor="red ">
</mx:VBox>
</mx:Canvas>
</mx:Application>

L’exemple produit l’image suivante.


c Fig. 3.17 :
Exemple de l’utilisation du Layout

111
3 Réaliser sa première interface

Utiliser les contraintes


Vous pouvez utiliser le système de contraintes afin de gérer la position et la taille de vos
composants dans un conteneur supportant la mise en forme absolue. Les contraintes sont
des ancres qui permettent de maintenir la disposition des contrôles dans le conteneur,
spécialement lorsque la taille de celui-ci est variable. Ces contraintes permettent de
donner une distance minimale entre le contrôle et l’un des bords du conteneur ou l’axe
de symétrie.
L’exemple suivant utilise un Canvas contenant trois HBox. La HBox du centre possède deux
contraintes symétriques sur les axes horizontal et vertical afin de la centrer. Les deux
autres possèdent des contraintes par rapport aux bords du Canvas plaçant les HBox à
10 pixels des bords, quelle que soit la taille du conteneur.
c Fig. 3.18 :
Exemple d’utilisation du Canvas

Pour définir une contrainte, Flex dispose d’un c Fig. 3.19 :


Conservation des
outil très pratique qui apparaît dans le panel contraintes sur un
Layout de l’onglet Flex Properties lorsque Canvas
l’on sélectionne un composant contenu dans redimensionné
un conteneur en layout absolute. Un petit
panel est dessiné entouré de checkbox représentant chaque contrainte possible. Une fois
la contrainte sélectionnée, un champ de saisie permet de définir la distance entre l’ancre
et le composant pour créer une marge. Les images suivantes montrent l’utilisation de cet
outil pour contraindre un contrôle.
c Fig. 3.20 :
Contraindre un contrôle

112
Les contrôles simples 3

c Fig. 3.21 :
Définition d’une contrainte sur un contrôle

La première image contraint le composant à avoir une marge de 10 pixels en haut et à


droite entre le conteneur et lui-même. Si nous ajoutons une nouvelle contrainte pour
ajouter une marge à droite ou en bas, la taille du composant sera automatiquement gérée
pour respecter toutes les contraintes. La seconde image contraint le composant à être
centré dans son conteneur.
Les contraintes peuvent être spécifiées directement dans le code MXML en utilisant les
propriétés top, right, bottom et left pour définir des marges ou verticalCenter et
horizontalCenter pour centrer selon un axe.

3.4 Les contrôles simples


Maintenant que vous savez disposer et organiser des contrôles graphiques sur votre
interface, nous allons nous attarder sur le contenu visible de votre application avec le
premier type de contrôles dits contrôles simples.

Utiliser Flex Component Explorer pour appréhender les contrôles


simples
Détailler chaque contrôle du framework Flex serait fastidieux et peu intéressant.
Néanmoins, il est nécessaire lorsqu’on veut utiliser un nouveau contrôle de savoir
comment s’en servir et de connaître l’ensemble de ses fonctionnalités pour ne pas perdre
de temps à redévelopper des actions qui sont cachées dans le composant. L’application en
ligne Component Explorer montre des cas d’utilisation typiques de la plupart des

113
3 Réaliser sa première interface

composants MXML disponibles dans le framework Flex. C’est un bon outil de départ
pour découvrir les possibilités du framework et un bon guide pour les utiliser
correctement.

c Fig. 3.22 : L’interface d’Adobe Flex Component Explorer

L’application est séparée en trois zones distinctes : l’arborescence de gauche permet de


retrouver des exemples d’utilisation d’un composant particulier. Une fois le composant
sélectionné, la partie en haut à droite montre un exemple tel qu’il est rendu après
compilation, et la partie en dessous vous donne le code pour refaire exactement cet
exemple. Généralement, un copier-coller de l’exemple suffit à le compiler chez soi.
Cette application en anglais est disponible à l’adresse suivante : http://www.adobe.com/go/
flex_explorer_app. Cette application est aussi disponible via la page Flex Start du Flex Buil-
der. Sinon, une recherche sur votre moteur de recherche favori avec la requête "Adobe Flex
Component Explorer" vous sortira le bon URL.

Afficher des images


Vous aurez rapidement besoin d’afficher des images dans votre application, que ce soit de
manière statique pour un élément de décoration (le logo de votre application typiquement)
ou de manière dynamique pour afficher le visuel d’un produit dans un catalogue.

114
Les contrôles simples 3

L’importation d’images à l’exécution ou à la compilation


Vous pouvez importer des images (au format .gif, .jpeg, .png, .svg et .swf) via le contrôle
Image. Cette importation peut être effectuée à l’exécution ou à la compilation. Importer
une image à la compilation est idéal pour les images statiques. Le chargement de l’image
sera immédiat lors du lancement de votre application car l’image sera incluse dans le
fichier swf généré. Cela présente tout de même des inconvénients : si vous voulez changer
l’image, vous devez obligatoirement recompiler votre application et votre fichier généré
sera aussi plus volumineux et donc le temps de chargement de votre application sera plus
long.
Si vous avez besoin d’afficher beaucoup d’images dans votre application (pour un
catalogue par exemple), vous ne devez pas utiliser cette méthode mais lui préférer plutôt
l’importation de vos images à l’exécution. Vous pouvez charger une ressource présente
dans le système de fichier local ou sur le réseau via une requête HTTP. Ces images sont
indépendantes de l’application Flex, ce qui permet de modifier les images sans toucher au
code ou repasser par une étape de compilation. Cependant, le temps de chargement de
l’image est notable, surtout si l’on utilise des ressources sur le réseau.

Sécurité du Player Flash et importation d’images

Lorsque vous importez des images à l’exécution, vous devez être attentif aux restrictions de sécurité du
Player Flash. En effet, les paramètres par défaut de sécurité permettent d’importer via le réseau des
images uniquement sur le même domaine que celui hébergeant l’application Flex. Si vous voulez
accéder à des images stockées sur d’autres serveurs, vous devez utiliser un fichier crossdomain.xml.

Le contrôle Image
Le contrôle Image permet de façon basique de :
j spécifier le chemin vers l’image ;
j redimensionner l’image ;
j positionner l’image sur le Canvas.

La propriété source de ce contrôle permet de spécifier le chemin absolu ou relatif, ou un


URL de l’image que vous voulez importer. Si le chemin est relatif, Flex ira chercher
l’image dans le dossier contenant le fichier utilisant le tag.
Pour importer une image à la compilation, la propriété source a l’allure suivante :
<mx:Image source="@Embed(’source=images/test.jpg’)" />

115
3 Réaliser sa première interface

Dans cet exemple, la taille et la position de l’image ont les valeurs par défaut. Il s’agit
d’un chemin relatif, donc Flex ira chercher l’image dans le répertoire images à la racine
de l’application. Dans la mesure où il s’agit d’une image importée à la compilation, la
valeur de l’attribut source ne peut pas être un URL.

Le dossier images

Il est primordial de rester organisé et de toujours savoir où se trouvent les ressources afin de pouvoir y
accéder facilement. C’est pourquoi, lorsque vous utilisez des images, il est fortement recommandé de créer
un nouveau dossier images à la racine de votre application et d’y stocker vos images statiques.

Pour importer une image à l’exécution, la propriété source a l’allure suivante :


<mx:Image source="http://www.monDomaine.com/images/test.jpg" />

Comme nous n’utilisons pas ici @Embed dans la propriété source, l’image sera importée
à l’exécution. Nous avons ici importé une image présente sur Internet mais nous aurions
pu mettre un chemin local. Notez également que les images de type SVG ne peuvent pas
être importées à l’exécution mais seulement à la compilation.

Le flag de compilation use−network

Lorsque le flag use−network est à false, vous pouvez utiliser des ressources du système de fichier local,
mais pas à travers le réseau. La valeur par défaut de ce flag est à true, ce qui vous permet d’accéder
aux ressources via le réseau mais pas via le système de fichier local.

Vous pouvez importer plusieurs fois la même image avec la même syntaxe ; Flex ne
chargera l’image qu’une seule fois et référencera ensuite cette image lors des autres
appels.
Si vous voulez changer d’image pendant l’exécution (par exemple passer à la photo
suivante sur un album photo), vous pouvez utiliser en ActionScript la méthode load sur
votre objet Image.
private function getNextImage(name:String):void {
var imageSource:String = ’images/’ + name + ’.jpg’;
image1.load(imageSource);
}

La méthode load va chercher l’image spécifiée comme le montre le bref exemple plus
haut. Il s’agit d’un chemin sur le système de fichier local or, on accède à une ressource

116
Les contrôles simples 3

lors de l’exécution, il ne faut donc pas oublier de compiler l’application avec le flag
use−network=true.

Redimensionner une image


Le redimensionnement d’une image, via les attributs width et height qui vous sont
familiers, conserve les proportions de l’image. Prenons pour exemple une image carrée
dont la taille originale est de 100 × 100 pixels et le tag suivant :
<mx:Image source="test.jpg" height="150" width="200" />

La zone du composant n’étant pas carrée, Flex redimensionne l’image au format


150 × 150 pixels, la taille la plus grande possible qui conserve les proportions de notre
image. L’espace restant 50 × 150 reste vide. Cependant, cet espace est réservé au contrôle
et aucun autre élément ne viendra le combler.
Si vous ne voulez pas maintenir les proportions lorsque vous redimensionnez une image,
utilisez la propriété maintainAspectRatio avec la valeur false.

Utiliser les Text Controls


Il existe cinq contrôles pour gérer l’affichage de vos textes et permettre à vos utilisateurs
d’écrire du texte dans votre application.

Afficher du texte
Vous avez pour cela deux contrôles possibles : le Label et le Text. Ces deux contrôles ne
peuvent pas être édités par vos utilisateurs et se différencient par le fait que le premier
affiche un texte sur une seule ligne tandis que le second est utilisé pour afficher un texte
sur plusieurs lignes.
La propriété text de ces contrôles permet de spécifier la chaîne de caractères à afficher.
La manière de spécifier les caractères spéciaux dépend du contexte d’utilisation de la
propriété (en MXML ou en ActionScript). Pour éviter de trop nombreux conflits, vous
pouvez utiliser une section CDATA lorsque votre texte comporte des caractères spéciaux en
utilisant la propriété text comme un élément fils du contrôle Text comme ceci :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Text width="100%">
<mx:text>
<![CDATA[Ce texte contient un chevron inférieur < et supérieur >,
une esperluette &, une apostrophe, ’, un mot-clé du langage
➥ return,

117
3 Réaliser sa première interface

et des guillemets ".]]>


</mx:text>
</mx:Text>
</mx:Application>

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 <b> <i> <a> <p> <li> ou <img>. L’exemple suivant montre un texte formaté en
HMTL avec des options de style provenant du contrôle :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
➥ backgroundColor="white">
<mx:Text width="100%" color="blue" fontStyle="bold" fontSize="12">
<mx:htmlText>
<![CDATA[
Ceci est un text
<ul><li>bleu</li>
<li>de taille 12</li>
<li>gras</li><ul>
<i><font color="#000000" size="10">
Ce texte est de taille 10 en noir et en italique.
</font></i>]]>
</mx:htmlText>
</mx:Text>
</mx:Application>

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 <font> 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 :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:TextArea id="textConfirm" width="300" height="100"
text="Votre messqge de confirmation! "/>
</mx:Application>

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 un TextArea permettant à l’utilisateur de saisir son texte ;
j 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.
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
[Bindable]
public var htmlTextData:String="<b>titre1</b><br>blablabla";
]]>
</mx:Script>
<mx:RichTextEditor id="rte" title="Rich Text Editor Control"
➥ htmlText="{htmlTextData}"/>
</mx:Application>

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 :
<mx:DataGrid width="100%" height="100%">
<mx:columns>
<mx:DataGridColumn headerText="Prénom" dataField="firstName"/>
<mx:DataGridColumn headerText="Nom" dataField="lastName"/>
</mx:columns>
</mx:DataGrid>

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.
<mx:dataProvider>
<mx:ArrayCollection>
<mx:Object firstName="Blandine" lastName="Dupont"/>
<mx:Object firstName="Jean" lastName="Frochen"/>
</mx:ArrayCollection>
</mx:dataProvider>

122
Mise en pratique : une interface d’annuaire 3

Chaque propriété des tags <mx:Object> 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 :
<mx:HBox width="100%">
<mx:TextInput text="recherche" width="100%" height="100%"/>
<mx:Image source="http://www.philatelie.free.fr/img/search.gif"
width="25" height="25" />
</mx:HBox>

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 :
<mx:Image source="@Embed(images/search.gif’)" width="25" height="25" />

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 :
<mx:Label x="105" y="10" text="{list.selectedItem.firstName}"/>

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 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.
j 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.
j 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 :
<mx:Script>
<![CDATA[
import mx.controls.Alert;

private function myListener(event:Event):void {


Alert.show("Evénement déclenché");

129
4 Gérer les événements

]]></mx:Script>

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 <mx:Button> de la
manière suivante :
<mx:Button id="myButton" label="Cliquer ici" click="myListener()"/>

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
Les événements clavier 4

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 <mx:Application /> 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 :
<mx:TextInput id="my_input" />
<mx:Label id="my_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 :
<mx:TextInput id="my_input" keyUp="autoFill()" />

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 :
<mx:Button id="myButton" label="Ctrl+click" click="autoFill()"/>

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 :
<mx:Button id="myButton" label="Click"
click="myInput.dispatchEvent(new Event(Event.CHANGE))"/>

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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">

</mx:Application>

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 Title : Mon petit convertisseur ;
j Width : 500 ;
j Height : 200 ;
j X : 20 ;
j 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 :
<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">

<mx:Panel x="20" y="20" width="500" height="200"


layout="absolute"
title="Mon petit convertisseur">
<mx:Label x="25" y="37" text="Prix en euros"/>
<mx:Label x="120" y="65" id="resultText"/>
<mx:TextInput x="120" y="35" id="priceInput"/>
<mx:Button x="290" y="35" label="Convertir en dollar"/>
</mx:Panel>

</mx:Application>

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 <mx:Script> 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.
<mx:Script>
<![CDATA[
private function priceCopy():void{
resultText.text = priceInput.text;
}

private function priceConvert():void{


var result:int = parseInt(priceInput.text);

result = result * 1.38;


resultText.text += " euros = " + result.toString() + " dollars";

140
Mise en pratique : un convertisseur de devises 4

}
]]>
</mx:Script>

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 :
<mx:TextInput x="120" y="35" id="priceInput" keyUp="priceCopy()"/>
<mx:Button x="290" y="35" label="Convertir en dollars"
click="priceConvert()"/>

Le TextInput réagira donc à la frappe du clavier et le bouton à un clic.


Au final, votre code devrait ressembler à ceci :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">
<mx:Script>
<![CDATA[
private function priceCopy():void{
resultText.text = priceInput.text;
}

private function priceConvert():void{


var result:int = parseInt(priceInput.text);

result = result * 1.38;


resultText.text += " euros = " + result.toString() + " dollars";
}
]]>
</mx:Script>

141
4 Gérer les événements

<mx:Panel x="20" y="20" width="500" height="200" layout="absolute"


title="Mon petit convertisseur">
<mx:Label x="25" y="37" text="Prix en euros"/>
<mx:Label x="120" y="65" id="resultText" fontSize="20"/>
<mx:TextInput x="120" y="35" id="priceInput" keyUp="priceCopy()"/>
<mx:Button x="290" y="35" label="Convertir en dollar"
click="priceConvert()"/>
</mx:Panel>

</mx:Application>

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 <mx:Application> :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" creationComplete="initEvents()">

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 <mx:Form>, vous pourrez utiliser des propriétés qui vous
simplifieront la tâche au quotidien :
j organisation des composants en les alignant à gauche ;
j accès à un bouton de soumission du formulaire ;
j définition de champs obligatoires ;
j validation de vos données ;
j 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 <mx:FormHeading> : permet d’afficher des titres pour des groupes d’items. C’est un
élément optionnel.
<mx:FormItem> : ce sont les champs du formulaire mais également des conteneurs.
j
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 <mx:Form>
mais certains de ses attributs permettent de jouer avec des paramètres comme les

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 le statut ;
j un nom ;
j un prénom ;
j une date de naissance ;
j un numéro de téléphone ;
j une adresse e-mail ;
j 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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
public function printUser():void
{
Alert.show("Données de l’utilisateur.",
"Nouvel utilisateur !");
}
]]>
</mx:Script>
<mx:Panel title="Inscription">
<mx:Form defaultButton="{print}">
<mx:FormHeading label="Détails"/>
<mx:FormItem>
<mx:ComboBox id="title">
<mx:dataProvider>
<mx:String>Mr</mx:String>
<mx:String>Mme</mx:String>
<mx:String>Mlle</mx:String>
</mx:dataProvider>
</mx:ComboBox>
</mx:FormItem>

147
5 Gérer les données

<mx:FormItem label="Prénom">
<mx:TextInput id="firstname"/>
</mx:FormItem>
<mx:FormItem label="Nom">
<mx:TextInput id="lastname"/>
</mx:FormItem>
<mx:FormItem label="Date de naissance">
<mx:TextInput id="birthday"/>
</mx:FormItem>
<mx:FormItem label="Numéro de téléphone">
<mx:TextInput id="phone"/>
</mx:FormItem>
<mx:FormItem label="Adresse email">
<mx:TextInput id="email"/>
</mx:FormItem>
<mx:FormItem label="Code postal">
<mx:TextInput id="zipcode"/>
</mx:FormItem>
</mx:Form>
<mx:ControlBar horizontalAlign="center">
<mx:Button id="print" label="Afficher l’utilisateur"
click="printUser()"/>
</mx:ControlBar>
</mx:Panel>
</mx:Application>

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 <mx:Model>
Les data models sont des objets ActionScript. Le moyen le plus simple de créer un data
model est d’utiliser la balise <mx:Model> 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 <mx:Model> 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 :
<mx:Model id="usermodel">
<user>
<title/>
<name>
<first/>
<last/>
</name>
<birthday/>
<phone/>
<email/>
<zipcode/>
</user>
</mx:Model>

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 :
<mx:Model id="usermodel">
<user>
<title>Mr</title>
<name>
<first>Edouard</first>
<last>Ruiz</last>
</name>
<birthday>10/05/1984</birthday>
<phone>0654321098</phone>
<email>edouard@yahoo.com</email>

149
5 Gérer les données

<zipcode>94130</zipcode>
</user>
</mx:Model>

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 :
<title>{""}</title>

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) :
<mx:Model id="usermodel">
<user>
<title>{title.value}</title>
<name>
<first>{firstname.text}</first>
<last>{lastname.text}</last>
</name>
<birthday>{birthday.text}</birthday>

150
Définir un data model 5

<phone>{phone.text}</phone>
<email>{email.text}</email>
<zipcode>{zipcode.text}</zipcode>
</user>
</mx:Model>

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
<?xml version="1.0"?> 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 : <mx:Model source="User.xml" id="usermodel"/>.

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 <mx:XML>
À la place de la balise <mx:Model>, vous pouvez utiliser <mx:XML> 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 <mx:XML> :


<mx:XML id="usermodel" format="e4x">
<user>
<title>{title.value}</title>
<name>
<first>{firstname.text}</first>
<last>{lastname.text}</last>
</name>
<birthday>{birthday.text}</birthday>
<phone>{phone.text}</phone>
<email>{email.text}</email>
<zipcode>{zipcode.text}</zipcode>
</user>
</mx:XML>

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 <mx:XML> 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
<mx:Script>. 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 <mx:Script> 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:"edouard@yahoo.com",
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 UserModel
{
public var title:String = "Mr";
public var firstname:String;
public var lastname:String;
public var birthday:Date;
public var phone:String;
public var email:String;
public var 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 <mx:Application>, le namespace model (ou tout autre nom) :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" xmlns:model="model.*">

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 :
<model:UserModel id="usermodel"/>

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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" xmlns:model="model.*">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
public function printUser():void
{
Alert.show(usermodel.getResume(), "Nouvel utilisateur !");
}
]]>
</mx:Script>

<model:UserModel id="usermodel"/>

<mx:Panel title="Inscription">
<mx:Form defaultButton="{print}">
<mx:FormHeading label="Détails"/>
<mx:FormItem>
<mx:ComboBox id="title"

154
Définir un data model 5

change="{usermodel.title = title.text;}">
<mx:dataProvider>
<mx:String>Mr</mx:String>
<mx:String>Mme</mx:String>
<mx:String>Mlle</mx:String>
</mx:dataProvider>
</mx:ComboBox>
</mx:FormItem>
<mx:FormItem label="Prénom">
<mx:TextInput id="firstname"
change="{usermodel.firstname = firstname.text;}"/>
</mx:FormItem>
<mx:FormItem label="Nom">
<mx:TextInput id="lastname"
change="{usermodel.lastname = lastname.text;}"/>
</mx:FormItem>
<mx:FormItem label="Date de naissance">
<mx:TextInput id="birthday"
change="{usermodel.birthday = new Date(birthday.text);}"/>
</mx:FormItem>
<mx:FormItem label="Numéro de téléphone">
<mx:TextInput id="phone"
change="{usermodel.phone = phone.text;}"/>
</mx:FormItem>
<mx:FormItem label="Adresse email">
<mx:TextInput id="email"
change="{usermodel.email = email.text}"/>
</mx:FormItem>
<mx:FormItem label="Code postal">
<mx:TextInput id="zipcode"
change="{usermodel.zipcode = uint(zipcode.text);}"/>
</mx:FormItem>
</mx:Form>
<mx:ControlBar horizontalAlign="center">
<mx:Button id="print" label="Afficher l’utilisateur"
click="printUser()"/>
</mx:ControlBar>
</mx:Panel>
</mx:Application>

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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">
<mx:Panel title="Data binding">
<mx:Form>
<mx:FormItem label="Nom">
<mx:TextInput id="lastname"/>
</mx:FormItem>
</mx:Form>
<mx:Label id="res"/>
</mx:Panel>
</mx:Application>

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 :
<mx:Label id="res" text="{lastname.text}"/>

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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">
<mx:Model id="personn">
<personn>
<title>{man.selected ? "Mr" : "Mme"}</title>
<name>{"De " + lastname.text}</name>
<age>{int(age.text) / 2}</age>
</personn>
</mx:Model>
<mx:Panel title="Data binding">
<mx:Form>
<mx:FormItem>
<mx:RadioButton id="man" label="Mr" groupName="title"
selected="true"/>
<mx:RadioButton id="woman" label="Mme" groupName="title"/>
</mx:FormItem>
<mx:FormItem label="Nom">
<mx:TextInput id="lastname"/>
</mx:FormItem>
<mx:FormItem label="Age">
<mx:TextInput id="age"/>
</mx:FormItem>
</mx:Form>
<mx:Label id="res" text="{personn.title + ’ ’ + personn.name
+ ’ a ’ + personn.age + ’ ans.’}"/>
</mx:Panel>
</mx:Application>

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 <mx:Binding> en MXML


Au lieu d’utiliser les accolades, vous pouvez également faire appel à la balise
<mx:Binding> 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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">
<mx:Binding source="lastname.text" destination="res.text"/>
<mx:Panel title="Data binding">
<mx:Form>
<mx:FormItem label="Nom">
<mx:TextInput id="lastname"/>
</mx:FormItem>
</mx:Form>
<mx:Label id="res"/>
</mx:Panel>
</mx:Application>

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 :
<mx:Binding source="’Texte : ’ + lastname.text" destination="res.text"/>

ou avec des accolades :


<mx:Binding source="{’Texte : ’ + lastname.text}" destination="res.text"/>

et :
<mx:Binding source="’Texte : ’ + {lastname.text}" destination="res.text"/>

Mais la balise Binding a d’autres atouts.

Plusieurs sources ou plusieurs destinations


Que ce soit avec les accolades ou avec la balise <mx:Binding>, 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 :
<mx:Binding source="lastname.text" destination="res2.text"/>

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 :
<mx:Binding source="lastname.text" destination="res.text"/>

159
5 Gérer les données

<mx:Binding source="firstname.text" destination="res.text"/>


<mx:Panel title="Data binding">
<mx:Form>
<mx:FormItem label="Nom">
<mx:TextInput id="lastname"/>
</mx:FormItem>
<mx:FormItem label="Prénom">
<mx:TextInput id="firstname"/>
</mx:FormItem>
</mx:Form>
<mx:Label id="res"/>
</mx:Panel>

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 :
<mx:Script>
<![CDATA[
import mx.binding.utils.BindingUtils;
private function initializeHandler():void
{
BindingUtils.bindProperty(res, "text", lastname, "text");
}
]]>
</mx:Script>

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 CreditCardValidator : les numéros de carte de crédit ;
j CurrencyValidator : les sommes d’argent ;
j DateValidator : les dates ;
j EmailValidator : les e-mails ;
j NumberValidator : les nombres ;
j PhoneNumberValidator : les numéros de téléphone ;
j RegExpValidator : les expressions régulières ;
j SocialSecurityValidator : les numéros de sécurité sociale ;
j StringValidator : les chaînes de caractères selon des critères ;
j ZipCodeValidator : les codes postaux.

Pour utiliser un validateur en MXML, il faut utiliser la balise <mx:Validator> 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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">

161
5 Gérer les données

<mx:PhoneNumberValidator id="phoneValidator" source="{phone}"


➥ property="text"/>
<mx:Panel title="Validation">
<mx:TextInput id="phone"/>
<mx:TextInput id="nothing"/>
</mx:Panel>
</mx:Application>

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

<mx:Script>
<![CDATA[
import mx.validators.PhoneNumberValidator;
private var validator:PhoneNumberValidator = new PhoneNumberValidator();
private function linkValidator():void
{
validator.source = phone;
validator.property = "text";
}
]]>
</mx:Script>
<mx:Panel title="Validation">
<mx:TextInput id="phone" creationComplete="linkValidator();"/>
<mx:TextInput id="nothing"/>
</mx:Panel>

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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" creationComplete="focusManager.setFocus(firstname);">
<mx:Script>
<![CDATA[
import mx.validators.Validator;
import mx.events.ValidationResultEvent;
import mx.controls.Alert;

163
5 Gérer les données

[Bindable]
public var formIsValid:Boolean = false;
private function printUser():void
{
Alert.show("Formulaire validé.", "Nouvel utilisateur !");
}
private function validateForm(event:Event):void
{
var resultTmp:ValidationResultEvent;
formIsValid = false;
if (firstname.text == "")
return;
resultTmp = firstnamevalid.validate();
if (resultTmp.type == ValidationResultEvent.INVALID)
return;
if (birthday.text == "")
return;
resultTmp = birthdayvalid.validate();
if (resultTmp.type == ValidationResultEvent.INVALID)
return;
if (phone.text == "")
return;
resultTmp = phonevalid.validate();
if (resultTmp.type == ValidationResultEvent.INVALID)
return;
if (email.text == "")
return;
resultTmp = emailvalid.validate();
if (resultTmp.type == ValidationResultEvent.INVALID)
return;
if (zipcode.text == "")
return;
resultTmp = zipcodevalid.validate();
if (resultTmp.type == ValidationResultEvent.INVALID)
return;
formIsValid = true;
}
]]>
</mx:Script>
<mx:StringValidator id="firstnamevalid" source="{firstname}"
property="text" minLength="2"/>
<mx:DateValidator id="birthdayvalid" source="{birthday}" property="text"/>
<mx:PhoneNumberValidator id="phonevalid" source="{phone}" property="text"/>
<mx:EmailValidator id="emailvalid" source="{email}" property="text"/>
<mx:ZipCodeValidator id="zipcodevalid" source="{zipcode}" property="text"/>
<mx:Panel title="Inscription">
<mx:Form defaultButton="{print}">

164
Valider des données 5

<mx:FormHeading label="Détails"/>
<mx:FormItem label="Prénom">
<mx:TextInput id="firstname" change="validateForm(event);"/>
</mx:FormItem>
<mx:FormItem label="Date de naissance">
<mx:TextInput id="birthday" change="validateForm(event);"/>
</mx:FormItem>
<mx:FormItem label="Numéro de téléphone">
<mx:TextInput id="phone" change="validateForm(event);"/>
</mx:FormItem>
<mx:FormItem label="Adresse email">
<mx:TextInput id="email" change="validateForm(event);"/>
</mx:FormItem>
<mx:FormItem label="Code postal">
<mx:TextInput id="zipcode" change="validateForm(event);"/>
</mx:FormItem>
</mx:Form>
<mx:ControlBar horizontalAlign="center">
<mx:Button id="print" label="Afficher l’utilisateur"
click="printUser();" enabled="{formIsValid}"/>
</mx:ControlBar>
</mx:Panel>
</mx:Application>

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 :
<mx:PhoneNumberValidator id="phonevalid" wrongLengthError="Nouveau
➥ message"/>

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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" xmlns:Comp="components.*">
<Comp:CompleteNameValidator source="{fullName}" property="text"/>
<mx:Panel title="Validation">
<mx:TextInput id="fullName"/>
<mx:TextInput id="nothing"/>
</mx:Panel>
</mx:Application>

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 CurrencyFormatter : des sommes d’argent ;
j DateFormatter : les dates ;
j NumberFormatter : les nombres ;
j PhoneFormatter : les numéros de téléphone ;
j 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 <mx:CurrencyFormatter> 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.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">
<mx:CurrencyFormatter id="formatter"
precision="2"
alignSymbol="right"
decimalSeparatorTo="."
thousandsSeparatorTo=" "
currencySymbol=" "
rounding="nearest"/>
<mx:Panel title="Formatage de données">
<mx:TextInput id="currency"/>
<mx:Label id="formattedCurrency" text="Prix :
➥ {formatter.format(currency.text)}"/>
</mx:Panel>
</mx:Application>

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 :
<mx:Script>
<![CDATA[
import mx.controls.Alert;
private function printError():void
{
Alert.show(formatter.error, "Erreur du formateur");
}

169
5 Gérer les données

]]>
</mx:Script>

Cette fonction sera appelée par un bouton situé dans le panel :


<mx:Button id="prError" label="Affiche l’erreur" click="printError();"/>

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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" defaultButton="{addDate}">
<mx:ArrayCollection id="dates"/>
<mx:Panel title="Formatage de données">
<mx:List id="datesList" dataProvider="{dates}">
<mx:itemRenderer>
<mx:Component>
<mx:VBox>
<mx:DateFormatter id="dateFormatter"
formatString="EEEE, MMMM DD, YYYY"/>
<mx:Label text="{dateFormatter.format(data)}"/>
</mx:VBox>
</mx:Component>
</mx:itemRenderer>
</mx:List>
<mx:TextInput id="input"/>

170
Travailler avec XML 5

<mx:ControlBar>
<mx:Button id="addDate" click="dates.addItem(input.text)"
label="Ajouter une date"/>
</mx:ControlBar>
</mx:Panel>
</mx:Application>

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 =
<users>
<user id="1">
<name>
<firstname>Edouard</firstname>
<lastname>Ruiz</lastname>
</name>
<age>23</age>
<email>toto@gmail.com</email>
</user>
<user id="2">
<name>
<firstname>Vianney</firstname>
<lastname>Baron</lastname>
</name>
<age>21</age>
<email>titi@gmail.com</email>
</user>
</users>

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 :
<mx:Panel title="Données en XML">
<mx:Text id="all" text="{’Objet XML :\r’+ userList.user}"/>
<mx:Label id="age" text="{’Age de l\’utilisateur en position 0 : ’ +
➥ userList.user[0].age}"/>
<mx:Label id="firstname" text="{’Prénom de l\’utilisateur ayant l\’id
➥ 2 : ’ + userList.user.(@id == 2).name.firstname}"/>
</mx:Panel>

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 :
<mx:Form>
<mx:FormItem label="Prénom">
<mx:TextInput
id="firstname"
text="{userList.user[0].name.firstname}"
change="{userList.user[0].name.firstname = firstname.text}"
/>
</mx:FormItem>
<mx:FormItem label="Nom">
<mx:TextInput
id="lastname"
text="{userList.user[0].name.lastname}"
change="{userList.user[0].name.lastname = lastname.text}"
/>

173
5 Gérer les données

</mx:FormItem>
<mx:FormItem label="Age">
<mx:TextInput
id="age"
text="{userList.user[0].age}"
change="{userList.user[0].age = age.text}"
/>
</mx:FormItem>
<mx:FormItem label="Email">
<mx:TextInput
id="email"
text="{userList.user[0].email}"
change="{userList.user[0].email = email.text}"
/>
</mx:FormItem>
</mx:Form>

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 :
<mx:DataGrid id="list" dataProvider="{userList.user}">
<mx:columns>
<mx:DataGridColumn dataField="@id"/>
<mx:DataGridColumn headerText="name">
<mx:itemRenderer>
<mx:Component>
<mx:Label text="{data.name.firstname + ’ ’ +
➥ data.name.lastname}"/>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
<mx:DataGridColumn dataField="age"/>
<mx:DataGridColumn dataField="email"/>
</mx:columns>
</mx: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 c Fig. 6.1 :
positionnements d’éléments différents. La balise Exemple de List
<mx:List> dispose les éléments de façon verticale
avec une barre de défilement latérale, la balise
<mx:HorizontalList> dispose les différents items
horizontalement et <mx:ComboBox> crée une liste déroulante.
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 <mx:String> comme balises
filles de <mx:List>. En effet, Flex interprète une succession de balises <mx:String>
comme un tableau :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:List id="ville_nievre">
<mx:dataProvider>
<mx:String>Nevers</mx:String>
<mx:String>Château-Chinon</mx:String>
<mx:String>Cosne-sur-Loire</mx:String>
</mx:dataProvider>
</mx:List>
</mx:Application>

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 :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
public function printData() : void
{
Alert.show("La ville sélectionnée par l’utilisateur est "
+ville_nievre.selectedItem.data);
}
]]>
</mx:Script>
<mx:List id="ville_nievre" click="printData()">
<mx:Object label="Ne" data="Nevers"/>
<mx:Object label="CC" data="Château-Chinon"/>
<mx:Object label="CL" data="Cosne-sur-Loire"/>
</mx:List>
</mx:Application>

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

<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">
<mx:Script>
<![CDATA[
import mx.collections.*;
import mx.controls.Image;
private var imgArray:ArrayCollection;
private var cat:Array = ["img\\Alien1.bmp", "img\\Alien2.bmp",
"img\\Balloon.bmp", "img\\Bear.bmp"];
private function initImgList(items:Array):void
{
imgArray = new ArrayCollection(items);
imgList.dataProvider = imgArray;
}
]]>
</mx:Script>
<mx:HorizontalList id="imgList" columnWidth="50" rowHeight="50"
columnCount="4"
itemRenderer="mx.controls.Image"
creationComplete="initImgList(cat)"/>
</mx:Application>

Ainsi, nous avons simplement c Fig. 6.4 :


créé un ArrayCollection (dans le Exemple de liste d’images
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 :


<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Tree labelField="@label">
<mx:XMLListCollection id="C">
<mx:XMLList>
<folder label="C:\">
<folder label="Windows"/>
<folder label="Program Files">
<Pfolder label="Office" />
<Pfolder label="Flex" />
</folder>
<folder label="Documents and Settings" />
<folder label="Corbeille" />
</folder>
</mx:XMLList>
</mx:XMLListCollection>
</mx:Tree>
</mx:Application>

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
<?xml version="1.0" encoding="utf-8"?>
<mx:Form xmlns:mx="http://www.adobe.com/2006/mxml"
width="400" height="300">

</mx:Form>

À 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
<?xml version="1.0" encoding="utf-8"?>
<mx:Form xmlns:mx="http://www.adobe.com/2006/mxml" width="268"
➥ height="124">
<mx:FormItem label="Login :">
<mx:TextInput id="login" displayAsPassword="false" editable="true"/>

183
6 Aller vers une interface riche

</mx:FormItem>
<mx:FormItem label="Password :">
<mx:TextInput id="password" displayAsPassword="true"
editable="true"/>
</mx:FormItem>
<mx:FormItem>
<mx:Button label="S’enregistrer"/>
</mx:FormItem>
</mx:Form>

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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:mcmp="components.*"
layout="absolute">

Vous remarquez que dans l’exemple précédent deux namespaces sont déclarés :
j mx, qui pointe à tous les composants fournis avec Flex et référencés dans le fichier
sur lequel pointe l’adresse Internet.
j 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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:mcomp="components.*"
layout="absolute">
<mx:Panel title="login">
<mcomp:Form_login />
</mx:Panel>
</mx: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 <mx:String>, <mx:Boolean> et
<mx:Number> 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 :
<mx:String id="test_de_propriete">Valeur par défaut</mx:String>

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 :
<!-- Exemples de propriétés chaîne de caractères : -->
<mx:String id="maPropriete">Bonjour, {NomUtilisateur}.</mx:String>
<mx:String id="maPropriete1"
source="http://www.exemple.com/fichier_test"/>

186
Créer ses propres composants 6

<!-- Exemples de propriétés nombre : -->


<mx:Number id="maPropriete2">15</mx:Number>
<mx:Number id="heures">{numJours * 24}</mx:Number>

<!-- Exemples de propriétés booléen : -->


<mx:Boolean id="maPropriete3">true</mx:Boolean>
<mx:Boolean id="status_connection">{isConnected}</mx:Boolean>

Maintenant, vous imaginez que pour utiliser ces propriétés dans vos propres composants
MXML, il suffit d’indiquer grâce aux balises que nous venons d’étudier quelles sont
celles dont vous avez besoin. Ensuite, la valeur de la propriété est passée en paramètre
lors de l’appel du composant :

ComboBoxRemplie.mxml
<?xml version="1.0"?>

<mx:ComboBox xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:String id="maPropriete"/>
<mx:dataProvider>
<mx:Array>
<mx:String>A</mx:String>
<mx:String>B</mx:String>
<mx:String>{maPropriete}</mx:String>
</mx:Array>
</mx:dataProvider>
</mx:ComboBox>

Voici comment renseigner la propriété maPropriete lors de l’appel du composant


ComboBoxPreRemplie :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:mcmp="components.*">
<mcmp:ComboBoxPreRemplie id="test" maPropriete="C" />
</mx:Application>

Vous pouvez donc remarquer qu’il est très aisé de renseigner la propriété définie dans le
composant MXML personnalisé.

En ActionScript
La balise <mx:Script> permet bien sûr de définir des propriétés ou des méthodes dans les
composants que vous fabriquez vous-même.

187
6 Aller vers une interface riche

Position de la balise <mx:Script>

La balise <mx:Script> doit être un enfant immédiat de la racine du fichier MXML.

Toute déclaration publique de fonctions ou de variables devient alors une méthode ou une
propriété du composant créé.
Par exemple, voici un bout de code dans lequel maPropriete et get_propriete() sont une
propriété et une méthode du composant monTextArea :
<?xml version="1.0"?>
<!-- monTextArea.mxml -->
<mx:TextArea xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
// Ici la variable qui devient de fait propriété du composant :
public function get_propriete() : String {

// Cette fonction est une méthode du composant


public function get_propriete() {
return "Le nombre indiqué dans la propriété maPropriete est : "
+ maPropriete;
}
]]>
</mx:Script>
</mx:TextArea>

Vous pouvez utiliser la méthode ainsi définie dans votre application Flex :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:mcmp="components.*">
<mcmp:monTextArea id="mta" maPropriete="4"
change="ta1.text = mta.get_propriete();"/>
<mx:TextArea id="ta1" width="300" height="150" />
</mx:Application>

À 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 déclaration d’un namespace ;
j 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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">

</mx:Application>

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 <mx:Box> :
<?xml version="1.0" encoding="utf-8"?>
<mx:Box xmlns:mx="http://www.adobe.com/2006/mxml">

</mx:Box>

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 <mx:columns> qui est un
conteneur pour les trois éléments <mx:DataGridColumn>. De plus, modifiez la propriété
headerText des trois colonnes afin de leur donner des noms significatifs :
<?xml version="1.0" encoding="utf-8"?>
<mx:Box xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:DataGrid id="masterList" columnWidth="200" >
<mx:columns>
<mx:DataGridColumn headerText="Id" dataField="col1"/>
<mx:DataGridColumn headerText="Nom" dataField="col2"/>
<mx:DataGridColumn headerText="Prénom" dataField="col3"/>
</mx:columns>

192
Mise en pratique : une interface maître-détail 6

</mx:DataGrid>
</mx:Box>

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 :
<?xml version="1.0" encoding="utf-8"?>
<collec>
<user>
<id>1</id>
<firstname>Edouard</firstname>
<lastname>Ruiz</lastname>
<birthday>10/05/1984</birthday>
<phone>0654321098</phone>
<email>edouard@yahoo.com</email>
<zipcode>94130</zipcode>
</user>
<user>
<id>2</id>
<firstname>Vianney</firstname>
<lastname>Baron</lastname>
<birthday>14/07/1985</birthday>
<phone>0658982345</phone>
<email>vianney@yahoo.com</email>
<zipcode>75017</zipcode>
</user>
<user>
<id>3</id>
<firstname>Jessy</firstname>
<lastname>Bernal</lastname>

193
6 Aller vers une interface riche

<birthday>23/01/1985</birthday>
<phone>0698235455</phone>
<email>Jessy@yahoo.com</email>
<zipcode>94800</zipcode>
</user>
</collec>

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 :
<mx:Model source="..\collection.xml" id="col"/>

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 :
<mx:Binding source="col.user" destination="detail.dataProvider" />

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 <mx:DataGridColumn> :
<?xml version="1.0" encoding="utf-8"?>
<mx:Box xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Model id="col" source="..\collection.xml" />
<mx:Binding source="col.user" destination="masterList.dataProvider" />
<mx:DataGrid id="masterList" columnWidth="200" >
<mx:columns>
<mx:Array>
<mx:DataGridColumn headerText="Id" dataField="id"/>
<mx:DataGridColumn headerText="Nom" dataField="lastname"/>
<mx:DataGridColumn headerText="Prénom" dataField="firstname"/>
</mx:Array>
</mx:columns>
</mx:DataGrid>
</mx:Box>

En faisant appel à ce nouveau module dans le fichier MasterDetail.mxml, nous obtenons


le résultat escompté :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
xmlns:master="components.master.*">
<master:master />
</mx:Application>

194
Mise en pratique : une interface maître-détail 6

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 : <mx:Script> et </mx:Script>.
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 <mx:Binding> et en rajouter
une nouvelle :

196
Mise en pratique : une interface maître-détail 6

/* …Début du fichier… */
<mx:Model id="col" source="..\collection.xml" />
<mx:Binding source="col.user" destination="arrayUser.source" />
<mx:Binding source="arrayUser" destination="masterList.dataProvider" />
<mx:ArrayCollection id="arrayUser"/>
<mx:DataGrid id="masterList" allowMultipleSelection="false">
/* …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 <mx:DataGrid> 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 <mx:Box> 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 :
<mx:Form>
<mx:FormItem label="Nom :">
<mx:TextInput id="lastname" text=""/>
</mx:FormItem>
<mx:FormItem label="Prénom :">
<mx:TextInput id="firstname"/>
</mx:FormItem>
<mx:FormItem label="Date de naissance :">
<mx:TextInput id="birthday"/>
</mx:FormItem>
<mx:FormItem label="Adresse email :">
<mx:TextInput id="email"/>
</mx:FormItem>
<mx:FormItem label="Numéro de téléphone :">
<mx:TextInput id="phone"/>
</mx:FormItem>
<mx:FormItem label="Code postal :">
<mx:TextInput id="zipcode"/>
</mx:FormItem>
</mx:Form>

Faites bien attention à fournir à chaque balise <mx:TextInput> 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 :
<mx:Script>
<![CDATA[
import components.User;

public function applyChange (user:User) : void


{
lastname.text = user.getLastName();
firstname.text = user.getFirstName();
birthday.text = user.getBirthDay();
email.text = user.getEmail();
phone.text = user.getPhone();
zipcode.text = user.getZipCode();
}
]]>
</mx:Script>

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) :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
xmlns:master="components.master.*" xmlns:detail="components.detail.*">

Et ensuite, vous insérez la balise correspondante à chaque module dans le corps du


fichier :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
xmlns:master="components.master.*" xmlns:detail="components.detail.*">

199
6 Aller vers une interface riche

<master:master id="masterInterface"/>
<detail:detail id="detailInterface"/>
</mx:Application>

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 <master:master> 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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
xmlns:master="components.master.*" xmlns:detail="components.detail.*">
<mx:Script>
<![CDATA[
private function transfertUser() : void
{
detailInterface.applyChange(masterInterface.getUser());
}
]]>
</mx:Script>
<mx:VBox horizontalAlign="center">
<master:master id="masterInterface" click="transfertUser()"/>
<mx:HRule width="338" height="3"/>
<detail:detail id="detailInterface"/>
</mx:VBox>
</mx:Application>

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 <mx:Application> 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 Taille par défaut : une ViewStack adopte la largeur et la hauteur du conteneur
affiché par défaut.
j Redimensionnement : une ViewStack ne change pas de taille lorsque le conteneur
actif change, il faut pour cela utiliser la propriété resizeToContent.
j 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
<mx:ViewStack> 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.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical">
<mx:ViewStack id="myVs" borderStyle="solid"
backgroundColor="white">
<mx:HBox id="hb1" label="conteneur 1"
width="600" height="600" >
<mx:Label text="Le conteneur 1 est affiché"
fontSize="26"/>
</mx:HBox>

<mx:HBox id="hb2" label="conteneur 2" width="600" height="600">


<mx:Label text="Le conteneur 2 est affiché"
fontSize="26"/>
</mx:HBox>

<mx:HBox id="hb3" label="conteneur 3" width="800" height="600">


<mx:Label text="Le conteneur 3 est affiché"
fontSize="26"/>
<mx:Spacer width="200"/>
<mx:Label text="tronqué" fontSize="26" />
</mx:HBox>
</mx:ViewStack>
</mx:Application>

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 <mx:label> 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 : <mx:ViewStack id="myVs" selectedIndex="1">.

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 :
<mx:Script>
<![CDATA[
public function switchconteneur(event:Event) : void
{
myVs.selectedIndex =
parseInt(cb_switch.selectedLabel) - 1;
}
]]>
</mx:Script>
<mx:HBox>
<mx:ComboBox id="cb_switch"
change="switchconteneur(event)">
<mx:dataProvider>
<mx:Array>
<mx:String>1</mx:String>
<mx:String>2</mx:String>
<mx:String>3</mx:String>
</mx:Array>
</mx:dataProvider>
</mx:ComboBox>
<mx:Label text="Le conteneur actif est le numéro
{myVs.selectedIndex + 1} / {myVs.numChildren} :
{myVs.selectedChild.name} "/>
</mx:HBox>

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

<mx:ViewStack id="myVs" borderStyle="solid"


backgroundColor="white"resizeToContent="true">

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 :
j ButtonBar ;
j ToggleButtonBar ;
j LinkBar ;
j TabBar.

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é :


<mx:ButtonBar dataProvider="myVs" />

c Fig. 7.9 :
Une ToggleButtonBar

Le code à nouveau est le suivant :


<mx:ToggleButtonBar dataProvider="myVs" />

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 label : le nom qui sera affiché sur le bouton ;
j 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 :
<mx:ButtonBar>
<mx:dataProvider>
<mx:Array>
<mx:Object label="conteneur 1"
toolTip="Afficher le premier conteneur"
icon="@Embed(source=’soleil.gif’/>
<mx:Object label="conteneur 2"
toolTip="Afficher le deuxième conteneur"/>
<mx:Object label="conteneur 3"
toolTip="Afficher le dernier conteneur"/>
</mx:Array>
</mx:dataProvider>
</mx:ButtonBar>

Le résultat visuel est le suivant :


c Fig. 7.10 :
ButtonBar associé à un
tableau d’objets

Bien sûr, il ne se passe plus rien quand l’utilisateur clique sur le bouton puisque le
dataProvider n’est plus une ViewStack. C’est que nous allons examiner.
Les deux composants ButtonBar et ToggleControlBar fournissent un seul et unique
événement pour la gestion des boutons. Il s’agit de l’événement ItemClick, de type
ItemClickEvent, qui contient des informations relatives au bouton cliqué :
j label : titre du bouton cliqué ;
j index : indice du bouton (de 0 jusqu’à n-1 où n est le nombre d’éléments du
dataProvider).

Le composant LinkBar
Le composant LinkBar est relativement similaire aux deux composants que nous venons
de voir, la différence la plus notable se situant à nouveau dans le design. Cette fois, les
éléments ne sont plus représentés par des contrôles Button mais par des LinkButton qui
ont l’apparence de liens HTML classiques. Là encore, il est possible de spécifier un
dataProvider de type ViewStack ou d’en déclarer un via un tableau de chaîne de

212
Manipuler une ViewStack 7

caractères. Nous allons donc ajouter un élément LinkBar et un bout de code ActionScript
qui se déclenchera sur l’événement itemClick que nous venons de voir.
Commençons par la définition de l’élément avec son dataProvider :
<mx:LinkBar id="lBar">
<mx:dataProvider>
<mx:Array>
<mx:String>Adobe</mx:String>
<mx:String>Google</mx:String>
<mx:String>Sun</mx:String>
</mx:Array>
</mx:dataProvider>
</mx:LinkBar>

Ce qui devrait donner ceci :


c Fig. 7.11 :
Le composant LinkBar

Ajoutons maintenant une méthode pour ouvrir une nouvelle page web lorsque l’utilisateur
clique sur un élément de la barre en utilisant les propriétés d’un objet ItemClickEvent.
Nous allons à cet effet utiliser la méthode NavigateToUrl qui prend en paramètre un objet
de type URLRequest et une chaîne indiquant le mode d’ouverture. Voici le résultat final :
<mx:Script>
<![CDATA[
public function openWindow(event:ItemClickEvent) : void{
navigateToURL(new URLRequest(’http://www.’ +
String(event.item).toLowerCase() + ’.com’), ’_blank’);
}
]]>
</mx:Script>
<mx:LinkBar id="lBar" itemClick="openWindow(event)">
<mx:dataProvider>
<mx:Array>
<mx:String>Adobe</mx:String>
<mx:String>Google</mx:String>
<mx:String>Sun</mx:String>
</mx:Array>
</mx:dataProvider>
</mx:LinkBar>
</mx:Application>

213
7 Naviguer dans son application

Le composant TabBar
Le comportement de ce composant est très similaire aux trois autres contrôles. Encore une
fois, la différence la plus notable se situe au niveau du design. Nous allons donc en
profiter pour vous parler d’une dernière propriété de ce type d’élément. Dans l’exemple
du composant ButtonBar, le nom du bouton était indiqué par la propriété label de l’objet
car c’est celle-ci que Flex recherche par défaut.
C’est d’ailleurs exactement comme cela que les boutons sont nommés : lorsque le
dataProvider est une ViewStack (collection de conteneur), c’est la propriété label des
sous-conteneurs qui est alors utilisée. Il est cependant possible d’en spécifier une autre
grâce à la propriété labelField de la manière suivante :
<mx:TabBar labelField="autreNom">
<mx:dataProvider>
<mx:Object autreNom="Menu 1"/>
<mx:Object autreNom="Menu 2"/>
<mx:Object autreNom="Menu 3"/>
</mx:dataProvider>
</mx:TabBar>

c Fig. 7.12 :
Aspect visuel d’une TabBar

Dimension des conteneurs enfants


Comme nous vous l’avons indiqué en début de chapitre, une ViewStack et ses composants
dérivés ne se redimensionnent pas automatiquement lors du changement du conteneur
actif. Bien sûr, vous pouvez choisir de changer ce comportement grâce à la propriété
resizeToContent mais il vaut mieux éviter qu’un conteneur de navigation ne change de
taille à chaque modification, car cela déplacerait les composants voisins par la même
occasion.
Le plus simple serait donc que la ViewStack adopte la taille du plus grand de ses
éléments, et comme vous avez pu le constater ce n’est pas le cas puisque c’est la taille
du premier composant affiché qui est utilisée. Vous avez donc plusieurs solutions pour
dimensionner une ViewStack :
j Imposer une taille au conteneur ViewStack (en valeur absolue ou en utilisant le
pourcentage) avec les propriétés width et height.
j Mettre tous les composants à la même taille de manière explicite (encore la propriété
width et height mais cette fois sur chaque sous-conteneur).

214
Les contrôles TabNavigator et Accordion 7

j Mettre le composant le plus grand en premier (ce qui n’est cependant pas très
pratique).

7.3 Les contrôles TabNavigator et Accordion


Il est relativement facile d’associer une ViewStack à une barre de navigation, mais il serait
cependant bien plus pratique de réunir les deux en un seul et unique composant. C’est le
rôle du TabNavigator et de l’Accordion.

Le composant TabNavigator
Un TabNavigator pourrait être comparé au niveau visuel et fonctionnel à une ViewStack
associée à un composant TabBar puisqu’il propose d’afficher un ensemble de conteneurs
sous la forme d’onglets navigables. Il se déclare également de façon identique :
<mx:TabNavigator id="myTn" borderStyle="solid" backgroundColor="white"
width="400" height="250">

<mx:HBox id="hb12" label="conteneur 1"


icon="@Embed(source=’soleil.gif’)" >
<mx:Label text="Le conteneur 1 est affiché" fontSize="26"/>
</mx:HBox>
<mx:HBox id="hb23" label="conteneur 2" >
<mx:Label text="Le conteneur 2 est affiché" fontSize="26"/>
</mx:HBox>
<mx:HBox id="hb34" label="conteneur 3" >
<mx:Label text="Le conteneur 3 est affiché" fontSize="26"/>
</mx:HBox>
</mx:TabNavigator>

c Fig. 7.13 :
Rendu visuel du
composant

215
7 Naviguer dans son application

Le nommage des onglets se base encore sur la propriété label des conteneurs enfants. Il
est aussi possible d’ajouter une icône grâce à la propriété icon de chaque élément comme
dans l’exemple précédent.
Les éléments sont rangés de gauche à droite dans l’ordre où ils ont été déclarés et ils sont
visibles par défaut, à moins de cacher un conteneur en mettant la propriété enabled à
false. Dans ce cas, l’onglet est toujours présent mais il n’est plus cliquable.
Enfin, ce composant, comme la ViewStack, rend accessible un événement change qui est
déclenché à chaque changement de conteneur actif.

Le composant Accordion
Le composant Accordion est un peu différent : c’est une variation intéressante du
composant ViewStack. Les conteneurs enfants ne sont ici plus affichés les uns par-dessus
les autres, mais ils sont simplement réduits verticalement de manière à ne laisser
apparaître qu’une barre de titre cliquable. Un clic entraîne la réduction du conteneur actif
et, évidemment, une restauration de l’élément sélectionné.
Ce composant peut se révéler très utile dans le cadre de formulaires assez longs et qui ne
tiendraient pas sur une page. Il est plus adapté qu’une navigation en forme d’onglet pour
ainsi rentrer des coordonnées, une adresse de livraison et un numéro de carte de crédit qui
sont souvent séparés en trois pages distinctes sur les sites web classiques.
Nous allons donc illustrer ce composant en se basant sur cet exemple. Il va falloir déclarer
un Accordion qui contiendra les trois formulaires (seul le premier formulaire sera réalisé
pour cet exemple) :
<mx:Accordion id="ExempleAccordion">
<mx:Form label="1. Informations personnelles"
width="400">
<mx:FormHeading label="Informations personnelles"/>
<mx:FormItem label="Nom">
<mx:TextInput/>
</mx:FormItem>
<mx:FormItem label="Prénom">
<mx:TextInput/>
</mx:FormItem>
<mx:FormItem label="Adresse">
<mx:TextInput/>
<mx:TextInput/>
</mx:FormItem>
<mx:FormItem label="Code postal" >
<mx:TextInput maxChars="5"/>
</mx:FormItem>

216
Les contrôles TabNavigator et Accordion 7

<mx:FormItem label="Ville">
<mx:TextInput/>
</mx:FormItem>
<mx:FormItem label="Numéro de téléphone">
<mx:TextInput/>
</mx:FormItem>
</mx:Form>
<mx:Form label="2. Coordonnées bancaires">
<!-- Formulaire à remplir. -->
</mx:Form>
<mx:Form label="3. Passer la commande">
<!-- Formulaire à remplir. -->
</mx:Form>
</mx:Accordion>

Voici le résultat visuel d’un conteneur de type Accordion :


c Fig. 7.14 :
Simulation d’un
formulaire d’achat avec
le composant Accordion

Navigation au clavier
Lorsqu’un composant de type Accordion ou TabNavigator est sélectionné, les touches du
clavier peuvent être utilisées pour remplacer la navigation à la souris. Flex définit une
action spécifique par défaut aux touches suivantes :

Tableau 7.2 : La navigation au clavier

Touche Fonctionnalité

[Ä] et [Barre}d'espace] Ouvre l’onglet sélectionné

217
7 Naviguer dans son application

Tableau 7.2 : La navigation au clavier

[Ö] Ouvre le premier onglet

Fin Ouvre le dernier onglet

[’] / [‘] Ouvre l’onglet suivant/précédent

[ÿ] et [ï] Sélectionne (sans l’ouvrir) l’onglet précédent

[Ÿ] et [î] Sélectionne (sans l’ouvrir) l’onglet suivant

Ajouter des boutons pour faciliter la navigation


Au début de ce chapitre, nous avons implémenté une navigation manuelle dans le
composant ViewStack en utilisant une ComboBox. Pour les composants Accordion ou un
TabNavigator, une méthode de navigation est fournie par défaut. Cependant il peut être
envisageable de rajouter des boutons pour avoir un second mode d’accès aux conteneurs.
Il suffirait ainsi dans notre exemple précédent de rajouter des boutons Suivant et
Précédent à chaque formulaire en utilisant ActionScript pour changer l’affichage :
<mx:Button id="prec" label="Précédent"
click="ExempleAccordion.selectedIndex =(( ExempleAccordion.selectedIndex
➥ - 1) % ExempleAccordion.numChildren);"/>

<mx:Button id="suiv" label="Suivant"


click="ExempleAccordion.selectedIndex =(( ExempleAccordion.selectedIndex
➥ + 1) % ExempleAccordion.numChildren);"/>

Le principe est très simple. L’onglet sélectionné est modifié en incrémentant ou en


décrémentant la propriété selectedIndex du composant, et un modulo utilisant la
propriété numChildren (nombre total d’onglets) permet de rendre la navigation circulaire.
On peut donc passer du dernier onglet au premier et vice versa.

7.4 Mise en pratique : mon CV en ligne


Nous allons mettre en pratique la navigation dans une application Flex en réalisant un
exemple de CV en ligne. Nous utiliserons plusieurs conteneurs pour mettre en forme les
éléments, le composant HtmlText pour structurer les informations et également un
Accordion pour séparer les différentes catégories.

218
Mise en pratique : mon CV en ligne 7

Création du projet
Commencez par créer un nouveau projet que vous appellerez MyResume. Nous allons
tout de suite changer l’apparence du fond ainsi que la disposition de l’application.
Mettez le layout de l’application à vertical et changez la couleur de fond par un
dégradé de couleurs, par exemple de la manière suivante :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical" backgroundGradientColors="[#007ab7,#FFFFFF]"
pageTitle="MyResume">

</mx:Application>

Ajoutez une VBox qui représentera la page du CV. Le conteneur aura une taille fixe
(600 × 700 par exemple). Nous allons également ajouter un contour et mettre un fond
blanc. Le mieux est d’utiliser les outils du mode Design de Flex Builder 3.
Ensuite, ajoutez une ombre portée. Il vous faut utiliser la balise <mx:Filter> qui permet
d’appliquer les effets de Flash à n’importe quel composant Flex. Nous utiliserons ici le
DropShadowFilter comme ceci :
<mx:filters>
<flash.filters:DropShadowFilter
xmlns:flash.filters="flash.filters.*" angle="60"
blurX="5" blurY="5" distance="4" alpha="0.6" color="0x000000" />
</mx:filters>

Ce qui donnera le rendu visuel suivant :


c Fig. 7.15 :
Utilisation du filtre DropDownShadow

Vous devez maintenant rajouter dans la partie supérieure de votre CV les informations
suivantes :
j nom et prénom ;
j coordonnées ;
j photographie.

219
7 Naviguer dans son application

Nous allons utiliser un conteneur de type HBox qui ne concernera que la partie supérieure
de la page. La HBox contiendra elle-même deux VBox et un Label pour afficher le titre du
CV. Nous séparerons les composants grâce à des Spacer. Les informations personnelles
seront placées dans le conteneur de gauche et la photo dans celui de droite. Voici le code
MXML pour l’instant :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical" backgroundGradientColors="[#007ab7,#FFFFFF]"
pageTitle="MyResume">
<mx:VBox width="600" height="700" borderStyle="outset"
borderColor="Black" backgroundColor="#FFFFFF" >
<mx:filters>
<flash.filters:DropShadowFilter
xmlns:flash.filters="flash.filters.*"
angle="60" blurX="5" blurY="5"
distance="4" alpha="0.6" color="0x000000" />
</mx:filters>
<mx:HBox width="100%" verticalAlign="middle"
color="#0E4084" backgroundColor="#8cbbfa"
backgroundAlpha="0.2">
<mx:VBox height="100%" paddingLeft="10" paddingTop="5">
<mx:Label text="Mr Stan Smith"
fontFamily="Verdana"
fontSize="13"
fontWeight="bold"
<mx:Label text="22, rue des Petits-Hôtels"
fontFamily="Verdana" fontSize="11"/>
<mx:Label text="75010 Paris" fontFamily="Verdana"
fontSize="11"/>
<mx:Label text="+33 1 42 37 ** **"
fontFamily="Verdana" fontSize="11"/>
<mx:Label text="stan.smith@gmail.com"
fontFamily="Verdana" fontSize="11"/>
</mx:VBox>
<mx:Spacer width="50%"/>
<mx:Label text="Ingénieur en Informatique"
fontFamily="Verdana" fontSize="20" enabled="true"/>
<mx:Spacer width="50%"/>

<mx:VBox height="100%" verticalAlign="bottom">


<mx:Image source="photo.jpg"/>
</mx:VBox>
</mx:HBox>
</mx:VBox>

</mx:Application>

220
Mise en pratique : mon CV en ligne 7

Ajout d’un composant de navigation


Nous allons maintenant ajouter le composant Accordion qui représentera les différentes
catégories de votre CV, à savoir :
j formation ;
j expérience ;
j compétences ;
j langues ;
j divers.

Chaque catégorie sera évidemment classée dans un conteneur puisque l’Accordion


n’accepte que ce type de composants :
<mx:Accordion width="100%">
<mx:VBox label="Formation">
</mx:VBox>

<VBox label="Expérience">
</mx:VBox>

<mx:VBox label="Compétences">
</mx:VBox>

<mx:VBox label="Langues">
</mx:VBox>

<mx:VBox label="Divers">
</mx:VBox>
</mx:Accordion>

Ajout des informations


Il faut maintenant ajouter des informations pour chaque catégorie. Le plus simple pour
formater le texte est d’utiliser la propriété htmlText qui, comme son nom l’indique,
permet d’afficher correctement du code HTML dans un composant Text standard :
<mx:Text>
<mx:htmlText>
<![CDATA[
]]>
</mx:htmlText>
</mx:Text>

221
7 Naviguer dans son application

Le code HTML des sous-catégories ne sera pas affiché pour des raisons de place. Nous
vous laissons donc le soin d’y mettre vos propres informations.

Mise en forme et design


Vous allez à présent modifier légèrement l’apparence des boutons de votre composant
Accordion.
Pour le design des composants, nous vous conseillons d’utiliser le Flex Style Explorer
que vous pouvez lancer à partir de l’écran d’accueil de Flex Builder 3. Vous pourrez ainsi
modifier les paramètres de chaque composant et avoir un aperçu direct du résultat. Au
final, il ne restera plus qu’à copier le CSS généré, comme celui-ci par exemple :
Accordion {
borderStyle: none;
headerHeight: 25;
textIndent: 3;
fillAlphas: 0.21, 0.19, 0.3, 0.3;
fillColors: #ffffff, #8cbbfa, #8cbbfa, #8cbbfa;
selectedFillColors: #8cbbfa, #8cbbfa;
themeColor: #8cbbfa;
headerStyleName: "myaccordionHeader";
}

.myaccordionHeader {
letterSpacing: 1;
}

Résultat final
Voici le code final (sans la partie HTML) de cet exemple de CV en ligne :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical" backgroundGradientColors="[#007ab7,#FFFFFF]"
➥ pageTitle="MyResume">
<mx:Style>
Accordion {
borderStyle: none;
headerHeight: 25;
textIndent: 3;
fillAlphas: 0.21, 0.19, 0.3, 0.3;
fillColors: #ffffff, #8cbbfa, #8cbbfa, #8cbbfa;
selectedFillColors: #8cbbfa, #8cbbfa;
themeColor: #8cbbfa;

222
Mise en pratique : mon CV en ligne 7

headerStyleName: "myaccordionHeader";
}
.myaccordionHeader {
letterSpacing: 1;
}
</mx:Style>
<mx:VBox width="600" height="700" borderStyle="outset"
borderColor="Black"
backgroundColor="#FFFFFF" >
<mx:filters>
<flash.filters:DropShadowFilter
xmlns:flash.filters="flash.filters.*" angle="60"
blurX="5" blurY="5"
distance="4" alpha="0.6" color="0x000000" />
</mx:filters>
<mx:HBox width="100%" verticalAlign="middle" color="#0E4084"
backgroundColor="#8cbbfa" backgroundAlpha="0.2">
<mx:VBox height="100%" paddingLeft="10" paddingTop="5"
borderStyle="none" backgroundAlpha="0.11">
<mx:Label text="Mr Stan Smith" fontFamily="Verdana"
fontSize="13" fontWeight="bold"/>
<mx:Label text="22, rue des Petits-Hôtels"
fontFamily="Verdana" fontSize="11"/>
<mx:Label text="75010 Paris" fontFamily="Verdana"
fontSize="11"/>
<mx:Label text="+33 1 42 37 ** **" fontFamily="Verdana"
fontSize="11"/>
<mx:Label text="stan.smith@gmail.com" fontFamily="Verdana"
fontSize="11"/>
</mx:VBox>
<mx:Spacer width="50%"/>
<mx:Label text="Ingénieur en Informatique"
fontFamily="Verdana" fontSize="20" enabled="true"
color="#0E4084"/>
<mx:Spacer width="50%"/>
<mx:VBox height="100%" verticalAlign="bottom">
<mx:Image source="photo.jpg"/>
</mx:VBox>
</mx:HBox>
<mx:Accordion width="100%" height="100%">
<mx:VBox label="Formation">
<mx:Text>
<mx:htmlText>
<![CDATA[
PARTIE HTML
]]>
</mx:htmlText>

223
7 Naviguer dans son application

</mx:Text>
</mx:VBox>
<mx:VBox label="Expérience">
<mx:Text>
<mx:htmlText>
<![CDATA[
PARTIE HTML
]]>
</mx:htmlText>
</mx:Text>
</mx:VBox>
<mx:VBox label="Compétences">
<mx:Text>
<mx:htmlText>
<![CDATA[
PARTIE HTML
]]>
</mx:htmlText>
</mx:Text>

</mx:VBox>
<mx:VBox label="Langues">
<mx:Text>
<mx:htmlText>
<![CDATA[
PARTIE HTML
]]>
</mx:htmlText>
</mx:Text>
</mx:VBox>
<mx:VBox label="Divers">
<mx:Text>
<mx:htmlText>
<![CDATA[
PARTIE HTML
]]>
</mx:htmlText>
</mx:Text>
</mx:VBox>
</mx:Accordion>
</mx:VBox>

</mx:Application>

Nous vous donnons le résultat en image :

224
Check-list 7

c Fig. 7.16 : Exemple de CV utilisant la navigation Flex

7.5 Check-list
Dans ce chapitre, nous avons vu :
a comment manipuler le composant ViewStack et ajouter des conteneurs enfants ;
a comment gérer la navigation de manière manuelle ;
a comment manipuler les barres de navigation ;
a comment automatiser la navigation avec le concept de dataProvider
a comment utiliser les composants de navigation intégrés (TabNavigator et
Accordion) ;
a comment naviguer au clavier.

225
8
8.1 Utiliser les comportements .............................. 228
8.2 Ajouter des effets ........................................ 234
8.3 ViewStates et transitions ................................ 238
8.4 Styliser l’interface ........................................ 242
8.5 Item renderers et editors ............................... 244
8.6 Check-list ................................................. 249
Personnaliser
son
application
L ’avantage d’utiliser des technologies telles que Flex est
de pouvoir créer des applications fonctionnelles aussi
agréables à voir et à utiliser. Ainsi, les animations
permettent notamment la mise en exergue des
changements de mise en page et de modifications dans
l’agencement des différents composants de vos
applications.
8 Personnaliser son application

8.1 Utiliser les comportements


À ce stade de lecture, Flex commence à ne plus avoir de secrets pour vous. Bien
évidemment, vous savez comment créer une application Flex, comment gérer les données
nécessaires au fonctionnement de celle-ci, comment les afficher et les mettre en forme,
mais le chemin reste long avant de maîtriser toutes les possibilités qu’Adobe vous offre
à travers la technologie Flex.
Ainsi, dans ce chapitre, il vous est proposé de découvrir comment améliorer
graphiquement votre application grâce aux multiples effets graphiques mis à votre
disposition ainsi qu’aux styles MXML qui se rapprochent beaucoup des traditionnelles
CSS (Cascading Style Sheets).
Les comportements sont des mouvements ou des animations qui serviront de réponses
animées aux actions des utilisateurs de votre application.
C’est, par exemple, grâce aux comportements qu’une boîte de dialogue apparaîtra
doucement comme sortant de l’interface principale.

Comment fonctionnent les comportements ?


Pour mettre en œuvre les comportements, il faut en fait utiliser deux notions de Flex : les
triggers, qui se rapprochent dans leur fonctionnement des événements, et les effets.
Un trigger est une action telle que cliquer sur un bouton à l’instant où un composant
devient visible tandis qu’un effet est un changement visuel d’un composant cible pendant
un laps de temps décompté en millisecondes. Les effets les plus connus sont les
mouvements, les redimensionnements ou les fondus.

Différence entre les événements et les triggers

Il ne faut pas confondre les événements et les triggers. Par exemple, un <mx:TextArea> possède à la fois
l’événement creationComplete et le trigger creationCompleteEffect. Bien sûr, l’événement va faire
commencer le trigger correspondant, mais alors que l’événement exécute l’action décidée lorsqu’il
arrive, le trigger ne fait que s’associer avec un effet.

<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<!-- Déclaration de l’effet -->
<mx:WipeRight id="monPremierEffet" duration="1000"/>
<!-- Assignation de l’effet en utilisant la liaison de données -->
<mx:TextArea creationCompleteEffect="{monPremierEffet}"/>
</mx:Application>

228
Utiliser les comportements 8

Dans l’exemple suivant, vous découvrirez comment déclarer un effet grâce à une balise
MXML. Ensuite, il suffit de le faire correspondre au trigger voulu en utilisant la liaison
de données. Ainsi, le TextArea apparaîtra comme en se répandant de la gauche vers la
droite.
c Fig. 8.1 :
Le début de l’affichage du TextArea

c Fig. 8.2 :
La fin de l’affichage du TextArea

Les effets disponibles dans Flex


Avant d’apprendre à créer vous-même des effets, nous allons étudier tout d’abord quels
sont les effets fournis par Flex que nous pourrons ajouter à nos applications.

Tableau 8.1 : Liste des effets disponibles dans Flex

Effet Description

AnimateProperty Cet effet propose de faire évoluer une propriété numérique (property)
d’un composant d’une valeur (fromValue) vers une autre (toValue) durant
un laps de temps défini (duration). Par exemple, vous pouvez faire
grandir un <mx:Button> en agissant sur sa propriété width.

Blur Cet effet fait apparaître un flou sur les bords du composant sur lequel il est
appliqué comme s’il se dissolvait dans le reste de l’interface.

Dissolve Cet effet permet de faire baisser la valeur alpha (transparence) du


composant en partant de la valeur alphaFrom jusqu’à alphaTo (0.0
= totalement transparent, 1.0 = totalement opaque). La transition est
possible dans les deux sens. Attention, la propriété color de l’effet permet
de régler la couleur de la couche dans laquelle disparaît le composant.

Fade Cet effet est le contraire de l’effet Dissolve. On fait apparaître un


composant en augmentant progressivement sa valeur alpha.

Glow Cet effet affiche un halo lumineux autour de l’élément sur lequel l’effet est
appliqué.

229
8 Personnaliser son application

Tableau 8.1 : Liste des effets disponibles dans Flex

Iris Cet effet Iris est une animation qui fait apparaître le composant comme
un rectangle qui s’agrandit des dimensions scaleXFrom et scaleYFrom aux
dimensions scaleXTo et scaleYTo.

Move Cet effet permet le déplacement d’un composant de la position (xFrom,


yFrom) à la position (xTo, yTo).
La valeur de départ ou d’arrivée peut être omise si vous spécifiez la valeur
xBy ou yBy qui donne le nombre de pixels de déplacement.

Pause Cet effet ne fait rien pendant une période de temps définie.
Cet effet est utile lorsque vous composez plusieurs effets comme nous le
verrons par la suite.

Resize Cet effet permet le redimensionnement d’un composant des valeurs


widthFrom et heightFrom aux valeurs widthTo et heightTo. De même
que pour l’effet Move, il peut être spécifié la valeur widthBy et/ou
heightBy qui permet d’omettre une des propriétés expliquées
précédemment.

Rotate Cet effet fait effectuer une rotation au composant de angleFrom à angleTo
autour du point originX et originY.

SoundEffect Cet effet joue un son MP3 lors du déclenchement du trigger. Le MP3 est
spécifié dans la propriété source de cet effet.

WipeLeft, WipeRight, Cet effet affiche un composant comme "s’il sortait de lui-même" vers la
WipeUp, WipeDown gauche, la droite, le haut ou le bas, suivant l’effet utilisé.

Zoom Cet effet permet de faire un zoom grossissant ou rapetissant sur un


composant. Le zoom part de la taille zoomHeightFrom et zoomWidthFrom
pour afficher en fin d’animation le composant en taille zoomHeightTo et
zoomWidthTo.
Ces quatre propriétés spécifient en nombre de fois la taille initiale du
composant.

Appliquer les comportements aux composants


Les comportements sont, comme la plupart des concepts Flex, applicables en MXML ou
en ActionScript.

En MXML
Pour appliquer un comportement en MXML, nous utilisons la propriété correspondante
au nom du trigger désiré. À cette propriété, nous affectons la valeur d’un effet déclaré
plutôt en liant le trigger avec l’identifiant de l’effet.

230
Utiliser les comportements 8

Par exemple, on déclare l’effet <mx:WipeUp> en lui assignant l’identifiant monWU :


<mx:WipeUp id="monWU" duration="500"/>

Puis on l’affecte à notre bouton en utilisant la propriété creationCompleteEffect :


<mx:Button label="Mon Bouton" creationCompleteEffect="{monWU}" />

Ainsi, le bouton apparaîtra de bas en haut.


Il est aussi pertinent de pouvoir faire évoluer les comportements en fonction de données
provenant de l’utilisateur. Imaginons une application qui afficherait une image sur
laquelle l’utilisateur pourrait zoomer en indiquant une valeur de zoom dans un TextInput
puis en cliquant sur l’image :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Zoom id="monZoom" zoomHeightTo="{Number(zoomValue.text)}"
zoomWidthTo="{Number(zoomValue.text)}"/>
<mx:Image source="img\Alien1.jpg" mouseDownEffect="{monZoom}"/>
<mx:Label text="Indiquez le zoom voulu pour l’image puis cliquez
➥ dessus."/>
<mx:TextInput id="zoomValue" text=""/>
</mx:Application>

Vous pouvez donc observer que la valeur de zoom est en fait liée avec la valeur contenue
dans la balise <mx:TextInput>.

Conversion du texte en nombre

Pour ne pas obtenir d’erreurs avec cet exemple, il faut bien penser à utiliser la méthode Number() du
langage ActionScript afin de convertir le texte en nombre.

Vous pouvez également appliquer des comportements en utilisant les styles MXML (que
vous découvrirez plus en détail dans la suite de ce chapitre). Chaque trigger est aussi
implémenté dans un style MXML, ce qui permet de l’associer à un effet en utilisant les
balises <mx:Style> ou en utilisant les méthodes ActionScript : setStyle() et
getStyle() :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<!-- On applique le zoom grâce aux styles MXML -->
<mx:Style>
Image { mouseDownEffect: monZoom; }

231
8 Personnaliser son application

</mx:Style>
<mx:Zoom id="monZoom" zoomHeightTo="{Number(zoomValue.text)}"
zoomWidthTo="{Number(zoomValue.text)}"/>
<mx:Image source="img\Alien1.jpg"/>
<mx:Label text="Indiquez le zoom voulu pour l’image puis cliquez
➥ dessus."/>
<mx:TextInput id="zoomValue" text=""/>
</mx:Application>

En ActionScript
Pour appliquer des effets sans forcément passer par les triggers, il est possible d’utiliser
directement les effets en ActionScript en utilisant la méthode play().
Le principe est de paramétrer un effet en ActionScript en s’aidant d’une fonction
d’événement, puis de l’appliquer (en appelant sa méthode play()) sur un composant, lors
d’un événement concernant un autre composant. Par exemple, le clic sur un bouton
permettra la dissolution (<mx:Dissolve>) d’une image.
Dans un premier temps, voyons comment paramétrer un effet en ActionScript :
// On importe d’abord les classes nécessaires :
import mx.effects.Dissolve
// puis on déclare l’effet qu’on instancie immédiatement
private var monDiss:Dissolve = new Dissolve();
//ensuite on déclare une fonction qui sera appelée
//lors de l’événement creationComplete de l’application
private function creerEffet(eventO:Event) :void
{
//On remplit les différentes propriétés nécessaires à l’effet
monDiss.alphaTo = 0.0;
monDiss.duration = 2000;
//On assigne une cible pour notre effet
monDiss.target = monImage;
}

Et ensuite nous demandons à l’événement click du <mx:Button> d’appeler la méthode


play() de l’effet déclaré en ActionScript :
<mx:Button label="Dissoudre" click="monDiss.play();"/>

Nous rajoutons une image dans notre application pour enfin obtenir le fichier :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="creerEffet(event);">

232
Utiliser les comportements 8

<mx:Script>
<![CDATA[
// On importe d’abord les classes nécessaires :
import mx.effects.Dissolve
// puis on déclare l’effet qu’on instancie immédiatement
private var monDiss:Dissolve = new Dissolve();
//ensuite on déclare une fonction qui sera appelée
//lors de l’événement creationComplete de l’application
private function creerEffet(eventO:Event) :void
{
//On remplit les différentes propriétés nécessaires à l’effet
monDiss.alphaTo = 0.0;
monDiss.duration = 2000;
//On assigne une cible pour notre effet
monDiss.target = monImage;
}
]]>
</mx:Script>
<mx:Image source="img\Alien1.jpg" id="monImage"/>
<mx:Button label="Dissoudre" click="monDiss.play();"/>
</mx:Application>

Utilisation de la méthode end()

Il est conseillé d’appeler avant la méthode play() la méthode end() qui permet de s’assurer que
l’effet voulu n’est pas déjà en cours d’application, auquel cas il serait stoppé pour appliquer le nouvel
effet.

Vous pouvez également spécifier à l’effet d’agir sur plusieurs composants en passant un
tableau de composants à la propriété targets de l’effet. C’est ce que montre l’exemple
suivant :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Resize id="monRes" widthTo="50" heightTo="50"
targets="{[button1, button2, button3]}" duration="500"/>
<mx:Button id="button1"/>
<mx:Button id="button2"/>
<mx:Button id="button3"/>
<mx:Button label="On agrandit !" click="monRes.end();
➥ monRes.play();"/>
</mx:Application>

233
8 Personnaliser son application

8.2 Ajouter des effets


Maintenant que nous avons abordé les effets simples, nous allons voir comment les
combiner ou comment utiliser les fonctions avancées des effets.

Retarder le lancement d’un effet


La propriété startDelay est utile lorsque vous combinez plusieurs effets comme nous
allons le voir dans le point suivant. Elle permet de définir une durée au terme de laquelle
l’effet démarrera. Il suffit d’indiquer dans la propriété le nombre de millisecondes désirées
pour le lancement de l’effet :
<mx:Rotate duration="1000" id="rotationRetardee" startDelay="100"/>

Combiner plusieurs effets


Souvent, les effets simples atteignent leurs limites et vous aimeriez pouvoir les combiner
de manière à obtenir des "animations" plus agréables. Il existe deux méthodes qui sont les
suivantes :
j la mise en parallèle, qui exécute les effets en même temps ;
j la mise en séquence, qui exécute les effets les uns après les autres.

<mx:Parallel>
Cette classe Flex permet le lancement simultané de plusieurs effets. Si vous voulez
effectuer un redimensionnement tandis que votre composant subit une rotation, il vous
suffit de mettre en parallèle les effets Resize et Rotate :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Parallel id="zoomAndResize">
<mx:Zoom zoomHeightTo="1.5" zoomWidthTo="1.5"/>
<mx:Rotate />
</mx:Parallel>
<mx:Image source="img\Alien1.bmp" mouseDownEffect="{zoomAndResize}"/>
</mx:Application>

Vous pouvez observer maintenant votre image qui s’agrandit en tournant sur elle-même
lorsque vous cliquez dessus.

234
Ajouter des effets 8

<mx:Sequence>
Il peut être aussi intéressant d’appliquer plusieurs effets à un composant les uns après les
autres.
Par exemple, vous voulez d’abord voir s’agrandir votre TextArea par le milieu avant de
le voir bouger vers la droite. Pour cela, il faut ajouter les effets Iris et Move dans le corps
de la balise <mx:Sequence> :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Sequence id="irisThenMove">
<mx:Iris />
<mx:Move xBy="10" />
</mx:Sequence>
<mx:TextArea text="Exemple de séquence d’effets"
mouseDownEffect="{irisThenMove}"/>
</mx:Application>

Combinaison de… combinaisons !


À présent, vous pouvez multiplier les combinaisons presque sans fin, car vous pouvez
imbriquer des Sequence dans des Parallel et inversement :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Sequence id="combinaisonOfCombinaison">
<mx:Parallel duration="2000">
<mx:Iris />
<mx:Rotate />
</mx:Parallel>
<mx:Move xBy="10" />
</mx:Sequence>
<mx:TextArea text="Exemple de combinaisons d’effets"
mouseDownEffect="{combinaisonOfCombinaison}"/>
</mx:Application>

La propriété duration

La propriété duration comme startDelay ou d’autres propriétés de temps s’appliquent à chacun des
effets présents dans la combinaison.

235
8 Personnaliser son application

Combiner en ActionScript
Bien évidemment, et vous en avez maintenant l’habitude, vous disposez d’un équivalent
ActionScript de ce que nous venons de voir précédemment.
En effet, les classes ActionScript Parallel et Sequence disposent de la méthode
addChild() qui prend en argument un objet de type Effect. Vous pouvez donc ajouter des
effets enfants aux objets de type Parallel et Sequence et ensuite les utiliser comme nous
l’avons déjà vu avec les effets simples.

Créer son propre effet d’apparition


Voyons comment créer un effet du type MaskEffect comme le sont Iris et la famille des
"Wipe". Ces effets sont en fait le résultat du mouvement d’un masque rectangulaire pour
les Wipe* et de l’agrandissement d’un masque rectangulaire centré pour Iris.
Pour créer vos propres effets, il faudra créer un nouveau masque en utilisant la propriété
createMaskFunction.
Nous allons ainsi réaliser l’effet Iris qui, au lieu d’un rectangle qui s’agrandit, fera
apparaître le composant avec un disque qui s’agrandit.
Tout d’abord, nous devons fabriquer l’objet de type Shape qui sera transmis à notre effet
Iris. Pour cela, nous instancions un objet Shape puis nous lui donnons les
caractéristiques nécessaires afin que notre disque ait le bon diamètre final, la bonne
position, etc.
public function createRoundMask(targ:Object, compDest:Rectangle):Shape
{
// On instancie l’objet.
var roundMask:Shape = new Shape();
// Puis on dessine un disque
roundMask.graphics.beginFill(0x00000, 0.0);
// On place notre disque de façon à le centrer sur le composant
// ainsi nous avons besoin d’avoir le centre du disque
// au centre du rectangle
roundMask.graphics.drawCircle(compDest.width/2,compDest.height/2,
Math.sqrt((compDest.height * compDest.height) +
(compDest.width * compDest.width)));
// La dimension du rayon est calculée grâce au théorème de
// Pythagore ( !) afin d’obtenir un cercle circonscrit au rectangle.
roundMask.graphics.endFill();

return roundMask;
}

236
Ajouter des effets 8

Ensuite, nous déclarons notre effet, en déclarant quelle est la fonction qui va créer notre
masque (vous aurez compris que c’est celle que l’on vient de coder) grâce à la propriété
createMaskFunction :
<mx:Iris duration="2000" id="showWL"
createMaskFunction="createRoundMask"
showTarget="true"/>

La propriété showTarget

La propriété showTarget sert à indiquer à Flex si nous voulons afficher le composant sur lequel est
appliqué l’effet ou pas à la fin de l’animation. Dans le cadre d’un effet de disparition de composant,
cette propriété sera à false. Or, nous voulons que notre effet fasse apparaître le composant : nous
réglons donc la propriété sur true.

Enfin, nous obtenons :


<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
public function createRoundMask(targ:Object,
➥ compDest:Rectangle):Shape
{
var roundMask:Shape = new Shape();
roundMask.graphics.beginFill(0x00000, 0.0);
roundMask.graphics.drawCircle(compDest.width/2,compDest.height/2,
Math.sqrt((compDest.height * compDest.height) +
(compDest.width * compDest.width)));
roundMask.graphics.endFill();

return roundMask;
}

]]>
</mx:Script>
<mx:Iris duration="2000" id="showWL"
createMaskFunction="createRoundMask" showTarget="true"/>
<mx:Image source="@Embed(’img\Alien1.jpg’)"
mouseDownEffect="{showWL}"/>
</mx:Application>

237
8 Personnaliser son application

c Fig. 8.3 :
Début de l’effet Iris personnalisé

c Fig. 8.4 :
L’effet Iris personnalisé en cours

8.3 ViewStates et transitions


Les ViewStates sont les différents affichages de votre application. Par exemple, votre
interface peut avoir un écran général qui va être enrichi si l’utilisateur s’enregistre afin
d’afficher un nouveau menu, un panneau qui récapitule les informations de l’utilisateur,
etc.
Flex permet grâce au mécanisme de ViewStates de structurer votre application afin de
gérer efficacement les différents affichages de votre interface sans avoir à gérer des
événements qui pourraient être complexes sans ce mécanisme.
De leur côté, les transitions sont l’application des effets vus précédemment aux
changements de ViewStates.

Mettre en œuvre les ViewStates


En premier lieu, vous devez retenir que les ViewStates sont applicables à n’importe quel
composant Flex, y compris le composant principal : <mx:Application>. La propriété
currentState devra être nulle pour signifier que le composant appartient à la vue de base
et sera changée afin de n’afficher que les composants qui appartiennent à telle ou telle
vue.
Nous allons à présent découvrir les ViewStates à travers un exemple qui affichera les
détails d’une image si l’utilisateur clique sur un lien, et les cachera s’il clique de nouveau
sur ce même lien.

238
ViewStates et transitions 8

Tout d’abord, nous devons créer l’interface basique qui consistera à afficher une image,
avec en dessous d’elle juste son nom et un lien pour afficher par la suite des détails sur
l’image :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Panel id="presObj" title="Image">
<mx:Image id="imgExp" source="img\Balloon.bmp"/>
<mx:ControlBar>
<mx:VBox id="vBoxInfo">
<mx:Label text="{imgExp.source}"/>
</mx:VBox>
</mx:ControlBar>
</mx:Panel>
</mx:Application>

Jusque-là, rien de bien difficile, nous avons juste défini un Panel qui contient une image
et une barre de contrôle pour afficher le chemin vers cette image.
c Fig. 8.5 :
Notre image et son chemin

Maintenant, nous allons ajouter dans la barre de contrôle le lien qui permettra de passer
de la vue de base, celle-ci (currentState="") à la vue détaillée
(currentState="details") :
<mx:LinkButton label="Afficher les détails"
id="affDetails" click="currentState=’details’"/>

C’est à ce moment précis que nous devons déterminer ce que nous voulons dans la vue
détaillée :
j un label affichant les dimensions de l’image ;
j un champ de texte pour éventuellement ajouter des mots-clés à l’image ;
j un lien pour revenir à la vue simple.

239
8 Personnaliser son application

Définissons donc notre vue détaillée grâce à la balise <mx:State>. Nous inclurons cette
balise dans une liste d’états grâce à : <mx:states>. La méthode AddChild permet
d’ajouter des composants qui seront enfants du composant renseigné dans la propriété
relativeTo. Ensuite, il ne nous reste plus qu’à modifier le titre du panel pour indiquer
que l’on est en vue détaillée, puis à supprimer le lien affDetails qui n’a plus lieu d’être :
<mx:states>
<mx:State name="details">
<mx:AddChild relativeTo="{vBoxInfo}"
position="lastChild" creationPolicy="all">
<mx:Label text="96 * 96"/>
</mx:AddChild>
<mx:AddChild relativeTo="{vBoxInfo}"
position="lastChild" creationPolicy="all">
<mx:TextInput text="mots clefs"/>
</mx:AddChild>
<mx:AddChild relativeTo="{vBoxInfo}"
position="lastChild" creationPolicy="all">
<mx:LinkButton label="Retour à la vue simple"
click="currentState=’’"/>
</mx:AddChild>
<mx:SetProperty target="{presObj}"
name="title" value="Détails de l’image"/>
<mx:RemoveChild target="{affDetails}"/>
</mx:State>
</mx:states>

Ce qui donne le fichier suivant :


<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:states>
<mx:State name="details">
<mx:AddChild relativeTo="{vBoxInfo}"
position="lastChild" creationPolicy="all">
<mx:Label text="96 * 96"/>
</mx:AddChild>
<mx:AddChild relativeTo="{vBoxInfo}"
position="lastChild" creationPolicy="all">
<mx:TextInput text="mots clefs"/>
</mx:AddChild>
<mx:AddChild relativeTo="{vBoxInfo}"
position="lastChild" creationPolicy="all">
<mx:LinkButton label="Retour à la vue simple"
click="currentState=’’"/>
</mx:AddChild>

240
ViewStates et transitions 8

<mx:SetProperty target="{presObj}"
name="title" value="Détails de l’image"/>
<mx:RemoveChild target="{affDetails}"/>
</mx:State>
</mx:states>

<mx:Panel id="presObj" title="Image">


<mx:Image id="imgExp" source="img\Balloon.bmp"/>
<mx:ControlBar>
<mx:VBox id="vBoxInfo">
<mx:Label text="{imgExp.source}"/>
<mx:LinkButton label="Afficher les détails"
id="affDetails" click="currentState=’details’"/>
</mx:VBox>
</mx:ControlBar>
</mx:Panel>
</mx:Application>

c Fig. 8.6 :
Exemple d’utilisation d’une ViewState en
mode Simple

c Fig. 8.7 :
Exemple d’utilisation d’une ViewState en
mode Détail

Appliquer des transitions


Les transitions permettent des changements de vue de l’interface très esthétiques. Elles
permettent de redimensionner, ou de bouger les composants de l’application lors d’un
changement de ViewState de celle-ci.

241
8 Personnaliser son application

Ainsi, les changements dans l’interface seront moins brusques et pourront faire apparaître
de manière moins abrupte les nouveaux composants du nouvel état.
Grâce aux propriétés toState et fromState, nous définissons pour chaque transition à
quel moment elle doit agir. Il existe cependant la wildcard (*) qui permet de prendre en
compte tous les états.
Les transitions sont regroupées dans un élément <mx:transitions> et elles contiennent
des éléments Parallel, Sequence, ou directement les effets voulus pour lesquels on a
précisé les cibles grâce aux propriétés target (si la cible est unique) et targets (si les
cibles sont multiples).
Vous pouvez tester ce que sont les transitions en ajoutant à l’exemple concernant les
ViewStates le morceau de code suivant :
<mx:transitions>
<mx:Transition fromState="*" toState="*">
<mx:Rotate duration="2000" target="{imgExp}"/>
</mx:Transition>
</mx:transitions>

Les transitions sont dans leur fonctionnement et leurs possibilités identiques aux effets.
Nous vous conseillons dans cette optique de vous reporter à la section traitant de ces
derniers.

8.4 Styliser l’interface


Pour les développeurs web chevronnés, la notion de style d’un élément ou d’une page n’a
pas de secret.
En Flex comme en HTML traditionnel, vous avez la possibilité de changer l’apparence
visuelle de votre application en utilisant des styles qui reprennent la syntaxe CSS. Un
autre point commun avec le HTML est la possibilité de styler son application de trois
manières : en utilisant une feuille de style extérieure, en incluant tous les styles entre les
balises <mx:Style> ou alors en incluant directement les déclarations de style dans les
balises concernées en utilisant les propriétés adéquates.
Plusieurs choses ne sont cependant pas paramétrables grâce aux CSS. En effet, les
coordonnées de positionnement, la hauteur et la largeur des composants sont des
propriétés de classes Flex et non des styles. Ainsi, nous devons continuer de passer par
les propriétés pour pouvoir les modifier.
Par ailleurs, nous verrons qu’il est aussi possible de modifier le style des composants en
passant par l’ActionScript.

242
Styliser l’interface 8

La balise <mx:Style>
Cette balise est la base de tout le système de décoration de vos applications. En effet, que
ce soit pour l’inclusion de feuilles de style externes ou la déclaration locale de style, nous
faisons appel à cette balise :
<mx:Style source="maCSS.css"/>
<mx:Style>
.monStyle { text-align : center;}
</mx:Style>

Les classes de style


Nous appelons classe de style la déclaration d’un ensemble de propriétés d’affichage
regroupées sous un même nom, qui vont ensuite être appliquées à tous les composants
dont la propriété styleName contiendra le nom du groupe.
En plus simple, soit la déclaration de la classe de style maClasseStyle :
<mx:Style>
.maClasseStyle {
text-align : center;
fontSize : 10;
color : #FFFF ;}
</mx:Style>

Tous les composants qui ont maClasseStyle comme valeur de leur propriété styleName
auront leur texte affiché en mode Centré, avec une police de taille 10 et de couleur
blanche.
Par extension, nous pouvons déclarer des styles pour toute une catégorie de composants :
<mx:Style>
TextArea {
text-align : center;
fontSize : 10;
color : #FFFF ;}
</mx:Style>

Ainsi, tous les TextArea bénéficieront des styles déclarés comme précédemment.

Le StyleManager
La classe StyleManager permet d’atteindre les styles de toutes les instances d’une classe
à l’exécution. Par exemple :

243
8 Personnaliser son application

StyleManager.getStyleDeclaration("Image").setStyle("Border", 0)

De cette façon, toutes les images de l’application vont avoir leur propriété de style Border
mise à 0.
Cette classe permet de remettre à jour tous les styles d’un type de composant au
lancement de l’application.

Le style inline
Pour chaque composant, vous avez la possibilité de modifier ses propriétés de style
directement dans la balise.
Suivant le type du composant, plusieurs propriétés sont à votre disposition pour modifier
l’aspect visuel de vos applications Flex :
<mx:HBox width="100" height="100" backgroundColor="{couleur}"/>

Ce qui permet de modifier le style du composant en utilisant un événement :


<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
[Bindable]
public var color:uint= 0x0;
public function changeColor() : void
{
color = 0xFFFFFF;
}
]]>
</mx:Script>
<mx:HBox backgroundColor="{color}" width="50" height="50"/>
<mx:Button click="changeColor()"/>
</mx:Application>

8.5 Item renderers et editors


Les items renderers et editors permettent aux contrôle-listes fournis par Flex d’afficher
et d’éditer correctement un certains type de données grâce à des connecteurs spéciaux.
Pour reprendre l’exemple le plus courant, vous pouvez grâce aux items renderers faire
afficher à vos listes des images qui seront présentées visuellement sous forme d’image et
non seulement sous forme de chemin comme elles pourraient l’être sans ces derniers.

244
Item renderers et editors 8

Les composants Flex qui sont des listes sont les suivants :
j DataGrid ;
j HorizontalList ;
j List ;
j TileList ;
j Tree ;
j Menu.

Ces derniers permettent d’afficher une collection d’objets que l’utilisateur pourra
parcourir, et dans laquelle il pourra sélectionner un ou plusieurs items. De plus, les Tree,
les DataGrid et les List permettent aux utilisateurs (si cela a été précisément formulé
dans le code : editable="true") d’éditer les données affichées dans leurs cellules. C’est
ici qu’interviennent les items editors.
Par défaut, l’item renderer du DataGrid ne permet que d’afficher des chaînes de
caractères, tandis que les autres permettent d’afficher du texte combiné à des images. Flex
nous permet de créer nos propres items renderers et editors afin d’afficher des données
mises en forme dans les composants de type List.
Nous allons maintenant voir comment créer nos propres items afin de pouvoir afficher ce
que nous souhaitons dans une liste.
Vous verrez qu’il existe trois façons de le faire :
j en appelant les renderers et editors fournis par Flex, c’est la méthode drop−in ;
j en appelant les renderers et editors fournis par Flex et en les paramétrant comme
des composants traditionnels, c’est la méthode inline ;
j en créant un composant personnalisé qui sera utilisé ensuite en mode Inline ou
Drop-in.

Vous pouvez vous reporter au chapitre 6 Aller vers une interface riche pour plus
de précisions sur la création de composants personnalisés.

Utiliser des renderers et des editors en méthode drop-in


Flex fournit des composants prêts à utiliser des données pour l’affichage dans les
composants listes. Ainsi, grâce aux propriétés itemRenderer et itemEditor, il est facile de
modifier le comportement par défaut.
Voici comment insérer dans un DataGrid un éditeur permettant d’incrémenter ou de
décrémenter un nombre :

245
8 Personnaliser son application

<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
[Bindable]
public var itemListe:Array = [
{name:"Item 1", qte:58},
{name:"Item 2", qte:51},
{name:"Item 3", qte:37}];
]]>
</mx:Script>
<mx:DataGrid variableRowHeight="true" dataProvider="{itemListe}"
editable="true">

<mx:columns>
<mx:DataGridColumn dataField="name" headerText="Nom"/>
<mx:DataGridColumn dataField="qte" headerText="quantité"
itemEditor="mx.controls.NumericStepper"
editorDataField="value"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>

L’éditeur qui s’appelle donc NumericStepper travaille sur des nombres (c’est pourquoi
nous déclarons directement le tableau (array) avec des entiers (int)) et permet
d’incrémenter ou de décrémenter de un. En revanche, vous avez sûrement remarqué qu’en
dépit des valeurs données, l’éditeur se borne à ne pas vouloir dépasser la valeur 10. En
effet, cette méthode ne permet pas de configurer l’éditeur et l’on se trouve vite limité.

Utilité de la propriété editorDataField

La propriété editorDataField permet de configurer quelle propriété du composant éditeur va devenir la


nouvelle valeur du champ modifié. Par défaut, la valeur de cette propriété est text ; cependant, le
NuméricStepper ne contient pas une telle propriété (c’est un éditeur spécialisé sur les nombres). Ainsi,
nous devons préciser le nom de la propriété qui nous intéresse.

La méthode inline
Cette méthode est la même que la méthode drop−in à la différence que l’on utilise une
balise <mx:itemEditor> pour faire appel à l’éditeur voulu.
Nous avons juste à modifier l’exemple précédent pour obtenir :
<?xml version="1.0"?>

246
Item renderers et editors 8

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
[Bindable]
public var itemListe:Array = [
{name:"Item 1", qte:58},
{name:"Item 2", qte:51},
{name:"Item 3", qte:37}];
]]>
</mx:Script>
<mx:DataGrid variableRowHeight="true" dataProvider="{itemListe}"
editable="true">

<mx:columns>
<mx:DataGridColumn dataField="name" headerText="Nom"/>
<mx:DataGridColumn dataField="qte" editorDataField="value">
<mx:itemEditor>
<mx:Component>
<mx:NumericStepper stepSize="1" maximum="100"/>
</mx:Component>
</mx:itemEditor>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
</mx:Application>

Ainsi, nous avons précisé à l’éditeur que le pas de progression était 1 et qu’il pouvait
monter jusqu’à 100, ce qui permet d’éditer au final les valeurs indiquées dans le tableau :
c Fig. 8.8 :
Un DataGrid pour lequel on a paramétré un
item editor.

Quels sont les composants Flex qui peuvent servir de renderer ou


d’editor ?
Beaucoup de composants Flex sont conçus pour pouvoir être utilisés en tant que tels.
Vous pouvez donc vous servir pour afficher vos données ou les éditer des composants
suivants :

247
8 Personnaliser son application

j Button ;
j CheckBox ;
j DateField ;
j Image ;
j Label ;
j NumericStepper ;
j Text ;
j TextArea ;
j TextInput.

Utiliser des items renderers et editors complexes


Vous pouvez naturellement combiner plusieurs composants Flex afin de mettre en forme
ou d’éditer vos données comme bon vous semble. Si vous avez une collection d’objets
complexes (comprenant à la fois des liens, des images et du texte), vous pouvez utiliser
la méthode inline pour combiner différents contrôles.
Bien entendu, il est possible et même préférable de créer un module séparé et de l’appeler
ensuite.
Prenons par exemple un tableau d’enregistrements composés chacun du nom d’un objet,
d’un lien vers le site Internet de l’objet et d’une image représentant cet objet. Il est alors
judicieux d’utiliser un item renderer personnalisé pour afficher le tout dans une liste.
Voici le tableau utilisé :
public var itemListe:Array = [
{name:"Alien", url:"http://www.monsite.com/alien",
img:"img\\Alien1.bmp"},
{name:"Balloon", url:"http://www.balloon-site.com/",
img:"img\\Balloon.bmp"},
{name:"Bear", url:"http://bear.test.com/", img:"img\\Bear.bmp"}];

Et le renderer :
<mx:itemRenderer>
<mx:Component>
<mx:VBox>
<mx:Image height="32" source="{data.img}"/>
<mx:HBox>
<mx:Label text="{data.name}"/>
<mx:Label text=’{String("URL :") + data.url}’/>
</mx:HBox>

248
Check-list 8

<mx:HRule width="100%"/>
</mx:VBox>
</mx:Component>
</mx:itemRenderer>

Nous vous donnons le résultat en image :


c Fig. 8.9 :
Exemple d’affichage personnalisé dans une
liste

8.6 Check-list
Dans ce chapitre, nous avons vu :
a comment utiliser les comportements et les associations triggers-effets ;
a comment créer ses propres effets en les composant ;
a comment modifier soi-même un effet ;
a la structuration d’applications en ViewStates ;
a les transitions entre les différentes vues qui permettent d’insérer des animations ;
a comment ajouter des styles à nos interfaces Flex ;
a comment utiliser les items renderers et editors ;
a comment fabriquer soi-même ses propres renderers et editors.
Dans le prochain chapitre, vous apprendrez à améliorer l’expérience utilisateur de vos
RIA en utilisant des notions propres aux applications lourdes.

249
9
9.1 Le glisser-déposer (drag-and-drop) .................... 252
9.2 L’historique de navigation (deep linking) ............. 256
9.3 Impression ............................................... 260
9.4 Internationalisation ...................................... 263
9.5 Check-list ................................................. 267
Améliorer
l’expérience
utilisateur
C e chapitre vous donne quelques solutions à certains
problèmes récurrents dans les projets Flex, et plus
généralement, les projets web. Une bonne gestion de
l’impression, de l’internalionalisation et de l’historique de
votre application la démarquera de ses concurrents.
L’utilisation du glisser-déposer fait également beaucoup de
sensation quand son utilité se fait ressentir.
9 Améliorer l’expérience utilisateur

9.1 Le glisser-déposer (drag-and-drop)


Le Drag and Drop Manager permet à l’utilisateur de déplacer un élément de votre
application Flex d’un point à un autre. Cette fonctionnalité est très pratique pour des
applications visuelles où les données sont représentées dans des listes, comme des images
ou des composants Flex.
L’opération glisser-déposer se décompose en trois temps, à savoir l’initialisation, le
déplacement (dragging), et la pose (dropping) :
1 L’utilisateur initie un drag-and-drop (glisser-déposer) en utilisant le clic gauche de la
souris pour sélectionner un composant Flex et en déplaçant le pointeur de la souris
de quelques pixels tout en gardant le bouton appuyé. Le composant sélectionné est
l’initiateur du drag (drag initiator).
2 L’utilisateur déplace sa souris dans l’application Flex en maintenant le bouton
gauche de la souris enfoncé. Flex affiche une image pendant le drag, appelé le drag
proxy. Le drag source (un objet DragSource) contient la donnée qui est déplacée.
3 Quand l’utilisateur déplace le drag proxy au-dessus d’un composant Flex, celui-ci
devient une cible potentielle pour le drop (drop target). Le drop target inspecte le
drag source pour déterminer si oui ou non le format des données est compatible. Si
c’est le cas, une petite icône verte indique que le dropping est possible et l’objet sera
accepté dans le nouveau composant si l’utilisateur relâche le bouton de la souris.
Sinon, rien n’est modifié. Lorsque l’opération réussit, Flex ajoute la donnée dans le
composant cible et, optionnellement, supprime la donnée du composant initial.
Les contrôles suivants possèdent un support par défaut pour le drag-and-drop :
j DataGrid ;
j HorizontalList ;
j List ;
j Menu ;
j PrintDataGrid ;
j TileList ;
j Tree.

Pour déplacer les éléments d’un de ces contrôles, il suffit de mettre la propriété
dragEnabled à true. Vous n’avez pas besoin de définir un listener pour commencer le
déplacement. Flex vous permet directement de déplacer les items du contrôle ou de les
copier si vous maintenez la touche [Ctrl] appuyée. Pour que le composant cible puisse
accepter des nouveaux éléments via le déplacement, il faut également lui spécifier une
propriété, dropEnabled, à true.

252
Le glisser-déposer (drag-and-drop) 9

L’exemple suivant utilise la fonctionnalité de drag-and-drop entre deux List :


<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" width="500"
height="200" borderStyle="solid" creationComplete="initApp();">
<mx:Script>
<![CDATA[
private function initApp():void {
srclist.dataProvider = [’Lire’, ’Courrir’, ’Danser’];
destlist.dataProvider =[];
}
]]>
</mx:Script>
<mx:HBox>
<mx:VBox>
<mx:Label text="Activités disponibles"/>
<mx:List id="srclist" height="100" dragEnabled="true"/>
</mx:VBox>
<mx:VBox>
<mx:Label text="Activités que j’aime"/>
<mx:List id="destlist" height="100" dropEnabled="true"/>
</mx:VBox>
</mx:HBox>
</mx:Application>
Vous devriez obtenir le résultat suivant lorsque vous essayez de faire glisser une activité
disponible dans celles que vous aimez :
c Fig. 9.1 :
Exemple de
drag-and-drop dans une
liste

Vous remarquerez lors de l’utilisation de cette application que les données sont copiées
dans la nouvelle liste, mais pas supprimées de l’ancienne. Si vous voulez que la donnée
soit supprimée, il faut que vous ajoutiez la propriété dragMoveEnabled avec la valeur true
au composant initiant le drag-and-drop. La valeur par défaut est false. Remplacez la liste
srclist du code précédent par celle-ci :
<mx:List id="srclist" height="100" dragEnabled="true"
dragMoveEnabled="true" />

L’action par défaut sera de déplacer la donnée d’une liste à l’autre. Si vous voulez copier
la donnée, il faudra maintenir obligatoirement la touche [Ctrl] appuyée pendant l’opération.

253
9 Améliorer l’expérience utilisateur

Vous pouvez également autoriser le déplacement de plusieurs éléments à la fois grâce à


la propriété allowMultipleSelection, comme nous le montre le code suivant :
<mx:List id="srclist" height="100" dragEnabled="true"
allowMultipleSelection="true" />

Un composant peut avoir les deux rôles en même temps, initier un drag-and-drop et
recevoir des données des autres composants. Voyons un exemple avec un autre
composant, le DataGrid :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="initApp();">
<mx:Script>
<![CDATA[
private function initApp():void {
srcGrid.dataProvider = [
{Artist:’Marcus Miller’, Album:’Free’, Price:16.98},
{Artist:’Diana Krall’, Album:’From This Moment On’, Price:9.99},
{Artist:’Sum 41’, Album:’UnderClass Hero’, Price:14.95},
{Artist:’Prince’, Album:’Planet Earth’, Price:11.95}
];
destGrid.dataProvider =[];
}
]]>
</mx:Script>
<mx:HBox>
<mx:VBox>
<mx:Label text="Album Dispo"/>
<mx:DataGrid id="srcGrid" allowMultipleSelection="true"
dragEnabled="true" dropEnabled="true" dragMoveEnabled="true">
<mx:columns>
<mx:DataGridColumn dataField="Artiste"/>
<mx:DataGridColumn dataField="Album"/>
<mx:DataGridColumn dataField="Prix"/>
</mx:columns>
</mx:DataGrid>
</mx:VBox>
<mx:VBox>
<mx:Label text="Mon Panier"/>
<mx:DataGrid id="destGrid" allowMultipleSelection="true"
dragEnabled="true" dropEnabled="true" dragMoveEnabled="true">
<mx:columns>
<mx:DataGridColumn dataField="Artiste"/>
<mx:DataGridColumn dataField="Album"/>
<mx:DataGridColumn dataField="Prix"/>

254
Le glisser-déposer (drag-and-drop) 9

</mx:columns>
</mx:DataGrid>
</mx:VBox>
</mx:HBox>
</mx:Application>

Le composant Tree permet de déplacer les éléments à l’intérieur de lui-même ou vers un


autre composant Tree. L’exemple suivant utilise un contrôle Tree avec les fonctionnalités
de drag-and-drop :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="initApp();">
<mx:Script>
<![CDATA[
private function initApp():void {
firstList.dataProvider = treeDP;
}
]]>
</mx:Script>
<mx:XML id="treeDP">
<node label="Mail"/>
<node label="Recus"/>
<node label="Dossier perso">
<node label="Demo"/>
</node>
<node label="Envoyes"/>
<node label="Corbeile"/>
</mx:XML>
<mx:Tree id="firstList" height="200" width="200"
showRoot="false"
labelField="@label"
dragEnabled="true" dropEnabled="true" dragMoveEnabled="true"
allowMultipleSelection="true" />
</mx:Application>

Vous devriez avoir le résultat suivant :


c Fig. 9.2 :
Exemple de drag-and-drop dans un arbre

255
9 Améliorer l’expérience utilisateur

Valeurs par défaut des propriétés de drag-and-drop

Les valeurs par défaut de certaines de ces propriétés sont différentes selon les composants. Par exemple,
la propriété dragMoveEnabled est par défaut à false pour la DataGrid et la List mais à true pour le
Tree.

Ces composants répondent à la majorité des cas d’utilisation d’un drag-and-drop. Si vous
voulez utiliser cette fonctionnalité avec d’autres composants, vous devrez implémenter
ces fonctionnalités vous-même. Pour y parvenir, vous aurez besoin des classes décrites
ci-après. Nous ne rentrerons pas plus dans les détails de l’implémentation manuelle du
drag-and-drop mais n’hésitez pas à consulter la documentation officielle de ces classes si
cela s’avère nécessaire.

Tableau 9.1 : Classes utilisées pour la fonctionnalité de drag-and-drop

Classe Description

DragManager Gère les opérations de drag-and-drop, comme la méthode doDrag() qui


initie le déplacement.

DragSource Identifie et contient la donnée déplacée.

DragEvent Contient les événements de drag-and-drop comme celui appelé lorsque


l’utilisateur déplace la donnée au-dessus d’un contrôle cible.

9.2 L’historique de navigation (deep linking)


Le deep linking permet d’utiliser les fonctionnalités de navigation de votre navigateur
Internet (boutons Précédent, Suivant, Favoris) au sein de votre application Flex.

Pour quoi faire ?


Les applications web classiques possèdent une adresse URL différente pour chaque page
de leur site. Ainsi, quand vous cliquez sur un lien, le navigateur enregistre
automatiquement dans l’historique votre action. Les applications AJAX et Flex ne
fonctionnent pas de la même manière. Afin d’améliorer l’expérience utilisateur, on évite
le plus possible les rafraîchissements de page, pour pouvoir faire par exemple des
transitions plus élégantes. Cependant, le navigateur n’enregistre aucune action dans
l’historique. En effet, l’application Flex est sur une page uniquement, et toute la
navigation du site ne se fait que dans le fichier Flash. Ainsi, lorsque vous arrivez sur une
application Flex, si vous naviguez dans l’application pendant un certain temps en passant
d’onglet en onglet, lorsque vous cliquerez sur le bouton précédent de votre navigateur,

256
L’historique de navigation (deep linking) 9

vous reviendrez sur la page qui pointait l’application. De même, vous ne pouvez pas
arriver sur un état particulier de l’application : à titre d’exemple, en rafraîchissant votre
navigateur, vous remarquerez que l’application est relancée intégralement. Toute votre
navigation est perdue.

Comment ça marche ?
Flex 3.0 propose une nouvelle solution pour permettre à vos utilisateurs de se servir des
fonctionnalités classiques d’un navigateur. Cette solution est basée sur la modification de
l’URL de la page de l’application Flex en lui rajoutant des paramètres du style
#view=1;details=true. L’application Flex écoute les modifications de navigateur et
réagit en conséquence.
L’implémentation du deep linking passe par le BrowserManager. Il permet à votre
application web de créer des fragments et d’en être avertie lorsque ces fragments sont
modifiés. Vous disposez de la classe URLUtil pour récupérer et convertir les fragments
d’URL en objets et vice versa. Malheureusement, cela n’est pas lié directement aux
contrôles Flex et risque de nécessiter quelques étapes :
1 Désactiver l’HistoryManager (qui ne gère l’historique basique que de quelques
contrôles).
2 Initialiser le BrowserManager avec un fragment par défaut.
3 Mettre à jour le fragment lorsque l’utilisateur interagit avec un composant et lorsque
vous voulez que cette action soit enregistrée dans l’historique.
4 Écouter les événements du BrowserManager pour savoir quand un utilisateur utilise
les fonctionnalités de son navigateur.
5 Interpréter un fragment et modifier l’application en conséquence lorsqu’un nouvel
événement est reçu par l’application.

Support du deep linking du template HTML

Le deep linking est géré d’un côté par Flash mais également par du code généré en ActionScript qui
va permettre de communiquer avec le navigateur. Il faut donc vous assurer d’utiliser un template HTML
qui supporte le BrowserManager. Pour cela, allez dans les propriétés de votre projet et, dans les options
de Flex Compiler, vérifiez que la case "Enable integration with browser navigation" est bien cochée.

Concrètement ?
Ce sera sûrement plus facile à comprendre et à refaire avec un exemple basique sous les
yeux. Voici une application MXML simple. Elle contient un TabNavigator avec deux

257
9 Améliorer l’expérience utilisateur

Panels et une CheckBox pour chacun. L’application va mettre à jour l’URL à chaque fois
que l’utilisateur changera d’onglet ou sélectionnera une case à cocher.
Créez une nouvelle application et modifiez la balise Application comme ceci afin de
désactiver l’HistoryManager :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="appInitialize()" historyManagementEnabled="false">

Maintenant, rajoutez une balise Script dans votre application. Nous allons tout de suite
initialiser notre BrowserManager. Vous aurez besoin des imports suivants, rajoutez-les :
import mx.events.BrowserChangeEvent;
import mx.managers.IBrowserManager;
import mx.managers.BrowserManager;
import mx.utils.URLUtil;

Déclarons maintenant notre browserManager pour pouvoir l’utiliser dans d’autres


fonctions et écrivons la fonction d’initialisation appInitialize, appelée après la création
de l’application :
public var browserManager:IBrowserManager;

private function appInitialize():void {


browserManager = BrowserManager.getInstance();
browserManager.init("", "Onglet 1");
browserManager.addEventListener(BrowserChangeEvent.BROWSER_URL_CHANGE,
parseURL);
}

Nous initialisons ici notre objet avec un fragment par défaut "". Cela signifie qu’il n’y a
rien de plus dans l’URL de notre navigateur. Nous ajoutons ensuite un listener qui écoute
les modifications d’URL du navigateur de l’utilisateur qui appellera la fonction parseURL.
Après votre balise Script, rajoutons le code de notre interface en spécifiant qu’on veut
appeler la méthode updateURL lorsque l’utilisateur change d’onglet ou coche une case :
<mx:TabNavigator id="tabNav" change="updateURL()" width="300" >
<mx:Panel label="Onglet 1">
<mx:CheckBox id="checkBox1" label="case 1" change="updateURL()" />
</mx:Panel>
<mx:Panel label="Onglet 2">
<mx:CheckBox id="checkBox2" label="case 2" change="updateURL()" />
</mx:Panel>
</mx:TabNavigator>

258
L’historique de navigation (deep linking) 9

Occupons-nous maintenant de la fonction parseURL :


private var parsingURL:Boolean = false;
private function parseURL(event:Event):void {
parsingURL = true;

var o:Object = URLUtil.stringToObject(browserManager.fragment);


if (o.view == undefined)
o.view = 0;
tn.selectedIndex = o.view;
tabNav.validateNow();

if (tabNav.selectedIndex == 0)
checkBox1.selected = o.is_selected;
else
checkBox2.selected = o.is_selected;
parsingURL = false;
}

Nous expliquerons l’intérêt de la variable parsingURL un peu plus loin. L’objet o contient
les fragments de l’URL sous forme d’entier. Le fragment view contient l’index de
l’onglet à afficher (0 ou 1) et le fragment is_selected vaut false ou true. L’URL de
votre application ressemble à #view=1;details=true.
Pour que cela marche, il faut que nous créions ces fragments avec les bonnes valeurs.
C’est la tâche qui incombe à la fonction updateURL() :
private function updateURL():void {
if (!parsing)
callLater(realUpdateURL);
}

private function realUpdateURL():void {


var o:Object = {};
if (tabNav.selectedIndex == 1) {
o.view = tabNav.selectedIndex;
if (checkBox1.selected)
o.details = true;
}
else {
o.view = tabNav.selectedIndex;
if (checkBox2.selected)
o.details = true;
}
var fragment:String = URLUtil.objectToString(o);
browserManager.setFragment(fragment);
}

259
9 Améliorer l’expérience utilisateur

Vous avez peut-être déjà compris l’utilité de la variable parsing : elle sert à éviter de
mettre à jour l’URL alors que celle-ci est en train d’être traitée par la fonction
parseURL(). Ces fonctions sont asynchrones, c’est-à-dire qu’elles peuvent être appelées
en même temps (si l’utilisateur appuie trop vite et répétitivement sur les onglets). La
fonction realUpdateURL() crée le nouveau fragment en créant un objet avec les propriétés
correspondant aux paramètres que l’on veut envoyer. Nous utilisons ensuite la fonction
inverse de la classe URLUtil pour transformer l’objet en une chaîne que l’on envoie au
navigateur, la fonction objectToString().
Malheureusement, Flex utilise des fonctionnalités du langage JavaScript qui ne sont pas
implémentées de la même manière dans les différents navigateurs. Ainsi, cette technique
ne fonctionne que sur :
j Internet Explorer 6, 7 ;
j Mozilla Firefox ;
j Safari.

La bibliothèque URLKit

Si l’historique est pour votre application une priorité et s’applique à de nombreux contrôles, cette
technique peut devenir très fastidieuse. Adobe conseille alors de vous orienter vers la bibliothèque
Open Source URL Kit. Vous aurez des règles à définir pour lier les contrôles aux fragments, mais vous
n’aurez pas à vous occuper des méthodes comme updateURL() ou parseURL() qui sont gérées par la
bibliothèque. Cette bibliothèque est expliquée et peut être téléchargée sur :
http://joeberkovitz.com/blog/urlkit/.

9.3 Impression
Vos utilisateurs auront certainement besoin d’imprimer tôt ou tard des éléments de votre
application Flex. Par exemple, la confirmation du bon déroulement d’une transaction
bancaire est une information souvent imprimée par les utilisateurs pour archiver. Ils
peuvent bien sûr utiliser les fonctionnalités classiques des navigateurs web pour imprimer
l’écran, mais il se peut que la page ne soit pas assez grande, ou mal adaptée à l’écran
qu’ils veulent imprimer.
Il existe alors plusieurs solutions pour imprimer et si vous avez de bonnes notions en
ActionScript, vous connaissez probablement déjà la classe PrintJob. Nous allons ici
détailler la classe FlexPrintJob, qui peut imprimer un ou plusieurs objets. Cette classe
découpe automatiquement les gros objets pour les imprimer sur plusieurs pages et inclut
des méthodes et propriétés pour ajouter de nombreux paramètres d’impression (comme
l’échelle par exemple).

260
Impression 9

Pour imprimer avec le FlexPrintJob, il faut créer une nouvelle tâche d’impression et
l’envoyer à l’imprimante en suivant la procédure suivante :
1 Créez une instance de la FlexPrintJobClass.
var printJob:FlexPrintJob = new FlexPrintJob();

2 Démarrez une nouvelle tâche d’impression (en anglais : print job) qui va obliger le
système d’exploitation à lancer une boîte de dialogue classique pour l’impression :
printJob.start();

3 Ajoutez un ou plusieurs objets à la tâche et spécifiez comment les redimensionner :


printJob.addObject(anyObject, FlexPrintJobScaleType.MATCH_WIDTH);

4 Envoyez la tâche à l’imprimante :


printJob.send();

Gestion des ressources utilisateurs

Parce que vous interagissez avec le système d’exploitation de l’utilisateur entre les appels aux méthodes
start() et send(), vous devez limiter le code entre ces deux appels. Le code intermédiaire doit être lié
à l’impression en cours. Par exemple, évitez des interactions avec l’utilisateur entre ces deux appels.

La méthode start() va ouvrir une boîte de dialogue pour l’impression et retournera true
si l’utilisateur lance l’impression et false s’il annule la demande d’impression. Vous ne
pouvez avoir qu’une seule tâche d’impression à la fois. Vous ne pouvez donc effectuer
une seconde tâche que si :
j la méthode start() a renvoyé false (la tâche a été annulée par l’utilisateur).
j la méthode send() s’est terminée.

La méthode addObject() permet d’ajouter des objets à imprimer. Chaque appel va lancer
l’impression de l’objet concerné sur une nouvelle page. Le second paramètre de cette
méthode est le type d’échelle voulu pour imprimer l’objet. Ce paramètre est optionnel et
a par défaut la valeur MATCH_WIDTH qui va redimensionner l’objet pour qu’il rentre en
largeur dans la page. Vous avez également à votre disposition les constantes
MATCH_HEIGHT, SHOW_ALL, FILL_PAGE et NONE.
Terminons cette partie avec un exemple concret d’impression en imprimant un tableau :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">

261
9 Améliorer l’expérience utilisateur

<mx:Script>
<![CDATA[
import mx.printing.*;

private function doPrint():void {


var printJob:FlexPrintJob = new FlexPrintJob();
// Démarre la tâche
if (printJob.start() != true) return;
// Ajoute l’objet à la tâche.
printJob.addObject(myDataGrid);
// Envoie la tâche à l’imprimante
printJob.send();
}
]]>
</mx:Script>
<mx:DataGrid id="myDataGrid" width="300">
<mx:dataProvider>
<mx:Object Country="Paris 19" Code="75019"/>
<mx:Object Country ="Villejuif" Code="94800"/>
</mx:dataProvider>
</mx:DataGrid>
<mx:Button label="Imprimer" click="doPrint();"/>
</mx:Application>

Si vous voulez imprimer le tableau et le bouton, vous devez rajouter un conteneur


invisible autour et lui spécifier un id pour pouvoir l’ajouter dans le printJob. Si vous
voulez imprimer le tableau et le bouton séparément, rajoutez un appel à addObject en
précisant l’id du bouton.
Vous pouvez également rajouter des objets supplémentaires pour compléter les
informations à imprimer puis les supprimer lorsque l’impression est terminée. Supposons
par exemple que dans l’exemple précédent, nous avions une VBox avec la propriété
id=myVBox. Nous voulons rajouter sur la page imprimée un titre à notre tableau ; voici ce
que nous devons donc ajouter après l’appel à la méthode printJob.start() :
var title:Label = new Label();
title.text = "liste des villes";
myVBox.addChild(title);

printJob.addObject(myVBox);
printJob.send();
removeChild(title);

Dans la mesure où l’on ne rend pas la main à l’utilisateur entre les deux appels start()
et send(), le Label ne sera vu par l’utilisateur que sur la page imprimée et jamais à

262
Internationalisation 9

l’écran. Vous pouvez ainsi formater à votre guise le rendu de l’impression en ajoutant et
modifiant les contrôles de l’application.

9.4 Internationalisation
Vous avez besoin d’une application gérant plusieurs langues ? Flex 3 propose une solution
complète pour prendre en charge l’internationalisation de votre application et pour
modifier la langue de votre application à l’exécution. Le but est d’être très flexible :
j Vous pouvez mettre les fichiers de langues dans des modules, plutôt que dans
l’application elle-même. Vous pouvez initialiser l’application avec la langue de votre
choix et charger ou changer de langue ultérieurement lors de l’exécution de l’application.
j Vous pouvez compiler les différentes versions dans une seule application ou module.
j Vous pouvez accéder aux ressources grâce au ResourceManager, qui peut gérer les
ressources pour plusieurs langues.
j Vous pouvez aussi utiliser des images, sons, etc., comme ressources en plus des
chaînes de caractères.
Voyons ceci avec un exemple concret dans la section suivante.

Faire une application localisée pas à pas


Nous allons créer une petite application qui sera en français et en anglais et qui
comportera une ComboBox pour changer dynamiquement la langue de l’application.
Commencez par créer un nouveau projet.
Comme cela se fait généralement lorsque l’on veut une application i18n
(internationalisée), vous devez séparer tout texte écrit en dur dans l’application dans un
fichier par langue (appelé bundle). On associe une variable (appelée une ressource) que
l’on utilise dans le code et que l’on associe au texte traduit dans les bundles.
Pour créer un nouveau bundle, créez un dossier locale à la racine de votre application.
Ensuite, créez un dossier pour chaque langue de votre application (que vous nommerez
conventionnellement en_US et fr_FR). Enfin, ajoutez dans chacun de ces dossiers un
fichier myRessources.properties comportant les ressources et leurs traductions respectives.
Le contenu du bundle français ressemble à ceci :
GREETING=Bonjour!
WELCOME_MESSAGE=Bienvenue dans votre application en français.

Le bundle anglais comporte la même chose, mais en anglais bien évidemment.


GREETING=Hello!
WELCOME_MESSAGE=Welcome in your application in English.

263
9 Améliorer l’expérience utilisateur

Un bundle est identifié par le nom de ce fichier. Ainsi, vous pouvez avoir plusieurs
bundles pour une même langue dans votre application. Cela permet pour une grosse
application d’organiser les fichiers de traduction. Ici, nous avons donc créé le bundle
myRessources.

Encodage des bundles

Le compilateur MXML s’attend à avoir un bundle encodé en utf-8. Si votre fichier n’est pas en utf-8, vous
aurez des problèmes d’affichage pour les caractères accentués. Pour passer un fichier en utf-8, ouvrez
la boîte de dialogue des Propriétés du fichier et changez l’encoding.

Maintenant, ajoutez un Label dans votre application au lieu d’écrire en dur la chaîne de
caractères comme ceci :
<mx:Label text="Hello!" />

Vous pouvez utiliser la directive @Ressource() du compilateur MXML pour dire que la
propriété text du contrôle Label doit être affectée avec une valeur localisée. Cette
directive prend deux paramètres, le bundle que vous voulez utiliser et la ressource que
vous voulez afficher pour le message traduit. Le code ressemble alors à ceci :
<mx:Label text="@Resource(bundle=’myResources’, key=’GREETING’)" />

Avant de compiler votre application, il va falloir rajouter des options de compilation afin
que les langues soient prises en compte. Ajoutez des options de compilation, ouvrez les
boîtes de dialogue des Propriétés du projet, sélectionnez le panel Flex Compiler, et
entrez ce qui suit dans Additional compiler arguments :
-locale=en_US -source-path=locale/{locale} -allow-source-path-overlap=true

Si vous compilez et lancez votre application, vous devriez voir affiché le message "Hello!".
Si vous voulez voir le texte affiché en français, remplacez :
-locale=en_US

par :
-locale=fr_FR

Recompilez et lancez votre application. Le tour est joué.


Passons aux choses sérieuses maintenant. Nous ne voulons pas recompiler à chaque fois
notre application pour passer d’une langue à une autre. Cela ne présenterait guère
d’intérêt. Voyons comment changer la langue dynamiquement, sans avoir à recompiler.

264
Internationalisation 9

Pour commencer, compilons notre application avec les deux langues, l’anglais et le
français, et ajoutons le code pour pouvoir alterner.
Changeons l’option de compilation −locale pour ceci :
-locale=en_US,fr_FR

Modifions maintenant notre fichier pour qu’il ressemble au suivant :


<?xml version="1.0" encoding="utf-8"?><br><mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml">

<mx:Metadata>
[ResourceBundle("myResources")]
</mx:Metadata>

<mx:Script>
<![CDATA[
[Bindable]
private var locales:Array = [ "en_US" , "fr_FR" ];
private function
➥ localeComboBox_initializeHandler(event:Event):void
{
localeComboBox.selectedIndex =
➥ locales.indexOf(resourceManager.localeChain[0]);
}

private function localeComboBox_changeHandler(event:Event):void


{
// Attribue à localeChain [ "en_US" ] ou [ "fr_FR" ].
resourceManager.localeChain = [ localeComboBox.selectedItem ];
}
]]>
</mx:Script>

<mx:Label text="{resourceManager.getString(’myResources’,
’GREETING’)}" />
<mx:ComboBox id="localeComboBox" dataProvider="{locales}"
initialize="localeComboBox_initializeHandler(event)"
change="localeComboBox_changeHandler(event)"/>

</mx:Application>

Lorsque vous compilez et lancez l’application, celle-ci s’initialise en anglais car en_US est
spécifié en tant que première locale (langue). Mais lorsque vous choisissez fr_FR dans la
ComboBox, le texte passe en français.

265
9 Améliorer l’expérience utilisateur

Vous avez sans doute remarqué l’objet resourceManager. C’est un singleton qui gère
l’internationalisation de toute l’application Flex, non seulement vos textes mais
également les composants du framework. Ainsi, vous pouvez utiliser cette instance pour
lier vos Labels aux ressources :
text="{resourceManager.getString(’myResources’, ’GREETING’)}"

Vous constaterez que nous n’utilisons pas la même technique pour afficher le texte
lorsque nous souhaitons le changer à la volée. La langue est définie par la propriété
localeChain du resourceManager (attention, cette valeur est un tableau contenant la
chaîne de la langue). Enfin, vous noterez l’ajout d’un tag au début de notre application :
<mx:Metadata>
[ResourceBundle("myResources")]
</mx:Metadata>

Ce tag est utilisé car lorsque nous utilisons resourceManager.getString(bundleName,


key) au lieu de la directive @Resource(), le compilateur n’est pas assez malin pour savoir
de quels bundles votre application va avoir besoin.

Mettre autre chose que des objets string dans les ressources
Vous n’êtes pas limité à des chaînes de caractères dans vos fichiers de ressources. Prenons
par exemple le fichier .properties suivant :
VALUE=24.90
DISTANCE=37
JUNIOR=false

Le compilateur ne va pas lire le fichier et décider tout seul que false doit être interprété
comme un booléen plutôt qu’une chaîne de caractères. Néanmoins, l’objet
resourceManager possède d’autres méthodes pour accéder aux ressources que
getString();. Par exemple :
resourceManager.getNumber("myResources", "VALUE");
// retourne le Number 24.90, et non la String "24.90"

resourceManager.getInt("myResources", "DISTANCE");
// retourne l’entier int 37, et non la String "37"

resourceManager.getBoolean("myResources", "SENIOR")
// retourne le Boolean false, et non la String "false"

266
Check-list 9

Ces méthodes sont en réalité des simples surcharges de la méthode getObject() qui
retourne la valeur de la ressource sans conversion.
Vous pouvez également utiliser des directives dans les fichiers .properties pour charger
des images, des sons ou des classes différentes selon la langue, comme :
LOGO=Embed("logo.jpg")
SORTER=ClassReference("sorters.Urdu")

Charger les fichiers de langue à l’exécution


Vous avez bien compris que ces langues sont incluses dans le SWF lors de la compilation.
Vous pouvez avoir besoin de charger vos bundles autrement, en allant par exemple
chercher les ressources dans une base de données ou un fichier XML.
Le ResourceManager peut charger un bundle que vous pouvez créer à l’exécution. Le code
suivant crée un nouveau bundle, lui ajoute quelques ressources et l’ajoute au
ResourceManager :
var moreResources:ResourceBundle =
new ResourceBundle("fr_FR", "moreResources");
moreResources.content["OPEN"] = "Ouvrez";
moreResources.content["CLOSE"] = "Fermez";
resourceManager.addResourceBundle(moreResources);

Une fois le bundle dans le ResourceManager, vous pouvez utiliser la méthode


getString() sur celui-ci pour trouver vos ressources :
resourceManager.localeChain = [ "fr_FR" ];
trace(resourceManager.getString("moreResources", "OPEN"));
// écrit "Ouvrez" sur la sortie

9.5 Check-list
Dans ce chapitre, nous avons vu :
a comment gérer le glisser-déposer dans une application ;
a comment utiliser l’historique de navigation de Flex ;
a comment gérer les subtilités de l’impression d’une application Flex ;
a comment créer une application multilangues.
Le prochain chapitre abordera la communication avec un serveur.

267
10
10.1 Comprendre les possibilités de récupération
de données .............................................. 270
10.2 HTTPService ............................................. 274
10.3 Services web ............................................ 285
10.4 RemoteObject ........................................... 290
10.5 Mise en pratique : une application avec Amazon .. 291
10.6 Check-list ................................................. 301
Communiquer
avec un
serveur
C e chapitre aborde les notions essentielles pour
comprendre le fonctionnement des communications
client/serveur dans une application Flex. Vous allez
bientôt pouvoir interagir avec des données ou des services
externes pour alimenter vos composants et charger
dynamiquement des ressources.
10 Communiquer avec un serveur

10.1 Comprendre les possibilités de récupération de données


Depuis le début de cet ouvrage, nous avons manipulé des données statiques sous la forme
d’objets ActionScript, de modèle avec le composant <mx:Model> ou encore de données
XML directement incluses dans le code. Vous en conviendrez, il serait nettement plus
intéressant de travailler avec des données extérieures provenant d’un flux XML ou encore
d’une base de données comme c’est le cas pour la plupart des sites web.
Comme vous le savez, Flex est utilisé pour le tiers de présentation côté client et n’a donc
pas vocation à gérer la logique métier d’une application web (traitement en base de
données notamment). Flex laisse alors le soin à des applications côté serveur d’effectuer
ce type de tâches.
Il existe donc un ensemble de classes permettant d’interagir avec d’autres applications
pour récupérer ou encore transmettre des objets en utilisant des protocoles standardisés.
C’est ce que nous allons voir au cours de ce chapitre. Mais avant toute chose, nous allons
voir comment récupérer des données du projet à l’exécution afin d’alléger la taille de
notre fichier SWF.

Chargement dynamique des données XML


Vous avez appris à manipuler des ensembles de données lors du chapitre 5 avec les
différents composants Flex afin d’inclure les données directement dans votre code
MXML ou dans un fichier séparé dans le projet tout en utilisant la propriété source du
composant <mx:XML> par exemple. Dans ces deux cas, les données sont dites incluses dans
l’application. Elles seront chargées à la compilation dans le fichier SWF généré, ce qui
implique forcément une recompilation à chaque modification des données. Il est donc
important de prendre en considération les questions suivantes :
j Les données vont-elles changer ?
j Le volume de l’ensemble des données est-il important ?

Si la réponse à l’une de ces questions est oui, alors il serait peut-être plus judicieux de
charger dynamiquement les données du projet. Le fichier XML par exemple, ou pourquoi
pas une image, ne sera alors chargé qu’à l’exécution de l’application. Cela implique certes
une légère latence au premier chargement mais le fichier sera ensuite stocké en cache
dans le navigateur. En conclusion, il est préférable d’utiliser le chargement dynamique à
la place de l’inclusion à la compilation.
Pour charger dynamiquement des ressources (fichier XML, image…), il faut utiliser la
classe URLoader d’ActionScript qui possède un système événementiel complet permettant
de notifier plusieurs types d’événements (Event.COMPLETE, ProgressEvent.PROGRESS,

270
Comprendre les possibilités de récupération de données 10

etc.). Nous allons utiliser les classes URLLoader et URLRequest pour gérer un chargement
dynamique d’un fichier XML dans un objet ActionScript :
Nous devons créer une application nommée dynamiqueXML ainsi qu’un fichier test.xml
qui contiendra les données suivantes :
<Mall>
<Shop>
<Name>Random Shop</Name>
<Article>
<Name>Pant</Name>
<Price>120</Price>
</Article>
<Article>
<Name>tshirt</Name>
<Price>30</Price>
</Article>
<Article>
<Name>Shoes</Name>
<Price>100</Price>
</Article>
<Article>
<Name>Sweaters</Name>
<Price>60</Price>
</Article>
<Article>
<Name>Suit</Name>
<Price>600</Price>
</Article>
</Shop>
</Mall>

Le but est de charger le contenu de ce fichier dynamiquement puis de l’afficher dans notre
application dont voici la structure :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
<mx:XML id="sourceCode"/>
<mx:Panel>
<mx:TextArea width="300" height="300" text="{sourceCode}"/>
<mx:Button label="Afficher le code source" click="loadXML()"/>
</mx:Panel>
</mx:Application>

Ce qui importe dans cette application n’est pas vraiment le design. Il s’agit ici d’utiliser
la classe URLLoader pour charger le contenu dynamiquement. Remarquez tout de même
la présence d’un élément XML nommé sourceCode et ne contenant pour l’instant aucune

271
10 Communiquer avec un serveur

donnée incluse. C’est dans cet objet que nous stockerons les données chargées. Voici donc
le code ActionScript :
<mx:Script>
<![CDATA[
public var loader:URLLoader = new URLLoader() ;
public function loadXML():void{

var url:String = "test.xml" ;

var request:URLRequest = new URLRequest( url ) ;

loader.addEventListener(Event.COMPLETE, onLoad);
loader.load( request ) ;
}

public function onLoad(evt:Event):void{


sourceCode= new XML(loader.data);
}
]]>
</mx:Script>

La première étape consiste à déclarer une variable de type URLoader que nous avons ici
nommée tout simplement loader. La fonction loadXML sera appelée sur l’événement click
du bouton de l’application. Cette méthode déclare une variable URLRequest avec le nom du
fichier cible dans le constructeur. Nous ajoutons ensuite un listener à notre loader (la
méthode onLoad qui aura pour seul rôle de remplir notre variable XML nommée
sourceCode). Finalement, nous demanderons explicitement à notre loader de charger les
données pointées par notre URLoader (la variable request). Une fois le chargement terminé,
l’événement complete est levé et récupéré par la méthode onLoad. Et voici le résultat final :
c Fig. 10.1 :
Chargement dynamique
d’un fichier XML

272
Comprendre les possibilités de récupération de données 10

La prochaine étape consistera à charger un fichier XML sur un autre serveur web. Nous
allons auparavant faire un point sur les règles de sécurité du Player Flash.

Un point sur le Player Flash et la sécurité


Nous allons bientôt utiliser les composants Flex permettant la communication entre une
application et des serveurs web distants. Le Player Flash définit cependant des règles de
sécurité assez strictes en ce qui concerne ce type de communication.
Le Player Flash d’Adobe tourne dans une zone sécurisée appelée sandbox (on parle aussi
de bac-à-sable) afin d’éviter que du code malveillant soit exécuté sur le client. De ce fait,
les règles suivantes sont toujours appliquées par défaut :
j Les ressources contenues dans une même sandbox sont toujours accessibles entre elles.
j Les fichiers SWF d’une sandbox distantes ne peuvent jamais accéder aux fichiers et
données locales.
Pour définir les droits d’accès, le Player Flash définit quatre types différents de zones de sécurité :

Tableau 10.1 : Les types de zones de sécurité

Zone Description

Distant (remote) Correspond aux ressources situées sur un autre domaine Internet.

Local et système de Permet d’accéder aux ressources locales et aux fichiers locaux mais sans
fichiers accès au réseau.

Local et réseau Les fichiers SWF peuvent accéder au réseau mais pas aux fichiers locaux.

Local autorisé (local Pas de restriction d’accès. L’accès aux fichiers locaux est permis si
trusted) l’utilisateur l’autorise.

L’appel à des ressources distantes est donc soumis à des règles d’accès. Tout d’abord,
l’application doit tourner dans une sandbox avec un accès vers l’extérieur (Local et réseau
par exemple). Ensuite, il est possible d’accéder à des médias distants sans restriction
(image, vidéos…) mais ce n’est pas le cas pour les données. En effet, dans ce cas précis,
il faut que vous soyez autorisé par le serveur distant à utiliser les données par le biais d’un
fichier situé à la racine du serveur : le fichier crossdomain.xml. Ce fichier qui définit une
liste d’URL permet d’indiquer que les données du serveur sont disponibles aux fichiers
SWF situés sur les domaines listés.
En fait, le principe est le suivant : quand un document Flash tente d’accéder à des
données distantes situées sur un autre domaine, le fichier crossdomain.xml est récupéré

273
10 Communiquer avec un serveur

sur le serveur appelé puis si le domaine du document Flash est inclus dans le fichier, alors
les données sont automatiquement accessibles.
Si nous abordons ce sujet, c’est que ce type de restriction peut poser des problèmes
d’accès aux données lors d’appel à des méthodes distantes une fois que vous déploierez
votre application sur un serveur web. Pour plus de détails, nous vous conseillons de vous
reporter à la documentation officielle.

10.2 HTTPService
Nous allons maintenant entrer dans le cœur du sujet : l’accès à des données distantes.
Nous allons pour cela commencer par la classe HTTPService qui permet de récupérer un
flux XML par le biais d’une requête http. Un composant HTTPService peut être créé aussi
bien en MXML qu’en ActionScript. Une fois l’objet créé, il est possible d’effectuer un
appel asynchrone à l’adresse URL spécifiée pour récupérer un flux statique ou dynamique
provenant de n’importe quel type de source (PHP, Ruby, JSP, .Net…) grâce à la méthode
send() qui retourne alors les données demandées. Le diagramme suivant schématise
l’interaction entre le client et le serveur par le biais des composants Flex.

c Fig. 10.2 : Communication client/serveur

274
HTTPService 10

Récupération de données via une requête http


Nous allons maintenant recourir au MXML pour lancer une requête distante. Nous allons
utiliser une des API Yahoo! pour rechercher un restaurant de San Francisco. Pour plus de
détails sur l’API Yahoo!,, nous vous invitons à vous rendre à cette adresse : http://developer
.yahoo.com/search/.
Nous stockerons ensuite le résultat dans une ArrayCollection, et nous afficherons le
premier résultat de la recherche.
L’API sera la LocalSearch maintenant disponible en version 3 ; la documentation est
disponible sur http://developer.yahoo.com/search/local/V3/localSearch.html.
Comme vous le constatez, il est nécessaire de passer des arguments pour obtenir un
résultat. Deux sont obligatoires. Il s’agit de :
j appid : applicationID qui identifie de manière unique votre application. Vous
pouvez en créer un ou utiliser YahooDemo.
j query : le texte recherché.

Nous recherchons les restaurants de San Francisco dont l’un des codes postaux est 94108.
Nous allons donc construire notre requête à partir de l’URL de base du service :
http://local.yahooapis.com/LocalSearchService/V3/localSearch.
Puis nous allons ajouter les trois paramètres suivants :
j appid=YahooDemo ;
j query=restaurant ;
j zip=94108.

Ce qui donne : http://local.yahooapis.com/LocalSearchService/V3/localSearch?appid=YahooDemo&query


=restaurant&zip=94108.
À présent, lancez le résultat dans un navigateur et observez le résultat final (voir
fig. 10.3).
La requête a retourné un flux XML contenant une mine d’informations comme :
j le nombre total de résultats ;
j le nombre de résultats retournés ;
j un lien Yahoo! Maps.

Et pour chaque restaurant :


j les coordonnées (adresse, téléphone ainsi que longitude et latitude) ;

275
10 Communiquer avec un serveur

c Fig. 10.3 : Résultat de la requête dans un navigateur

j une note (bien pratique) ;


j la dernière critique ;
j le type de cuisine ;
j un lien Yahoo! Maps ;
j etc.

Il est temps d’appeler cet URL depuis une application Flex et d’utiliser le composant
HTTPService. Créez une nouvelle application. Nous y ajouterons un bouton pour appeler
la requête, et cinq champs pour afficher les informations de base du premier résultat :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical">

276
HTTPService 10

<mx:Label id="Nom"/>
<mx:Label id="Adresse"/>
<mx:Label id="Telephone"/>
<mx:Label id="Note"/>
<mx:Label id="URL"/>
<mx:Button label="Lancer la recherche" />
</mx:Application>

Ajoutons maintenant le HTTPService que nous nommerons restaurant :


<mx:HTTPService id="restaurant"
➥ url="http://local.yahooapis.com/LocalSearchService/V3/localSearch
➥ ?appid=YahooDemo&query=restaurant&zip=94108"/>

L’URL est spécifié par la propriété URL, ce qui est logique ; cependant, le code juste
au-dessus ne marche pas et Flex Builder vous signale le message d’erreur suivant :
The reference to entity "query" must end with the ’;’ delimiter. <Enrichissement ?>
En fait, il n’est pas possible de construire la requête "à la main" comme dans un
navigateur. À défaut, il faut utiliser la balise <mx:Request> de la manière suivante :
<mx:HTTPService id="restaurant"
url="http://local.yahooapis.com/LocalSearchService/V3/localSearch">
<mx:request>
<appid>YahooDemo</appid>
<query>restaurant</query>
<zip>94108</zip>
</mx:request>
</mx:HTTPService>

Comme vous le constatez, il faut ensuite créer une balise XML pour chaque paramètre de
la requête.
Maintenant que la requête est définie correctement, il va falloir l’appeler et stocker le
résultat dans le tableau que nous avons défini précédemment. Il ne restera plus qu’à
remplir les champs associés à chaque propriété.

Appeler une requête http


Pour appeler une requête http, il faut invoquer la méthode send() d’un objet de type
HTTPService. Cette méthode effectue une requête http ou https en mode GET, POST, HEAD,
OPTIONS, PUT, TRACE, ou DELETE. Une réponse http est ensuite renvoyée avec les résultats
de la requête. Les résultats sont récupérés dans la propriété lastResult d’un objet
HTTPService.

277
10 Communiquer avec un serveur

Nous allons maintenant passer à la pratique en commençant par appeler la méthode


send() dès que notre application est chargée grâce à l’événement creationComplete de
la balise <mx:Application>. Il ne reste plus qu’à exploiter le résultat avec une méthode
qui remplira nos cinq champs grâce au contenu de lastResult. Voici donc le code final :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx=http://www.adobe.com/2006/mxml
layout="vertical" creationComplete="restaurant.send()">
<mx:Script>
<![CDATA[
public function appel() : void{

Nom.text = restaurant.lastResult.ResultSet.Result[0].Title;
Adresse.text = restaurant.lastResult.ResultSet.Result[0].Address;
Telephone.text = restaurant.lastResult.ResultSet.Result[0].Phone;
Note.text =
restaurant.lastResult.ResultSet.Result[0].Rating.AverageRating;
URL.text = restaurant.lastResult.ResultSet.Result[0].BusinessUrl;
}
]]>
</mx:Script>
<mx:HTTPService id="restaurant"
url="http://local.yahooapis.com/LocalSearchService/V3/localSearch">
<mx:request>
<appid>YahooDemo</appid>
<query>restaurant</query>
<zip>94108</zip>
</mx:request>
</mx:HTTPService>

<mx:Label id="Nom"/>
<mx:Label id="Adresse"/>
<mx:Label id="Telephone"/>
<mx:Label id="Note"/>
<mx:Label id="URL"/>
<mx:Button label="Lancer la recherche" click="appel()"/>
</mx:Application>

Veillez à la manière dont vous accédez aux éléments de la réponse dans la méthode
appel(). Nous accédons aux différentes informations en suivant l’arbre XML récupéré
directement dans la propriété lastResult. Souvenez-vous également que l’appel à la
méthode send() est indispensable (ici appelée en réponse à l’événement
creationComplete de l’application) avant de l’utiliser, car dans le cas contraire, la
propriété lastResult serait égale à null.

278
HTTPService 10

Voici enfin un visuel de l’application affichant les informations du premier restaurant de


la recherche :
c Fig. 10.4 :
Visuel de l’application

Comme vous le constatez, les résultats correspondent bien aux flux XML que vous aviez
précédemment affichés dans votre navigateur.

Type de retour d’une requête http


Il est possible de choisir le type de retour de la réponse http grâce à la propriété
resultFormat de la classe HTTPService qui accepte les valeurs suivantes :

Tableau 10.2 : Les options pour resultFormat

Valeur Description

array Tableau d’objets représentant l’ensemble des nœuds d’un même niveau
dans l’arborescence XML.

e4x Le résultat est renvoyé sous la forme d’une instance XML pouvant être
manipulée par les opérateurs ECMAScript for XML (e4x).

flashvars Les valeurs sont stockées sous forme de texte de type nom=valeur séparées
par le caractère &.

object Les valeurs XML sont parsées en un arbre d’objets ActionScript.

text L’ensemble du résultat est stocké directement dans une chaîne sans aucun
traitement.

XML Le résultat est stocké dans une instance de la classe XMLNode représentant
le nœud parent.

XML ou e4x

Lorsque les données retournées par un objet HTTPService correspondent à un document XML, il est
préférable d’utiliser e4x comme format de résultat car le format XML est utilisé à titre de compatibilité
avec les versions précédentes d’ActionScript.

279
10 Communiquer avec un serveur

Utiliser le binding
Nous venons d’utiliser la classe HTTPService pour récupérer des données XML
dynamiques à partir d’une requête http statique. Les informations pertinentes du premier
résultat ont ensuite été récupérées par une méthode ActionScript pour être affichées
correctement dans des Labels. Mais il serait bien plus pratique de pouvoir formuler notre
requête http en fonction des informations saisies par l’utilisateur et de mettre à jour
automatiquement les données à chaque nouvelle requête. C’est bien évidement possible
grâce au binding de données que nous avons abordé au chapitre 5.
Nous allons donc légèrement modifier l’application précédente en remplaçant dans un
premier temps les Labels par une DataGrid puis en rajoutant un formulaire pour saisir les
données nécessaires à la requête. Enfin, nous changerons la place de l’appel à la requête
http qui se trouve actuellement dans l’événement creationComplete de l’application pour
l’appeler sur l’événement click du bouton.
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical" >

<mx:HTTPService id="restaurant"
url="http://local.yahooapis.com/LocalSearchService/V3/localSearch" >
<mx:request>
<appid>YahooDemo</appid>
<query>{formQuery.text}</query>
<zip>{formZip.text}</zip>
</mx:request>
</mx:HTTPService>

<mx:Form label="paramètres de la requête">


<mx:FormItem label="Query">
<mx:TextInput id="formQuery" />
</mx:FormItem>
<mx:FormItem label="Code postal">
<mx:TextInput id="formZip" />
</mx:FormItem>
</mx:Form>
<mx:DataGrid dataProvider="{restaurant.lastResult.ResultSet.Result}"
width="900" height="300">
<mx:columns>
<mx:DataGridColumn dataField="Address"/>
<mx:DataGridColumn dataField="Title"/>
<mx:DataGridColumn dataField="BusinessClickUrl" headerText="URL"/>
<mx:DataGridColumn dataField="City"/>
<mx:DataGridColumn dataField="Phone"/>
</mx:columns>

280
HTTPService 10

</mx:DataGrid>
<mx:Button label="Lancer la recherche" click="restaurant.send()"/>
</mx:Application>

Comme vous le constatez, les champs du formulaire ont été liés aux paramètres contenus
dans la balise <mx:Request> du HTTPService. C’est également le cas pour la propriété
DataProvider de la DataGrid qui est directement liée aux nœuds ResultSet.Result du
XML renvoyés en réponse. Le nombre de colonnes a également été limité afin de
n’afficher que les informations utiles.
Nous vous donnons le résultat en image :

c Fig. 10.5 : Recherche de restaurants à San Francisco en utilisant la liaison de données

Récupérer les résultats de manière événementielle


Jusqu’à présent, nous avons récupéré les données directement dans la propriété
lastResult d’un objet HTTPService qui stocke le résultat de la réponse retournée après
l’appel à la requête. Le résultat en question n’est cependant pas accessible directement
après l’appel de la méthode send() puisque la requête peut prendre plus ou moins de
temps en fonction du débit. Un accès prématuré à la propriété lastResult peut donc
entraîner des erreurs à l’exécution comme vous pouvez le constater avec ce petit bout de
code ActionScript qu’il est possible d’insérer dans l’application précédente :
public function accessResult():void
{
restaurant.send();
formQuery.text = restaurant.lastResult.toString();
}

281
10 Communiquer avec un serveur

Son exécution provoquera l’erreur suivante :


TypeError: Error #1009: Cannot access a property or method of a null object reference.
<Enrichissement ?>
En effet, la réponse n’a pas encore eu lieu lorsque l’on tente d’accéder au résultat ; en
conséquence, la valeur de lastResult est null, ce qui provoque cette erreur classique.
La meilleure méthode pour se prémunir de ce genre d’exception si l’on souhaite accéder
au résultat de la réponse est d’utiliser l’événement result de la classe HTTPService.
Celui-ci se déclenche lorsque la réponse a été correctement envoyée par le serveur. Nous
allons donc mettre cela en pratique en déclarant une fonction qui se chargera d’afficher
le nombre de résultats total de la recherche.
Il suffit simplement de procéder comme suit :
1 Rajoutez un Label sous le bouton que vous nommerez nbResult
<mx:Label id="nbResult"/>

2 Créez une fonction ActionScript (ici processResult) prenant en argument un


événement de type ResultEvent
<mx:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;
public function processResult(evt:ResultEvent):void
{
nbResult.text = "Nombre total de résultats : ";
nbResult.text += evt.result.ResultSet.totalResultsAvailable;
}
]]>
</mx:Script>

3 Affectez la fonction à l’événement result de notre HTTPService


<mx:HTTPService id="restaurant"
url="http://local.yahooapis.com/LocalSearchService/V3/localSearch"
result="processResult(event)" >
<mx:request>
<appid>YahooDemo</appid>
<query>{formQuery.text}</query>
<zip>{formZip.text}</zip>
</mx:request>
</mx:HTTPService>

282
HTTPService 10

La recherche avec les paramètres restaurant et 94108 pour le code postal nous indique
qu’il existe 8 432 restaurants référencés à San Francisco.

c Fig. 10.6 : Utilisation d’un gestionnaire d’événements

Gérer les erreurs


Nous venons d’utiliser un gestionnaire d’événements pour traiter les résultats d’une
requête http effectuée avec succès, mais malheureusement tout ne se passe pas toujours
aussi bien. Une requête peut échouer pour un grand nombre de raisons comme les
suivantes :
j un serveur injoignable ;
j une requête mal formatée ;
j un temps d’attente dépassé ;
j et bien d’autres raisons encore.

Il est donc nécessaire de prendre en compte ce genre d’éventualités afin d’éviter le


déclenchement d’exception à l’exécution du code. Vous pouvez tester par vous-même les
conséquences d’une mauvaise requête. Il suffit de ne pas remplir le champ query de notre
application. Comme spécifié sur la documentation Yahoo!, ce champ est obligatoire pour
toute requête (il en est de même pour le champ appid que nous avons mis en directement
dans notre code) (voir fig. 10.7).
L’envoi de la requête sans le paramètre query provoque l’erreur suivante :
RPC Fault faultString="HTTP request error" faultCode="Server.Error.Request"
faultDetail="Error: [IOErrorEvent type="ioError" <Enrichissement ?>

283
10 Communiquer avec un serveur

c Fig. 10.7 : Erreur à la suite d’une mauvaise requête http

Flex propose donc d’intercepter les erreurs de type RPC grâce à un gestionnaire d’événements.
À chaque erreur déclenchée lors d’un appel à la méthode send() d’un HTTPService, un
événement de type FaultEvent est envoyé. Ce dernier contient entre autres :
j un objet de type Fault (propriété fault) descendant de la classe Error et contenant
les détails liés à l’incident (FaultCode, FaultDetail, FaultString et RootCause) ;
j un message (qui contient l’ensemble des informations précédentes).

C’est l’événement fault d’un HTTPService qui permet d’intercepter ce type d’erreur.
Nous allons maintenant afficher un pop-up en cas d’erreur lors de l’envoi de notre
requête. Il suffit de procéder comme suit :
1 Créez une méthode ActionScript prenant en paramètre un objet de type FaultEvent :
import mx.controls.Alert;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;

public function faultHandler(evt:FaultEvent):void


{
Alert.show("Une erreur s’est produite\n : " +
"\nDetails\n" +
"faultCode : " + evt.fault.faultCode + "\n" +
"faultDetail : " + evt.fault.faultDetail + "\n" +
"faultString : " + evt.fault.faultString + "\n");

2 Affectez cette méthode à l’événement fault de votre HTTPService :


<mx:HTTPService id="restaurant"
url="http://local.yahooapis.com/LocalSearchService/V3/localSearch"

284
Services web 10

result="processResult(event)"
fault="faultHandler(event)">
<mx:request>
<appid>YahooDemo</appid>
<query>{formQuery.text}</query>
<zip>{formZip.text}</zip>
</mx:request>
</mx:HTTPService>

Voici un exemple d’erreur produite par notre gestionnaire d’événements (ici, nous
n’avons pas rempli le champ query).
c Fig. 10.8 :
Gestion d’une erreur
RPC

La propriété message d’un objet FaultEvent

Le message contenu dans un événement de type FaultEvent contient une mine d’informations pouvant
vous aider à trouver la cause de cette erreur. Cependant, ce message reste peu explicite pour un
utilisateur lambda. Il est donc conseillé de le remplacer par un message plus simple lorsque vous
entrerez en phase de production.

10.3 Services web


En plus des requêtes http standard, le framework Flex permet d’interagir avec des
services web qui prennent une importance croissante dans les architectures orientées
services (SOA en anglais pour Service Oriented Architecture).
À titre de rappel, le concept de services web signifie simplement que vous pouvez accéder
à des fonctionnalités ou méthodes que vous pouvez invoquer sur un serveur distant afin
de déclencher un traitement spécifique et/ou obtenir une réponse ou un résultat en retour.
Les services web définissent également leurs propres standards avec notamment SOAP
pour l’échange des messages et WSDL pour la description des messages et des types de
données à travers le protocole http.

285
10 Communiquer avec un serveur

Utiliser des services web de type SOAP


L’utilisation des services web en Flex est assez similaire aux HTTPServices. Cependant,
pour une adresse donnée il peut exister plusieurs méthodes différentes. En effet, imaginez
un serveur proposant des informations sur la finance. Ce serveur pourrait proposer de
connaître le cours d’un indice ou d’une matière première donnée par exemple ou encore
proposer des taux de change entre les monnaies. Il pourrait donc exister une méthode
distincte par type d’informations recherchées.
Un service web se définit donc en Flex par :
j l’adresse du document wsdl décrivant le service (propriété wsdl) ;
j une ou plusieurs méthodes à appeler (balise <mx:operation>).

Nous allons à présent déclarer un service web dans une application afin de traduire un
texte du français à l’anglais ou de l’anglais au français. Pour cela, nous allons utiliser
celui situé à l’adresse suivante :
http://www.webservicex.net/WCF/ServiceDetails.aspx?SID=47
Vous y trouverez un lien vers le document wsdl ainsi qu’une description des méthodes
disponibles (dans notre cas seulement translate).
La méthode translate prend en paramètre deux arguments :
1 le type de traduction limité à une énumération de valeurs (comme frenchToEnglish
par exemple d’après le document wsdl) ;
2 le texte à traduire.

Créez une nouvelle application (myTranslator) et déclarez-y un composant WebService


comme ceci :
<mx:WebService id="translatorService"
wsdl="http://www.webservicex.net/TranslateService.asmx?wsdl">
</mx:WebService>

Vous pouvez, tout comme un HTTPService, définir un certain nombre de propriétés ou de


méthodes à appeler sur des événements spécifiques. Le tableau suivant vous donnera un
aperçu des fonctionnalités les plus importantes.

Tableau 10.3 : Fonctionnalités essentielles d’un compoant WebService

Propriété Description

Id Le nom de l’instance de l’objet WebService créée dans Flex.

286
Services web 10

Tableau 10.3 : Fonctionnalités essentielles d’un compoant WebService

Wsdl L’emplacement du service web à utiliser.

Load Spécifie une action à effectuer après le chargement de l’objet WebService. Cet
événement est souvent utilisé pour invoquer une méthode distance immédiatement après
que l’application et le service ont été chargés.

result Le gestionnaire d’événements est appelé lorsque les données sont retournées par le
service web.

Fault Le gestionnaire d’événements est appelé lorsqu’une erreur est retournée par le service web.

Appeler des méthodes distantes


Comme nous l’avons dit précédemment, un service web peut offrir plusieurs méthodes à
appeler. Il n’est donc pas envisageable d’utiliser une seule et unique fonction pour invoquer
ces méthodes comme c’est le cas avec le send() du HTTPService. Il faut donc définir
chaque méthode à appeler au sein de la balise <mx:WebService>. Chaque méthode sera
définie dans une balise <mx:operation> spécifique comme le montre le code suivant :
<mx:WebService id="translatorService"
wsdl="http://www.webservicex.net/TranslateService.asmx?wsdl">
<mx:operation name="Translate">
<mx:request xmlns="">
</mx:request>
</mx:operation>
</mx:WebService>

La page de description du service nous indique qu’il fournit une unique méthode nommée
Translate qui prend en paramètre deux arguments (le type de traduction et le texte à
traduire). Pour invoquer cette méthode, il suffit d’appeler le service web avec le nom
correspondant suivi de la méthode send(). Cela donne donc translatorService
.Translate.send() pour le code précédent.
Enfin, le résultat de cet appel se trouvera logiquement dans translatorService
.Translate.lastResult.

Passer des arguments aux méthodes de services web


De la même manière que pour un HTTPService, il est possible de passer des arguments
au service web de deux manières distinctes :
j par la liaison de données dans la balise <mx:request> (vu précédemment pour les
HTTPService) ;

287
10 Communiquer avec un serveur

j directement dans l’appel de la méthode en ActionScript de la manière suivante :


translatorService.Translate(arg1,arg2).

Nous allons donc compléter notre application pour pouvoir appeler le service web
correctement. Pour cela, il faut procéder comme suit :
1 Ajoutez un bouton pour appeler la méthode distante.
2 Complétez le service web pour prendre en compte les deux paramètres.
3 Ajoutez deux TextInput pour saisir le texte à traduire et afficher le résultat.
4 Ajoutez une ComboBox pour choisir le type de traduction.

Voici le code final :


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx=http://www.adobe.com/2006/mxml
layout="vertical" verticalAlign="middle">
<mx:WebService id="translatorService"
wsdl="http://www.webservicex.net/TranslateService.asmx?wsdl">
<mx:operation name="Translate">
<mx:request xmlns="">
<LanguageMode>{mode.selectedItem.value}</LanguageMode>
<Text>{input.text}</Text>
</mx:request>
</mx:operation>
</mx:WebService>
<mx:TextInput id="input"/>
<mx:TextInput id="output" editable="false"
text="{translatorService.Translate.lastResult}"/>
<mx:Spacer height="20"/>
<mx:ComboBox id="mode">
<mx:dataProvider>
<mx:Array>
<mx:Object value="FrenchTOEnglish" label="Français à anglais"/>
<mx:Object value="EnglishTOFrench" label="Anglais à français"/>
</mx:Array>
</mx:dataProvider>
</mx:ComboBox>
<mx:Button id="process" label="Traduire"
click="translatorService.Translate.send()"/>
</mx:Application>

Nous avons tout simplement lié les paramètres de la requête avec les champs input et
mode et le bouton appelle la méthode distante. Le résultat de cette requête est directement
lié au champ output pour afficher la traduction.

288
Services web 10

c Fig. 10.9 :
Résultat d’une traduction de l’anglais vers le
français grâce au service web

Différence d’utilisation entre service web et HTTPService


Comme vous l’avez constaté, le fonctionnement des composants WebService et
HTTPService sont relativement similaires. Voici donc un tableau récapitulatif des
différences entre ces deux composants :

Tableau 10.4 : Méthodes d’accès aux données distantes

Demande de données Résultat

HTTPService serviceId.send() serviceId.lastResult

WebService serviceId.methodeId.send() serviceId.methodeId.lastResult

Tableau 10.5 : Adresse des ressources

Propriété Description

HTTPService url= Adresse web de la ressource demandée

WebService wsdl= Adresse du document wsdl de description du


service

Tableau 10.6 : Paramètres et méthodes

Nombres de méthodes/paramètres Détail

HTTPService Méthodes : 1 Paramètres : n Le composant ne fournit un accès qu’à


(<mx:request>) une unique ressource externe.

WebService Méthodes : n : autant que de Le composant permet de définir


méthodes décrites dans le fichier wsdl plusieurs méthodes au sein du même
Paramètres : n (<mx:request>) service web par le biais de la balise
<mx:operation>.

289
10 Communiquer avec un serveur

10.4 RemoteObject
En plus des requêtes http et des services web, il existe une troisième et dernière méthode
pour utiliser des données externes dans Flex. Il s’agit des RemoteObject. Ils sont
généralement utilisés pour appeler des méthodes directement sur des composants
ColdFusion ou des objets Java situés sur un serveur d’application grâce à
LiveCycle Data Services (reportez-vous à cet effet au chapitre 13).
Les RemoteObject peuvent également s’interconnecter avec des applications tierces et
ainsi appeler des méthodes sur des objets .Net, PHP ou Ruby par exemple. Les principales
applications permettant de réaliser cela sont les suivantes :
j AMFPHP : http://amfphp.sourceforge.net/ ;
j SabreAMF : http://www.osflash.org/sabreamf ;
j Midnight Coders WebORB : http://www.themidnightcoders.com/.

Les composants HTTPService et WebService utilisent principalement le XML pour


échanger des données avec une application Flex. Ce n’est cependant pas le cas des
RemoteObject qui utilisent le protocole AMF3 (Action Message Format). Les données
sont ainsi sérialisées dans un format binaire directement compris par le Player Flash.
Ainsi, les données circulent plus rapidement et peuvent être désérialisées en moins de
temps que des données XML. Cela se traduit donc par un gain de performance notable
en particulier lorsque de grandes quantités de données sont échangées.
Les services web utilisent un fichier wsdl pour déterminer à quoi doit ressembler le
message SOAP. Les RemoteObjects ne fonctionnent pas de cette façon et nécessitent un
fichier de configuration (service-message.xml) qui permet de déterminer comment
effectuer les appels au serveur.
Voici un exemple de fichier service-message.xml pour utiliser le composant RemoteObject
avec AMFPHP1.9 :
<services-config>
<services>
<service id="amfphp-flashremoting-service"
class="flex.messaging.services.RemotingService"
messageTypes="flex.messaging.messages.RemotingMessage">
<destination id="amfphp">
<channels>
<channel ref="my-amfphp"/>
</channels>
<properties>
<source>*</source>
</properties>

290
Mise en pratique : une application avec Amazon 10

</destination>
</service>
</services>
<channels>
<channel-definition id="my-amfphp"
class="mx.messaging.channels.AMFChannel">
<endpoint uri="http://localhost:88/amfphp/gateway.php"
class="flex.messaging.endpoints.AMFEndpoint"/>
</channel-definition>
</channels>
</services-config>

Nous déclarons un service utilisant amfphp1.9 auquel nous affectons une destination qui
sera utilisée plus tard par le composant RemoteObject pour utiliser ce service, et un
channel qui spécifie l’adresse du serveur hébergeant les objets distants.
Ensuite, nous devons déclarer le composant RemoteObject dans une application Flex :
<mx:RemoteObject id="myservice" fault="faultHandler(event)"
showBusyCursor="true" source="tutorial.HelloWorld" destination="amfphp">
<mx:method name="sayHello" result="resultHandler(event)" />
</mx:RemoteObject>

Certaines propriétés ont fait leur apparition par rapport aux deux composants précédents :
j source : le chemin de l’objet distant ;
j destination : le nom du service déclaré dans le fichier XML ;
j une balise <mx:method> qui fonctionne de la même manière que la balise
<mx:operation> du composant WebService.

Enfin, il ne reste plus qu’à invoquer la méthode déclarée de la manière suivante :


Myservice.sayHello();

10.5 Mise en pratique : une application avec Amazon


Nous allons maintenant mettre en pratique les connaissances acquises au cours de ce
chapitre en réalisant une petite application permettant de rechercher et d’afficher des
musiques grâce aux services web fournis par le site Amazon.
Le principe est simple : il suffira d’entrer un texte dans un champ puis de cliquer sur
Rechercher pour afficher les résultats associés dans la base de données du site Amazon.
Le résultat final, comme vous le constatez, vous permet de vous faire une idée de ce que
nous allons faire.

291
10 Communiquer avec un serveur

c Fig. 10.10 : Exemple avec Amazon

Nous allons donc commencer par créer l’interface utilisateur. Celle-ci se compose d’une
VBox regroupant les éléments suivants :
j une zone pour la saisie et la recherche ;
j une grille pour afficher les résultats ;
j une deuxième zone pour afficher des détails sur un élément de la recherche :
- une image ;
- le titre ;
- la date de sortie ;
- le label ;
- le numéro de produit Amazon ;
- des critiques ou commentaires.
Voici le code MXML de l’interface :

292
Mise en pratique : une application avec Amazon 10

<mx:VBox width="600" horizontalAlign="center"


paddingTop="20" paddingBottom="20" backgroundAlpha="0.5"
backgroundColor="#ffffff">
<mx:HBox>
<mx:Label text="Rechercher une musique :"/>
<mx:TextInput id="inputBox"/>
<mx:Button id="btn_Search" label="Rechercher" click="search()"/>
</mx:HBox>
<mx:DataGrid width="90%" height="350" id="dtg_res"
dataProvider="{res}">
<mx:columns>
<mx:DataGridColumn headerText="Artiste"/>
<mx:DataGridColumn headerText="Titre"/>
<mx:DataGridColumn headerText="Label"/>
<mx:DataGridColumn headerText="ASIN" dataField="ASIN"/>
</mx:columns>
</mx:DataGrid>
<mx:Spacer height="20"/>
<mx:HBox paddingLeft="10" paddingRight="10"
paddingTop="10" paddingBottom="10" backgroundAlpha="0.7"
borderStyle="solid" dropShadowEnabled="true" width="90%">
<mx:Image width="250" height="250"
id="pochette" scaleContent="true" />
<mx:Spacer width="50"/>
<mx:VBox width="100%">
<mx:Label id="lbl_title" fontSize="12" fontWeight="bold"/>
<mx:HBox>
<mx:Label text="Date : "/>
<mx:Label id="lbl_date"/>
</mx:HBox>
<mx:HBox>
<mx:Label text="Label : "/>
<mx:Label id="lbl_label"/>
</mx:HBox>
<mx:HBox>
<mx:Label text="Nombres de CD : "/>
<mx:Label id="lbl_nbcd"/>
</mx:HBox>
<mx:HBox>
<mx:Label text="ASIN : "/>
<mx:Label id="lbl_asin"/>
</mx:HBox>
</mx:VBox>
<mx:Spacer width="50"/>
<mx:VBox>
<mx:Label text="Commentaires"/>
<mx:TextArea id="txt_comment" width="250"

293
10 Communiquer avec un serveur

height="250" editable="false"
wordWrap="true" backgroundAlpha="0.0"/>
</mx:VBox>
</mx:HBox>

</mx:VBox>

Comme vous le remarquez, les colonnes à afficher ont été explicitement décrites afin de
n’afficher que les informations utiles. Vous noterez également la présence d’une méthode
search() et de divers objets permettant de stocker les données. Nous allons les ajouter
dans un instant.
Avant cela, nous allons ajouter les services web d’Amazon. Nous allons tout d’abord
commencer par créer un compte (qui est gratuit) à l’adresse suivante : http://aws.amazon.com/.

c Fig. 10.11 : Page d’accueil du service d’Amazon

Nous allons utiliser le service e-commerce (ECS) qui permet d’accéder aux informations
sur les produits du catalogue d’Amazon. Vous trouverez la documentation complète à
cette adresse : http://www.amazon.com/gp/browse.html?node=12738641.
Une fois votre inscription validée, vous recevrez un identifiant vous permettant d’accéder
au service en ligne. Une fois ces formalités remplies, ajoutons le service web à notre
projet. Nous allons ajouter le service que nous nommerons WS_amazon et dans lequel nous
ajouterons deux opérations :
j ItemSearch qui permet de rechercher tous les articles correspondant à notre saisie ;
j ItemLookup qui permet d’obtenir des détails sur un produit sélectionné.

294
Mise en pratique : une application avec Amazon 10

Il faudra également ajouter les paramètres nécessaires aux deux requêtes que nous venons
juste de décrire. Voici à présent le code MXML permettant de déclarer le service web
dont le wsdl se situe à l’adresse suivante : http://webservices.amazon.com/AWSECommerceService/
AWSECommerceService.wsdl.
<mx:WebService id="WS_amazon"
wsdl="{’http://webservices.amazon.com/’ +
’AWSECommerceService/AWSECommerceService.wsdl’}"
showBusyCursor="true" fault="Alert.show(event.fault.faultString)">
<mx:operation name="ItemSearch" resultFormat="object"
result="processResult(event)">
<mx:request>
<AWSAccessKeyId>****************</AWSAccessKeyId>
<Shared>
<Keywords>{input}</Keywords>
<SearchIndex>Music</SearchIndex>
<Count>20</Count>
</Shared>
</mx:request>
</mx:operation>
<mx:operation name="ItemLookup" resultFormat="object"
result="Alert.show(’ok’)">
<mx:request>
<AWSAccessKeyId>****************</AWSAccessKeyId>
<Shared>
<ItemId>{dtg_res.selectedItem.ASIN}</ItemId>
<ResponseGroup>
ItemAttributes,Images,Tracks,EditorialReview
</ResponseGroup>
</Shared>
</mx:request>
</mx:operation>
</mx:WebService>

Dans notre cas, l’identifiant Amazon Web Service a été remplacé par des étoiles ; c’est
entre les balises <AWSAccessKeyId></AWSAccessKeyId> que vous devez mettre celui que
vous avez récupéré il y a un instant.
Notez également que les données retournées le seront sous la forme d’objets ActionScript
grâce à la propriété resultFormat. Un objet input est lié à la propriété keywords de la
requête et une méthode processResult est appelée pour gérer les données reçues. Nous
allons également déclarer la méthode search() qui est appelée sur l’événement click du
bouton de recherche :
<mx:Script>

295
10 Communiquer avec un serveur

<![CDATA[
import mx.rpc.events.ResultEvent;
import mx.controls.Alert;
import mx.collections.ArrayCollection;
[Bindable]
private var input:String = "";

[Bindable]
private var res:ArrayCollection;

private function processResult(evt:ResultEvent):void


{
res = evt.result.Items.Item;
}
private function search():void
{
input = escape(inputBox.text);
WS_amazon.ItemSearch.send();
}
]]>
</mx:Script>

La méthode escape() permet ici de renvoyer une chaîne correctement formatée pour une
requête (les espaces sont simplement remplacés par %20).
Nous allons à présent apporter quelques modifications sur la DataGrid pour afficher
correctement les informations grâce à la propriété labelFunction des DataGridColumn :
private function getArtist(item:Object, column:DataGridColumn):String
{
return item.ItemAttributes.Artist;
}
private function getTitle(item:Object, column:DataGridColumn):String
{
return item.ItemAttributes.Title;
}
private function getLabel(item:Object, column:DataGridColumn):String
{
return item.ItemAttributes.Manufacturer;
}

Nous allons maintenant afficher les détails de l’album sélectionné dans notre DataGrid
grâce à la seconde méthode du service web que nous appellerons à chaque fois que
l’élément sélectionné changera.

296
Mise en pratique : une application avec Amazon 10

Commençons par déclarer deux variables qui seront utilisées par la suite pour la liaison
de données avec les différentes informations affichées :
[Bindable]
private var selectedItem:Object;

[Bindable]
private var selectedItemDetail:Object;

Il ne reste ensuite qu’à créer la fonction qui formatera correctement les données et
remplira ces deux variables :
private function showDetail(evt:ResultEvent):void
{
selectedItem = evt.result.Items.Item;
selectedItemDetail = selectedItem.ItemAttributes;

var titre:String = "";


if (!selectedItemDetail.Artist)
titre = "Inconnu - " + selectedItemDetail.Title;
else
titre = selectedItemDetail.Artist + " - " + selectedItemDetail.Title;
lbl_title.text = titre;

var comments:String = "";


if (selectedItem.EditorialReviews is ArrayCollection){
for each (var rev:Object in selectedItem.EditorialReviews)
comments += rev.Content + "<br /><br />";
}
txt_comment.text = comments;

if(selectedItem.LargeImage)
pochette.source = selectedItem.LargeImage.URL;
}

Il faut ensuite appeler celle-ci sur l’événement result de la seconde méthode distante :
<mx:operation name="ItemLookup" resultFormat="object"
result="showDetail(event)">

Et il faut également appeler la méthode distante sur l’événement change :


<mx:DataGrid width="90%" height="350" id="dtg_res"
dataProvider="{res}" change="WS_amazon.ItemLookup.send()">

Et enfin, il ne reste plus qu’à lier les données avec les composants de type Label.

297
10 Communiquer avec un serveur

Voici donc le code complet de l’application avec un effet visuel de flou (<mx:blur>) qui
a été rajouté lors du changement de l’image :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx=http://www.adobe.com/2006/mxml
layout="vertical" backgroundGradientColors="[#000000,#ffffff]">
<mx:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;
import mx.controls.Alert;
import mx.collections.ArrayCollection;
[Bindable]
private var input:String = "";

[Bindable]
private var res:ArrayCollection;

[Bindable]
private var selectedItem:Object;

[Bindable]
private var selectedItemDetail:Object;

private function processResult(evt:ResultEvent):void


{
res = evt.result.Items.Item;
}
private function search():void
{
input = escape(inputBox.text);
WS_amazon.ItemSearch.send();
}

private function getArtist(item:Object,


column:DataGridColumn):String
{
return item.ItemAttributes.Artist;
}
private function getTitle(item:Object,
column:DataGridColumn):String
{
return item.ItemAttributes.Title;
}
private function getLabel(item:Object,
column:DataGridColumn):String
{
return item.ItemAttributes.Manufacturer;
}

298
Mise en pratique : une application avec Amazon 10

private function showDetail(evt:ResultEvent):void


{
selectedItem = evt.result.Items.Item;
selectedItemDetail = selectedItem.ItemAttributes;
blurMain.target = pochette;
blurMain.play();
var titre:String = "";
if (!selectedItemDetail.Artist)
titre = "Inconnu - " + selectedItemDetail.Title;
else
titre = selectedItemDetail.Artist +
" - " + selectedItemDetail.Title;
lbl_title.text = titre;

var comments:String = "";


if (selectedItem.EditorialReviews is ArrayCollection){
for each (var rev:Object in selectedItem.EditorialReviews)
comments += rev.Content + "<br /><br />";
}
txt_comment.htmlText = comments;

if(selectedItem.LargeImage)
pochette.source = selectedItem.LargeImage.URL;
blurMain.end();
unblurMain.target = pochette;
unblurMain.play();
}
]]>
</mx:Script>
<!--EFFET VISUEL-->
<mx:Blur id="blurMain" duration="1000"
blurXFrom="0.0" blurXTo="10.0"
blurYFrom="0.0" blurYTo="10.0" />
<mx:Blur id="unblurMain" duration="1000"
blurXFrom="10.0" blurXTo="0.0"
blurYFrom="10.0" blurYTo="0.0" />

<!--DESCRIPTION DU WEBSERVICE -->


<mx:WebService id="WS_amazon"
wsdl="{’http://webservices.amazon.com/’ +
’AWSECommerceService/AWSECommerceService.wsdl’}" showBusyCursor="true"
fault="Alert.show(event.fault.faultString)">
<mx:operation name="ItemSearch" resultFormat="object"
result="processResult(event)">
<mx:request>

299
10 Communiquer avec un serveur

<AWSAccessKeyId>********************</AWSAccessKeyId>
<Shared>
<Keywords>{input}</Keywords>
<SearchIndex>Music</SearchIndex>
<Count>20</Count>
</Shared>
</mx:request>
</mx:operation>
<mx:operation name="ItemLookup" resultFormat="object"
result="showDetail(event)">
<mx:request>
<AWSAccessKeyId>********************</AWSAccessKeyId>
<Shared>
<ItemId>{dtg_res.selectedItem.ASIN}</ItemId>
<ResponseGroup>
ItemAttributes,Images,Tracks,EditorialReview
</ResponseGroup>
</Shared>
</mx:request>
</mx:operation>
</mx:WebService>

<!--INTERFACE UTILISATEUR -->


<mx:VBox width="900" horizontalAlign="center" paddingTop="20"
paddingBottom="20" backgroundAlpha="0.5" backgroundColor="#ffffff"
id="main">
<mx:HBox>
<mx:Label text="Rechercher une musique :"/>
<mx:TextInput id="inputBox"/>
<mx:Button id="btn_Search" label="Rechercher" click="search()"/>
</mx:HBox>
<mx:DataGrid width="90%" height="350" id="dtg_res"
dataProvider="{res}" change="WS_amazon.ItemLookup.send()" >
<mx:columns>
<mx:DataGridColumn headerText="Artiste"
labelFunction="getArtist"/>
<mx:DataGridColumn headerText="Titre" labelFunction="getTitle"/>
<mx:DataGridColumn headerText="Label" labelFunction="getLabel"/>
<mx:DataGridColumn headerText="ASIN" dataField="ASIN" />
</mx:columns>
</mx:DataGrid>
<mx:Spacer height="20"/>
<mx:HBox paddingLeft="10" paddingRight="10" paddingTop="10"
paddingBottom="10" backgroundAlpha="0.7" borderStyle="solid"
dropShadowEnabled="true" width="90%">
<mx:Image width="250" height="250" id="pochette"
scaleContent="true" />

300
Check-list 10

<mx:Spacer width="50"/>
<mx:VBox width="100%">
<mx:Label id="lbl_title" fontSize="12" fontWeight="bold"/>
<mx:HBox>
<mx:Label text="Date : "/>
<mx:Label id="lbl_date"
text="{selectedItemDetail.OriginalReleaseDate}"/>
</mx:HBox>
<mx:HBox>
<mx:Label text="Label : "/>
<mx:Label id="lbl_label" text="{selectedItemDetail.Label}"/>
</mx:HBox>
<mx:HBox>
<mx:Label text="Nombres de CD : "/>
<mx:Label id="lbl_nbcd"
text="{selectedItemDetail.NumberOfDiscs}"/>
</mx:HBox>
<mx:HBox>
<mx:Label text="ASIN : "/>
<mx:Label id="lbl_asin" text="{selectedItem.ASIN}"/>
</mx:HBox>

</mx:VBox>
<mx:Spacer width="50"/>
<mx:VBox>
<mx:Label text="Commentaires"/>
<mx:TextArea id="txt_comment" width="250" height="250"
editable="false" wordWrap="true" backgroundAlpha="0.0"/>
</mx:VBox>
</mx:HBox>

</mx:VBox>

</mx:Application>

10.6 Check-list
Dans ce chapitre, nous avons vu :
a comment charger des ressources externes à l’exécution avec la classe URLLoader ;
a comment récupérer des données par des requêtes http avec le composant
HTTPService ;
a comment invoquer des méthodes distantes avec les services web ;
a comment passer des arguments aux méthodes distantes.

301
11
11.1 Introduction à Flex Charting ........................... 304
11.2 Les différents types de graphiques .................... 305
11.3 Mettre en forme les graphiques ....................... 309
11.4 Interaction avec les graphiques ....................... 315
11.5 Mise en pratique : un module de statistiques ........ 321
11.6 Check-list ................................................. 327
Présenter les
données
graphiquement
L orsque vous manipulez beaucoup de données, il est
toujours plus parlant pour l’utilisateur de voir un
graphique synthétique plutôt qu’une interminable liste de
données. L’interprétation sera beaucoup plus simple et
l’interface sera plus esthétique. Ce chapitre va vous
révéler comment y parvenir grâce à Flex.
11 Présenter les données graphiquement

11.1 Introduction à Flex Charting


Flex propose des composants simples d’utilisation pour créer de multiples types de
graphiques, avec beaucoup de variations possibles dans chaque type.
Ces composants sont inclus dans le framework Flex lors de son installation, mais font
l’objet d’une licence séparée. Vous pouvez jouer avec les composants de Flex Charting
pendant la période d’essai de Flex Builder mais vous aurez un watermark sur vos
graphiques. Nous partons du principe dans ce chapitre que Flex Charting est installé et
qu’il est activé ou en période d’essai, avec toutes les fonctionnalités activées.

Utiliser un composant de Flex Charting


Les graphiques, comme toujours dans Flex, sont des composants. Bien que la présentation
soit très différente d’un type à l’autre, le code pour les créer est très similaire. Vous
pouvez voir des exemples de graphiques dans l’application de démonstration des
composants Flex à l’adresse : http://www.adobe.com/go/flex_explorer_app. L’image suivante
montre que vous pouvez faire avec Flex des camemberts lorsque vous sélectionnez le
composant PieChart situé dans le dossier Chart de l’application.

c Fig. 11.1 : Le composant PieChart dans Flex Component Explorer

304
Les différents types de graphiques 11

Attardons-nous quelques instants sur le code du PieChart ci-après ; nous détaillerons


chaque partie dans le chapitre.

c Fig. 11.2 : Code pour créer un camembert

Pour travailler avec les graphiques, vous n’avez pas d’autres alternatives que de passer
par le code MXML. L’interface design ne permet que de poser le type de graphique, mais
cela ne suffira pas à voir vos données s’afficher. Vous remarquerez que le graphique se
compose de plusieurs contenus dans le tag père définissant le type de graphique :
<mx:PieChart>. Nous verrons que c’est dans ce tag que nous spécifions notre source de
données (dataprovider) ou l’affichage de bulles d’information (DataTips).
Dans ce tag, nous avons le conteneur <mx:series>. Ce conteneur permet de lier un champ
de vos données à un affichage. Un camembert ne présente généralement qu’une seule liste
d’information mais des composants comme le LineChart ou le ColumnChart peuvent
présenter plusieurs données pour les comparer. Nous aurons alors plusieurs séries.

11.2 Les différents types de graphiques


Comme vous avez peut-être pu déjà le constater en naviguant dans
Flex Component Explorer, il existe différentes sortes de graphiques qui répondent aux
besoins les plus fréquents. Nous allons vous les présenter ainsi que leurs variations
possibles.

Le PieChart
Le contrôle PieChart permet de créer des camemberts. Les valeurs des données sont
automatiquement calculées pour adapter la taille de chaque partie entre elles.

305
11 Présenter les données graphiquement

Le PieChart peut prendre plusieurs séries dans le même graphique, ce qui se traduit
graphiquement par des anneaux pour chaque série. Vous pouvez également personnaliser
l’affichage du camembert en le présentant comme un donut en spécifiant un rayon
intérieur avec la propriété innerRadius. Vous pouvez aussi exploser le camembert avec
la propriété explodeRadius qui, tout comme la propriété innerRadius, attend comme
valeur un flottant entre 0 et 1.

c Fig. 11.3 : Les différents types de PieChart

L’AreaChart
Le contrôle AreaChart permet de présenter des données sous forme d’aire sous une ligne
délimitant les valeurs. Vous pouvez utiliser des images ou des symboles pour différencier
chaque point de la ligne ou n’afficher qu’une simple ligne. L’image suivante représente
un simple AreaChart :
c Fig. 11.4 :
Un simple AreaChart

Vous pouvez utiliser l’AreaChart pour représenter des variations entre plusieurs données
en superposant les aires ou en faisant un rapport entre les aires en utilisant la propriété
type avec les valeurs suivantes :
j clustered ;

306
Les différents types de graphiques 11

j overlaid ;
j stacked ;
j 100%.

Vous aurez alors les résultats suivants :

c Fig. 11.5 : Les différents types d’AreaChart

Le type de série

Ce type de présentation s’applique également au BarChart et au ColumnChart.

Le ColumnChart et le BarChart
Le ColumnChart permet de présenter les données en colonnes tandis que le BarChart
permet de les présenter en lignes. Les deux composants sont fort similaires et partagent
de nombreuses propriétés.

c Fig. 11.6 : Un ColumnChart et un BarChart

307
11 Présenter les données graphiquement

Le LineChart
Le contrôle LineChart permet d’afficher dans un espace cartésien des couples de données
qui seront liés aux deux axes de graphiques. Chaque donnée représente un point du
graphique qui est lié à la donnée précédente et à la suivante. Il existe plusieurs types de
formes pour relier les points entre eux. Vous pouvez les changer simplement en utilisant
l’attribut form du tag LineSeries avec l’une des valeurs suivantes :
j segment ;
j curve ;
j step ;
j reverseStep ;
j vertical ;
j horizontal.

Parce qu’il existe un vieil adage qui dit qu’une image vaut mieux que mille mots, voici
une image qui illustre les diverses formes du LineChart listées précédemment :

c Fig. 11.7 : Les différentes allures du LineChart

Le BubbleChart et le PlotChart
Le contrôle PlotChart permet de représenter les données avec des coordonnées
cartésiennes où chaque point est déterminé par deux valeurs pour chaque axe. Vous
pouvez spécifier à Flex la forme de chaque point affiché.

308
Mettre en forme les graphiques 11

Le BubbleChart possède une information supplémentaire qui est la taille de la bulle à


afficher. La taille maximale de la bulle peut être définie grâce à l’attribut maxRadius du
tag <mx:BubbleChart>. Flex calculera une taille proportionnelle à la plus grande pour
toutes les bulles. La valeur par défaut est de 30 pixels.

c Fig. 11.8 : Un BubbleChart et un PlotChart

11.3 Mettre en forme les graphiques


Nous allons prendre un exemple simple pas à pas pour comprendre les principaux
concepts.
Créez un nouveau projet Flex avec le nom et l’emplacement qui vous plairont.
Commençons par définir les donnés que nous voulons présenter.

Les données
Vous allez créer un simple tableau contenant des données relatives à des statistiques de
vente de livres. Nous voulons afficher le nombre de livres vendus par catégorie. Il nous
faut donc un tableau contenant le nom de la catégorie, associé au nombre de livres
vendus. Copiez le code MXML suivant dans votre application :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">
<mx:Script><![CDATA[
[Bindable]
private var bookStats:Array = [
{bookCat: "Science-fiction", Sales: 346},
{bookCat: "Drame", Sales: 234},
{bookCat: "Classique", Sales: 89},

309
11 Présenter les données graphiquement

{bookCat: "Enfant", Sales: 109} ];


]]></mx:Script>
</mx:Application>

Vous pouvez récupérer vos données d’où vous voulez, comme vous l’avez appris dans le
chapitre 5. Notre exemple est simple mais il suffit à étayer notre propos.
Ajoutez maintenant un camembert. Pour lier les données à un graphique, il faut
commencer par lui spécifier quelle source il doit prendre en compte. Pour cela, il faut
renseigner la propriété dataProvider du composant. Si vous ne vous sentez pas à l’aise
sur le sujet, reportez-vous encore une fois au chapitre 5. Sinon, copiez le code suivant à
la suite de votre application :
<mx:PieChart width="50%" height="50%" dataProvider="{bookStats}">

</mx:PieChart>

Si vous lancez l’application à cet instant, vous n’aurez pas d’erreur mais vous ne verrez
rien s’afficher. En effet, une fois que vous avez lié votre source de données à votre
graphique, il faut encore préciser quel champ de vos données vous voulez présenter. Cela
se passe au niveau des séries.

Les séries
Comme nous venons de le voir, Flex ne sait pas quel champ afficher ni comment
l’afficher. Une série est associée à un champ de vos données. Un graphique peut avoir
plusieurs séries pour comparer plusieurs séries de données. Vous devez donc ajouter le tag
<mx:series> dans lequel nous allons rajouter nos séries.
<mx:PieChart width="50%" height="50%" dataProvider="{bookStats}">
<mx:series>

</mx:series>
</mx:PieChart>

Dans ce conteneur, nous allons ajouter un élément PieSeries (car nous avons créé un
PieChart) et lui préciser qu’il doit afficher les données du champ sales grâce à l’attribut
field.
<mx:PieChart width="50%" height="50%" dataProvider="{bookStats}">
<mx:series>
<mx:PieSeries field="Sales" />
</mx:series>
</mx:PieChart>

310
Mettre en forme les graphiques 11

Vous remarquerez que vous ne devez pas mettre la valeur de l’attribut field entre
accolades.
Vous pouvez maintenant lancer votre application, vous aurez le résultat suivant :
c Fig. 11.9 :
Le PieChart minimal

Le composant a effectué lui-même les calculs pour rendre un camembert avec les bonnes
proportions pour chaque catégorie. Le composant, dans l’état actuel, est ce qu’il y a de
plus basique.
Nous ne savons pas, par exemple, quelles zones représentent quelles catégories. Nous
allons donc ajouter les labels. Rajoutez l’attribut labelPosition comme ceci :
<mx:PieSeries field="Sales" labelPosition="inside" />

c Fig. 11.10 :
Le PieChart avec des labels

Vous avez maintenant les valeurs qui s’affichent, mais toujours pas de catégories. Flex ne
peut pas deviner que vous voulez afficher les valeurs des autres champs de votre source
de données. Pour arriver à nos fins, nous devons définir une fonction qui va prendre
exactement quatre paramètres et retourner une chaîne de caractères. La signature de cette
fonction doit être respectée pour que Flex puisse l’interpréter correctement. De plus, cette
fonction change d’un type de graphique à l’autre. Retournez dans le bloc de script et
recopiez la fonction suivante :
private function chartLabel(dataItem:Object, field:String, index:int,
dataPercent:Number):String
{

311
11 Présenter les données graphiquement

return dataItem.bookCat + " (" + Math.round(dataPercent) + "%)";


}

La fonction affiche la catégorie des livres puis le pourcentage arrondi qui est calculé par
le composant. Appliquez alors cette fonction à notre camembert :
<mx:series>
<mx:PieSeries field="Sales" labelPosition="inside"
labelFunction="chartLabel" />
</mx:series>

Nous avons alors le résultat suivant :


c Fig. 11.11 :
Le PieChart avec des labels personnalisés

Vous pouvez également modifier la position du label pour le mettre à l’extérieur du


camembert en remplaçant la valeur de l’attribut labelPosition par la valeur callout.
Vous aurez alors le résultat suivant :
c Fig. 11.12 :
Le PieChart avec des
labels à l’extérieur

Les axes
Nous avons jusqu’à présent suivi la construction du PieChart ; or, c’est un graphique qui
a la particularité de ne pas avoir d’axe. Des graphiques comme le ColumnChart ou le
LineChart reposent sur deux axes. Nous allons voir par l’exemple comment utiliser les
axes.

312
Mettre en forme les graphiques 11

Reprenez le tableau du projet précédent, et créez un ColumnChart lié à ce tableau comme


vous l’avez fait pour le PieChart. Voici le code que vous devez avoir dans un premier
temps :
<mx:ColumnChart dataProvider="{bookSales}" width="50%" height="50%">

</mx:ColumnChart>

Si vous lancez l’application, vous aurez un squelette de graphique avec deux axes
dessinés, mais aucune colonne.
La première chose à faire est de définir l’axe horizontal. Nous voulons ici afficher nos
catégories de livres. Nous allons donc rajouter dans le ColumnChart l’élément
horizontalAxis. Ensuite, à l’intérieur de cet élément, nous allons rajouter le composant
CategoryAxis et l’associer au champ bookCat de notre source de données via l’attribut
categoryField de l’élément. Vous devriez aboutir au code suivant :
<mx:ColumnChart dataProvider="{bookStats}" width="50%" height="50%">
<mx:horizontalAxis>
<mx:CategoryAxis categoryField="bookCat"/>
</mx:horizontalAxis>
</mx:ColumnChart>

Nous verrons plus tard qu’il existe d’autres axes.


Si vous lancez l’application à cet instant, vous verrez apparaître le nom des catégories de
livres sur l’axe horizontal.
c Fig. 11.13 :
Mise en place des
catégories sur l’axe
horizontal

Ajoutons finalement les données en ajoutant une série. Procédez comme nous l’avons fait
pour la série du PieChart. Notez cependant que nous utilisons actuellement un
ColumnChart et qu’il faut donc utiliser un ColumnSeries. La différence avec la PieSeries
est que le ColumnSeries doit être lié avec les données sur les deux axes, autrement dit,

313
11 Présenter les données graphiquement

il faut lier d’une part les ventes sur l’axe vertical via l’attribut yField, et d’autre part les
catégories sur l’axe horizontal via l’attribut xField. Vous aurez finalement le code
suivant :
<mx:ColumnChart dataProvider="{bookStats}" width="50%" height="50%">
<mx:horizontalAxis>
<mx:CategoryAxis categoryField="bookCat"/>
</mx:horizontalAxis>
<mx:series>
<mx:ColumnSeries xField="bookCat" yField="Sales"/>
</mx:series>
</mx:ColumnChart>

Ce qui vous donnera un graphique exploitable lorsque vous lancerez l’application :


c Fig. 11.14 :
Mise en place des
données sur les axes

Les axes numériques


Nous venons de voir les CategoryAxis qui permettent d’afficher des valeurs discrètes
représentant des catégories. La valeur de cet axe est typiquement une chaîne de
caractères. Mais il se peut que notre axe horizontal représente des données continues
comme une plage dans le temps ou une plage d’entiers (des volumes de vente ou des
salaires). Il existe alors trois types d’axes pour répondre à ces besoins :
j LinearAxis ;
j LogAxis ;
j DateTimeAxis.

Le LinearAxis est le plus simple d’utilisation. Il permet d’associer les valeurs des
données entre un minimum et un maximum et il répartit correctement les valeurs entre les
deux bornes. Par défaut, Flex calcule automatiquement le minimum et le maximum en
fonction des données que vous lui donnez, mais vous pouvez forcer les bornes de cet axe
si vous en avez besoin comme le montre l’exemple suivant :
<mx:verticalAxis>

314
Interaction avec les graphiques 11

<mx:LinearAxis minimum="30" maximum="50"/>


</mx:verticalAxis>

Le DateTimeAxis est un composant très intéressant et très puissant qui vous simplifiera
grandement la présentation des données basée sur le temps. Il calcule automatiquement
les dates minimale et maximale selon vos données ainsi que l’intervalle idéal pour que
l’affichage des labels sur l’axe reste lisible. Nous étudierons plus en détail cet axe lors de
la mise en pratique dans ce chapitre.

11.4 Interaction avec les graphiques


Contrairement aux graphiques statiques que vous pouvez voir sur les applications web
actuelles, et qui sont généralement des images, Flex permet d’avoir une réelle interaction
entre l’utilisateur et les graphiques qu’il visionne.

Les bulles d’information


Lorsque vous utilisez le PieChart, vous pouvez choisir de ne pas afficher les informations
en permanence via l’attribut labelPosition mais ne les afficher que lorsque l’utilisateur
positionne sa souris sur l’une des zones du camembert. De même, lorsque vous utilisez
le composant LineChart, vous pouvez faire en sorte d’afficher les valeurs précises d’une
donnée en affichant une bulle d’aide générée par Flex. L’écran suivant montre l’affichage
d’une bulle d’information sur un composant AreaChart.
c Fig. 11.15 :
Affichage d’une bulle
d’information

Il suffit de rajouter simplement l’attribut showDataTips au composant du graphique


comme le montre la portion de code suivante :
<mx:Script>
[Bindable] public var datas:Array = [
{date: "12/01", field1: 6, field2:1},

315
11 Présenter les données graphiquement

{date: "13/01", field1: 7, field2:4},


{date: "14/01", field1: 4, field2:3},
{date: "15/01", field1: 8, field2:3},
];
</mx:Script>
<mx:AreaChart id="chart" height="100%" width="100%"
dataProvider="{datas}" showDataTips="true">
<mx:horizontalAxis>
<mx:CategoryAxis dataProvider="{datas}" categoryField="date"/>
</mx:horizontalAxis>
<mx:series>
<mx:AreaSeries yField="field1" />
<mx:AreaSeries yField="field2" />
</mx:series>
</mx:AreaChart>

Bien que l’affichage du DataTip dépende du type de graphique, il affiche généralement le


nom du champ dans le dataProvider et sa valeur. Ici, ce n’est pas le cas, et pour que
l’information soit compréhensible par l’utilisateur, il faut encore spécifier l’affichage du
nom du champ dans la série. Modifiez donc les séries pour rajouter l’attribut displayName
comme le montre le code suivant :
<mx:AreaSeries yField="field1" displayName="Total livres vendus"/>
<mx:AreaSeries yField="field2" displayName="Total livres invendus"/>

c Fig. 11.16 :
Affichage d’une bulle
d’information plus
compréhensible

Nous avons encore un détail à régler. Lorsque vous nommez l’axe de la catégorie, celle-ci
s’affiche en italique également, ce qui rend la bulle d’information plus complète :
<mx:horizontalAxis>
<mx:CategoryAxis dataProvider="{datas}"
categoryField="date" displayName="Date"/>
</mx:horizontalAxis>

316
Interaction avec les graphiques 11

Vous avez maintenant une bulle d’information plus intéressante pour l’utilisateur :
c Fig. 11.17 :
Affichage d’une bulle
d’information complète

Enfin, de la même manière que l’on a pu choisir l’affichage du texte dans le PieChart,
nous pouvons choisir comment présenter le texte de cette bulle d’aide bien que dans la
plupart des cas, Flex génère une bulle d’information très complète. Supposons que notre
dataProvider soit le tableau utilisé précédemment pour formater nos graphiques ; voici
la fonction à appliquer pour avoir un DataTip personnalisé :
public function dtFunc(e:ChartItemEvent):String {
return e.hitData.item.bookCat + ": <b>$" + e.hitData.item.Sales +
"</b>";
}

Les légendes
Vous avez également la possibilité d’ajouter des légendes à vos graphiques. Vous
utiliserez à cet effet le composant <mx:Legend> 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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="horizontal" backgroundColor="white">
<mx:Script>
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},


];
</mx:Script>
<mx:BarChart id="chart" dataProvider="{expenses}">
<mx:verticalAxis>
<mx:CategoryAxis dataProvider="{expenses}"
categoryField="Person"/>
</mx:verticalAxis>
<mx:series>
<mx:BarSeries xField="Sport" displayName="Sport"/>
<mx:BarSeries xField="Reading" displayName="Lecture"/>
<mx:BarSeries xField="Tv" displayName="Télévision"/>
</mx:series>
</mx:BarChart>

<mx:Legend dataProvider="{chart}"/>

</mx:Application>

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 bookStats1:Array = [
{bookCat: "Science-fiction", Sales: 250, NoSales:46},
{bookCat: "Drame", Sales: 234, NoSales:56},
{bookCat: "Classique", Sales: 89, NoSales:156},
{bookCat: "Enfant", Sales: 109, NoSales:56} ];
[Bindable]
private var bookStats2:Array = [
{bookCat: "Science-fiction", Sales: 246, NoSales:15},
{bookCat: "Drame", Sales: 52, NoSales:250},
{bookCat: "Classique", Sales: 189, NoSales:56},
{bookCat: "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 :
<mx:ColumnChart dataProvider="{bookStats1}" width="50%" height="50%"
id="myChart">
<mx:horizontalAxis>
<mx:CategoryAxis categoryField="bookCat"/>
</mx:horizontalAxis>
<mx:series>
<mx:ColumnSeries xField="bookCat" yField="Sales"
displayName="Livres vendus" />
<mx:ColumnSeries xField="bookCat" yField="NoSales"
displayName="Livres invendus" />
</mx:series>
</mx:ColumnChart>

Nous voulons maintenant animer notre graphique. Nous avons trois transitions possibles :
j SeriesInterpolate ;

319
11 Présenter les données graphiquement

j SeriesSlide ;
j SeriesZoom.

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 :
<mx:SeriesInterpolate id="chartTransition" duration="1500"/>

Il faut maintenant lier cette transition aux séries via l’attribut showDataEffect. Les tags
des deux séries doivent ressembler à ceci :
<mx:series>
<mx:ColumnSeries xField="bookCat" yField="Sales"
displayName="Livres vendus" showDataEffect="{chartTransition}"/>
<mx:ColumnSeries xField="bookCat" yField="NoSales"
displayName="Livres invendus" showDataEffect="{chartTransition}"/>
</mx:series>

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 :
<mx:VBox>
<mx:RadioButton groupName="bookShop" label="Statistiques de la
➥ librairie 1"
selected="true" click="myChart.dataProvider=bookStats2;"/>
<mx:RadioButton groupName="bookShop" label="Statistiques de la
➥ librairie 2"
click="myChart.dataProvider=bookStats1;"/>
</mx:VBox>

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
Mise en pratique : un module de statistiques 11

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 :
<mx:SeriesSlide id="chartSlideIn" duration="1500" direction="up"/>
<mx:SeriesSlide id="chartSlideOut" duration="1500" direction="down"/>

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 :
<mx:series>
<mx:ColumnSeries xField="bookCat" yField="Sales"
displayName="Livres vendus" showDataEffect="{chartSlideIn}"
hideDataEffect="{chartSlideOut}"/>
<mx:ColumnSeries xField="bookCat" yField="NoSales"
displayName="Livres invendus" showDataEffect="{chartSlideIn}"
hideDataEffect="{chartSlideOut}"/>
</mx:series>

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 :
<stats>
<salesStats>
<record>
<date>01/01/2007</date>
<total>34</total>
</record>
</salesStats>
<categoryStats>
<record>
<category>Science-fiction</category>
<total>55</total>
<record>
</categoryStats>
</stats>

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
Mise en pratique : un module de statistiques 11

c Fig. 11.21 : Le design de l’application dans Flex Builder

Vérifions maintenant que vous avez un code similaire à celui-ci :


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical" backgroundColor="white">
<mx:Script source="as/application.as" />
<mx:Label text="Statistiques des librairies Dupont" fontSize="24"/>
<mx:RadioButtonGroup id="bookShop"/>
<mx:RadioButton groupName="bookShop" value="paris"
label="Boutique à Paris" selected="true"/>
<mx:RadioButton groupName="bookShop" value="lyon"
label="Boutique à Lyon" />
<mx:HBox width="100%" height="100%">
<mx:Panel layout="vertical" width="100%" height="100%">
<mx:AreaChart id="areaChart" width="100%" height="100%">
</mx:AreaChart>
<mx:Legend/>
</mx:Panel>
<mx:Panel width="40%" height="100%">
<mx:PieChart id="pieChart" width="100%" height="100%">
</mx:PieChart>
<mx:Legend height="30%" />
</mx:Panel>
</mx:HBox>
</mx:Application>

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

<mx:HTTPService id="httpService" result="{setCharts()}" />

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 :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
backgroundColor="white" creationComplete="{getStats()}">

<mx:RadioButton groupName="bookShop" value="paris" selected="true"
click="{getStats()}"/>
<mx:RadioButton groupName="bookShop" value="lyon" click="{getStats()}" />

Voyons maintenant le code des deux fonctions que nous venons de citer. Créez un tag
Script et copiez les deux fonctions suivantes :
<mx:Script>
[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();
}
</mx:Script>

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
Mise en pratique : un module de statistiques 11

<mx:PieChart width="100%" id="pieChart" dataProvider="{CategoryStats}"


showDataTips="true" height="100%">
<mx:series>
<mx:PieSeries field="total" nameField="category" displayName="Nombre
➥ de visiteurs" />
</mx:series>
</mx:PieChart>
<mx:Legend height="30%" dataProvider="{pieChart}" />

Attaquons-nous maintenant à notre AreaChart. Commençons par définir les axes :


<mx:AreaChart width="100%" id="areaChart" dataProvider="{SalesStats}"
showDataTips="true" height="100%">
<mx:horizontalAxis>
<mx:DateTimeAxis labelFunction="dateTimeAxisLabel"/>
</mx:horizontalAxis>
<mx:verticalAxis>
<mx:LinearAxis interval="100"/>
</mx:verticalAxis>
</mx:AreaChart>

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 :
<mx:AreaChart width="100%" id="areaChart" dataProvider="{SalesStats}"
showDataTips="true" height="100%">
...
<mx:series>
<mx:AreaSeries yField="total" xField="date"
displayName="Nombre de ventes"
showDataEffect="{chartInterpolate}">
<mx:areaStroke>
<mx:Stroke color="0xA3C643" alpha="1" weight="2" />
</mx:areaStroke>
<mx:areaFill>
<mx:SolidColor color="0xA9BAC3" alpha=".6"/>

325
11 Présenter les données graphiquement

</mx:areaFill>
</mx:AreaSeries>
</mx:series>
</mx:AreaChart>

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 :
<mx:SeriesInterpolate id="chartInterpolate" duration="2000" />
...
<mx:AreaSeries yField="total" xField="date"
showDataEffect="{chartInterpolate}">
...
<mx:PieSeries field="total" nameField="category"
showDataEffect="{chartInterpolate}" />

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 :
<mx:DateTimeAxis labelFunction="dateTimeAxisLabel"/>

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
Passer de Flex à AIR 12

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 AIRTest.mxml : c’est le fichier principal de l’application, celui qui sera défini comme
fichier d’application par défaut.
j 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 <mx:WindowedApplication/>. 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 :
<?xml version="1.0" encoding="UTF-8"?>

334
Passer de Flex à AIR 12

<application xmlns="http://ns.adobe.com/air/application/1.0.M4"
➥ appId="AIRTestProject" version="1.0 Beta">
<name>AIR Test</name>
<title/>
<description>A test project</description>
<copyright>2007</copyright>
<rootContent systemChrome="standard" transparent="false"
➥ visible="true">[SWF reference is generated]</rootContent>
</application>

Les balises utilisées sont assez explicites et permettront d’afficher des informations à
l’installation par exemple.
<rootContent> 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 <icon> qui contiendra des balises
<image16x16>, <image32x32>, <image48x48> ou <image128x128>. Ces images serviront
de miniatures à votre application. <fileTypes> 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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" creationComplete="initApp();">
<mx:Script>
<![CDATA[
import flash.html.HTMLControl;
private var htmlControl:HTMLControl;
private function initApp():void
{
htmlControl = new HTMLControl();
htmlControl.width = 800;
htmlControl.height = 600;
var urlRequest:URLRequest = new
➥ URLRequest("http://www.google.fr/");
htmlControl.load(urlRequest);
componentContainer.addChild(htmlControl);
}
]]>
</mx:Script>
<mx:UIComponent id="componentContainer" width="100%" height="100%"/>
</mx:WindowedApplication>

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("<html><b>AIR</b> affiche du HTML !</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() :
<mx:HBox>
<mx:Button id="back" label="Reculer"
click="htmlControl.historyBack();"/>
<mx:Button id="forward" label="Avancer"
click="htmlControl.historyForward();"/>
</mx:HBox>

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 = "<html>" +
"<script>" +
"variable = 42;" +
"function fonction() { return ’Hello World !’; }" +
"</script>" +
"<body>" +
"<p id=’toto’>Coucou !</p>" +
"</body>" +
"</html>”;

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 :
<mx:Button label="Click Me"
click="htmlControl.window.document.getElementById(’idHTML’).innerHTML
➥ = ’Le contenu a changé’;"/>

Voici l’affichage, une fois le bouton cliqué :

c Fig. 12.16 : Modifier les variables

342
Utiliser HTML 12

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 <mx:HTML> 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

<?xml version="1.0" encoding="utf-8"?>


<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
creationComplete="mainPage.location = ’http://www.google.fr/’;">
<mx:HBox width="98%">
<mx:Button id="back" label="Back"
click="mainPage.htmlControl.historyBack();"/>
<mx:Button id="forward" label="Forward"
click="mainPage.htmlControl.historyForward();"/>
<mx:TextInput id="adress"
text="{mainPage.location}" width="100%"

343
12 Utiliser AIR

enter="mainPage.location = adress.text"/>
<mx:Button id="go" label="Go"
click="mainPage.location = adress.text"/>
</mx:HBox>
<mx:HTML id="mainPage" width="98%" height="100%"/>
</mx:WindowedApplication>

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 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.
j 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.).
j 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 12

j 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.
j 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 :
j userDirectory : c’est le répertoire utilisateur, sous Vista : C:\Users\userName.
j documentsDirectory : c’est le répertoire Mes Documents, sous Vista :
C:\Users\userName\Documents.
j desktopDirectory : le Bureau de l’utilisateur, sous Vista :
C:\Users\userName\Desktop.
j applicationResourceDirectory : le répertoire dans lequel s’exécute l’application.
j 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 :
<mx:Script>
<![CDATA[
import flash.filesystem.File;
private var fileVar:File;

private function loadFile():void


{
fileVar = new File();
fileVar.addEventListener(Event.SELECT, dirSelected);
fileVar.browseForDirectory("Sélectionnez un répertoire");
}
private function dirSelected(e:Event):void
{
lbl.text = fileVar.nativePath;
}
]]>
</mx:Script>
<mx:Label id="lbl"/>

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).
j exists : est à true si le fichier ou dossier existe, à false sinon.
j extension : donne l’extension du fichier sans le ..
j icon : renvoie un objet contenant l’icône du fichier.
j isDirectory : est à true si le chemin est un répertoire, à false sinon.
j modificationDate : donne la date de dernière modification.
j name : donne le nom du fichier ou du dossier (sans le chemin).
j parent : donne le répertoire parent du chemin (est à null si le chemin est à la
racine).
j size : donne la taille du fichier en octets.

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
Gérer des fichiers 12

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 READ : le fichier est ouvert en lecture seulement.
j WRITE : le fichier est ouvert en écriture, si le fichier n’existe pas il est créé à
l’ouverture, sinon tout est écrasé.
j APPEND : le fichier est créé s’il n’existe pas, et dans le cas contraire, l’écriture se fait
à la suite.
j 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
Utiliser SQLite 12

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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
➥ layout="vertical" creationComplete="initApp();">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import flash.filesystem.File;
import flash.data.SQLConnection;
private var conn:SQLConnection = new SQLConnection();
private var dbFile:File =
➥ File.applicationStorageDirectory.resolve("user.db");

private function initApp():void


{
conn.open(dbFile);
conn.addEventListener(SQLErrorEvent.ERROR, connectionFailed);
conn.addEventListener(SQLEvent.OPEN, connectionSucceed);
}
private function connectionSucceed(event:Event):void
{
Alert.show("Connexion à " + dbFile.name + " réussi !");
}
private function connectionFailed(event:Event):void
{
Alert.show("Connexion échouée !");
}
]]>
</mx:Script>
</mx:WindowedApplication>

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
Utiliser SQLite 12

"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’, ’toto.tata@gmail.com’)";
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
Personnaliser ses fenêtres 12

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 :
j type : définit un type de fenêtre (Normal, Utility ou Lightweight).
j 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 ;
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 :
<mx:Style>
WindowedApplication
{
background-image:"";
background-color:"";
}
</mx:Style>

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 Event.ACTIVATE ;
j Event.DEACTIVATE ;
j Event.CLOSING ;
j Event.CLOSE ;
j Event.FOCUS_IN ;

360
Check-list 12

j Event.FOCUS_OUT ;
j NativeWindowBoundsEvent.MOVING ;
j NativeWindowBoundsEvent.MOVE ;
j NativeWindowBoundsEvent.RESIZING ;
j NativeWindowBoundsEvent.RESIZE ;
j NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING ;
j 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 L’utilisateur effectue une action (il clique sur un bouton par exemple).
j Le contrôleur réagit à l’événement, généralement via un listener.
j Le contrôleur accède au modèle, et déclenche les éventuelles modifications
concernant les données.
j Une vue adaptée utilise le modèle pour modifier l’interface utilisateur.
j 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
Cairngorm 13

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 :
<view:LoginPanel id="login" login="{ model.login }"/>

Comme vous pouvez le constater, il s’agit d’un appel à la vue, au composant


LoginPanel plus précisément.

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.
j 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.
j 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().
j 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.
j 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
Tests unitaires 13

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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
➥ layout="absolute">

</mx:Application>

À 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 :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
➥ layout="absolute"
xmlns:flexunit="flexunit.flexui.*">

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 :
<flexunit:TestRunnerBase id="testRunner" width="100%" height="100%" />

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 HTTP URL, représenté par le composant HTTPService, qui utilise les méthodes POST
et GET.
j Service web, représenté par le composant WebService, qui est compatible avec le
protocole SOAP.
j 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
<mx:Button label="Clic" />

392
Antisèches 14

c Fig. 14.1 :
Exemple de bouton

Bouton

LinkButton
<mx:LinkButton label="Clic" />

c Fig. 14.2 :
Exemple de lien

Lien

PopUpMenuButton
<mx:XML id="menuData">
<root>
<editItem label="Fichier"/>
<editItem label="Quitter"/>
</root>
</mx:XML>

<mx:PopUpMenuButton id="menu" dataProvider="{menuData}"


labelField="@label" showRoot="false" />

Bouton déroulant

c Fig. 14.3 :
Exemple de bouton déroulant

RadioButton
<mx:RadioButton groupName="sex" id="male" label="Homme" />
<mx:RadioButton groupName="sex" id="female" label="Femme" />

c Fig. 14.4 :
Exemple de bouton radio

393
14 Annexes

Bouton radio

Contrôles textuels

Label
<mx:Label text="Bonjour"/>

c Fig. 14.5 :
Exemple de label

Label

RichTextEditor
<mx:RichTextEditor/>

Éditeur de texte

c Fig. 14.6 :
Exemple d’éditeur de texte

Text
<mx:Text text="Bonjour"/>

394
Antisèches 14

c Fig. 14.7 :
Exemple de texte

Texte

TextArea
<mx:TextArea text="Bonjour"/>

Zone de texte

c Fig. 14.8 :
Exemple de zone de texte

TextInput
<mx:TextInput id="myInput"/>

Champ de saisie

c Fig. 14.9 :
Champ de saisie

Les autres

Image
<mx:Image source="logo.jpg"/>

Image

c Fig. 14.10 :
Exemple d’image

395
14 Annexes

DateChooser
<mx:DateChooser/>

Calendrier

c Fig. 14.11 :
Exemple de calendrier

Les conteneurs : mx.containers

Les boîtes

HBox
<mx:HBox>
<mx:Button label="Un"/>
<mx:Button label="Deux"/>
<mx:Button label="Trois"/>
</mx:Box>

Boîte horizontale

c Fig. 14.12 :
Exemple de boîte horizontale

VBox
<mx:VBox>
<mx:Button label="Un"/>
<mx:Button label="Deux"/>
<mx:Button label="Trois"/>
</mx:Box>

396
Antisèches 14

Boîte verticale

c Fig. 14.13 :
Exemple de boîte verticale

Panel
<mx:Panel title="Mon panel">

</mx:Panel>

Panneau

c Fig. 14.14 :
Exemple de panneau

Form
<mx:Form id="myForm">
<mx:FormHeading label="Informations"/>

<mx:FormItem label="Prénom">
<mx:TextInput id="fname" width="100%"/>
</mx:FormItem>
</mx:Form>

Formulaire

c Fig. 14.15 :
Exemple de formulaire

397
14 Annexes

La navigation

Accordion
<mx:Accordion id="myAccordion">
<mx:VBox label="Première page">
<mx:TextInput/>
<mx:Button label="Valider"/>
</mx:VBox>
<mx:VBox label="Seconde Page">
<mx:TextInput/>
<mx:Button label="Valider"/>
</mx:VBox>
</mx:Accordion>

Accordéon

c Fig. 14.16 :
Exemple d’accordéon

TabBar
<mx:TabBar>
<mx:dataProvider>
<mx:String>Dossiers</mx:String>
<mx:String>Factures</mx:String>
<mx:String>Contacts</mx:String>
</mx:dataProvider>
</mx:TabBar>

Barre de navigation

c Fig. 14.17 :
Exemple de barre de navigation

ViewStack
<mx:TabBar dataProvider="myVS"/>
<mx:ViewStack id="myVS">
<mx:VBox label="Page 1">

398
Antisèches 14

</mx:VBox>
<mx:VBox label="Page 2">

</mx:VBox>
</mx:ViewStack>

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
<mx:HTTPService id="myService"
url="http://weblogs.macromedia.com/mchotin/index.xml"
useProxy="false"/>

Utilisation
<mx:Panel title="{myService.lastResult.root.title}">

WebService
<mx:WebService id="translatorService"
wsdl="http://www.webservicex.net/TranslateService.asmx?wsdl" />

Les graphiques : mx.charts


Nous allons nous contenter de présenter les graphiques les plus utilisés.

PieChart
<mx:PieChart id="piechart1">
<mx:series>
<mx:PieSeries displayName="Series 1" field=""/>
</mx:series>
</mx:PieChart>

399
14 Annexes

<mx:Legend dataProvider="{piechart1}"/>

Le camembert

c Fig. 14.18 :
Le camembert

LineChart
<mx:LineChart id="linechart1">
<mx:series>
<mx:LineSeries displayName="Series 1" yField=""/>
</mx:series>
</mx:LineChart>
<mx:Legend dataProvider="{linechart1}"/>

Les courbes

c Fig. 14.19 :
Les courbes

400
Antisèches 14

ColumnChart
<mx:ColumnChart id="columnchart1">
<mx:series>
<mx:ColumnSeries displayName="Series 1" yField=""/>
</mx:series>
</mx:ColumnChart>
<mx:Legend dataProvider="{columnchart1}"/>

Les bâtons

c Fig. 14.20 :
Les bâtons

Les validateurs : mx.validators

Nombre
<mx:NumberValidator id="numV" source="{numInput}" property="text"
minValue="1" maxValue="10" domain="int"/>

Chaîne de caractères
<mx:StringValidator source="{userNameInput}" property="text"
minLength="6" maxLength="12"/>

Date
<mx:DateValidator id="dateV" source="{dateInput}" property="text"
inputFormat="dd/mm/yyyy" allowedFormatChars="*#~/"/>

401
14 Annexes

Adresse e-mail
<mx:EmailValidator id="emV" source="{emailInput}" property="text"/>

Numéro de téléphone
<mx:PhoneNumberValidator id="pnVCell" ="{phoneInput}" property="text"/>

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 id : l’identifiant du composant, essentiel pour pouvoir faire référence au composant
dans l’application.
j label : le texte qui habille le composant, généralement un bouton ou bien un
mx:Label.
j text : similaire au label mais utilisé pour les entrées de texte, typiquement
mx:TextInput.
j dataProvider : utilisé pour peupler un tableau, une grille, un arbre, etc.

Taille et position
j 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
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 click : déclenché par un clic sur le bouton gauche de la souris.
j change : déclenché dès que le composant subit une modification.

402
Antisèches 14

j keyUp, keyDown : déclenchés respectivement lorsque l’on appuie et lorsque l’on


relâche une touche du clavier.
j focusIn, focusOut : déclenchés respectivement lorsque l’on entre dans un champ de
saisie et lorsque l’on en sort.
j 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 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
// Entrez votre code ActionScript
]]>
</mx:Script>

</mx:Application>

Dans un fichier séparé


À présent, un appel à un fichier ActionScript :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script source="asCode.as"/>

</mx:Application>

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 :
<mx:HTML id="html" width="100%" height="100%"
location="http://www.oreilly.com" complete="onHtmlComplete( )" />

Et voilà.

Personnaliser la fenêtre
Dans le fichier application.xml, ajoutez :
<rootContent systemChrome="none" transparent="true"
visible="true">main.swf</rootContent>

Puis dans votre application :


<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx=http://www.adobe.com/2006/mxml

layout="vertical" title="Transparency Test" alpha="0.5">

</mx:WindowedApplication>

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 Bubble Chart, 308


Button, 392
Accolades en MXML, 156 ButtonBar, 210
Accordion, 215, 398
ActionScript, 48, 189, 405
ActionScript 3.0, 20
Adobe Integrated Runtime (AIR),
C
22, 32, 330 Cairngorm, 364
AIR, 22, 330 Canvas, 97, 107
AIR Debug launcher, 32 Cascading Style Sheet (CSS), 242, 405
Apollo, 330 Chaîne de caractères, 59
package, 336 Change, 133
AltKey, 136 Chargement dynamique, 270
Amazon, 291 des données XML, 270
AMF3, 290 Chemins relatifs, 346
AnimateProperty, 229 Classes, 69, 405
Apollo, 330 Clavier, 135
Application, 99 codes, 135
ApplicationControlBar, 102 événements, 133
Arborescence Client, 405
du SDK, 32 Codes clavier, 135
Flex Builder 3, 32 ColdFusion, 30, 290
projet Flex, 38 ColumnChart, 307, 401
Architecture, 364 ComboBox, 178
AreaChart, 306 Command, 366
As, 61 Compiler, 44
Attributs, 70 Complétion Flex, 41
Axes, 312 Comportement, 228
Composant, 90, 405
Conteneur, 96, 405

B d’agencement, 96
Contenu d’une variable, 83
Balises fermantes, 41 Contraintes, 112
BarChart, 307 ControlBar, 101
Binding, 156 Contrôles, 405
Blur, 229 avancés, 178
Boolean, 59 Image, 115
Booléen, 59 Contrôleur, 364
Breakpoint, 81 Conversion du texte en nombre, 231

410
INDEX

Convertisseur de devises, 138 Drop target, 252


CreationComplete, 133 Drop-in, 246
CSS, 242, 405 Duration, 235
CtrlKey, 136
CurrencyFormatter, 168
E
D Ebay San Dimas, 17
Eclipse, 26
Data binding, 156 ECMAScript, 48
Data Management, 384 Effet, 229, 234
Data model, 146 EmailValidator, 402
Data models, 146 Encodage des bundles, 264
DataGrid, 180 End, 233
DataTips, 315 Entier, 59
DateChooser, 396 non signé, 59
DateFormatter, 168 Error, 133
Dates, 59 Espace de noms, 184, 407
DateTimeAxis, 325 Événements, 128, 228, 406
Déboguer, 405 clavier, 133
Deep Linking, 256 clavier-souris, 136
Design Pattern, 364 Event, 128
Devises, 138 EventDispatcher, 129
DispatchEvent, 137 EXtensible Markup Language
Dissolve, 229 (XML), 408
DividedBox, 103 Extreme programming, 373
Do while, 67
Document PDF, 339
Données
formater, 168 F
récupération, 270 Fade, 229
valider, 161 Fault, 287
Drag and Drop, 252 FaultEvent, 285
Drag initiator, 252 File, 346
Drag proxy, 252 Firefox, 406
Drag source, 252 Flash, 273
DragEvent, 256 Flex Builder 3, 26
DragManager, 256 arborescence, 32
DragSource, 256 installer, 27

411
INDEX

Flex Builder et AIR, 331 Hypertext Markup Language


Flex Charting, 304 (HTML), 406
Flex Data Services, 383
FlexPrintJob, 260
FlexUnit, 373-374, 391
Fonction, 406 I
For, 66 Id, 91
For each in, 66 IDE, 26
For in, 66 If else, 67
Form, 397 Image, 395
Formater les données, 168 Importation d’images à l’exécution, 115
Formulaire, 146 Imprimer, 260
validateur, 163 Inclusion, 270
Forum, 386 Inline, 130, 244, 246
Adobe Flex, 386 Int, 59
Framework, 406 Interfaces, 73
Internationalisation, 263
Internet Explorer, 406
G Iris, 230
Is, 61
GetChildAt, 92 Item Editor, 244
GetChildByName, 92 Item Renderer, 244
Glow, 229
Graphiques, 315
Grid, 104
J
Java Runtime Environnement, 32
H JavaScript, 407
Joost, 17
Harley Davidson Customizer, 17
Hbox, 97, 396
HDividedBox, 103
Héritage, 74 L
Historique, 256 Label, 394
HorizontalAxis, 313 Layout, 99
HorizontalList, 178 Légende, 317
HTML, 406 Licence, 22
HTMLControl, 337 LineChart, 308, 400
HTTPService, 274, 279, 383, 399 LinkBar, 212

412
INDEX

LinkButton, 393 Navigator, 36


List, 178 Nombre, 59
Listener, 129 Not a Number, 59
LiveDragging, 104 Null, 60
Load, 287 Number, 59, 231
NumberFormatter, 168
NumberValidator, 401
M NumChildrend, 208
NumericStepper, 246
Maître-détail, 190
Messaging, 384
Méthode, 72, 186, 407
drop-in, 245
O
Mode Objet, 407
Debug, 78 programmation orientée objet, 68
Design, 42 Opérateurs courants, 65
Source, 39
Model, 149
Modèle, 364
stockage des modèles, 151 P
Modèle Vue Contrôleur (MVC), 146, 158, Package, 55, 407
364, 407 AIR, 336
ModelLocator, 365 Panel, 99, 397
Module de statistiques, 321 Pause, 230
Move, 230 PDF, 339
MVC, 146, 158, 364, 407 PhoneFormatter, 168
selon Cairngorm, 365 PhoneNumberValidator, 402
Mx PieChart, 304-305, 399
Binding, 158 Play, 233
Script, 188 Player Flash et la sécurité, 273
XML, 151 PlotChart, 308
MXML, 20-21, 38, 407 Point d’arrêt, 79, 81
accolades, 156 ajout, 82
Popfly, 17
PrintJob, 260
N Profiler, 45
Programmation orientée objet, 68
Namespace, 55, 184, 407 Propriétés, 186
Navigateur Firefox, 406

413
INDEX

R Simple Object Access Protocol (SOAP),


286, 408
RadioButton, 393 Small Web Format, 408
Récupération de données, 270 SOAP, 286, 408
Remote Procedure Call, 383, 407 Sony Phone Selector, 17
RemoteObject, 290, 383 SoundEffect, 230
Resize, 230 Spacer, 102
ResourceManager, 263 SQLConnection, 352
Result, 287 SQLite, 352
ResultFormat, 279 SQLStatement, 354
Resume, 83 StartDelay, 235
Rich Internet Application (RIA), 15, 26, Statistiques, 321
407 Step Into, 83
avantages, 16 Step Over, 83
RichTextEditor, 394 Step Return, 83
Rotate, 230 Stockage des modèles, 151
RPC, 383, 407 String, 60
StringValidator, 401
Style, 242-243

S StyleManager, 243
Suspend, 83
Sandbox, 273 SWF, 44, 408
Scroll, 133 Switch, 68
SDK, 26
arborescence, 32
Sécurité du Player Flash, 115
SelectedChild, 208
T
SelectedIndex, 208 TabBar, 214, 398
SelectedItem, 179 Tableaux, 59
SerieInterpolate, 319 TabNavigator, 215
Séries, 310 Terminate, 83
Serveur, 407 TestRunner, 379
web, 408 Tests unitaires, 372-373
Service Oriented Architecture (SOA), 285 TestSuite, 380
Services Text, 394
web, 286, 408 Text Controls, 117
web et HTTPService, 289 TextArea, 395
ShiftKey, 136 TextInput, 395
ShowTarget, 237 This, 92

414
INDEX

Tile, 106 Void, 60


ToggleButtonBar, 210 Vue, 364
Trace, 85
Transitions, 238, 241
Tree, 181
Triggers, 228 W
WebService, 383, 399
While, 67
U WipeDown, 230
WipeLeft, 230
UIComponent, 338 WipeRight, 230
Uint, 60 WipeUp, 230
Undefined, 60 Workspace, 35
Uniform Resource Locator (URL), 408 Wsdl, 287
URL, 408
URLKit, 260
Use-network, 116
X
XML, 408
V chargement dynamique, 270
Mx, 151
Validateur, 401, 408
dans un formulaire, 163
prédéfinis, 161
Validators, 401 Y
Valider des données, 161 Yahoo ! Maps, 17
Value Objects, 365
Variable, 83
VBox, 97, 396
VDividedBox, 103 Z
View states, 238 ZipCodeFormatter, 168
ViewStack, 204, 398 Zoom, 230

415
Composé en France par Jouve
11, bd de Sébastopol - 75001 Paris

Vous aimerez peut-être aussi