Flex Et AIR
Flex Et AIR
Flex Et AIR
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).
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
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.
bas
Sommaire
1 Créer son premier projet avec Flex 25
14 Annexes 389
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
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
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
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
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).
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
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.
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
Nous utiliserons donc cet IDE tout au long de cet ouvrage puisqu’il facilite grandement
le développement Flex.
26
Initiation à Flex Builder 3 1
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.
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.
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.
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.
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
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.
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
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.
31
1 Créer son premier projet avec Flex
Répertoire Description
/jre Contient le Java Runtime Environnement utilisé par défaut par l’IDE
en mode Standalone
/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.
Répertoire Description
32
Initiation à Flex Builder 3 1
/frameworks/themes Contient les thèmes par défaut des différents composants Flex
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.
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.
34
Créer sa première application 1
c Fig. 1.11 :
Création d’un nouveau
projet
35
1 Créer son premier projet avec Flex
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.
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
37
1 Créer son premier projet avec 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.
.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.
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.
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
</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.
41
1 Créer son premier projet avec Flex
Nous allons maintenant passer l’éditeur en mode Design afin d’avoir un premier aperçu
de notre travail et d’ajouter les autres composants de manière visuelle.
Cliquez sur le bouton Design dans le sélecteur de mode.
Mode Design
Le mode Design peut s’avérer très utile pour placer des composants, avoir un aperçu
global de l’application ou encore gérer les différents états (voir le chapitre 8,
Personnaliser son application). Cette vue permet également de modifier les propriétés et
le design des composants grâce au panneau de droite.
Votre IDE devrait maintenant ressembler à l’écran suivant :
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
À 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
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.
À 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
48
Démarrer avec ActionScript dans Flex Builder 2
Nous pouvons déjà exécuter notre application en cliquant avec le bouton droit de la souris
sur le fichier MXML et sélectionner Run Application. Vous pourrez constater par
vous-même que le champ de texte est vide.
c Fig. 2.1 :
L’application vide
Passons à présent à notre fonction ActionScript qui va nous permettre d’afficher notre
message.
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()"/>
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!
52
Démarrer avec ActionScript dans Flex Builder 2
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!";
}
}
}
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.
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.
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!";
}
}
}
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;
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 déclarer un namespace, il suffit d’utiliser le mot-clé namespace, suivi de son nom :
namespace myNamespace;
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.
59
2 Découvrir l’ActionScript 3.0
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.
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;
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é
Les conversions
Il existe deux sortes de conversions de variables :
j la conversion implicite ou coercition ;
j la conversion explicite ou cast.
61
2 Découvrir l’ActionScript 3.0
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
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
}
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);
}
64
Les bases de la programmation 2
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) :
Catégorie Opérateurs
Multiplicatif * / %
Additif + −
Et (bits) &
Ou exclusif (bits) ^
Ou (bits) |
Et logique &&
Ou logique ||
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.
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
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);
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
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.
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;
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;
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
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;
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;
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;
}
}
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;
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;
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
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
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
]]>
</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
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.
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
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.
Nous allons maintenant exécuter notre programme en mode Pas à pas et nous en
profiterons pour expliquer le fonctionnement des deux panneaux.
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.
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.
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
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;
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
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
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>
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
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.
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
95
3 Réaliser sa première interface
96
Les conteneurs d’agencement 3
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.
97
3 Réaliser sa première interface
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
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.
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
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>
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.
102
Les conteneurs d’agencement 3
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.
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
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
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>
105
3 Réaliser sa première interface
</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.
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.
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.
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.
111
3 Réaliser sa première interface
112
Les contrôles simples 3
c Fig. 3.21 :
Définition d’une contrainte sur un contrôle
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.
114
Les contrôles simples 3
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.
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.
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.
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.
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
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>
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>
120
Mise en pratique : une interface d’annuaire 3
121
3 Réaliser sa première interface
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.
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
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
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.
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.
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);
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é");
}
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.
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 :
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é.
133
4 Gérer les é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.
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()" />
134
Les événements clavier 4
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.
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
Tout le texte contenu dans notre TextInput est reporté dans le Label.
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()"/>
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.
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);
137
4 Gérer les événements
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.
138
Mise en pratique : un convertisseur de devises 4
</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.
139
4 Gérer les événements
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">
</mx:Application>
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.
141
4 Gérer les événements
</mx:Application>
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
À 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
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>
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>[email protected]</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>
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
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.
152
Définir un data model 5
first:"Edouard",
last:"Ruiz"
},
birthday:"10/05/1984",
phone:"0654321098",
email:"[email protected]",
zipcode:"94130"
}
Passons à présent à la méthode que nous vous recommandons d’utiliser pour vos modèles.
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.*">
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
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}"/>
156
Lier des données 5
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
158
Lier des données 5
et :
<mx:Binding source="’Texte : ’ + {lastname.text}" destination="res.text"/>
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
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
160
Valider des données 5
161
5 Gérer les données
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>
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 :
165
5 Gérer les données
Dès que toutes les conditions sont respectées, on peut soumettre le formulaire :
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;
167
5 Gérer les données
Vous êtes à présent armé pour intégrer la validation de données dans vos applications.
168
Formater les données 5
169
5 Gérer les données
]]>
</mx:Script>
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
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
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>[email protected]</email>
</user>
<user id="2">
<name>
<firstname>Vianney</firstname>
<lastname>Baron</lastname>
</name>
<age>21</age>
<email>[email protected]</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>
172
Travailler avec XML 5
c Fig. 5.18 :
Accès aux données XML
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
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
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.
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
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>
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.
181
6 Aller vers une interface riche
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.
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.
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
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.
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
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.
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
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>
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
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 {
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éé
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.
189
6 Aller vers une interface riche
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.
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.
193
6 Aller vers une interface riche
<birthday>23/01/1985</birthday>
<phone>0698235455</phone>
<email>[email protected]</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"/>
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>
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
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);
}
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;
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… */
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);
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
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;
Lors de l’appel à cette fonction, les champs se rempliront avec les données contenues
dans l’objet user.
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());
}
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
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 :
205
7 Naviguer dans son application
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>
207
7 Naviguer dans son application
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 :
Propriété Utilisation
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
209
7 Naviguer dans son application
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).
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
c Fig. 7.9 :
Une ToggleButtonBar
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
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>
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>
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
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).
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">
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>
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 :
Touche Fonctionnalité
217
7 Naviguer dans son application
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>
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="[email protected]"
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:Application>
220
Mise en pratique : mon CV en ligne 7
<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>
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.
.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="[email protected]" 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>
224
Check-list 7
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
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
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.
Glow Cet effet affiche un halo lumineux autour de l’élément sur lequel l’effet est
appliqué.
229
8 Personnaliser son application
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.
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.
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é.
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
Vous pouvez donc observer que la valeur de zoom est en fait liée avec la valeur contenue
dans la balise <mx:TextInput>.
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;
}
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>
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
<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>
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.
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.
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
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>
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>
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
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.
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>
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}"/>
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.
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é.
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.
247
8 Personnaliser son application
j Button ;
j CheckBox ;
j DateField ;
j Image ;
j Label ;
j NumericStepper ;
j Text ;
j TextArea ;
j TextInput.
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>
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
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
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
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>
255
9 Améliorer l’expérience utilisateur
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.
Classe Description
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.
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;
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
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);
}
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();
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.*;
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.
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.
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
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
<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]);
}
<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>
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")
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
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{
loader.addEventListener(Event.COMPLETE, onLoad);
loader.load( request ) ;
}
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.
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.
274
HTTPService 10
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.
275
10 Communiquer avec un serveur
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>
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é.
277
10 Communiquer avec un serveur
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
Comme vous le constatez, les résultats correspondent bien aux flux XML que vous aviez
précédemment affichés dans votre navigateur.
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 &.
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>
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 :
281
10 Communiquer avec un serveur
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.
283
10 Communiquer avec un serveur
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;
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
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.
285
10 Communiquer avec un serveur
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.
Propriété Description
286
Services web 10
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.
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.
287
10 Communiquer avec un serveur
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.
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
Propriété Description
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/.
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.
291
10 Communiquer avec un serveur
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
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/.
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;
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;
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 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;
298
Mise en pratique : une application avec Amazon 10
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" />
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>
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
304
Les différents types de graphiques 11
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.
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.
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%.
Le type de série
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.
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 :
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
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
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
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>
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
</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>
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>
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
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.
315
11 Présenter les données graphiquement
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
<mx:Legend dataProvider="{chart}"/>
</mx:Application>
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} ];
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 :
320
Mise en pratique : un module de statistiques 11
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.
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.
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
323
11 Présenter les données graphiquement
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;
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
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 :
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;
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
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.
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.
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
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
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
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 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.
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>
338
Utiliser HTML 12
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.
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
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>
340
Utiliser HTML 12
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
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);.
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é’;"/>
342
Utiliser HTML 12
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>
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
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:\\";
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
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.
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.
347
12 Utiliser AIR
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);
348
Gérer des fichiers 12
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 !");
}
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 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
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");
353
12 Utiliser AIR
c Fig. 12.20 :
Connexion réussie
354
Utiliser SQLite 12
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.
L’insertion
Pour l’insertion, il faut utiliser une requête INSERT en spécifiant les champs et leur valeur.
Pour ajouter une valeur à la table names, ajoutez un eventListener à la requête
permettant la création de la table. Lorsque celle-ci enverra l’événement SQLEvent.RESULT,
vous ferez appel à la méthode addElement :
private function addElement(event:Event):void
{
var statement:SQLStatement = new SQLStatement();
statement.sqlConnection = conn;
statement.text = "INSERT INTO names(firstname, lastname, email) " +
"VALUES (’Toto’, ’Tata’, ’[email protected]’)";
statement.execute();
}
Vous pouvez également ajouter un eventListener pour agir en cas d’erreur, auquel cas
il faudra récupérer l’événement SQLErrorEvent.ERROR.
La sélection
Pour récupérer des éléments de votre table, il faut utiliser SELECT. Cette méthode va
récupérer tous les éléments de votre table names :
private function getElement(event:Event):void
{
statement = new SQLStatement();
statement.addEventListener(SQLEvent.RESULT, getSucceed);
355
12 Utiliser AIR
statement.sqlConnection = conn;
statement.text = "SELECT firstName, lastName, email "
+ "FROM names";
statement.execute();
}
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.
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.
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;
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>
359
12 Utiliser AIR
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
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.
Entité Rôle
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
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.
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.
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 :
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
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
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
Dossier Description
Commands Nous trouvons ici les commandes, à savoir des classes chargées de réagir
à un événement précis.
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 }"/>
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.
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.
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 :
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
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
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 :
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
</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;
380
Tests unitaires 13
package
{
public class CashConverter
{
public static function toDollar(euros:int):int
{
return euros * 1.38;
}
import flexunit.framework.TestCase;
import flexunit.framework.TestSuite;
/**
* Ensures the Euro to Dollar conversion works as expected.
*/
public function testToDollar():void {
var Euro:int = 100;
381
13 Aller plus loin
/**
* 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 );
}
}
}
Le résultat
Vous pouvez à présent lancer votre application et admirer le résultat :
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
383
13 Aller plus loin
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).
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
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.
Sélectionnez Flex. Vous accédez alors à l’espace dédié à Flex et à ses produits dérivés :
386
Check-list 13
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
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.
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>
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 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.
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" />
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
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
Utiliser ActionScript
Voici les deux méthodes pour utiliser ActionScript.
</mx:Application>
</mx:Application>
AIR
Voici ce que vous devez retenir à propos de AIR.
403
14 Annexes
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>
</mx:WindowedApplication>
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
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
411
INDEX
412
INDEX
413
INDEX
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
415
Composé en France par Jouve
11, bd de Sébastopol - 75001 Paris