Programmation Flex 3 : Applications Internet riches avec Flash

Transcription

Programmation Flex 3 : Applications Internet riches avec Flash
Flex 3, framework de référence pour le développement Flash
Open Source, le SDK de Flex offre un véritable environnement en phase avec les bonnes pratiques de génie logiciel
(MVC…) et de gestion de projet (travail collaboratif…). Il propose des bibliothèques de composants graphiques et des
fonctions pour dialoguer avec le serveur, et s’interfacer avec des bases de données via des serveurs PHP/J2EE.
Une bible avec de nombreux cas pratiques et retours d’expérience
Programmation Flex 3 explique aux développeurs web, qu’ils soient ou non rompus à Flash et ActionScript, comment
utiliser le framework Flex pour concevoir et créer des applications web dites « riches » (RIA), à l’instar des applications
Ajax ou Silverlight. Tout en rappelant les langages sur lesquels s’adosse cette technologie (ActionScript, MXML), l’ouvrage passe en revue l’intégralité des techniques de développement Flex : maîtrise de l’environnement de travail, création
d’interfaces interactives et évoluées avec les vues, transitions et thèmes, gestion des données et échanges avec le
serveur via RPC, mais aussi gestion et création des composants, débogage et optimisation. Il les met ensuite en situation avec deux études de cas détaillant la création d’un site e-commerce puis d’un lecteur MP3 tournant sur Adobe Air.
Au sommaire
Pourquoi utiliser Flex ? • Flex dans une architecture trois tiers • Flex et MVC • MXML et Actionscript •
Procédures et fonctions • Programmation objet • Mécanisme client/serveur • Flex SDK et Flex Builder • Gestion
d’un projet • Arborescence d’un projet Flex Builder • Exécution et test • Travail collaboratif • Export et import •
Création d’interfaces graphiques • Composants de contrôles • Boutons • Listes • Zones de texte • Tableaux •
Animations et vidéos Flash • Composants de navigation • Autres contrôles • Dimensionner et positionner •
ApplicationControlBar • Canvas • Hbox • Grid • Panel • TitleWindow • Styles • CSS et ActionScript • Skinning •
Utilisation d’images et de fichiers SWF • États, transitions et effets • Créer ses composants • MXML ou
ActionScript ? • compc • Gestion des données • DataBinding • Validation des données • Accès aux services de
la couche métier • HTTPService ou REST • RemoteObject • Flex et PHP • AMFPHP • HTTPService et
ActionScript • Le générateur de Flex Builder • Flex et J2EE avec BlazeDS • Composants émetteurs et récepteurs • Créer des applications modulaires • Interagir avec le conteneur web • Deep linking • Flex-Ajax Bridge •
Débogage d’une application • Points d’arrêt et exécution pas à pas • Analyse des performances • Optimisation
et déploiement • Réduire la taille des fichiers SWF • Adobe AIR • Flex 4 Gumbo.
A.Vannieuwenhuyze
Ingénieur concepteur dans
une SSII et responsable
d’applications pour
l’association Outcomerea,
spécialisée dans le domaine
de la recherche médicale,
Aurélien Vannieuwenhuyze
s’est d’abord investi dans la
conception et la réalisation
d’applications J2EE.
Pour créer des applications
Internet riches, il a étudié
les frameworks alliant
richesse et rapidité de
réalisation. Son choix s’est
porté sur Flex, avec lequel
il a réalisé des applicatifs
à vocation médicale et des
extranets pour de grandes
entreprises.
R. Pouclet
Passionné de développement
multimédia depuis plusieurs années,
Romain Pouclet se tourne aujourd’hui
vers le développement d’interfaces
riches et de solutions pour supports
mobiles.
À qui s’adresse cet ouvrage ?
Conception : Nord Compo
9 782212 123876
@
Sur le site www.editions-eyrolles.com
– Téléchargez le code source des exemples
et cas pratiques du livre
Code éditeur : G12387
ISBN : 978-2-212-12387-6
– À toute la communauté des concepteurs et développeurs web 2.0 (Flash, PHP, Java, Ajax, XHTML/CSS) qui désirent développer des applications Internet riches.
– Aux webmestres et développeurs connaissant Flash et ActionScript, qui recherchent un framework pour industrialiser la création d’interfaces graphiques pour leurs applications.
– Aux développeurs amenés à créer des applications autonomes exécutables avec ou sans navigateur web.
35 €
Flex 3
Applications Internet riches avec Flash ActionScript 3, MXML
et Flex Builder
A. Vannieuwenhuyze
Flex 3
Programmation
Programmation
Programmation
e
Couvr tés
uveau
o
n
s
le
x 4
de Fle
Flex 3
Applications Internet riches
avec Flash ActionScript 3,
MXML et Flex Builder
Aurélien Vannieuwenhuyze
Programmation
FLEX 3
Programmation
FLEX 3
Applications Internet riches
avec Flash ActionScript 3, MXML et Flex Builder
Aurélien
Vannieuwenhuyze
Avec
la
contribution de
Romain Pouclet
CHEZ LE MÊME ÉDITEUR
G. Leblanc. – Silverlight 2.
N°12375, 2008, 330 pages.
D. Séguy, P. Gamache. – Sécurité PHP 5 et MySQL.
N°12114, 2007, 240 pages.
G. Ponçon et J. Pauli. – Zend Framework.
N°12392, 2008, 460 pages.
R. Rimelé. – Mémento MySQL.
N°12012, 2007, 14 pages.
E. Daspet et C. Pierre de Geyer. – PHP 5 avancé.
N°12369, 5e édition, 2008, 844 pages.
M. Nebra. – Réussir son site web avec XHTML et CSS.
N°12307, 2e édition, 2008, 316 pages.
C. Porteneuve. – Bien développer pour le Web 2.0.
N°12391, 2e édition 2008, 600 pages.
A. Clarke. – Transcender CSS. Sublimez le design web !
N°12107, 2007, 370 pages.
A. Boucher. – Ergonomie web. Pour des sites web
efficaces.
N°12158, 2007, 426 pages.
J.-M. Defrance. – Premières applications Web 2.0 avec
Ajax et PHP.
N°12090, 2008, 450 pages (Collection Blanche).
A. Boucher. – Mémento Ergonomie web.
N°12386, 2008, 14 pages.
K. Djaafar. – Développement JEE 5 avec Eclipse Europa.
N°12061, 2008, 380 pages.
R. Goetter. – CSS 2 : pratique du design web.
N°11976, 2e édition, 2007, 324 pages.
E. Sloïm. – Sites web. Les bonnes pratiques.
N°12101, 2007, 14 pages.
A. Tasso. – Apprendre à programmer en ActionScript.
N°12199, 2007, 438 pages.
S. Bordage, D. Thévenon, L. Dupaquier, F. Brousse. –
Conduite de projets Web.
N°12325, 4e édition 2008, 394 pages.
N. Chu. – Réussir un projet de site Web.
N°12400, 5e édition ,2008, 246 pages.
S. Powers. – Débuter en JavaScript.
N°12093, 2007, 386 pages.
T. Templier, A. Gougeon. – JavaScript pour le Web 2.0.
N°12009, 2007, 492 pages.
D. Thomas et al. – Ruby on Rails.
N°12079, 2e édition 2007, 800 pages.
W. Altmann et al. – Typo3.
N°11781, 2006, 532 pages.
L. Bloch, C. Wolfhugel. – Sécurité informatique.
Principes fondamentaux pour l’administrateur système.
N°12021, 2007, 350 pages.
O. Andrieu. – Réussir son référencement web.
N°12264, 2008, 302 pages.
G. Gete. – Mac OS X Leopard efficace. Déploiement,
administration et réparation.
N°12263, 2008, 476 pages.
G. Ponçon. – Best practices PHP 5. Les meilleures pratiques
de développement en PHP.
N°11676, 2005, 480 pages.
M. Mason. – Subversion. Pratique du développement
collaboratif avec SVN.
N°11919, 2006, 206 pages.
ÉDITIONS EYROLLES
61, bd Saint-Germain
75240 Paris Cedex 05
www.editions-eyrolles.com
Le code de la propriété intellectuelle du 1er juillet 1992 interdit en effet expressément la photocopie à
usage collectif sans autorisation des ayants droit. Or, cette pratique s’est généralisée notamment dans les
établissements d’enseignement, provoquant une baisse brutale des achats de livres, au point que la possibilité
même pour les auteurs de créer des œuvres nouvelles et de les faire éditer correctement est aujourd’hui
menacée.
En application de la loi du 11 mars 1957, il est interdit de reproduire intégralement ou partiellement le
présent ouvrage, sur quelque support que ce soit, sans autorisation de l’éditeur ou du Centre Français d’Exploitation du
Droit de Copie, 20, rue des Grands-Augustins, 75006 Paris.
© Groupe Eyrolles, 2009, ISBN : 978-2-212-12387-6
=Flex3 FM.book Page V Mardi, 2. décembre 2008 3:32 15
Table des matières
Avant-propos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
XIX
Structure de l’ouvrage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
XIX
À qui s’adresse cet ouvrage ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
XXI
Remerciements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
XXI
PARTIE I
Comprendre Flex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
CHAPITRE 1
Pourquoi Flex ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
Les enjeux du développement d’applications web . . . . . . . . . . . . . . . .
3
Flex en questions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
Est-ce une technologie récente ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Qu’est-ce que Flex ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Quel est son fonctionnement ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Sur quelles technologies repose t-il ? . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Choisir la méthode Open Source ou propriétaire ? . . . . . . . . . . . . . . . . . .
5
6
6
6
7
Quelles différences avec Ajax ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8
Flex et ses concurrents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
Les limites de Flex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
Pourquoi choisir Flex ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
=Flex3 FM.book Page VI Mardi, 2. décembre 2008 3:32 15
VI
Programmation Flex 3
CHAPITRE 2
À la découverte du framework Flex 3 . . . . . . . . . . . . . . . . . . . . . . .
13
Rôle du front end . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Architecture n-tiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Positionnement d’une application Flex . . . . . . . . . . . . . . . . . . . . . . . . . . .
L’application et le modèle-vue-contrôleur . . . . . . . . . . . . . . . . . . . . . . .
Le langage MXML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Le langage ActionScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Les variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Les boucles et les conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Les procédures et les fonctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
La programmation objet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Le mécanisme client/serveur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
En résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
13
14
15
17
18
18
19
21
22
23
25
CHAPITRE 3
Développer avec le kit Flex SDK . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
Prérequis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Installation du kit Flex SDK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Les compilateurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
mxmlc : le compilateur d’application . . . . . . . . . . . . . . . . . . . . . . . . . . . .
compc : le compilateur de composants . . . . . . . . . . . . . . . . . . . . . . . . . . .
Première application Flex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Conception graphique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Création du projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Écriture du fichier MXML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Écriture du fichier ActionScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Liaison graphique et action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Intégration dans une page web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Déploiement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Automatisation de la compilation à l’aide de Ant . . . . . . . . . . . . . . . . .
Ant et Flex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Installation de Ant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Création d’un script de compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
En résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
28
29
30
30
31
32
32
33
33
35
35
36
38
39
39
40
40
40
45
=Flex3 FM.book Page VII Mardi, 2. décembre 2008 3:32 15
Table des matières
VII
CHAPITRE 4
Développer des applications à l’aide de Flex Builder . . . . . .
47
Présentation de Flex Builder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Les différentes versions de Flex Builder . . . . . . . . . . . . . . . . . . . . . . . . . .
Les différents modes de distribution de Flex Builder . . . . . . . . . . . . . . . .
47
48
48
Installation de Flex Builder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Le mode Autonome . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Le mode Plug-in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
49
Les perspectives de Flex Builder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
La perspective de développement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
La perspective de design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
La perspective de débogage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
La perspective de profiling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
56
Créer un projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Arborescence d’un projet Flex Builder . . . . . . . . . . . . . . . . . . . . . . . . . . .
Exécution et tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Travail collaboratif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
49
54
58
59
61
62
63
65
68
68
Exporter/importer un projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Exportation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Importation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
72
En résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
74
72
73
CHAPITRE 5
Les composants de contrôle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
75
Les boutons et interrupteurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Button . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
ToogleButton . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
75
Permettre le choix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
76
Les zones de texte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Les libellés : Label et Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Les zones de saisie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Les zones de texte « riches » . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
82
Les tableaux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
DataGrid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
AdvancedDataGrid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
76
76
82
82
83
85
85
88
=Flex3 FM.book Page VIII Mardi, 2. décembre 2008 3:32 15
VIII
Programmation Flex 3
Analyser un cube OLAP avec OLAPDataGrid . . . . . . . . . . . . . . . . . .
Qu’est-ce qu’un cube OLAP ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Création d’un cube OLAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Requête sur le cube . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
92
Insérer des images, des animations et vidéos Flash . . . . . . . . . . . . . . .
Intégrer des animations Flash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Insérer des images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Lecteur vidéo Flash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
100
Choisir une couleur dans une palette avec ColorPicker . . . . . . . . . . .
103
Contrôler le format de date avec DateChooser et DateField . . . . . . .
104
Ajouter un curseur avec HSlider et VSlider . . . . . . . . . . . . . . . . . . . . .
105
L’incrémentation avec NumericStepper . . . . . . . . . . . . . . . . . . . . . . . . .
106
Présentation de données avec HorizontalList et TileList . . . . . . . . . .
106
Réaliser des hyperliens grâce à LinkButton . . . . . . . . . . . . . . . . . . . . .
107
Afficher des données sous forme d’arborescence . . . . . . . . . . . . . . . . .
Implémentation et alimentation en données . . . . . . . . . . . . . . . . . . . . . . .
Interaction avec l’utilisateur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
108
En résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
110
92
93
95
100
100
101
108
109
CHAPITRE 6
Les composants conteneurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
111
Créer une barre de menus avec ApplicationControlBar . . . . . . . . . . .
111
Le composant Canvas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
112
Aligner verticalement ou horizontalement les composants . . . . . . . . .
Les composants HBox et VBox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Les composants HDividedBox et VDividedBox . . . . . . . . . . . . . . . . . . . .
113
Créer des formulaires avec Form, FormHeading et FormItem . . . . .
115
Créer une grille grâce à Grid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
116
Les panneaux : Panel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
117
Créer des fenêtres pop-ups avec TitleWindow . . . . . . . . . . . . . . . . . . .
Création du pop-up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Appel du pop-up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Communiquer avec le pop-up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
118
En résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
122
113
113
118
119
120
=Flex3 FM.book Page IX Mardi, 2. décembre 2008 3:32 15
Table des matières
IX
CHAPITRE 7
Les composants de navigation et de reporting . . . . . . . . . . . . .
123
Les composants de navigation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Navigation par onglets avec TabNavigator . . . . . . . . . . . . . . . . . . . . . . . .
Vues empilées avec ViewStack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Navigation « en accordéon » : Accordion . . . . . . . . . . . . . . . . . . . . . . . . .
Les composants de graphique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Implémentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
En pratique : création d’un outil de reporting . . . . . . . . . . . . . . . . . . . . . .
En résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
123
123
124
126
128
128
130
133
CHAPITRE 8
Réaliser le design des interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . .
135
Dimensionner et positionner les composants . . . . . . . . . . . . . . . . . . . . .
Spécifier les dimensions des composants . . . . . . . . . . . . . . . . . . . . . . . . .
Positionner les composants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Utiliser les styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
La balise Style . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Le fichier CSS externe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
CSS et ActionScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Habiller les composants : skinning . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Utiliser des images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Utiliser des fichiers SWF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
L’habillage par programmation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
En résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
135
135
138
147
148
149
150
151
152
152
153
155
CHAPITRE 9
Le dynamisme applicatif à l’aide des états,
des transitions et des effets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Les états ou view states . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Étude de cas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Les transitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Combiner des effets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Mise en pratique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Écrire des transitions en ActionScript . . . . . . . . . . . . . . . . . . . . . . . . . .
En résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
157
157
158
163
165
166
169
172
=Flex3 FM.book Page X Mardi, 2. décembre 2008 3:32 15
X
Programmation Flex 3
CHAPITRE 10
Créer des composants personnalisés . . . . . . . . . . . . . . . . . . . . . .
173
Penser composant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
173
Qu’est–ce qu’un composant ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
MXML ou ActionScript ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Le compilateur compc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
174
174
174
Créer un composant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Description du composant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Méthodologie de création . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Réemploi du composant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
175
175
177
195
En résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
198
CHAPITRE 11
Gérer les données . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
199
Lier des données . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Utilisation de la balise <mx:Binding> . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Le DataBinding en ActionScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
199
201
201
Stocker des données grâce au modèle . . . . . . . . . . . . . . . . . . . . . . . . . . .
Implémenter le modèle à l’aide de la balise <mx:Model> . . . . . . . . . . . .
Les modèles et ActionScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
206
206
209
Valider des données . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Rendre la saisie obligatoire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Vérification du format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Personnalisation des messages d’erreur . . . . . . . . . . . . . . . . . . . . . . . . . . .
Les événements de validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Gestion de la validation en ActionScript . . . . . . . . . . . . . . . . . . . . . . . . . .
212
213
215
215
215
216
Formater des données . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
218
En résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
221
CHAPITRE 12
Accéder aux services de la couche métier . . . . . . . . . . . . . . . . .
223
Employer les requêtes HTTP avec HTTPService
ou REST-Style webservice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
223
Le composant WebService . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Le service web en détail . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
229
230
=Flex3 FM.book Page XI Mardi, 2. décembre 2008 3:32 15
Table des matières
XI
Création de l’interface graphique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Appel du service web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Analyse du fonctionnement de l’application . . . . . . . . . . . . . . . . . . . . . . .
234
235
236
Accéder aux classes distinctes grâce à RemoteObject . . . . . . . . . . . . .
Comprendre RemoteObject . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Implémentation de RemoteObject . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
238
238
238
En résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
240
CHAPITRE 13
Flex et PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
241
Accès aux services PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
241
Installation et fonctionnement de la passerelle AMFPHP . . . . . . . . . .
241
Cas pratique : gestion d’un magasin informatique . . . . . . . . . . . . . . .
Préparation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Implémentation du composant HTTPService en ActionScript . . . . . . . . .
RemoteObject en pratique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
244
244
247
250
Le générateur d’application de Flex Builder . . . . . . . . . . . . . . . . . . . . .
257
En résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
262
CHAPITRE 14
BlazeDS : ouverture Open Source vers le monde J2EE
et la communication d’applications . . . . . . . . . . . . . . . . . . . . . . . . .
Le projet BlazeDS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Les différentes versions du serveur BlazeDS . . . . . . . . . . . . . . . . . . . . . .
Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Le serveur Tomcat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Test d’installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
263
263
264
264
265
268
Interaction avec les méthodes J2EE . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Processus d’exécution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Exemple d’application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
268
Échanger des données en temps réel . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Création du projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Configuration du serveur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
<mx:Producer> et <mx:Consumer> : les composants émetteurs
et récepteurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
276
269
270
277
278
279
=Flex3 FM.book Page XII Mardi, 2. décembre 2008 3:32 15
XII
Programmation Flex 3
Les procédures de communication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Test de l’application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
280
282
En résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
282
CHAPITRE 15
Créer des applications modulaires . . . . . . . . . . . . . . . . . . . . . . . . .
285
La notion de module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
285
Créer un module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
286
Intégrer un module dans une application . . . . . . . . . . . . . . . . . . . . . . . .
Charger les modules à l’aide du composant ModuleLoader . . . . . . . . . . .
Gestion des modules avec ActionScript . . . . . . . . . . . . . . . . . . . . . . . . . . .
288
288
288
En résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
297
CHAPITRE 16
Interagir avec le conteneur web . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
299
La notion de deep linking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Principe de fonctionnement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Mise en pratique du deep linking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Déploiement du projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
299
299
301
305
Communiquer avec le conteneur web . . . . . . . . . . . . . . . . . . . . . . . . . . .
De l’application Flex vers le conteneur web . . . . . . . . . . . . . . . . . . . . . . .
Du conteneur web vers l’application Flex . . . . . . . . . . . . . . . . . . . . . . . . .
305
306
309
La bibliothèque Flex-Ajax Bridge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Ajout de la bibliothèque à un projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Utilisation de la bibliothèque . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Déploiement et test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
313
313
313
315
En résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
317
CHAPITRE 17
Déboguer une application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
319
Création de l’application d’étude . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
319
Identifier et corriger les erreurs grâce à la vue Problems . . . . . . . . . .
321
Le débogage avancé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Utilisation des points d’arrêt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Modifier la valeur des variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
321
322
325
=Flex3 FM.book Page XIII Mardi, 2. décembre 2008 3:32 15
Table des matières
XIII
Tracer un parcours . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Sélectionner les variables à surveiller . . . . . . . . . . . . . . . . . . . . . . . . . . . .
325
326
En résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
327
CHAPITRE 18
Analyser les performances et optimiser l’application . . . . . .
329
Présentation de l’analyseur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
329
L’analyseur en action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
330
Analyse des performances . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Analyse de l’occupation mémoire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
331
333
Méthodes d’analyse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
334
Détecter les allocations mémoire inutiles . . . . . . . . . . . . . . . . . . . . . . . . .
Analyser le temps d’exécution des méthodes . . . . . . . . . . . . . . . . . . . . . .
Déterminer le nombre d’instances d’une classe . . . . . . . . . . . . . . . . . . . .
Visualiser les allocations d’objets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
334
335
336
336
Bonnes pratiques d’optimisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
337
Calculer les performances applicatives . . . . . . . . . . . . . . . . . . . . . . . . . . .
Améliorer l’exécution sur les postes clients . . . . . . . . . . . . . . . . . . . . . . .
Réduire la taille des fichiers SWF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Multiplier les fichiers SWF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Améliorer les méthodes de codage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
337
338
339
340
340
Déployer une application Flex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
341
L’incontournable liste de contrôle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Mise en ligne de l’application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
341
342
En résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
344
CHAPITRE 19
Adobe AIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
345
Le projet Adobe AIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
345
Fonctionnement d’une application AIR . . . . . . . . . . . . . . . . . . . . . . . . . .
Nouveaux composants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
345
346
Première application AIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
349
Création du projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Déploiement de l’application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
349
352
=Flex3 FM.book Page XIV Mardi, 2. décembre 2008 3:32 15
XIV
Programmation Flex 3
Gestion des données avec la bibliothèque SQLite . . . . . . . . . . . . . . . . .
Utiliser la bibliothèque SQLite dans une application AIR . . . . . . . . . . . .
SQLite par l’exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
354
355
En résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
362
354
PARTIE II
Cas pratiques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
363
CHAPITRE 20
Création d’un projet de site e-commerce . . . . . . . . . . . . . . . . . . .
365
Définition des besoins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
365
Conception UML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
366
Architecture du projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
368
Création du projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Le squelette . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Accès à l’espace d’administration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Préparation du serveur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
368
369
371
374
Faisons le point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
377
CHAPITRE 21
Module d’administration du site e-commerce . . . . . . . . . . . . . .
379
Création du module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Phase préparatoire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Design de l’interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
380
Gestion des fournisseurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Création des services PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Création des classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Logique IHM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Logique applicative . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Vérification des données transmises . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Saisie obligatoire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Vérifier le format du code postal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Aspect graphique de la validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
380
381
386
386
389
392
394
398
399
400
401
=Flex3 FM.book Page XV Mardi, 2. décembre 2008 3:32 15
Table des matières
À vos claviers : la gestion des produits . . . . . . . . . . . . . . . . . . . . . . . . . .
Quelques pistes de travail . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Version de déploiement du module . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Intégration du module dans l’application principale . . . . . . . . . . . . . .
En résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
XV
403
403
405
419
419
421
CHAPITRE 22
Module de vente en ligne : le panier d’achat . . . . . . . . . . . . . . . .
423
Création du module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Design de l’interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Les états . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Les transitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Affichage du détail d’un produit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
423
424
424
435
437
Gestion du panier d’achat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Design du panier avec ItemRenderer . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Ajouter un produit au panier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Vider le panier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
439
439
441
442
À vos claviers : création de l’interface graphique . . . . . . . . . . . . . . . .
Ce qu’il faut réaliser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
443
443
445
En résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
450
CHAPITRE 23
Module de vente en ligne : commande et facturation . . . . . .
451
Création de la commande . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Implémenter le glisser-déposer dans le tableau de commander . . . . . . . .
Supprimer l’article du panier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Calcul du prix total de la commande . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Création de la facture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Implémentation du pop-up de facturation . . . . . . . . . . . . . . . . . . . . . . . . .
Impression de la facture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
À vos claviers : création d’un pop-up de paiement
et de validation de la commande . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Répétition de composants : <mx:Repeater> . . . . . . . . . . . . . . . . . . . . . . .
Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
451
452
453
455
457
457
462
463
464
465
=Flex3 FM.book Page XVI Mardi, 2. décembre 2008 3:32 15
XVI
Programmation Flex 3
Déploiement du module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
468
Optimisation et déploiement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
470
Optimiser le temps de chargement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Faire patienter l’utilisateur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Déploiement de l’application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
470
473
475
Fin du site E-Reflex ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
477
CHAPITRE 24
Créer un lecteur MP3 avec Adobe AIR . . . . . . . . . . . . . . . . . . . . . .
479
Rechercher des MP3 à l’aide de <mx :FileSystemTree> . . . . . . . . . . .
479
Implémentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Interaction avec l’utilisateur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
480
481
Lire un fichier MP3 avec ActionScript . . . . . . . . . . . . . . . . . . . . . . . . . .
482
Principales fonctions de lecture d’un fichier audio . . . . . . . . . . . . . . . .
485
Stopper et mettre en pause . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Connaître la progression de la lecture . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Exemple complet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
485
485
486
Définition des fonctionnalités de notre application . . . . . . . . . . . . . . . .
488
Gestion de la liste de lecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Interface de lecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
489
492
À vos claviers : création d’un lecteur MP3 . . . . . . . . . . . . . . . . . . . . . .
493
Fichier de styles CSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Code de la classe ClassesLecteurMp3 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Fichier LecteurMP3AS3.as . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Fichier principal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
493
495
500
505
Déploiement du projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
506
En résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
507
CHAPITRE 25
Flex 4 Gumbo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
509
Les nouveautés de Flex 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
509
Installer le Flash Player 10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
510
FXG 1.0, nouveau format graphique . . . . . . . . . . . . . . . . . . . . . . . . . . . .
511
=Flex3 FM.book Page XVII Mardi, 2. décembre 2008 3:32 15
Table des matières
XVII
MXML 2009 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Un nouvel espace de noms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
La balise <private> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Le couple de balises <library> et <description> . . . . . . . . . . . . . . . . . . . .
Le DataBinding bi-directionnel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
513
513
514
514
516
Amélioration de certains composants de Flex 3 . . . . . . . . . . . . . . . . . .
Remplacement du composant <mx:Label> . . . . . . . . . . . . . . . . . . . . . . . .
Le composant <TextInput> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Le composant <TextArea> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
517
517
517
517
Installation de l’environnement de développement . . . . . . . . . . . . . . .
518
Première application 3D avec Flex 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Création et configuration du projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Création de l’interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Codage de l’application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
520
520
521
523
En conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
526
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
527
=Flex3 FM.book Page XVIII Mardi, 2. décembre 2008 3:32 15
=Flex3 FM.book Page XIX Mardi, 2. décembre 2008 3:32 15
Avant-propos
Le marché des applications web est en plein essor, et la tendance actuelle est de développer
mieux et plus vite. Deux solutions s’offrent à nous : se contenter de réaliser une application fonctionnelle reléguant l’aspect graphique au second plan, ou faire primer l’aspect
graphique sur la qualité du développement. Comme aucune de ces deux propositions
n’est satisfaisante, les méthodes de développement ont évolué pour donner naissance aux
frameworks, des ensembles d’outils facilitant le travail du développeur.
En effet, une application web doit être aussi attrayante et performante que n’importe
quelle autre. De plus, la démocratisation des connexions haut débit fait sauter la contrainte
technique majeure des application en ligne. Aussi les utilisateurs se montrent-ils de plus
en plus exigeants et apprécient les clients riches (ou RIA, Rich Internet Application),
capables de reproduire les fonctionnalités d’une application bureautique dans la fenêtre
d’un navigateur.
Pour répondre à une telle attente, les frameworks facilitent la création d’interfaces graphiques de qualité et d’applications complètes en un minimum de temps. Flex allie justement
la puissance de Flash à des outils connus pour le développement rapide – comme le Flex
Builder –, issus du fameux environnement Eclipse. Mais les applications riches ne se
cantonnent pas à l’univers du Web : les techniques de développement sont applicables à
la création d’applications pour les postes clients (ou RDA, Rich Desktop Application),
grâce au runtime Adobe AIR.
Structure de l’ouvrage
Nous souhaitons qu’à l’issue de votre lecture, le développement d’applications Internet
et bureautiques riches à l’aide du framework Flex 3 n’ait plus de secret pour vous. Nous en
verrons donc toutes les facettes : de la conception de l’interface graphique au déploiement
de votre projet, en passant par la gestion des données et du contrôle de la saisie de l’utilisateur. La première partie de cet ouvrage couvre l’ensemble des concepts fondamentaux.
Présentation de Flex 3, le chapitre 1 vous donnera une vue d’ensemble sur les capacités
du framework, sa structure et ses points forts. Le chapitre 2 se focalise ensuite sur la
programmation de type MVC et situe Flex dans ce contexte.
=Flex3 FM.book Page XX Mardi, 2. décembre 2008 3:32 15
XX
Programmation Flex 3
Entrée en matière dans l’utilisation du framework, le chapitre 3 propose l’étude du SDK
et des différents compilateurs. Ce sera l’occasion de créer une première application Flex.
Nous passerons alors au chapitre 4 à la présentation de l’outil de développement Flex
Builder.
Le chapitre 5 est le premier d’une trilogie consacrée à la présentation des composants du
framework. Nous commencerons par l’interaction entre l’utilisateur et l’interface. Dans
un deuxième temps, le chapitre 6 passe en revue les composants chargés d’en contenir
d’autres. Le chapitre 7 terminera notre trilogie des composants par ceux dédiés à la
représentation d’analyses statistiques.
Suite logique des trois chapitres précédents, le chapitre 8 présente les techniques d’agencement des composants afin de créer le design de nos applications. Dans le chapitre 9,
nous verrons comment réaliser effets et transitions au sein de nos interfaces graphiques.
Puis, le chapitre 10 se penchera sur la création de composants personnalisés.
Le chapitre 11 explore les possibilités qu’offre le framework en matière de gestion de
données au sein d’une interface (saisie obligatoire, formatage…) et le chapitre 12 étudie
les méthodes d’accès aux données contenues dans une base de données.
Le chapitre 13 présente l’interaction de Flex 3 avec PHP. Quant au chapitre 14, il aborde
les relations de notre framework avec Java.
Le chapitre 15 détaille la notion d’application modulaire et la création de modules. Au
chapitre 16 nous verrons les méthodes qui permettent à une application Flex de communiquer avec la page web qui la contient.
Le chapitre 17 explore les notions de débogage avant de passer, au chapitre 18, à l’étude
des méthodes d’optimisation d’une application Flex. Enfin, le chapitre 19 terminera la
première partie avec le runtime Adobe AIR.
La seconde partie met en œuvre l’ensemble des concepts étudiés dans la première partie
dans des cas pratiques. Nous détaillerons le développement d’une application e-commerce
sur quatre chapitres et terminerons avec une application multimédia réalisée à l’aide du
runtime Adobe AIR.
Le chapitre 20 définit le cadre du projet qui sera développé au cours des trois chapitres
suivants. Le chapitre 21 décrit le développement de la partie d’administration de l’application. Le chapitre 22 est consacré à la réalisation de son module principal, et le chapitre 23
détaille le déploiement de l’application.
Le chapitre 24 propose la réalisation d’un lecteur MP3 avec Adobe AIR.
Enfin, cet ouvrage se termine au chapitre 25, consacré à la future version du framework.
Il vous permettra de vous familiariser dès aujourd’hui avec Flex 4 Gumbo.
En pratique
Chaque chapitre de la seconde partie commence par une partie d’accompagnement à la réalisation et se
termine par une rubrique « À vos claviers » : en situation, vous pourrez ainsi vérifier que vous avez bien
assimilé les différents concepts énoncés tout au long de cet ouvrage.
=Flex3 FM.book Page XXI Mardi, 2. décembre 2008 3:32 15
Avant-propos
À qui s’adresse cet ouvrage ?
Cet ouvrage s’adresse autant :
• aux étudiants en programmation qui veulent apprendre à réaliser des applications clientes
riches basées sur Flash ;
• aux développeurs aguerris qui souhaitent réaliser des interfaces graphiques performantes
pouvant être intégrées à des projets Java ou PHP déjà existants ;
• aux chefs de projets qui désirent se faire une idée de la richesse technologique et des
possibilités techniques de ce framework, notamment au niveau de la productivité ;
• aux décideurs qui cherchent à rendre leurs applications plus attrayantes du point de vue
utilisateur.
Remerciements
Mes premiers remerciements vont tout naturellement à ma compagne, qui a fait preuve
de compréhension pour tous les week-ends et soirées monopolisés par l’écriture de cet
ouvrage, sans oublier les nombreux sacrifices que cela a pu engendrer.
Je remercie toute l’équipe des éditions Eyrolles et plus particulièrement Muriel Shan Sei
Fan, Eliza Gapenne, Matthieu Montaudouin et Sandrine Paniel. Merci également à Romain
Pouclet pour sa relecture technique et son avis de premier lecteur.
Je n’oublie pas le Professeur Jean-François Timsit et le Docteur Alexis Tabah de l’association Outcomerea (www.outcomerea.org), qui m’ont donné l’occasion de travailler sur
des projets mettant en œuvre Flex.
Pour finir, merci à mes parents de m’avoir aidé et accompagné dans la réalisation de mon
plus grand souhait : faire de l’informatique mon métier.
XXI
=Flex3 FM.book Page XXII Mardi, 2. décembre 2008 3:32 15
=Flex3 FM.book Page 1 Mardi, 2. décembre 2008 3:32 15
Partie I
Comprendre Flex 3
=Flex3 FM.book Page 2 Mardi, 2. décembre 2008 3:32 15
=Flex3 FM.book Page 3 Mardi, 2. décembre 2008 3:32 15
1
Pourquoi Flex ?
Les enjeux du développement d’applications web
Commençons ce premier chapitre par une constatation : 75 % des nouvelles applications
sont de type web, c’est-à-dire qu’elles ont pour support le navigateur Internet. Si nous
analysons les raisons de cet engouement pour ce mode de développement, nous pouvons
avancer trois points de réflexion :
• Une application web est disponible à tout moment et en tout point du globe. En effet,
dès lors que l’utilisateur dispose d’une connexion Internet, il peut profiter de son application. Citons comme exemple la possibilité de consulter les informations de son
compte bancaire, indépendamment de l’endroit où l’on se trouve.
• Une application web est compatible avec tous les systèmes d’exploitation. Ainsi, les
problèmes d’incompatibilité rencontrés avec les clients lourds (applications s’exécutant sur le système d’exploitation) sur les environnements Windows, Linux ou Macintosh sont maintenant révolus. Cette compatibilité est rendue possible notamment par la
mise en place de recommandations de développement (par le W3C, entre autres) et
l’utilisation de langages normalisés, tels que le JavaScript ou le HTML, interprétables
par l’ensemble des navigateurs web.
W3C
Le World Wide Web Consortium, fondé en 1994 par Tim Berners-Lee, n’a pas pour fonction première de
créer des normes de développement mais plutôt des recommandations. Son domaine d’activité se
concentre sur les langages orientés vers le développement d’applications Internet (HTML, XML…) afin
d’assurer leur interopérabilité (http://www.w3.org/).
=Flex3 FM.book Page 4 Mardi, 2. décembre 2008 3:32 15
4
Comprendre Flex 3
PARTIE I
• Enfin, le dernier point est la légèreté du mode de distribution de ces applications. Si
pour une application lourde nous devions posséder un CD-Rom d’installation, nous
n’avons plus qu’à saisir une URL dans un navigateur. Notons également que ceci
réduit d’autant le coût de distribution de l’application.
Néanmoins, ce phénomène induit tout de même un effet secondaire néfaste. Les applications
disponibles depuis le Web ou les différents intranets d’entreprise sont aujourd’hui tellement nombreuses que se développe le syndrome d’applications « jetables ». Ainsi, comme
il suffit de saisir une simple URL dans un navigateur pour exécuter une application, si
celle-ci ne nous convient pas pour des raisons X ou Y, nous n’aurons qu’à lancer une
requête dans un moteur de recherche pour en trouver une autre, similaire.
Dès lors, pour développer une application web viable et durable, les outils que nous
pouvons désormais qualifier, de façon réductrice, de « simplistes » dédiés uniquement au
développement et ne prenant pas en compte le processus complet de réalisation de l’application (de la conception au déploiement) ne sont plus de mise. Nous disposons maintenant
de frameworks qui sont un ensemble d’outils réunis dans une seule application. Grâce à
eux, nous pouvons à présent déboguer une application web, disposer d’autocomplétion
de code et « designer » des interfaces. L’utilisation d’un framework facilite la mise en
place de la standardisation du code et de méthodes d’optimisation. Les applications développées sont ainsi homogènes, ce qui diminue le temps d’analyse et facilite l’apport de
correctifs, augmentant donc la productivité.
Alternatives
Notons que nous avons parlé de frameworks au pluriel. En effet, il n’existe pas un mais des frameworks.
Citons par exemple le framework ZendStudio pour le langage PHP, le Google Web Toolkit et bien entendu
Flex 3.
Pourquoi choisir le framework Flex 3 plutôt qu’un autre ? Sans entrer dans le détail, car
nous aurons l’occasion d’y revenir tout au long de ce chapitre, le framework Flex permet de
créer des applications web basées sur la technologie Flash (employée dans les applications
graphiques) procurant une qualité d’interface graphique très appréciée des utilisateurs.
De plus, sa prise en main est facilitée par l’outil de développement Flex Builder basé sur
le célèbre IDE Eclipse, très largement utilisé par les développeurs de nouvelles technologies.
Cette facilité de prise en main séduira donc les développeurs juniors et seniors qui verront
dans ce framework la possibilité de créer rapidement des applications web alliant esthétique
et technique. Les jeunes développeurs seront sans doute intéressés par le coté « nouveau »
de cette technologie, source de motivation et moteur de créativité, les plus aguerris y
verront le moyen de créer des interfaces graphiques très performantes tout en minimisant
le temps de développement. Notre framework ravira également les décideurs (chef de
projets ou d’entreprise), car il permet, d’une part, de produire des applications esthétiques
appréciées des utilisateurs et, d’autre part, de réduire les délais de développement grâce
aux avantages énoncés précédemment.
=Flex3 FM.book Page 5 Mardi, 2. décembre 2008 3:32 15
Pourquoi Flex ?
CHAPITRE 1
Nous sommes sûrs qu’à la suite de ces quelques lignes, vous vous posez certaines questions.
C’est pourquoi nous allons poursuivre ce chapitre en tentant d’y répondre.
Flex en questions
En tant que spécialiste, lorsque vous évoquez le framework avec des chefs de projets,
développeurs ou tout autre acteur d’un projet de développement informatique, plusieurs
questions reviennent immanquablement :
• Est-ce une technologie récente ?
• Qu’est-ce que le framework Flex ?
• Comment fonctionne-t-il ?
• De quoi est-il composé ?
• S’agit-il d’un logiciel Open Source ou d’une solution propriétaire ?
Voyons comment répondre à ces questions.
Est-ce une technologie récente ?
Flex vu le jour en mars 2004. Initié par Macromédia, repris en 2006 par Adobe, le projet
a connu une évolution rapide comme le montre le tableau 1-1 qui récapitule les mises en
production des différentes versions.
Tableau 1-1
Historique des versions du framework Flex
Date
Événement
Mars 2004
Sortie de Flex version 1.0
Octobre 2004
Flex 1.5
Octobre 2005
Flex 2.0 alpha
Février 2006
Flex 2.0 bêta 1
Mars 2006
Flex 2.0 bêta 2
Mai 2006
Flex 2.0 bêta 3
Janvier 2007
Flex 2.01
Février 2008
Flex 3
Courant 2009
Flex 4 qui portera vraisemblablement le nom de « Gumbo ».
Si l’on considère cette chronologie, on constate la mise en production d’une nouvelle
version par an. On peut en déduire que cette technologie est chère à Adobe, qui investit
largement dans ce projet.
Sans chercher à décrire les différentes versions du framework, il est tout de même important
de noter qu’à l’origine, Flex a été créé pour le développement de la couche graphique
5
=Flex3 FM.book Page 6 Mardi, 2. décembre 2008 3:32 15
6
Comprendre Flex 3
PARTIE I
d’une application (partie front end) J2EE. Ceci nécessitait la présence d’un serveur Flex
qui a totalement disparu dès la version 2. La version 3 apporte également son lot de
nouveautés comme l’ouverture vers le monde libre de certaines parties du SDK, ou
l’apparition de nouveaux composants. L’environnement de développement Flex Builder
comporte aussi de nouvelles fonctionnalités telles que le mode de débogage avancé.
Qu’est-ce que Flex ?
Flex est un framework qui sert à la création d’interfaces client riches (front end de
l’application) basé sur l’usage de la technologie Adobe Flash. En effet, si celle-ci apporte
une grande souplesse pour la création d’interfaces graphiques riches, elle est souvent perçue
par les non-initiés comme complexe.
De plus, pour bon nombre de techniciens spécialisés dans le développement d’application,
la conception et la réalisation de l’interface graphique de l’application semblent souvent
secondaires : ils préfèrent se focaliser complètement sur la fonctionnalité à développer
plutôt que sur la présentation du résultat. Le framework Flex a ainsi pour objectif de faciliter
cette partie du développement, en supprimant la notion de time line.
Time line
Bien connu des développeurs Flash, le time line sert à définir des actions sur les composants selon un axe
temporel. Ce mode de développement est réservé aux spécialistes de Flash et diffère du mode de développement standard basé sur la disposition de composants sur une page web.
Grâce au framework Flex, l’utilisation de Flash n’est plus l’apanage des seuls designers :
les développeurs peuvent maintenant créer des interfaces graphiques attrayantes grâce à
un langage de description basé sur XML.
Quel est son fonctionnement ?
Une application Flex n’est autre qu’un fichier portant l’extension .swf (ShockWave Flash)
issu de la compilation de fichiers MXML et ActionScript, insérés dans une page web.
Les fichiers MXML (Macromedia XML) servent à la description des interfaces graphiques,
en définissant la position des composants et leurs propriétés. Quant aux fichiers ActionScript 3, ils ont la charge de la logique applicative : gestion d’événements, écriture de
procédure, fonctions…
Sur quelles technologies repose t-il ?
Voyons à présent le socle sur lequel repose Flex 3 et les technologies associées. Le
framework Flex 3 s’articule autour des quatre éléments suivants :
• Le Flash Player 9 – Équipant près de 97 % des ordinateurs (Windows, Mac OS et
Linux), le Flash Player assure la compatibilité des applications développées en Flash
sur l’ensemble des environnements et navigateurs web.
=Flex3 FM.book Page 7 Mardi, 2. décembre 2008 3:32 15
Pourquoi Flex ?
CHAPITRE 1
• Le Flex 3 SDK – Ouvert au monde Open Source, le SDK (Software Development Kit)
permet de créer des applications Flex gratuitement à l’aide des compilateurs et du
débogueur qu’il intègre.
• Flex Builder 3 – Environnement de développement basé sur le célèbre IDE (Integrated
Development Environment) Eclipse, il propose un ensemble de fonctionnalités permettant
de réaliser facilement des interfaces graphiques conviviales. Depuis sa version 3, il
offre également des fonctions avancées de débogage comme le profiling d’application
(qui intervient notamment dans la description de la charge mémoire utilisée par
l’application). Cet outil est disponible en version standard et professionnelle mais
nécessitera cependant un investissement non négligeable (environ 600 € pour la version
professionnelle). À noter qu’il existe une version pour les étudiants.
• Blaze DS – Ce composant s’adresse à celles et ceux qui souhaitent créer des applications
Flex communiquant avec le back end J2EE. Il s’agit d’un sous-ensemble de projets Open
Source basés sur les briques principales de son homologue LiveCycle Data services
d’Adobe, qui est payant.
Front end et back end d’une application
Le back end est chargé de contenir la logique métier de l’application (règles de gestion, traitements des
données…). Le front end, quant à lui, gère la partie interface homme machine (IHM) de l’application.
Flash 9 obsolète ?
À l’heure ou nous écrivons ces lignes, Adobe vient de mettre à disposition le nouveau Flash Player 10.
Cependant, la compatibilité descendante est respectée : les fonctionnalités du Flash Player 9 sont aussi
disponibles dans le Flash Player 10. Cela n’a également aucun impact sur l’utilisation du framework
Flex 3.
Choisir la méthode Open Source ou propriétaire ?
Voilà la grande question que tout le monde est en droit de se poser. Comportant l’ensemble
des bibliothèques et compilateurs nécessaires au développement, certaines parties du
Flex SDK sont à présent Open Source. Néanmoins, nous verrons, lors du chapitre 3, que
son utilisation n’est pas des plus aisées. Cependant, pour faciliter le travail du développeur,
Adobe propose l’environnement de développement propriétaire Flex Builder. Vous
disposez ainsi d’un environnement de développement, de test et de déploiement efficace.
Bien entendu, cet environnement de développement a un prix : il faut débourser environ
600 € pour acquérir une licence. Mais, comme nous venons de l’indiquer, le Flex Builder
n’est qu’un « plus » qui facilite l’utilisation du framework. Il est donc tout à fait possible
de développer vos applications avec Flex sans débourser un sou… si vous pouvez vous
contenter d’un simple éditeur de texte et d’un compilateur en ligne de commande.
7
=Flex3 FM.book Page 8 Mardi, 2. décembre 2008 3:32 15
8
Comprendre Flex 3
PARTIE I
Quelles différences avec Ajax ?
Comme nous venons de l’indiquer, si vous souhaitez recourir à l’IDE Flex Builder, il
faudra bourse délier. Bien entendu, cet investissement financier sera d’autant plus important que les développeurs amenés à l’utiliser seront nombreux. Vous êtes donc en droit
de vous demander pourquoi effectuer une telle dépense, alors qu’en optant pour un
framework Ajax, vous pourriez tout à fait réaliser des RIA (Rich Internet Application) et,
ce, de façon totalement gratuite tout en profitant des forces des projets Open Source.
Qu’est-ce qu’Ajax ?
Ajax (Asynchronous Javascript and XML, XML et JavaScript asynchrone) est une méthode de développement d’application web combinant différentes technologies telles que HTML, Javascript, XML ou encore le
protocole HTTP. On l’utilise notamment pour créer des interfaces interactives. Pour en résumer le principe,
Ajax permet d’interagir avec un serveur web sans devoir recharger l’intégralité de la page. De nombreux
frameworks Ajax – comme Openlaszlo (http://www.openlaszlo.org/) – mettent à profit cette méthode
de développement pour la réalisation d’interfaces client riches.
Le principal argument que nous pouvons avancer est le suivant : Ajax se base sur le
langage JavaScript dont l’interprétation peut varier d’un navigateur à l’autre. Ceci implique
donc l’adaptation du code pour chaque navigateur. Une application Flash reposant exclusivement sur le Flash Player, son comportement sera identique quelle que soit la plateforme ou l’environnement dans lequel elle est exécutée.
Un second argument peut également être avancé : il est plus facile et rapide de développer
une interface graphique à fonctionnalités équivalentes avec le framework Flex qu’avec la
technologie Ajax. Comme nous l’avons évoqué au début de ce chapitre, nous sommes
dans une société de consommation d’applications web, où la durée de vie de celles-ci est
limitée et où l’aspect esthétique est devenu primordial. Par conséquent, si nous souhaitons
réaliser une application ayant une interface attrayante tout en réduisant son coût de développement, nous avons tout intérêt à nous diriger vers l’usage du framework Flex.
Tableau 1-2
Comparaison entre une application développée avec Flex et avec Ajax
Critère
Flex
Ajax
Nécessité d’un plug-in sur le poste
client pour l’exécution de l’application
Oui
Non, même s’il nécessite l’activation
de JavaScript sur le poste client
Coût du développement de
l’application
Gratuit pour l’utilisation du SDK.
Payant pour l’utilisation de l’IDE
Gratuit
Portabilité de l’application
Comportement identique sur
l’ensemble des navigateurs
Le comportement de l’application
peut différer selon le navigateur web
(hors utilisation d’un framework)
Insertion de contenu multimédia
(vidéo, son…) dans l’application à
l’aide de fonctionnalités pré-existantes
De par son lien avec Flash,
les fonctionnalités multimédias sont
incluses dans le framework
Les fonctionnalités multimédias ne
sont pas incluses
=Flex3 FM.book Page 9 Mardi, 2. décembre 2008 3:32 15
Pourquoi Flex ?
CHAPITRE 1
Tableau 1-2
Comparaison entre une application développée avec Flex et avec Ajax (suite)
Critère
Flex
Ajax
Composants graphiques prêts à
l’emploi
Flex intègre de nombreux composants
graphiques (menus accordéon…)
Ajax ne comporte pas de composants
graphiques, c’est au développeur de
les créer
Nombre de langages utilisés
2 : MXML et ActionScript
2 : JavaScript et XML
Le tableau 1-2 établit une comparaison entre l’utilisation du framework Flex et la méthode
de développement Ajax. Bien entendu, il s’agit là moins de comparer le framework Flex à
l’ensemble des frameworks Ajax (tels que OpenLazlo ou bien encore Google Web Toolkit),
que de mesurer le résultat obtenu.
Comme vous le constatez, la frontière séparant le framework Flex de la méthode de développement Ajax est très mince. Mais si nous faisons le bilan de cette comparaison, il est
évident que l’atout majeur de Flex est sa faculté à rendre les applications compatibles
avec l’ensemble des navigateurs, grâce à Flash tout en proposant un panel de composants
prêts à l’emploi. C’est également grâce à Flash et ses possibilités multimédias et de mise
en forme des composants que Flex se démarque d’Ajax.
Néanmoins, le principal inconvénient des applications Flex est qu’elles sont hermétiques
à leur environnement : au sein d’une page web, la communication avec les éléments
HTML, JavaScript, etc. est inexistante, à moins de passer par un pont de communication,
réalisé en JavaScript et portant le nom de Flex-Ajax Bridge. Mais nous aurons l’occasion
de revenir sur cette notion dans le chapitre 16. Plutôt que de chercher à se démarquer de
la solution Ajax, les développeurs du framework Flex ont pris conscience de ses faiblesses
et ont opté pour une alliance de technologies.
De plus, on souligne souvent que l’exécution d’une application Flash est plus lente
qu’une application HTML utilisant Ajax. Si ce point n’est pas négligeable, rappelons
qu’une application Flex est développée pour un Flash Player précis, et compilée pour
fonctionner avec ce dernier, ce qui permet une meilleure interopérabilité et donc un gain de
performance. Nous verrons qu’il nous est possible d’optimiser ce temps d’exécution grâce
à l’analyse des processus et à l’étude de l’occupation mémoire de certaines procédures.
Flex et ses concurrents
Encore restreint il y a quelques années, le marché de la RIA, tend peu à peu à se développer :
• La technologie XUL (XML-based User interface Language), initiée par Mozilla, consiste,
tout comme le framework Flex, à décrire les interfaces graphiques à l’aide de XML.
• Le framework OpenLazlo se rapproche du framework Flex par la génération d’interfaces graphiques basées sur la technologie Flash (http://www.openlaszlo.org/).
• Entièrement basé sur la technologie Ajax, le framework Google Web Toolkit, permet
de créer également des interfaces client riches assez intéressantes en termes de
9
=Flex3 FM.book Page 10 Mardi, 2. décembre 2008 3:32 15
10
Comprendre Flex 3
PARTIE I
fonctionnalités. Citons par exemple l’application de géolocalisation Google Map
(http://maps.google.fr/).
Néanmoins, le principal concurrent de Flex 3 est la plate-forme de développement
Silverlight de Microsoft. Elle offre un environnement de développement semblable en
termes de fonctionnalités, tout en se différenciant par l’utilisation du langage XAML
pour la description des interfaces et de JavaScript pour la partie logique applicative.
L’exécution de ces applications diffère également par l’utilisation d’un plug-in à installer
sur le navigateur.
Alors, vers quelle solution faut il se diriger ? La première chose à prendre en compte est
la politique informatique de l’entreprise. Si la norme est de limiter l’usage des projets
libres ou si l’entreprise est en partenariat avec Microsoft, le choix s’orientera naturellement
vers Silverlight, sinon l’usage de Flex semble être tout indiqué. Le second argument en
faveur de la technologie Flex est qu’elle utilise le Flash Player, compatible avec toutes les
plates-formes, pour exécuter l’application, alors qu’il faudra télécharger un plug-in propre
à Microsoft, qui ne semble pas encore être officiellement compatible avec Linux.
Silverlight et Linux
Selon certaines sources, ce problème de compatibilité avec Linux devrait bientôt complètement disparaître.
Enfin, pour utiliser Silverlight, il faut employer l’environnement de développement Visual
Studio dont le prix avoisine les 1 000 €. Ce point peut éventuellement porter préjudice à
Silverlight et avantager Flex. En effet, là où nous avons besoin d’un module applicatif,
nous sommes obligés d’acquérir l’ensemble de l’environnement de développement. Mais
les choses devraient sans doute évoluer au cours de l’année 2009. Ce produit est donc à
suivre de très près.
Bibliographie
Silverlight 2 de Gérard Leblanc, éditions Eyrolles, 2008.
Les limites de Flex
Comme toute solution informatique, Flex a ses propres limites, parfois décriées par les
développeurs Ajax ou Flash désireux de remettre en question jusqu’à l’utilité de ce
framework. Nous allons donc essayer d’apporter quelques éléments de réponse afin
d’éclaircir tout ceci.
« L’exécution d’une application Flex nécessite la présence du Flash Player sur le
poste client ! »
Cette condition sine qua non peut en effet être un frein à l’utilisation des applications
Flex. Néanmoins, le lecteur Flash assure une stabilité d’exécution des applications sur
l’ensemble des machines à l’inverse d’Ajax dont le comportement peut différer d’un
navigateur à un autre. Il s’agit donc d’un mal pour un bien. Sachant que la plupart des
=Flex3 FM.book Page 11 Mardi, 2. décembre 2008 3:32 15
Pourquoi Flex ?
CHAPITRE 1
machines sont équipées du Flash Player… est-ce une raison valable pour en dénigrer
l’utilisation ?
« Le framework Flex ne propose pas d’outils dédiés au graphisme ! »
Comme nous l’avons évoqué précédemment, Flex est basé sur Flash, ce qui simplifie
beaucoup la réalisation d’interfaces graphiques riches. Il n’est nullement question de
créer des animations comme nous pourrions le faire avec Flash CS3 ! Pour pallier ce
problème, Flex contient un composant, nommé SWFLoader, permettant d’importer des
animations Flash.
« Le Flash Player n’est pas compatible avec les processeurs 64 bits ! »
En effet, à l’heure ou nous écrivons ces lignes, le Flash Player n’est pas supporté par les
machines équipées d’un processeur 64 bits. Bien que cela concerne actuellement peu de
machines, la solution préconisée par Adobe consiste à exécuter un navigateur 32 bits
compatible avec les machines 64 bits pouvant alors afficher les applications Flash.
« Dans une application Flash, il est impossible d’utiliser les boutons Précédent et
Suivant du navigateur ! »
Depuis la version 3 du framework, ceci est tout à fait possible grâce à la notion de deep
linking. En effet, elle permet de naviguer à l’intérieur d’une application à l’aide des boutons
Suivant et Précédent du navigateur, comme il est possible de le faire dans toute application
web. Nous développerons cette fonctionnalité dans le chapitre 16.
« Une application Flash est difficile à référencer dans les moteurs de recherche ! »
Certains moteurs de recherche comme Google sont dorénavant capables d’analyser le
contenu d’un fichier SWF. Le référencement d’une animation Flash est donc possible. Dans
tous les cas, n’oublions pas qu’une application Flash est généralement contenue dans une
page HTML. Ceci permet alors d’y stocker l’ensemble des informations de référencement
même si, à l’heure où nous écrivons ces lignes, les informations indexées ne sont pas
aussi pertinentes que celles d’un site HTML.
Bien entendu, nous n’avons pas recensé l’ensemble des remarques soulevées par les « proAjax » ou « pro-Flash ». Il est important de retenir qu’Adobe met tout en œuvre pour
pallier l’ensemble des problèmes qui pourraient mettre son produit en difficulté. Ceci
nous amène donc à dire que le projet Flex 3 a atteint un degré de maturité non négligeable
et qu’il s’agit d’une valeur sûre.
Pourquoi choisir Flex ?
Il ne s’agit pas de reprendre les arguments commerciaux édictés par Adobe mais de vous
faire part de nos constatations suite à notre expérience de l’utilisation de ce framework à
travers des projets de différentes natures.
Si nous devions vous convaincre d’utiliser Flex plutôt qu’une autre technologie, voici ce
que nous vous avancerions :
11
=Flex3 FM.book Page 12 Mardi, 2. décembre 2008 3:32 15
12
Comprendre Flex 3
PARTIE I
• Flex apporte une valeur ajoutée indéniable au niveau commercial par la richesse des
interfaces développées (ce qui est beau est vendeur). Pour vous en rendre compte, il
vous suffit de visiter la page d’exemple du site d’Adobe : http://www.adobe.com/devnet
/flex/?tab:samples=1.
• Ce framework augmente la rapidité et la qualité de développement grâce à l’IDE Flex
Builder.
• Il s’adapte aux besoins en offrant la possibilité de créer ses propres composants. Nous
nous pencherons sur ce point au chapitre 10.
• Les applications se comportent de manière identique quelles que soient les plates-formes
et les conditions d’utilisation.
• Flex permet de réaliser des applications bureautiques riches (ou RDA, Rich Desktop
Application) grâce à la machine virtuelle Adobe AIR (ce que nous verrons au
chapitre 19).
=Flex3 FM.book Page 13 Mardi, 2. décembre 2008 3:32 15
2
À la découverte
du framework Flex 3
Dans ce chapitre – peut être l’un des plus importants de cet ouvrage – nous allons disposer
les premières briques qui vont nous permettre de comprendre les fondements essentiels
du framework Flex. Ces fondements sont la base de l’utilisation du framework car ils
permettent d’en connaître le fonctionnement et les possibilités mais également les limites.
Rôle du front end
La notion de découpage d’une application en trois couches distinctes est bien connue des
développeurs de nouvelles technologies (J2EE, PHP…). Néanmoins, si vous êtes néophyte
en la matière et que cela ne vous évoque rien, ne vous inquiétez pas, nous allons tout de
suite remédier à cela.
Architecture n-tiers
Une application peut être divisée en plusieurs couches ou tiers applicatifs, nous parlons
alors d’une architecture n-tiers. Ainsi, si nous subdivisons une application en trois couches
distinctes, nous obtenons une architecture 3-tiers :
• La couche Présentation est chargée, comme son nom l’indique, de présenter les données
(interface Homme-Machine ou IHM).
• La couche Métier implémente la logique métier (règle de gestion, etc.).
• La couche d’accès aux données réalise la tâche de persistance des données (stockage)
via l’utilisation d’une base de données, par exemple.
=Flex3 FM.book Page 14 Mardi, 2. décembre 2008 3:32 15
14
Comprendre Flex 3
PARTIE I
Chaque couche propose des services qu’elle met à disposition de la couche qui lui est
directement supérieure. Ainsi, la couche la plus élevée ne peut communiquer avec la
couche la plus basse de l’architecture que par la couche intermédiaire, comme l’illustre la
figure 2-1.
Figure 2-1
Architecture 3-tiers
Positionnement d’une application Flex
Au cours du chapitre précédent, nous avons défini le rôle du framework Flex comme
étant un outil de création d’interfaces clientes riches (RIA). De ce fait, le positionnement
des applications réalisées à l’aide de ce framework dans une architecture de type 3-tiers,
se fera naturellement au niveau de la couche Présentation (tiers 1).
Ce positionnement en haut de l’architecture implique donc une notion que nous devrons
toujours prendre en compte lors de la création d’une nouvelle application : une application
réalisée à l’aide du framework Flex ne peut pas accéder directement aux informations
contenues dans une base de données, comme c’est le cas pour les applications Java ou
PHP.
Par conséquent, si nous souhaitons développer une application utilisant des informations
contenues dans une base de données, nous devrons implanter une couche Métier intermédiaire offrant un certain nombre de services écrits dans un langage serveur (PHP, Java,
ColdFusion…). Ces services seront capables de se connecter à la base de données et d’y
effectuer des requêtes pour ensuite renvoyer les résultats à notre application. L’appel de
ces services à partir de l’application se fera via des composants spécifiques du framework
Flex tels que les composants HTTPService ou RemoteObject (voir chapitre 13).
=Flex3 FM.book Page 15 Mardi, 2. décembre 2008 3:32 15
À la découverte du framework Flex 3
CHAPITRE 2
Dans cette section, nous avons donc vu un élément essentiel du framework Flex dont
l’impact n’est pas négligeable si vous souhaitez créer des applications accédant à des
données : la mise en place impérative d’une couche Métier écrite dans un langage serveur.
Néanmoins, toutes les applications Flex n’utilisent pas forcément des données, c’est le
cas par exemple d’une calculatrice ou d’un simulateur d’emprunt. Qui plus est, il nous est
également possible de stocker des informations de façon temporaire au sein de notre application à l’aide d’un modèle de données qui, là encore, est bien connu des développeurs Java.
L’application et le modèle-vue-contrôleur
Maintenant que nous savons que le framework Flex n’a pour but que la création de la
partie graphique d’une application, nous pouvons entrer dans le détail de la couche
graphique en abordant la notion de modèle-vue-contrôleur (MVC). Cette couche peut
elle aussi se découper en trois éléments :
• Le modèle représente les données et les règles métiers via un ensemble de classes et de
méthodes associées. Il permet également l’accès aux services décrits dans la couche
Métier de l’architecture 3-tiers. Enfin, c’est lui qui se chargera de prévenir la vue d’un
changement de données afin que celle-ci se mette à jour.
• La vue va afficher les données du modèle et permettre l’interaction avec l’utilisateur,
c’est l’interface homme-machine (IHM) de votre application. Notons, qu’il est tout à
fait possible d’avoir plusieurs vues affichant les données d’un même modèle.
• Le contrôleur, quant à lui, va jouer le rôle d’interface entre la ou les vues et le modèle.
Il récupère les actions de l’utilisateur pour ensuite les rediriger vers le modèle sous
forme d’événements et mettre à jour la vue appropriée.
Si vous n’avez jamais été confronté à la notion de MVC, ce qui vient d’être énoncé doit
vous paraître assez obscur. Pour vous aider à mieux comprendre cette notion, nous allons
l’illustrer à l’aide d’un petit exemple. Considérons l’action sur un bouton permettant de
lister l’ensemble des données contenues dans une table et de les afficher dans une grille
de résultats (figure 2-2).
1. L’utilisateur clique sur le bouton Afficher les données. Cette action déclenche alors
un événement que la vue se charge de faire suivre au contrôleur.
2. Le contrôleur approprié à cette action traite l’information reçue. Ce traitement
consiste à choisir la vue appropriée et à lui fournir les informations dont elle a besoin
en les choisissant à partir du modèle.
3. Le modèle fait appel au service de la couche Métier de l’architecture 3-tiers permettant
d’exécuter la requête de sélection, et se met à jour en fonction des données reçues.
Cette mise à jour peut être notifiée à la vue afin que cette dernière puisse être actualisée.
4. Le modèle indique au contrôleur que le traitement est terminé et envoie les données
au contrôleur.
5. Le contrôleur met à jour la vue afin de présenter les données à l’utilisateur.
15
=Flex3 FM.book Page 16 Mardi, 2. décembre 2008 3:32 15
16
Comprendre Flex 3
PARTIE I
Figure 2-2
Architecture MVC
Le modèle MVC et la notion de design pattern
Le modèle MVC est un design pattern (modèle de conception), ce qui signifie qu’il peut être appliqué dans
tout type d’application et ne se limite donc pas aux applications Flex.
Si nous transposons cette explication à l’utilisation du framework Flex, l’implémentation
du modèle peut s’effectuer à l’aide du langage ActionScript, dont l’orientation objet, très
poussée depuis la dernière version en date, permet de créer facilement des classes et des
méthodes associées. Le contrôleur dont le rôle principal est l’interfaçage entre le modèle
et la vue sera lui aussi développé à l’aide de ce langage et souvent mis en application
grâce à la notion de DataBinding (voir chapitre 11). La vue sera quant à elle implémentée
à l’aide du langage MXML prévu à cet effet ; celui-ci ayant pour fonction principale la
description des interfaces graphiques.
Balise MODEL
Le langage MXML met à disposition la balise MODEL qui permet, comme son nom l’indique, de déclarer un
modèle de données.
Les langages ActionScript et MXML peuvent vous être totalement inconnus si vous n’êtes
pas habitué à développer des applications Flash. Comme nous l’avons déjà évoqué, une
application Flex est le résultat du mariage de ces deux langages où l’un permet de créer
l’interface graphique et l’autre de mettre en place la logique applicative. C’est donc tout
naturellement que nous allons poursuivre par la présentation de ces deux langages.
=Flex3 FM.book Page 17 Mardi, 2. décembre 2008 3:32 15
À la découverte du framework Flex 3
CHAPITRE 2
Le langage MXML
Le MXML (Macromedia fleX Markup Language) est avant tout un langage de balises basé
sur XML. Son rôle principal est de permettre l’agencement des composants au sein d’une
interface graphique. Ainsi, chaque composant est défini par des balises spécifiques :
• Un bouton est défini par les balises <mx:Button></mx:Button>.
• Une zone de saisie est définie par les balises <mx:TextInput></mx:TextInput>.
• Un panel servant de conteneur de composants est défini par les balises <mx:Panel>
</mx:Panel>.
Bien entendu, le langage MXML ne se limite pas uniquement à la mise en place de
composants graphiques. Il permet également d’implémenter des composants capables de
faire appel à des services web, par exemple les composants HTTPService (<mx:HTTPService/>)
et WebService (<mx:WebServices/>).
Dans la mesure où le framework Flex a pour rôle de créer la couche graphique d’une
application, il est indispensable que toute application soit composée d’au moins un fichier
portant l’extension .mxml et dont le contenu de base sera le suivant (cas d’une application
exécutée dans le navigateur web) :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
</mx:Application>
La balise mx:Application permet d’indiquer qu’il s’agit du fichier applicatif principal. La
référence à l’espace de noms http://www.adobe.com/2006/mxml sert à définir l’ensemble
des balises du langage. Cet espace de noms est préfixé par la valeur mx, ce qui est fort
apprécié lors de l’utilisation de plusieurs espaces de noms au sein d’un même fichier
MXML. En effet, le préfixe permet d’identifier l’espace de noms concerné et de faire appel
aux balises associées, évitant ainsi toute confusion possible. De ce fait, les balises du
langage MXML seront appelées comme suit :
<mx:Button></mx:Button>
Chaque balise MXML correspond à une classe ou à des propriétés de classes d’ActionScript. Lors de la phase de compilation du fichier applicatif principal, l’ensemble du
fichier MXML est analysé et transformé en classes ActionScript, ces dernières étant
compilées en code-octet (pour être exécutées par le Flash Player) et stockées dans un
fichier au format SWF. Vous l’aurez compris, tout ce qui est effectué à l’aide du langage
MXML pourrait être réalisé directement avec ActionScript.
Multiplicité des espaces de noms dans le framework Flex
Il est nécessaire de préfixer les espaces de noms afin d’éviter toute confusion quant à leur utilisation dans
le code. La question que l’on est en droit de se poser est l’utilité d’en déclarer plusieurs au sein d’une
même application Flex. Au chapitre 10, nous verrons que pour utiliser des composants personnalisés,
nous aurons recours à plusieurs espaces de noms, chacun étant associé à un composant.
17
=Flex3 FM.book Page 18 Mardi, 2. décembre 2008 3:32 15
18
Comprendre Flex 3
PARTIE I
Flex 4
Flex 4 n’est annoncé que pour la seconde partie de l’année 2009. Mais nous savons dores et déjà, que
l’utilisation du MXML y sera quelque peu différente. En effet, le FXG, nouveau langage dédié à la réalisation
du design des interfaces, laissera à MXML 2009 les fonctions que l’on pourrait qualifier de « fonctions
métiers », à savoir la gestion d’appel du service web, de validation de données, etc. Nous aurons l’occasion
de revenir sur ce point au chapitre 25.
Le langage ActionScript
L’ECMA (European Computer Manufacturers Association) est une organisation travaillant
dans le domaine de la standardisation informatique, notamment des langages de scripts
grâce au standard ECMAScript. Ce standard couvre, entre autres choses, les langages
ActionScript et JavaScript. C’est la raison pour laquelle leurs syntaxes se ressemblent en
bien des points.
ActionScript est donc un langage standardisé (via le standard ECMA-262) dont l’usage
est restreint aux applications Flash et donc à celles créées à l’aide du framework Flex. Ce
langage est orienté objet et permet le développement de la partie dynamique de l’application
ainsi que l’implémentation de la notion de modèle abordée précédemment.
Afin que vous puissiez lire facilement les extraits de code ActionScript présents dans cet
ouvrage, nous avons jugé bon de vous apporter les bases de ce langage en abordant des
notions communes à tout apprentissage d’un nouveau langage :
• les variables ;
• les boucles et les conditions ;
• les opérations booléennes ;
• les procédures et les fonctions ;
• la programmation objet.
Version d’ActionScript
Le framework Flex 3 utilise le langage ActionScript dans sa version 3.
Les variables
Les variables permettent de stocker des informations en vue de les utiliser dans divers
traitements.
Une variable est déclarée par un nom précédé de la mention var. Il est également indispensable de spécifier le type de la variable déclarée :
var nomVariable:type
=Flex3 FM.book Page 19 Mardi, 2. décembre 2008 3:32 15
À la découverte du framework Flex 3
CHAPITRE 2
Le tableau 2-1 présente des exemples de déclaration de variables.
Tableau 2-1
Déclaration de variables
Code
Description
var maChaine:String
Chaîne de caractères.
var monNombre:Number
Nombre décimal pouvant être positif ou négatif.
var monEntier:int
Nombre entier pouvant être positif ou négatif.
var monBooleen:Boolean
Booléen prenant pour valeur 0, 1, true ou false.
var monTableau:Array = new Array("1","2","3")
Tableau contenant trois éléments.
Les boucles et les conditions
Nous sommes souvent confrontés à la mise en place de boucles de traitement et à la vérification de conditions. Voyons comment les implémenter.
Les boucles
Le tableau 2-2 présente la transcription en langage ActionScript des principaux algorithmes
de boucles. Ils permettent de réaliser un traitement selon un nombre d’itérations prédéfinies.
Tableau 2-2
Les boucles
Algorithme
Transcription
Pour i est un entier = 1 à i<10 Faire
[Traitement]
I = i +1
Fin pour
For (i:int=1; i<10;i++) {
[Traitement]
}
I est un entier = 1
Tant que I<10 faire
I = i + 1
Fin tant que
i:int = 1;
while (i<10){
i++
}
Les conditions
Il existe deux types de conditions : la première consiste à vérifier si une situation est vraie,
la seconde à exécuter un traitement selon un cas précis. Le tableau 2-3 présente leur
implémentation.
Vous pourriez très bien utiliser une suite de if, else… if et else à la place d’un switch,
mais ce dernier vous apporte un plus non négligeable en matière de lisibilité du code.
19
=Flex3 FM.book Page 20 Mardi, 2. décembre 2008 3:32 15
20
Comprendre Flex 3
PARTIE I
Tableau 2-3
Les conditions
Algorithme
Transcription
X est un entier = 2
Si x est supérieur à 10 Alors
[Traitement]
Sinon
[Traitement]
Fin Si
var x:int =2
if (x>10) {
[Traitement]
} else {
[Traitement]
}
X est un entier = 10
Selon x
Cas 10 :
Cas 20 :
Fin selon
var x:int = 2
Switch (i) {
Case 10 :
[Traitement]
Break;
Case 20 :
[Traitment]
Break;
}
Pour pouvoir vérifier si une condition est vraie, nous avons besoin d’opérateurs de comparaison. Le tableau 2-4 en dresse la liste exhaustive :
Tableau 2-4
Les opérateurs
Expression
Description
X == Y
X est égal à Y.
X != Y
X est différent de Y.
X === Y
X est strictement égal à Y.
X !== Y
X est strictement différent de Y.
X > Y
X est supérieur à Y.
X < Y
X est inférieur à Y.
X >= Y
X est supérieur ou égal à Y.
X <= Y
X est inférieur ou égal à Y.
Les opérations booléennes
Comment déclencher un traitement lorsque deux conditions sont vraies ou lorsque l’une des
deux est vraie ? Le tableau 2-5 présente les opérateurs capables de réaliser ces opérations
de vérification.
=Flex3 FM.book Page 21 Mardi, 2. décembre 2008 3:32 15
À la découverte du framework Flex 3
CHAPITRE 2
Tableau 2-5
Les opérations booléennnes
Expression
Description
! X
X prend la valeur opposée. Ainsi, si X = vrai alors ! X = faux.
X && Y
X ET Y doivent être vérifiés (égaux à vrai) pour que le traitement puisse être effectué.
X || Y
X OU Y doit être vrai pour que le traitement soit effectué.
Les procédures et les fonctions
Les procédures et les fonctions sont déclarées par un nom, précédé de la mention function.
Elles ont pour rôle d’exécuter un traitement susceptible d’être appelé plusieurs fois dans
un script. Une fonction retourne un résultat dont le type est spécifié en fin de déclaration.
A contrario, une procédure ne retourne rien, nous spécifierons donc void à la place d’un
type de retour.
Portée des procédures et des fonctions
La portée des procédures et des fonctions doit obligatoirement être mentionnée :
• private (privée) : la procédure ou la fonction ne peut être appelée que par la classe qui la contient.
• protected (protégée) : la procédure ou la fonction ne peut être appelée que par la classe qui la contient
ou par la classe héritant de cette classe.
• public (publique) : la procédure ou la fonction peut être appelée par l’ensemble des procédures et
fonctions du projet.
• static (statique) : la procédure ou la fonction n’est créée qu’une seule fois par classe et non pas dans
chaque objet instancié par la classe. On peut donc l’appeler sans instancier l’objet dans lequel elle est
déclarée.
Notons que ces portées peuvent également être appliquées aux variables.
L’exemple de code suivant présente la déclaration d’une procédure dont la portée est
publique et qui accepte un paramètre de type chaîne.
public function enregistrerDonnees(donnees:string):void {
[Traitement d’enregistrement]
}
Par la mention :String, on identifie qu’il s’agit d’une fonction renvoyant une chaîne de
caractères. On constate également que la portée de la fonction est privée par la présence
du terme private.
private function afficherDonnee():String{
var laDonneeARenvoyer:String="info"
Return laDonneeARenvoyer
}
21
=Flex3 FM.book Page 22 Mardi, 2. décembre 2008 3:32 15
22
Comprendre Flex 3
PARTIE I
La programmation objet
Décrire l’ensemble des fonctionnalités d’ActionScript en termes de programmation objet
prendrait une place trop importante au sein de cet ouvrage et n’y apporterait pas de réelle
valeur. C’est par l’analyse de quelques lignes de code que nous vous proposons de découvrir
comment implémenter une classe et ses méthodes.
Package com.monpackage
{
import mx.containers.Canvas;
public class MaClasse extends Canvas
{
// Attribut
private var _nom:String
// Constructeur de la classe
public function MaClasse(parametre:String)
{
super();
_nom = parametre;
}
// Setter et Getter de l’attribut
public function set nom(parametre:String):void{
_nom = parametre
}
public function get nom():String{
return _nom;
}
}
}
Analysons à présent ce code. La première ligne sert à définir le package dans lequel se
situe la classe.
La notion de package
Le fait de séparer votre code en différents packages vous permettra par la suite de pouvoir le relire ou le
modifier facilement. Il s’agit ni plus ni moins de le structurer en dossiers et sous-dossiers.
Vient ensuite l’importation des classes nécessaires aux traitements décrits dans les
méthodes ou à la notion d’héritage. En effet, le compilateur ne connaissant pas votre
code, il vous faut lui indiquer explicitement quelles classes seront utilisées.
On constate qu’une classe est déclarée par la mention class suivie du nom attribué à cette
classe. La notion d’héritage est ici implémentée à l’aide du mot-clé extends. Dans notre
cas, la classe MaClasse hérite de la classe Canvas.
=Flex3 FM.book Page 23 Mardi, 2. décembre 2008 3:32 15
À la découverte du framework Flex 3
CHAPITRE 2
Les attributs sont ensuite déclarés à la manière d’une variable dont le nom est précédé du
caractère de soulignement (_). Il est ainsi possible d’écrire les méthodes d’accès à cet
attribut comme suit : set nomattribut() et get nomattribut():type.
La méthode set a pour fonction d’affecter une valeur à un attribut, laquelle peut ensuite être
récupérée par l’emploi de la méthode get.
Enfin, pour créer des objets à partir d’une classe, il est nécessaire d’instancier cette
dernière. Pour cela, nous disposons d’un constructeur. Il s’agit d’une méthode portant le
nom de la classe et qui sera automatiquement appelée au moment de l’instanciation de
l’objet. À noter que le type de retour n’est pas précisé pour un constructeur.
Nous venons de décrire les éléments de bases du langage ActionScript dont vous aurez
besoin pour comprendre au mieux les différents extraits de code présentés dans cet
ouvrage. Néanmoins, les subtilités de ce langage n’ayant pas été abordées, nous ne
saurions que trop vous recommander l’acquisition d’un ouvrage spécialisé ou la pratique
d’ActionScript. Nous vous conseillons également de consulter les sites web spécialisés
tels que le site ActionScript.org (http://www.actionscript.org/), qui constitue une mine
d’informations sur ce langage et propose des cours et tutoriaux en téléchargement.
Intéressons nous à présent au mécanisme client/serveur d’une application Flex.
Le mécanisme client/serveur
Comme nous l’avons vu, une application Flex est composée d’un fichier MXML principal
faisant appel à des fichiers ActionScript permettant d’intégrer la notion d’architecture
MVC. L’ensemble de ces fichiers est ensuite compilé, donnant naissance à un fichier
SWF pouvant être intégré dans une page HTML. Ceci n’est qu’une petite partie du
processus. Nous allons à présent rassembler l’ensemble des informations véhiculées tout
au long de ce chapitre afin d’observer le mécanisme complet d’une application Flex.
Tout d’abord, nous avons vu qu’il est possible d’architecturer une application en trois
couches distinctes, chacune d’entre elles pouvant être hébergée (sous sa forme extrême)
sur trois serveurs différents :
• le serveur de base de données (couche Accès aux données) ;
• le serveur d’application (couche Métier) ;
• le serveur Flex (couche Présentation contenant le fichier SWF et la page web associée).
Imaginons à présent un utilisateur souhaitant utiliser l’application Flex située à l’adresse
http://www.monapplicationflex.com et pointant bien évidemment sur le serveur de présentation qui sera le point d’entrée du processus (figure 2-6).
La première phase va consister à offrir l’application au client connecté (figure 2-6, ➊ et
➋). Nous entendons par « offrir » le fait que l’application sera téléchargée et exécutée sur
le poste client, ce qui nécessite par conséquent que Flash Player soit installé sur celui-ci.
23
=Flex3 FM.book Page 24 Mardi, 2. décembre 2008 3:32 15
24
Comprendre Flex 3
PARTIE I
Attention
Le fait qu’une application soit exécutée sur le poste client induit un paramétrage consciencieux de cette
dernière. Lors du développement de l’application, nous devons faire appel aux services situés sur des
serveurs présents sur notre réseau local. Lorsque l’application est mise en ligne, n’oubliez pas que ces
serveurs ne sont plus accessibles via l’adresse IP locale mais à l’aide de leur adresse publique ! Les schémas
des figures 2-3, 2-4 et 2-5 illustrent ce principe.
Figure 2-3
Accès aux
services dans
un environnement
de développement
Sur ce schéma, nous pouvons accéder facilement aux services présents sur le serveur puisqu’il fait partie
de notre réseau local.
Figure 2-4
Paramétrage
incorrecte
de l’application :
recherche des
services sur le réseau
local du client
Si le changement d’adresse IP du serveur contenant les services n’est pas effectué lors du déploiement,
ces derniers ne seront plus accessibles par le poste client.
Figure 2-5
Paramétrage correcte
de l’application :
recherche
des services via
l’adresse IP Wan
du serveur
Pour résoudre ce problème, nous vous conseillons de définir l’ensemble des paramétrages dans un fichier
XML qui sera lu lors de l’initialisation de l’application sur le poste client. L’usage de ce type de fichier exclut
de ce fait une recompilation de l’application pour chaque modification de paramétrage.
=Flex3 FM.book Page 25 Mardi, 2. décembre 2008 3:32 15
À la découverte du framework Flex 3
CHAPITRE 2
L’application présente sur le serveur permettant de lister les produits d’un magasin, la
deuxième étape va consister à faire appel à une suite de services permettant d’obtenir le
résultat attendu (ici, la liste des produits).
Lorsque l’utilisateur cliquera sur le bouton Mise à jour situé sur l’interface graphique,
cela déclenchera un événement qui sera transmis au contrôleur (figure 2-6, ➌), lequel ira
chercher le modèle concerné par cet événement (➍).
Le modèle va ensuite faire appel au service approprié situé sur le serveur d’application (➎).
Ce service va alors exécuter une requête sur le serveur de base de données (➏), s’en
suivra une succession de réponses de la part des différents serveurs concernés (➐ et ➑).
La dernière étape consistera ensuite à mettre à jour la couche de présentation via l’interaction du modèle avec le contrôleur (➒ et ➓).
Figure 2-6
Mécanisme client/serveur
En résumé
Dans ce chapitre, nous avons voulu poser les premières pierres de l’édifice en vous
apportant les connaissances de base sur le rôle et l’utilisation du framework Flex. Les
points essentiels à retenir sont les suivants :
• Flex ne concerne que la partie graphique d’une application (front end).
• Une application Flex est composée de fichiers aux formats MXML et ActionScript. Le
langage MXML sert au développement de l’interface graphique et chacune de ses
balises correspond à une classe ou une propriété du langage ActionScript. Tout ce qui
est réalisé à l’aide du langage MXML peut également l’être réalisé à l’aide d’ActionScript.
25
=Flex3 FM.book Page 26 Mardi, 2. décembre 2008 3:32 15
26
Comprendre Flex 3
PARTIE I
• La partie graphique peut être implémentée selon l’architecture MVC, largement répandue
dans la plupart des grosses applications et ce, à l’aide de la combinaison des langages
ActionScript (modèle et contrôleur) et MXML (vues). Flex ne peut interagir directement
avec une source de données, mais uniquement en faisant appel à des services externes
ayant cette capacité.
• Une application Flex est téléchargée et exécutée sur le poste client, ce qui nécessite un
paramétrage assidu de l’application lorsque celle-ci fait appel à des services.
Ce chapitre nous a permis de délimiter le périmètre d’action du framework Flex. À ce
stade, vous pouvez légitimement vous interroger sur l’utilité de développer vos interfaces
en Flex alors que le langage HTML sait très bien le faire. À cette interrogation, nous
pouvons répondre que Flex étant basé sur la technologie Flash, dont la réputation en
termes d’animation n’est plus à faire, la richesse des IHM en termes de design et de fonctionnalité s’en trouve accrue, ce qui augmente le pouvoir de séduction de vos applications
et par conséquent leur rentabilité ! Il ne nous reste plus qu’à nous mettre au travail et à
poursuivre par l’étude du SDK du framework Flex.
=Flex3 FM.book Page 27 Mardi, 2. décembre 2008 3:32 15
3
Développer
avec le kit Flex SDK
Un peu à la manière de Java et son SDK (Software Development Kit), le kit de développement Flex SDK offre un ensemble de fonctionnalités permettant de réaliser gratuitement des applications à l’aide du framework Flex. Ce kit comprend des compilateurs, un
débogueur ainsi que les bibliothèques de composants du framework permettant de créer
des applications.
Depuis la version 3 de Flex, la volonté d’Adobe est de rendre le SDK disponible sous
licence MPL (Mozilla Public License). Selon l’éditeur, le passage à l’Open Source permettra
une augmentation de l’utilisation de son produit. En effet, le SDK pourra être intégré au
sein de divers IDE (Integrated Development Environment) et les entreprises à philosophie
Open Source pourront opter pour l’utilisation de Flex. Enfin, comme chacun le sait, les
produits libres sont souvent supportés par une communauté active, ce qui permet de
les faire évoluer et d’offrir un support très réactif. Ceci assure ainsi à Flex une place
prédominante par rapport à ses concurrents, notamment le géant Microsoft et son produit
SilverLight, dont le choix stratégique viserait à imiter Adobe.
Licence MPL
Contrairement à la licence GPL (General Public License), qui oblige à fournir les sources de l’ensemble
d’un programme, la MPL permet de ne pas divulguer certaines parties du programme. Ainsi, l’entreprise
éditrice peut ne communiquer que certaines parties du code de son logiciel et garder secrètes les parties
qu’elle juge sensibles.
=Flex3 FM.book Page 28 Mardi, 2. décembre 2008 3:32 15
28
Comprendre Flex 3
PARTIE I
Prérequis
Avant d’aller plus loin, il convient de vérifier la présence des éléments indispensables au
bon fonctionnement du SDK.
Du point de vue matériel, vous devez disposer au minimum de 512 Mo de RAM et de
200 Mo d’espace disque.
Pour l’aspect logiciel, il est impératif que Java soit installé et correctement configuré sur
votre machine, bien que le Runtime de Java (JRE, Java Runtime Environment) suffise pour
exécuter Flex SDK.
JRE et JDK (Java Developpement Kit)
Il peut être intéressant d’installer le Java Developpement Kit (JDK) si vous souhaitez par la suite développer
vos propres applications Java. Sur ce point, nous verrons au chapitre 14 que Flex est capable d’interagir
avec les applications développées dans ce langage. De plus, vous en aurez besoin pour mener à bien les
exemples mentionnés dans ce chapitre. Étant donné que le JRE est contenu dans le JDK, pourquoi s’en
priver ?
Dans cet ouvrage, nous utiliserons la version 6 du JDK (Java SE6), qui peut être téléchargée
sur le site web de Sun Microsystems à l’adresse suivante : http://java.sun.com/ (rubrique
Downloads>Java SE). Une fois l’archive téléchargée, procédez à son installation en suivant
les indications de l’assistant.
Vous pouvez éventuellement configurer la variable d’environnement PATH de votre
système en y ajoutant le chemin du répertoire bin de Java. Ceci vous permettra d’appeler
les programmes Java (java.exe, javac.exe, etc.) à partir de n’importe quel répertoire de
votre système.
Important
Les instructions d’installation de logiciel ou de configuration d’environnement présentées dans cet ouvrage
sont essentiellement orientées vers le système d’exploitation Windows, car il s’agit de l’environnement le
plus utilisé.
Voici la marche à suivre pour modifier la variable PATH :
1. Cliquez sur Démarrer et sélectionnez Panneau de configuration>Système.
2. Dans la fenêtre qui apparaît alors à l’écran, cliquez sur l’onglet Avancé puis sur le
bouton Variables d’environnement.
3. Dans la zone Variables système, sélectionnez la variable PATH et cliquez sur le bouton
Modifier.
4. À la suite des valeurs déjà présentes, ajoutez le chemin du répertoire bin de Java (par
défaut, C:\Program Files\Java\jdk1.6.0_<version>\bin) précédé d’un point-virgule.
5. Validez la saisie et fermer l’ensemble des fenêtres précédemment ouvertes.
=Flex3 FM.book Page 29 Mardi, 2. décembre 2008 3:32 15
Développer avec le kit Flex SDK
CHAPITRE 3
L’installation du JDK de Java est à présent terminée. Pour vérifier la bonne configuration
de votre système, ouvrez l’invite de commandes MS-DOS et saisissez l’instruction
suivante :
java –version
Le résultat obtenu doit être semblable à celui de la figure 3-1.
Figure 3-1
Vérification de la bonne configuration de Java
Vous aurez également besoin du Flash Player 9 d’Adobe, grâce auquel vous pourrez
exécuter les applications Flex. Son installation s’effectue en ligne à partir du site web
d’Adobe : http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=Shockwave
Flash.
Vous disposez à présent de tous les outils nécessaires pour utiliser le kit Flex SDK
correctement. Passons maintenant à son installation.
Mise en garde quant au choix du Flash Player
Comme nous l’avons vu au chapitre précédent, la version actuelle du Flash Player est la version 10.
Cependant, il se peut que vous possédiez encore la version 9. Mettre à jour le Flash Player alors que vous
avez déjà installé l’environnement de développement peut engendrer des disfonctionnements du Flex
Builder, notamment pour la fonctionnalité de débogage. Afin de réaliser l’ensemble des cas pratiques de
cet ouvrage dans les meilleurs conditions, nous vous conseillons de choisir l’une ou l’autre version et de
ne pas procéder encore à la mise à jour. Si pour une raison ou une autre, votre Flash Player est mis à jour
pour la version 10, reportez-vous au chapitre 25, où nous expliquerons comment adapter votre projet à la
version 10. Enfin, nous attirons votre attention sur le fait que la version 10 du Flash Player étant récente,
nous n’avons pas pu tester dessus l’ensemble des fonctionnalités de Flex 3. Par prudence, nous vous
conseillons d’installer la version 9 (http://www.adobe.com/support/flashplayer/downloads.html),
dans le cas où vous auriez déjà effectué la mise à jour de votre système.
Installation du kit Flex SDK
Pour commencer, téléchargez le kit Flex SDK sur le site d’Adobe à l’adresse suivante :
http://www.adobe.com/products/flex/flexdownloads/.
Une fois le téléchargement terminé, décompressez l’archive obtenue dans un répertoire
de votre choix. Nous avons ici choisi le répertoire C:\flex_sdk que nous nommerons
29
=Flex3 FM.book Page 30 Mardi, 2. décembre 2008 3:32 15
30
Comprendre Flex 3
PARTIE I
root_flexsdk par convention. Le répertoire root_flexsdk contient désormais les dossiers
présentés et décrits dans le tableau 3-1.
Tableau 3-1
Les différents dossiers du répertoire root_flexsdk
Nom du dossier
Description
ant
Contient un ensemble de tâches Ant permettant d’automatiser certaines opérations lors des
phases de compilation et de déploiement.
asdoc
Contient l’ensemble de la documentation de l’outil ASDoc permettant de créer la documentation de votre application sous forme de pages HTML.
bin
Contient un ensemble d’exécutables, tels que mxmlc.exe, compc.exe (voir sections suivantes)
ou encore asdoc.exe.
frameworks
Contient l’ensemble des classes, des fichiers de configuration et du code source du framework.
lib
Contient l’ensemble des bibliothèques Java du framework.
runtimes
Contient les exécutables permettant d’installer l’environnement Adobe AIR et le module de
débogage de Flash Player 10.
samples
Contient des exemples d’applications.
templates
Contient des templates de pages HTML contenant l’application Flex. Ceux-ci contiennent
notamment la fonctionnalité de détection du Flash Player. Ainsi, si vous utilisez un template
proposant cette fonctionnalité et que l’utilisateur ne possède pas le Flash Player, son téléchargement sera automatiquement proposé.
L’installation est à présent terminée et le Flex SDK est opérationnel. Voyons à présent le
cœur du SDK, dont les compilateurs sont les principaux éléments.
Les compilateurs
Comme nous l’avons vu au chapitre précédent, une application Flex est composée de
fichiers MXML et ActionScript. Ces fichiers sont ensuite compilés, donnant naissance à
un fichier SWF. Flex distingue deux types de compilations qui dépendent chacune d’un
compilateur spécifique : la compilation d’application et la compilation de composants.
mxmlc : le compilateur d’application
Le rôle principal du compilateur mxmlc est de créer un fichier de type SWF (Shockwave
Flash) à partir des fichiers ActionScript et MXML d’une application Flex (figure 3-2).
Ce compilateur s’exécute en ligne de commande à l’aide de l’exécutable mxmlc.exe situé
dans le dossier bin du répertoire root_flexsdk.
=Flex3 FM.book Page 31 Mardi, 2. décembre 2008 3:32 15
Développer avec le kit Flex SDK
CHAPITRE 3
Figure 3-2
Mécanisme de compilation mxmlc
La syntaxe générale d’exécution de la compilation est la suivante :
mxmlc options fichier
où mxmlc fait appel au compilateur mxmlc.exe, options spécifie les options de compilation
(date de création, nom du fichier SWF généré…) et fichier indique le fichier MXML à
compiler.
Le fichier MXML principal de l’application est spécifié en omettant les fichiers ActionScript associés à celle-ci. Cependant, les fichiers ActionScript liés à l’application ne sont
pas oubliés lors de la compilation grâce aux liens spécifiés dans le fichier MXML principal.
Il est également important de noter que ce compilateur ne génère pas la page HTML
chargée de contenir le SWF créé. Elle devra être créée manuellement.
compc : le compilateur de composants
Flex offre la possibilité de créer des composants afin de les réutiliser dans plusieurs
applications différentes. Un composant peut être assimilé à une application Flex dans la
mesure où il est également composé d’un fichier MXML et de fichiers ActionScript.
La compilation de ces composants est réalisée à l’aide du compilateur compc dont la
syntaxe est décrite par l’exemple suivant :
compc -o composant.swc -root fichierMXML.mxml
où l’option –o permet de spécifier le nom du composant compilé et l’option –root indique
le nom du fichier MXML utilisé pour la compilation du composant. Cette simple ligne de
code permet de générer un composant (composant.swc) à partir d’un fichier MXML.
31
=Flex3 FM.book Page 32 Mardi, 2. décembre 2008 3:32 15
32
Comprendre Flex 3
PARTIE I
Le fonctionnement du compilateur compc est identique à celui du compilateur mxmlc à
la seule différence qu’il génère un fichier de type SWC (Shockwave Component) et non
SWF (figure 3-3).
Figure 3-3
Mécanisme de compilation compc
Si nous récapitulons, voici ce que nous avons appris jusqu’à présent :
• Comment configurer un environnement pour exécuter le kit de développement Flex
SDK et les applications Flex.
• Comment installer le kit Flex SDK.
• Quelques connaissances de base sur les différents compilateurs.
Cela peut paraître léger, mais nous allons voir qu’avec ces trois éléments seulement, nous
sommes en mesure de créer notre première application Flex.
Première application Flex
Nous vous proposons ici de développer le fameux programme cher à tout informaticien
et informaticienne, à savoir l’incontournable Hello World ! dont le but est d’afficher un
message de bienvenue à l’écran.
Conception graphique
Nombreux sont les projets prenant naissance à partir d’un dessin griffonné sur un coin de
table. Notre projet n’a pas échappé à cette règle comme l’illustre la figure 3-4.
=Flex3 FM.book Page 33 Mardi, 2. décembre 2008 3:32 15
Développer avec le kit Flex SDK
CHAPITRE 3
Figure 3-4
Conception graphique
Le principe de cette application est simple : un composant, nommé Panel contient un
bouton qui, lorsqu’on clique dessus, affiche le message « Hello World ! ».
Création du projet
Au cours du chapitre précédent, nous avons abordé la notion d’arborescence des projets
Flex et nous avons vu que tout projet doit posséder un répertoire racine contenant un
sous-répertoire src dans lequel seront enregistrées les sources de l’application.
Le kit Flex SDK propose différents exemples d’applications situés dans le dossier
samples. C’est dans ce dossier que nous allons placer la racine de notre projet, que l’on
nommera HelloWorld. Dans la mesure où il s’agit du fichier racine de l’application, ce
répertoire contiendra un sous-répertoire nommé src (figure 3-5).
Figure 3-5
Arborescence du projet
Écriture du fichier MXML
Tout projet Flex comporte un fichier portant l’extension .mxml servant de base à l’application
et permettant, entre autres choses, la description des interfaces graphiques.
Mais il ne suffit pas de créer des composants, il faut également définir leurs caractéristiques (nom, hauteur, largeur...) et leur positionnement. Les tableaux 3-2 et 3-3 présentent
les différentes caractéristiques des composants Panel et Button que nous allons créer.
33
=Flex3 FM.book Page 34 Mardi, 2. décembre 2008 3:32 15
34
Comprendre Flex 3
PARTIE I
Tableau 3-2
Les différentes caractéristiques du composant Panel
Caractéristique
Description
Rôle
Conteneur principal de l’application
Nom
pn_principal
Titre (title)
Hello World !
Largeur (width)
270 pixels
Hauteur (height)
150 pixels
Position sur l’axe des X
10 pixels
Position sur l’axe des Y
10 pixels
Disposition (layout)
absolute (permet le positionnement des composants à l’aide de leurs coordonnées x et y).
Tableau 3-3
Les différentes caractéristiques du composant Button
Caractéristique
Description
Rôle
Bouton déclenchant l’affichage du message.
Nom
btn_message
Label
Hello !!
Largeur (width)
120 pixels
horizontalCenter
0 (centre le bouton à l’intérieur du panel sur l’axe horizontal de celui-ci).
verticalCenter
0 (centre le bouton à l’intérieur du panel sur l’axe vertical de celui-ci).
Figure 3-6
Mise en place des composants
=Flex3 FM.book Page 35 Mardi, 2. décembre 2008 3:32 15
Développer avec le kit Flex SDK
CHAPITRE 3
Nous allons à présent nous placer dans le répertoire src et créer un nouveau fichier
nommé HelloWorld.mxml, dans lequel nous saisirons le code suivant à l’aide du Bloc-notes
de Windows :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<!-- Ajout du panneau -->
<mx:Panel id="panneau" x="10" y="10" width="270" height="150" layout="absolute"
➥title="Hello World !!">
<!-- Ajout du bouton -->
<mx:Button id="bouton_action" label="Hello !!" width="120" horizontalCenter="0"
➥verticalCenter="0"/>
</mx:Panel>
</mx:Application>
Les caractéristiques décrites aux tableaux 3-2 et 3-3 sont bien spécifiées pour chacun des
composants. Notre interface graphique est à présent terminée. Passons maintenant à la
partie ActionScript qui permettra d’afficher le message « Hello World !! ».
Écriture du fichier ActionScript
Tout d’abord, créez un nouveau fichier nommé HelloActionScript.as dans le répertoire
src de l’application qui va contenir la procédure permettant d’afficher le message. Saisissez
ensuite le code suivant dans ce fichier :
import mx.controls.Alert;
public function afficherMessage():void
{
Alert.show("Hello World !!");
}
Nous importons tout d’abord la bibliothèque nécessaire à l’utilisation de la classe Alert.
Vient ensuite la création de la procédure afficherMessage() de type void étant donné
qu’aucune valeur de retour n’est attendue. Cette procédure fait appel à la méthode show
de la classe Alert dont l’analyse syntaxique du code suffit à sa compréhension.
Liaison graphique et action
Nous possédons à présent un fichier MXML servant à la description de l’interface
graphique et un fichier ActionScript permettant d’afficher le message « Hello World !! ».
L’étape suivante va consister à créer la liaison entre ces deux fichiers et à définir l’action
qui fera appel à la fonction afficherMessage(). Cette liaison s’effectue dans le fichier
MXML à l’aide de la balise <mx:Script> pour laquelle il suffit de spécifier la source du
script à utiliser, c’est-à-dire le chemin relatif du fichier ActionScript :
<mx:Script source="HelloActionScript.as"></mx:Script>
35
=Flex3 FM.book Page 36 Mardi, 2. décembre 2008 3:32 15
36
Comprendre Flex 3
PARTIE I
Lors de la phase de conception graphique, nous avons décidé que le message doit s’afficher
lorsque l’utilisateur clique sur l’unique bouton de l’interface. Cela se fera via la définition
de l’action sur click du bouton faisant appel à la fonction afficherMessage().
<mx:Button id="bouton_action" label="Hello !!" width="120" horizontalCenter="0"
➥verticalCenter="0"
click="afficherMessage()"/>
Pour plus de clarté, voici le script complet du fichier HelloWorld.mxml :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script source="HelloActionScript.as"></mx:Script>
<mx:Panel id="panneau" x="10" y="10" width="270" height="150" layout="absolute"
➥title="Hello World !!">
<mx:Button id="bouton_action" label="Hello !!" width="120" horizontalCenter="0"
➥verticalCenter="0" click="afficherMessage()"/>
</mx:Panel>
</mx:Application>
Compilation
Il nous faut à présent compiler notre application, ce qui aura pour effet de créer un fichier
SWF pouvant être inséré dans une page HTML et diffusé sur Internet.
Pour cela, ouvrez, l’invite de commandes MSDOS et placez-vous dans le répertoire
root_flexsdk\bin avec la commande cd root_flexsdk\bin. Étant donné qu’il s’agit d’une
application, il convient d’utiliser le compilateur mxmlc. Voici donc la commande à saisir
pour générer le fichier SWF de notre application :
mxmlc ../samples/HelloWorld/src/Helloworld.mxml
Placez-vous ensuite dans le répertoire src du projet, vous devriez à présent y trouver le
fichier HelloWorld.swf issu de la compilation.
Que s’est-il passé ? Le compilateur mxmlc a analysé le fichier .mxml de l’application et a
constaté qu’il possédait un lien vers un fichier ActionScript. Il a donc pris en compte ce
fichier et a transformé le fichier MXML en un ensemble de classes ActionScript pour
ensuite les intégrer dans un fichier de type SWF.
À ce stade, nous pouvons déjà tester notre application à l’aide du Flash Player. En
cliquant sur le bouton, vous devriez en effet voir apparaître le message « Hello World !! »
(figures 3-7 et 3-8).
=Flex3 FM.book Page 37 Mardi, 2. décembre 2008 3:32 15
Développer avec le kit Flex SDK
CHAPITRE 3
Figure 3-7
Exécution de l’application dans le Flash Player 9
Figure 3-8
Affichage du message « Hello World !! »
37
=Flex3 FM.book Page 38 Mardi, 2. décembre 2008 3:32 15
38
Comprendre Flex 3
PARTIE I
Nous disposons maintenant d’un fichier SWF complet et autonome. Nous entendons par
là que ce fichier n’a pas besoin des fichiers sources (MXML et ActionScript) pour son
exécution car ceux-ci ont été compilés et intégrés au fichier SWF. L’étape suivante va
consister à intégrer ce fichier dans une page web afin de diffuser notre application sur
Internet.
Intégration dans une page web
Pour intégrer notre application dans une page web, que nous nommerons index.html,
nous allons utiliser le langage HTML et ses balises <object> qui nous permettront de faire
référence au fichier SWF.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/1998/
➥REC-html40-19980424/strict.dtd">
<html>
<head>
<title>Hello World !</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>
<object type="application/x-shockwave-flash" data="HelloWorld.swf"
➥width="100%" height="100%">
<param name="movie" value="HelloWorld.swf">
</object>
</p>
</body>
</html>
Cette insertion est des plus simples. Notez l’utilisation des propriétés width et height
permettant de spécifier la taille de l’objet SWF par rapport à celle de la page HTML.
Dans notre cas, l’application prendra la taille de la page HTML affichée dans le navigateur
(figure 3-9).
Nous verrons dans la section « Création d’un script de compilation » qu’il est possible de
définir plusieurs options pour l’inclusion du fichier SWF, notamment la détection de la
présence du Flash Player sur le poste client, nécessaire à l’exécution de l’application
(cette fonctionnalité n’est pas implémentée ici).
=Flex3 FM.book Page 39 Mardi, 2. décembre 2008 3:32 15
Développer avec le kit Flex SDK
CHAPITRE 3
Figure 3-9
Application insérée dans une page HTML
Déploiement
Si vous possédez un serveur web, il vous suffit de placer les fichiers HelloWorld.swf et
index.html dans l’un de ses répertoires, cela terminant par ailleurs la phase de déploiement.
Libre à vous ensuite de communiquer l’URL de votre application à l’ensemble de vos
contacts. Dans la mesure où celle-ci ne permet pas de détecter la présence du Flash
Player sur le poste client, n’oubliez pas de mentionner qu’il est nécessaire et doit être
installé pour pouvoir exécuter votre application.
Automatisation de la compilation à l’aide de Ant
Nous verrons au chapitre suivant que l’utilisation de Flex Builder facilite grandement le
déploiement d’une application Flex. Néanmoins, en fonction de votre budget, vous préférerez peut-être le kit Flex SDK. Vous devrez alors procéder à une compilation manuelle,
mais cette tâche est particulièrement fastidieuse (notamment lors des phases de test).
Nous vous proposons donc de voir comment automatiser les tâches de compilation à
l’aide de Ant, outil développé par la Apache Software Foundation et communément
utilisé dans le déploiement des applications Java.
39
=Flex3 FM.book Page 40 Mardi, 2. décembre 2008 3:32 15
40
Comprendre Flex 3
PARTIE I
Ant
Projet de la Apache Software Foundation, Ant, signifie Another Neat Tool. Il est écrit en Java et a été développé par James Duncan Davidson en 2000. Ant permet d’automatiser la compilation et le déploiement
des projets. Il repose sur l’exécution de scripts de « build » au format XML comportant un projet et un
ensemble de tâches, organisées ou non, qui y sont liées.
Ant et Flex
Lors de l’analyse du répertoire principal de Flex, nous avons noté la présence d’un
dossier nommé ant. Ce répertoire contient la bibliothèque nécessaire à Ant pour pouvoir
compiler et déployer des projets Flex. Cette bibliothèque est nommée flexTasks.jar et se
trouve dans le répertoire lib du dossier ant. Elle contient trois tâches Ant qui permettent
d’utiliser :
• le compilateur mxmlc ;
• le compilateur compc ;
• la tâche html-wrapper permettant de générer la page HTML intégrant le fichier .swf
créé lors de la compilation.
Voyons comment utiliser le couple Ant/flexTasks pour automatiser la compilation et le
déploiement d’une application Flex.
Installation de Ant
Commencez par télécharger Ant à partir de l’adresse suivante : http://ant.apache.org.
Décompressez ensuite l’archive obtenue dans le répertoire de votre choix et configurez
votre système d’exploitation comme suit :
1. Créez une variable d’environnement nommée ANT_HOME pointant sur le répertoire ant
(par exemple, c:\ant).
2. Modifiez la variable PATH en ajoutant le chemin du répertoire bin comme suit :
%ANT_HOME%\bin
3. Ouvrez ensuite l’invite de commandes MS-DOS et tapez la commande ant. Si l’environnement est correctement configuré, vous devriez voir apparaître ceci :
Buildfile: build.mxml does not exist !
BuildFailed
Passons maintenant aux choses sérieuses !
Création d’un script de compilation
Avant tout, récapitulons : nous disposons d’un fichier MXML nommé HelloWorld.mxl situé
dans le répertoire root_flexsdk\samples\HelloWorld\src, ainsi que d’un fichier ActionScript
=Flex3 FM.book Page 41 Mardi, 2. décembre 2008 3:32 15
Développer avec le kit Flex SDK
CHAPITRE 3
nommé HelloActionScript.as. Notre objectif est de compiler et d’intégrer automatiquement
le fichier SWF issu de la compilation dans une page HTML. Voyons comment procéder.
Nous avons choisi de placer les scripts de compilation Ant dans le répertoire root_flexsdk
\ant. Comme nous l’avons vu, un script de compilation est un fichier XML contenant une
suite de tâches. La première étape va donc consister à créer ce fichier XML, que l’on
nommera HelloWorld.xml. Nous devrons ensuite spécifier le projet Ant en lui affectant un
nom.
<?xml version="1.0" encoding="utf-8"?>
<project name="Compilateur HelloWorld">
</project>
Une fois cela fait, nous devrons préciser le chemin du fichier flexTasks.jar. Si vous avez
choisi de placer le fichier de compilation dans le répertoire ant du Flex SDK, le fichier
attendu se situe dans le répertoire suivant root_flexsdk\ant\lib :
<taskdef resource="flexTasks.tasks" classpath="c:/root_flexsdk/ant/lib/flexTasks.jar" />
Vous devrez ensuite paramétrer les variables qui seront utilisées lors de la compilation :
• FLEX_HOME : répertoire d’installation du kit Flex SDK (root_flexsdk) ;
• APPLICATION_HOME : répertoire du fichier à compiler (root_flexsdk/samples/HelloWorld/
src).
<property name="FLEX_HOME" value="c:/root_flexsdk"/>
<property name="APPLICATION_HOME" value="c:/root_flexsdk/samples/HelloWorld/src"/>
Vient ensuite la spécification de la tâche à réaliser. Une tâche (<target>) est définie par un
nom qui sera invoqué lors de l’utilisation de Ant.
<target name="compilation">
</target>
Chaque tâche doit comporter un certain nombre d’instructions. La première que nous
allons écrire est l’action de création du fichier SWF. Comme nous l’avons vu précédemment, pour compiler un fichier ActionScript ou MXML relatif à une application, nous
devons utiliser le compilateur mxmlc :
<echo message=">> Génération du fichier SWF" />
<mxmlc file="${APPLICATION_HOME}/HelloWorld.mxml"></mxmlc>
Ce script a pour résultat d’afficher un message « Génération du fichier SWF » et de réaliser
la compilation de l’application en prenant les fichiers MXML et ActionScript situés dans
le répertoire source spécifié dans la variable ${APPLICATION_HOME}.
41
=Flex3 FM.book Page 42 Mardi, 2. décembre 2008 3:32 15
42
Comprendre Flex 3
PARTIE I
Avant d’aller plus loin, testons notre script. Vérifiez d’abord que son contenu est indique
à cela :
<?xml version="1.0" encoding="utf-8"?>
<project name="My App Builder">
<taskdef resource="flexTasks.tasks" classpath="c:/root_flexsdk/ant/lib/flexTasks
➥.jar" />
<property name="FLEX_HOME" value="c:/root_flexsdk"/>
<property name="APPLICATION_HOME" value="c:/root_flexsdk/samples/HelloWorld/src"/>
<target name="compilation">
<echo message=">> Génération du fichier SWF" />
<mxmlc file="${APPLICATION_HOME}/HelloWorld.mxml"></mxmlc>
</target>
</project>
Ensuite, ouvrez l’invite de commandes MS-DOS et placez-vous dans le répertoire contenant le fichier de build que nous venons de créer :
cd c:\root_flexsdk\ant
Pour exécuter le script, saisissez la commande suivante, faisant appel à la tâche de
compilation :
ant -buildfile HelloWorld.xml compilation
Si tout s’est correctement déroulé lors de la compilation, le fichier SWF est créé dans le
répertoire de l’application Flex, root_flexsdk/samples/HelloWorld/src.
Passons maintenant à l’instruction qui permet de générer le fichier HTML contenant le
fichier SWF. Cette action est possible grâce à la tâche html-wrapper qui fournit plusieurs
templates de génération. Le tableau 3-4 présente les différents arguments de la tâche
html-wrapper.
Tableau 3-4
Les arguments de la tâche html-wrapper
Arguments
Description
application
Nom de l’application SWF.
bgcolor
Couleur d’arrière-plan de la page HTML (blanc par défaut).
height
Hauteur de l’application SWF (400 pixels par défaut).
width
Largeur de l’application SWF (400 pixels par défaut).
output
Chemin de génération de la page HTML.
swf
Nom du fichier SWF à inclure (ne pas spécifier l’extension .swf du fichier).
=Flex3 FM.book Page 43 Mardi, 2. décembre 2008 3:32 15
Développer avec le kit Flex SDK
CHAPITRE 3
Tableau 3-4
Les arguments de la tâche html-wrapper (suite)
Arguments
Description
template
Trois types de templates sont disponibles :
• client-side-detection : détecte la version du Flash Player installée sur le poste
client et propose son téléchargement le cas échéant.
• express-installation : détecte si Flash Player est présent et propose son installation
en mode Express s’il n’est pas installé.
• no-player-detection : ne vérifie pas la présence du Flash Player.
history
Permet d’utiliser la fonction de DeepLinking, c’est-à-dire la navigation à l’aide des boutons Précédent et Suivant du navigateur ( false par défaut).
title
Titre de la page HTML ( Flex application par défaut).
version-major
Indique la version majeure du Flash Player à utiliser (version 9 par défaut). Cet argument
n’a de sens que si le type de template spécifié est client-side-detection ou
express-installation.
version-minor
Indique la version mineure du Flash Player à utiliser (version 0 par défaut). Cet argument
n’a de sens que si le type de template spécifié est client-side-detection ou
express-installation.
version-revision
Indique la version de mise à jour du Flash Player à utiliser (version 0 par défaut). Cet
argument n’a de sens que si le type de template spécifié est client-side-detection
ou express-installation.
Ajoutons donc une nouvelle action de génération de fichier HTML :
<target name="generationHTML" depends="compilation">
<echo message=">> Génération du fichier HTML" />
<html-wrapper
swf = "HelloWorld"
height = "100%"
width = "100%"
application = "HelloWorld"
template = "express-installation"
version-major = "9"
version-minor = "0"
version-revision = "0"
output="${APPLICATION_HOME}"
title = "Hello World !!"/>
</target>
Avant d’exécuter ce script, attardons-nous sur la notion de dépendance entre les différentes
tâches dans un fichier de compilation de Ant. En analysant l’exemple de code précédent,
nous voyons que le terme depends a été ajouté à la tâche generationHTML. Cela signifie
qu’elle ne pourra être exécutée que si la tâche compilation l’a été au préalable.
43
=Flex3 FM.book Page 44 Mardi, 2. décembre 2008 3:32 15
44
Comprendre Flex 3
PARTIE I
Ajoutons également la propriété default au projet, qui permet de spécifier la première
tâche à réaliser lors de la compilation.
<project name="My App Builder" default="generationHTML">
On définit la première tâche comme étant celle réalisant la génération du fichier HTML.
Ne pouvant s’exécuter avant la tâche de compilation, Ant va d’abord compiler le projet
puis terminer son travail par la génération de la page web. Lors de l’exécution du script Ant,
il ne nous sera plus nécessaire de spécifier la tâche à exécuter étant donné que celle-ci est
maintenant précisée. La nouvelle commande de compilation est donc :
ant -buildfile HelloWorld.xml
Afin que tout ceci soit plus clair, voici le script de compilation dans sa totalité :
<?xml version="1.0" encoding="utf-8"?>
<project name="My App Builder" default="generationHTML">
<taskdef resource="flexTasks.tasks" classpath="c:/root_flexsdk/ant/lib/flexTasks.jar" />
<property name="APPLICATION_HOME" value="c:/root_flexsdk/samples/HelloWorld/src"/>
<target name="compilation">
<echo message=">> Génération du fichier SWF" />
<mxmlc file="${APPLICATION_HOME}/HelloWorld.mxml"></mxmlc>
</target>
<target name="generationHTML" depends="compilation">
<echo message=">> Génération du fichier HTML" />
<html-wrapper
swf = "HelloWorld"
height = "100%"
width = "100%"
application = "HelloWorld"
template = "express-installation"
version-major = "9"
version-minor = "0"
version-revision = "0"
output="${APPLICATION_HOME}"
title = "Hello World !!"/>
</target>
</project>
Procédons à la compilation et rendons-nous ensuite dans le répertoire src de l’application.
Nous notons alors la création des fichiers suivants :
• AC_OETags.js : il s’agit du fichier JavaScript vérifiant la version du Flash Player
installée en fonction des paramètres version-major, version-minor et version-revision
spécifiés dans la tâche html-wrapper.
=Flex3 FM.book Page 45 Mardi, 2. décembre 2008 3:32 15
Développer avec le kit Flex SDK
CHAPITRE 3
• playerProductInstall.swf : application permettant l’installation du Flash Player requis
si le client ne le possède pas.
• index.html : page HTML contenant le fichier SWF généré lors de la compilation.
Nous pourrions nous arrêter là, mais nous avons décidé de pousser l’automatisation jusqu’au
bout en évitant la saisie de la commande ant dans la console MS-DOS. Pour ce faire,
nous vous proposons de créer un script bat qui s’exécutera en double-cliquant dessus.
Nous vous invitons donc à créer un fichier nommé compilation.bat dans le répertoire src de
l’application et contenant les paramètres suivants (à adapter selon votre configuration) :
@ECHO OFF
cls
echo ***************************************
echo .:::::
COMPILATION ANT
:::::.
echo ***************************************
ant -buildfile c:\root_flexsdk\ant\HelloWorld.xml
Double-cliquez ensuite dessus pour l’exécuter. Grâce à ce script exécutant la tâche ant
spécifiée auparavant, nous automatisons les tâches de déploiement et diminuons ainsi le
nombre d’opérations à effectuer dans la console MS-DOS. Ceci réduit le temps requis
pour le déploiement et les tests d’exécution de l’application.
En résumé
Ce chapitre vous a permis de créer votre première application Flex. Certes, elle est très
simple, mais elle nous a néanmoins permis de découvrir les principaux aspects de la
réalisation d’une application. Nous avons également vu les différentes phases de développement d’une application :
• la conception de l’interface graphique ;
• la création du fichier MXML dérivé de la conception ;
• le développement des traitements ActionScript ;
• la mise en relation entre les actions et l’interface graphique ;
• la compilation ;
• le déploiement.
De toutes ces phases, la plus compliquée est sans doute celle visant à concevoir l’interface
graphique, car elle demande une grande part d’abstraction, notamment pour disposer les
composants à l’aide de leurs coordonnées. Le rêve serait qu’un un outil WYSIWG
regroupant toutes ces phases existe ! Eh bien ce rêve est devenu réalité grâce à Flex Builder,
que nous vous invitons à découvrir grâce au chapitre suivant.
45
=Flex3 FM.book Page 46 Mardi, 2. décembre 2008 3:32 15
=Flex3 FM.book Page 47 Mardi, 2. décembre 2008 3:32 15
4
Développer des applications
à l’aide de Flex Builder
Flex Builder est un environnement de développement intégré (EDI ou IDE en anglais),
basé sur l’outil Eclipse, bien connu des développeurs Java. Son principal objectif est de
faciliter le développement des applications Flex en offrant au sein d’un seul environnement, toutes les fonctionnalités nécessaires au cycle de vie d’un projet (développement,
compilation, tests et déploiement). Son interface conviviale fait de Flex Builder l’outil de
prédilection pour la création d’applications Flex.
Dans ce chapitre, nous allons tout d’abord présenter cet outil, puis nous verrons comment
l’installer sur notre environnement de travail. Enfin, nous nous intéresserons aux
nombreuses fonctionnalités qu’il propose.
Présentation de Flex Builder
Au cours du chapitre précédent, nous avons vu qu’il est possible de créer une application
à partir du kit de développement Flex SDK. Le résultat obtenu est certes concluant, mais
le développement à l’aide du SDK n’est pas des plus aisés, car la tâche de compilation
peut très rapidement devenir lourde à mettre en place, le design de l’interface graphique
est difficile à réaliser et la phase de développement manque de convivialité.
Avec Flex Builder, toutes ces difficultés disparaissent. Pour vous faire une petite idée de
la puissance de cet outil, voici une liste non exhaustive des fonctionnalités qu’il offre :
• un mode Design de type WYSIWYG pour la création d’interface graphique ;
=Flex3 FM.book Page 48 Mardi, 2. décembre 2008 3:32 15
48
Comprendre Flex 3
PARTIE I
• un mode Code évolué permettant la détection des éventuelles erreurs de programmation
et offrant une aide au développement grâce à la fonction d’auto-complétion ;
• un débogueur ;
• un outil de tests intégré (gestion de la mémoire, test de régression, etc.) ;
• la prise en charge native des applications Adobe AIR ;
• la refactorisation (maintenance) du code ;
• la création de composants personnalisés ;
• la génération des fichiers SWF et HTML associées.
Les différentes versions de Flex Builder
Flex Builder est disponible en version standard ou en version professionnelle. Dans sa
version standard, il offre les fonctionnalités de base nécessaires à la création d’applications.
La version professionnelle, quant à elle, permet la réalisation de graphiques utiles dans
les applications de reporting. Elle met également à la disposition des développeurs un
outil de tests très performant permettant, entre autres, de visualiser la capacité mémoire
utilisée par l’application et de générer des tests automatisés. Le choix de la version
dépend donc du type d’applications que vous souhaitez développer et de votre budget.
Les différents modes de distribution de Flex Builder
Deux modes de distribution de Flex Builder sont proposés :
• Le mode Plug-in, qui concerne les développeurs possédant déjà l’IDE Eclipse, plateforme sur laquelle Flex Builder peut être ajouté sous forme de plug-in.
• Le mode Autonome, qui consiste à installer une version « autonome », contenant
l’IDE Eclipse et le plug-in Flex Builder pré-installé.
L’intérêt du second mode de distribution est qu’il permet de disposer d’un environnement
entièrement dédié au développement d’applications Flex, non pollué par les divers plug-ins
pouvant déjà être installés dans Eclipse. Néanmoins, si votre espace disque est limité,
optez pour le premier mode car il évite de réinstaller l’IDE Eclipse qui nécessite 400 Mo !
Version de Flex Builder
Cet ouvrage traite de Flex Builder dans sa version professionnelle. Le mode de distribution retenu est le
mode Autonome.
Évaluer avant d’acheter une licence
À ce stade de l’ouvrage, il est prématuré de faire l’acquisition d’une licence. Faites-vous d’abord une idée
de Flex Builder professionnel en téléchargeant une version de démonstration limitée dans le temps sur le
site d’Adobe. Pour cela, rendez-vous à l’adresse suivante : http://www.adobe.com.
=Flex3 FM.book Page 49 Mardi, 2. décembre 2008 3:32 15
Développer des applications à l’aide de Flex Builder
CHAPITRE 4
Installation de Flex Builder
Il est temps à présent de passer à la phase d’installation de Flex Builder qui nous permettra
de l’étudier en détail. Flex Builder est disponible sous Mac et sous Windows. Nous avons
choisi ici de détailler son installation sous Windows.
À noter que si vous optez pour le mode de distribution Plug-in et que vous êtes dans un
environnement Mac, vous devez disposer au minimum de la version 3.2 d’Eclipse pour
que l’installation soit concluante.
Flex Builder 3 et Linux
La version commerciale de Flex Builder n’est malheureusement pas compatible avec Linux. Néanmoins,
pour les utilisateurs de cet environnement, Adobe a développé le projet Flex Builder Public Alpha, qui
consiste en un plug-in à ajouter à l’IDE Eclipse et offrant notamment les fonctionnalités de coloration
syntaxique, de compilation, de débogage… Ce plug-in est téléchargeable à l’adresse suivante :
http://labs.adobe.com/technologies/flex/flexbuilder_linux/.
Le mode Autonome
Voici la marche à suivre pour installer Flex Builder professionnel en mode Autonome :
1. Enregistrez-vous sur le site d’Adobe. Vous pouvez acheter soit une version téléchargeable soit un CD-Rom. Si vous optez pour la version téléchargeable, vous disposez
alors d’un exécutable nommé FB3_win.exe.
Version d’évaluation
Avant d’acquérir Flex Builder, vous pouvez télécharger la version d’évaluation (disponible uniquement en
anglais) sur le site d’Adobe.
2. Double-cliquez sur ce fichier pour lancer la procédure d’installation (figure 4-1).
Figure 4-1
Extraction des fichiers d’installation
49
=Flex3 FM.book Page 50 Mardi, 2. décembre 2008 3:32 15
50
Comprendre Flex 3
PARTIE I
3. La fenêtre qui s’affiche à la fin de la procédure d’extraction des fichiers d’installation permet de sélectionner la langue souhaitée. Cliquez sur OK pour poursuivre
l’installation.
Figure 4-2
Choix de la langue d’installation
4. Acceptez les termes de la licence d’utilisation (figure 4-3) et cliquez sur le bouton
Next.
Figure 4-3
Acception des termes de la licence d’utilisation de Flex Builder
5. Sélectionnez le répertoire souhaité pour l’installation (figure 4-4) et cliquez sur Next.
=Flex3 FM.book Page 51 Mardi, 2. décembre 2008 3:32 15
Développer des applications à l’aide de Flex Builder
CHAPITRE 4
Figure 4-4
Choix du répertoire d’installation
6. Cochez les deux options permettant d’installer Flash Player 9 et, éventuellement, les
options permettant d’installer les extensions ColdFusion pour Flex Builder et le plug-in
JSEclipse (figure 4-5), si vous utilisez l’un des deux éléments. Cliquez ensuite sur le
bouton Next pour continuer.
Figure 4-5
Sélection des éléments additionnels à installer (Flash Player 9, extensions ColdFusion
et plug-in JSEclipse)
51
=Flex3 FM.book Page 52 Mardi, 2. décembre 2008 3:32 15
52
Comprendre Flex 3
PARTIE I
ColdFusion
Actuellement disponible dans sa version 8, Adobe ColdFusion est un langage de balises permettant la
réalisation d’applications web. Pour plus d’informations sur ce produit, nous vous invitons à vous rendre à
l’adresse suivante : http://www.adobe.com/fr/products/coldfusion/.
JSEclipse
JSEclipse est un plug-in gratuit développé par interAKT (qui est une branche d’Adobe), permettant
l’édition de fichier JavaScript en proposant une coloration syntaxique, l’auto-complétion…
7. Cliquez sur le bouton Install de la fenêtre récapitulant les paramètres d’installation
(figure 4-6). L’installation démarre alors (figure 4-7), suivie de sa configuration
(figure 4-8).
Figure 4-6
Récapitulatif des paramètres de l’installation
=Flex3 FM.book Page 53 Mardi, 2. décembre 2008 3:32 15
Développer des applications à l’aide de Flex Builder
CHAPITRE 4
Figure 4-7
État d’avancement de l’installation de Flex Builder
Figure 4-8
Configuration de Flex Builder
53
=Flex3 FM.book Page 54 Mardi, 2. décembre 2008 3:32 15
54
Comprendre Flex 3
PARTIE I
Figure 4-9
Fin de l’installation
Voilà, l’installation est terminée (figure 4-9). Double-cliquez sur le programme flexBuilder
.exe situé dans le répertoire d’installation spécifié afin de vérifier que tout s’est déroulé
correctement et que le logiciel se lance bien.
Le mode Plug-in
Le principal prérequis pour ce mode de distribution est la présence de l’IDE Open Source
Eclipse, Flex Builder étant basé sur cet outil, qui peut être téléchargé à l’adresse suivante :
http://www.eclipse.org/.
L’installation d’Eclipse se résume en la décompression de l’archive téléchargée sur le site
de l’éditeur dans un répertoire du disque dur de votre machine. Un nouveau répertoire est
alors créé, contenant le fichier eclipse.exe (figure 4-10).
Figure 4-10
Répertoire d’installation d’Eclipse
=Flex3 FM.book Page 55 Mardi, 2. décembre 2008 3:32 15
Développer des applications à l’aide de Flex Builder
CHAPITRE 4
Si vous avez opté pour l’installation du plug-in Eclipse, vous devez être en possession du
programme FB3_WWEJ_Plugin.exe, préalablement téléchargé depuis le site d’Adobe. Doublecliquez alors sur cet exécutable pour lancer la procédure d’installation dont les différentes
étapes sont les suivantes :
1. Extraction des fichiers d’installation.
2. Choix de la langue d’installation souhaitée (anglais par défaut).
3. Acception des termes de la licence d’utilisation.
4. Spécification du chemin d’installation du plug-in.
5. Indication du chemin d’installation d’Eclipse.
6. Configuration du plug-in.
7. Installation de Flash Player 9 et des extensions ColdFusion et JSEclipse optionnelles.
8. Après une reconfiguration du plug-in, un récapitulatif d’installation est affiché.
9. Installation du plug-in.
10. Fin de l’installation.
Pour vérifier que l’installation du plug-in s’est correctement déroulée, exécutez l’IDE
Eclipse et créez un nouveau projet de type Flex Project en procédant comme suit :
1. Sélectionnez le menu File>New>Other.
2. Dans la fenêtre qui s’ouvre alors, sélectionnez Flex Builder puis Flex Projet.
3. Une série de questions vous est alors posée. Acceptez les options proposées par défaut
en indiquant Test pour le nom du projet.
4. Après validation, une perspective Eclipse s’affiche, identique à celle de Flex Builder
en mode Autonome (figure 4-11).
Flex Builder est désormais correctement installé. Étudions à présent ses caractéristiques
et son mode de fonctionnement dans le détail.
55
=Flex3 FM.book Page 56 Mardi, 2. décembre 2008 3:32 15
56
Comprendre Flex 3
PARTIE I
Figure 4-11
Perspective Eclipse de Flex Builder
Les perspectives de Flex Builder
Dans cette partie, nous allons aborder les deux notions essentielles de Flex Builder que
nous retrouverons tout au long de cet ouvrage : la perspective et la vue.
Le terme « perspective » peut être défini par une combinaison d’éditeurs et de vues
permettant de réaliser des tâches précises.
Comme son nom l’indique, un éditeur permet d’éditer des fichiers. Dans le cas d’une
application Flex, il existe trois éditeurs :
• un éditeur MXML ;
• un éditeur ActionScript ;
• un éditeur CSS.
Une vue, quant à elle, est liée à un éditeur. Si, par exemple, on souhaite éditer un fichier de
type MXML dont le rôle principal est la description d’une interface graphique, nous verrons
apparaître à l’écran les composants disponibles pouvant être insérés dans cette interface ainsi
=Flex3 FM.book Page 57 Mardi, 2. décembre 2008 3:32 15
Développer des applications à l’aide de Flex Builder
CHAPITRE 4
que leurs propriétés respectives. Si nous éditons à présent un fichier ActionScript, une
autre vue sera affichée présentant les variables et les classes du fichier en cours d’édition.
Flex Builder professionnel est composé de quatre perspectives :
• la perspective de développement, permettant de visualiser le code de l’application ;
• la perspective de design qui nous permet de créer les interfaces graphiques de nos
applications ;
• la perspective de débogage nous offre une aide précieuse pour corriger les problèmes
rencontrés lors de l’exécution d’une application ;
• la perspective de profiling ajoute des fonctionnalités à la perspective de débogage en
permettant d’étudier le temps processeur ou l’occupation mémoire de certaines
procédures.
Lors de la création d’un nouveau projet, la perspective Design est sélectionnée par défaut
(figure 4-12). Pour passer à la perspective de développement, il suffit de cliquer sur le
bouton Source situé dans la barre de menus de la vue centrale (figure 4-13).
Figure 4-12
La perspective de design
57
=Flex3 FM.book Page 58 Mardi, 2. décembre 2008 3:32 15
58
Comprendre Flex 3
PARTIE I
Figure 4-13
Boutons permettant d’afficher les perspectives
de design et de développement
La perspective de développement
La perspective de développement comprend les éditeurs et les vues nécessaires à la création
des fichiers en mode Code. Nous pouvons ainsi éditer des fichiers ActionScript, CSS,
MXML…
Au centre de cette perspective (figure 4-14) se trouve l’éditeur principal permettant la saisie
du code. La vue Flex Navigator, située en haut à gauche, affiche l’arborescence du projet
et l’ensemble des fichiers qu’il contient. La vue Outline présente la structure hiérarchique
du code saisi et permet également de visualiser les alertes et erreurs présentes. Enfin, la
vue Problems, située sous l’éditeur, présente l’ensemble des alertes et erreurs de compilation pouvant perturber le bon déroulement de l’application.
Figure 4-14
La perspective de développement
=Flex3 FM.book Page 59 Mardi, 2. décembre 2008 3:32 15
Développer des applications à l’aide de Flex Builder
CHAPITRE 4
La perspective de design
Cette perspective vous permettra de disposer facilement les composants d’une interface
graphique comme nous le ferions avec un éditeur WYSWYG (figure 4-15).
Figure 4-15
La perspective de design
Au centre de cette perspective se trouve l’éditeur MXML. Pour y ajouter des composants,
il suffit de les sélectionner dans la vue Components et de les faire glisser dans l’éditeur.
Par ailleurs, leurs propriétés peuvent être modifiées dans la vue Flex Properties, située à
droite de l’éditeur MXML. La vue States permet, quant à elle, de créer des états d’interface.
Il est ainsi possible de définir différents états pour une interface donnée.
Prenons pour exemple une interface graphique contenant un panneau permettant de saisir
un identifiant et un mot de passe. À l’état initial, sont affichés les deux zones de saisie, le
59
=Flex3 FM.book Page 60 Mardi, 2. décembre 2008 3:32 15
60
Comprendre Flex 3
PARTIE I
bouton Valider et le bouton Perte du mot de passe. Cet état est représenté par l’état principal (Base state, figure 4-16). Si l’utilisateur clique sur le bouton Perte du mot de passe,
un nouvel état apparaîtra dans la vue States (perteMDP) et une zone de texte s’affichera
demandant la saisie de l’adresse e-mail à laquelle envoyer le mot de passe oublié. Ce
nouvel état, créé à partir de l’état principal, est illustré par la figure 4-17. Pour le moment,
nous ne développerons pas davantage la notion d’état, que nous détaillerons au chapitre 9.
Figure 4-16
L’état « Saisie du mot de passe »
Figure 4-17
L’état « Perte du mot de passe »
=Flex3 FM.book Page 61 Mardi, 2. décembre 2008 3:32 15
Développer des applications à l’aide de Flex Builder
CHAPITRE 4
La perspective de débogage
La perspective de débogage (figure 4-18) est activée lors de l’exécution de l’application
en mode Débogage (menu Run>Debug). Elle est très intéressante pour résoudre les
problèmes dans vos applications, comme lorsqu’une fonction renvoie une erreur ou bien
lorsqu’un appel à un service web échoue.
Figure 4-18
La perspective de débogage
La vue Debug affiche les différentes tâches (thread/processus) réalisées par l’application.
Cette vue permet de suspendre ou de reprendre l’exécution d’une tâche précédemment
suspendue afin d’analyser l’exécution de l’application.
61
=Flex3 FM.book Page 62 Mardi, 2. décembre 2008 3:32 15
62
Comprendre Flex 3
PARTIE I
Multithreading
Il est important de souligner qu’une application Flex n’est pas multithread (multi-tâche). Par conséquent,
l’implémentation d’une barre de progression permettant d’afficher l’état d’avancement de l’exécution d’un
traitement n’est pas envisageable.
Il peut parfois s’avérer intéressant de stopper l’exécution à un point précis de son avancement. Pour cela, il suffit de placer des points d’arrêt dans le code applicatif. La vue
Breakpoints présente les différents points d’arrêt insérés et permet de les gérer (désactivation, passage au point d’arrêt suivant et suppression).
Par ailleurs, pour vérifier qu’un traitement a bien été effectué, il peut parfois être nécessaire
de « tracer » son passage. Pour cela, il convient d’utiliser la fonction trace du langage
ActionScript. La vue Console permet de visualiser l’ensemble du traçage réalisé.
La vue Variables, quant à elle, affiche les valeurs prises par les différentes variables déclarées
dans le code ce qui permet de résoudre les problèmes de variables non affectées.
Enfin, la vue Expressions permet de surveiller les variables jugées critiques pour l’application (saisie d’un mot de passe, etc.). Les valeurs des variables présentes dans cette vue
peuvent être modifiées dynamiquement à l’aide de la vue Variables.
Affichage des différentes vues
Il se peut que l’ensemble des vues ne soit pas affiché par défaut. Dans ce cas, il suffit de sélectionner le
menu Window et de choisir la vue désirée parmi la liste proposée. Néanmoins, lors de l’exécution du projet
en mode Débogage, Flex Builder vous demandera si vous souhaitez ou non utiliser la perspective de
débogage.
La perspective de profiling
Cette perspective est la grande nouveauté de la version 3 de Flex Builder professionnel.
Grâce à elle, il est désormais possible d’analyser en profondeur l’exécution d’une application Flex. En effet, la perspective Profile permet d’effectuer une analyse statistique du
nombre d’objets instanciés, de la place mémoire qu’ils occupent, des méthodes exécutées
et de leur temps d’exécution.
La perspective Profile (figure 4-19) comprend deux vues essentielles :
• la vue Live Objects, qui permet de visualiser les objets créés et les méthodes exécutées ;
• la vue Memory usage, dédiée à la visualisation du taux d’utilisation de la mémoire.
Maintenant que nous avons passé en revue les différentes perspectives, nous allons nous
consacrer à la création de projets Flex.
=Flex3 FM.book Page 63 Mardi, 2. décembre 2008 3:32 15
Développer des applications à l’aide de Flex Builder
CHAPITRE 4
Figure 4-19
La perspective de profiling
Créer un projet
Tout nouveau développement commence inévitablement par la création d’un nouveau
projet ; voici la marche à suivre pour effectuer cela dans Flex Builder :
1. Sélectionnez le menu File>New>Flex Project.
2. Dans la fenêtre qui s’ouvre alors (figure 4-20), saisissez le nom projet (ici ProjetFlex)
et choisissez le type d’application souhaité :
– Web application permet de créer une page HTML contenant le fichier SWF issu de
la compilation ;
– Desktop application permet de créer une application Adobe AIR.
3. Pour spécifier le répertoire de destination du projet, désactivez l’option Use Default
Location et spécifiez le chemin du répertoire dans le champ Folder.
63
=Flex3 FM.book Page 64 Mardi, 2. décembre 2008 3:32 15
64
Comprendre Flex 3
PARTIE I
4. Indiquez ensuite la technologie serveur à utiliser grâce à la liste déroulante Application
server type. En effet, pour pouvoir accéder à des données stockées dans une base, Flex
doit être couplé à un langage serveur (ASP.Net, ColdFusion, J2EE, PHP, etc.) qui
servira de passerelle. Notez que si vous sélectionnez J2EE ou ColdFusion, Flex propose
d’utiliser l’outil LiveCycle Data Services ES (voir encadré) permettant d’accéder aux
services de la couche métier développée dans ces technologies.
LiveCycle Data Services ES et ColdFusion Flash Remoting
LiveCycle Data Services ES permet une intégration complète de Flex dans une architecture J2EE en autorisant la simplification du code et en offrant certaines fonctionnalités telles que l’édition de rapports PDF.
ColdFusion Flash Remoting facilite l’intégration de Flex à la technologie ColdFusion qui offre une fonction
de création d'applications Internet riches (RIA) côté serveur. Il rend également Flex et la technologie J2EE
interopérables.
Ces deux produits sont développés par Adobe.
Figure 4-20
Création d’un nouveau projet
5. Cliquez ensuite sur le bouton Next. La fenêtre qui apparaît alors permet de préciser le
répertoire dans lequel les fichiers issus de la compilation seront enregistrés (bin-debug
par défaut). Même si le chemin du répertoire est spécifié manuellement, il apparaîtra
=Flex3 FM.book Page 65 Mardi, 2. décembre 2008 3:32 15
Développer des applications à l’aide de Flex Builder
CHAPITRE 4
tout de même sous le nom bin-debug dans l’arborescence du projet, mais il s’agira d’un
raccourci vers le répertoire spécifié.
6. Cliquez à nouveau sur le bouton Next. La fenêtre qui s’affiche alors permet de configurer le répertoire dans lequel les sources du projet seront enregistrées (src par
défaut), ainsi que le nom du fichier principal de l’application (figure 4-21). Il est
également possible de désigner des répertoires de sources externes et d’importer des
bibliothèques telles que des composants personnalisés.
Figure 4-21
Spécification des répertoires
7. Cliquez enfin Finish pour terminer la création du projet.
Arborescence d’un projet Flex Builder
L’arborescence d’un projet Flex Builder dépend du type d’application choisi lors de la
création du projet.
65
=Flex3 FM.book Page 66 Mardi, 2. décembre 2008 3:32 15
66
Comprendre Flex 3
PARTIE I
Les applications de type web
Lorsque l’option Web Application est activée (figure 4-20), votre projet aura une arborescence semblable à celle illustrée par la figure 4-22.
Figure 4-22
Arborescence d’un projet Flex Builder
Le tableau 4-1 détaille les répertoires et fichiers de cette arborescence.
Tableau 4-1
Arborescence d’un projet de type Web
Répertoire/Fichier
Description
\ProjetFlex
Répertoire racine du projet.
\bin-debug
Répertoire de compilation.
\history
Répertoire contenant un ensemble de fichiers dédiés à la prise en charge des
actions sur les boutons Suivant et Précédent du navigateur web
history.css
Feuille de styles utilisée par la page historyFrame.html.
history.js
Fichier JavaScript traitant les actions sur les boutons Suivant et Précédent du
navigateur web.
historyFrame.html
Page HTML affichant le résultat du traitement réalisé par le fichier history .js.
AC_OETags.js
Script détectant la présence du Flash Player sur le poste client. Associé au
fichier playerProductInstall.swf, il permet son exécution le cas échéant.
playerProductInstall.swf
Fichier SWF réalisant l’installation du Flash Player si ce dernier n’est pas présent
sur le poste client.
=Flex3 FM.book Page 67 Mardi, 2. décembre 2008 3:32 15
Développer des applications à l’aide de Flex Builder
CHAPITRE 4
Tableau 4-1
Arborescence d’un projet de type Web (suite)
Répertoire/Fichier
Description
ProjetFlex.html
Page HTML contenant le fichier SWF de l’application.
ProjetFlex.swf
Fichier SWF de l’application.
\html-template
Répertoire dans lequel sont placés les fichiers nécessaires à la génération de la
page HTML contenant le fichier SWF.
index.template.html
Page HTML utilisée comme modèle pour la création de la page w eb contenant
le fichier SWF.
\libs
Répertoire accueillant les bibliothèques.
\src
Répertoire des sources de l’application.
ProjetFlex.mxml
Fichier MXML de l’application.
Les applications Adobe AIR
Une application Adobe AIR s’exécute sur le poste client à la manière d’une application
standard (figure 4-23). De ce fait, le fichier SWF n’est pas contenu dans une page web, ce qui
implique que nous ne trouverons pas les fichiers relatifs à la gestion des événements sur
les boutons Suivant et Précédent du navigateur dans le répertoire \history, ni ceux nécessaires à la création de la page web, normalement situés dans le répertoire \html-template.
Nous constatons cependant l’apparition d’un nouveau fichier XML, nommé nomDuProjet
app.xml situé dans le répertoire src contenant l’ensemble des informations permettant de
créer la fenêtre applicative.
Figure 4-23
Application de type Adobe AIR
67
=Flex3 FM.book Page 68 Mardi, 2. décembre 2008 3:32 15
68
Comprendre Flex 3
PARTIE I
Le tableau 4-2 détaille l’ensemble des répertoires et des fichiers de l’arborescence représentée à la figure 4-24.
Tableau 4-2
Arborescence d’un projet Adobe AIR
Répertoire/fichier
Description
\ProjetAir
Répertoire racine du projet.
\bin-debug
Répertoire de compilation.
ProjetAir.swf
Fichier SWF de l’application.
ProjetAir-app.xml
Fichier XML chargé de décrire les spécificités de la fenêtre d’exécution du projet.
\libs
Répertoire contenant les bibliothèques du projet.
\src
Répertoire contenant les sources du projet.
ProjetAir.mxml
Fichier applicatif principal.
Figure 4-24
Arborescence d’un projet
de type AIR
Exécution et tests
L’exécution d’un projet s’effectue en cliquant sur l’icône Run
de la barre d’outils
de Flex Builder. Si vous souhaitez l’exécuter en mode Débogage, cliquez sur l’icône
. La perspective de débogage, dont les fonctionnalités ont été décrites précédemment, s’affiche alors. Nous ne nous étendrons pas d’avantage sur ces notions de test et de
débogage qui seront abordées en détail dans le chapitre 17.
Travail collaboratif
Flex Builder offre la possibilité d’effectuer un travail collaboratif sur un projet, ce qui
peut s’avérer très intéressant pour les projets de grande envergure. Néanmoins, vous
devrez pour cela disposer d’un serveur CVS (Concurrent Versions System) capable de
gérer les différentes versions du projet, de répercuter les modifications effectuées par
chaque développeur tout en analysant leurs impacts.
Un système CVS fonctionne selon le principe suivant. Les sources du projet sont copiées
dans un répertoire de synchronisation situé sur un serveur. Les acteurs participant au
développement du projet peuvent ainsi télécharger ces sources sur leur poste de travail à
l’aide d’un client CVS. Chaque développeur possède alors une copie des sources
=Flex3 FM.book Page 69 Mardi, 2. décembre 2008 3:32 15
Développer des applications à l’aide de Flex Builder
CHAPITRE 4
(working copy) qu’il peut modifier à l’envi. Une fois toutes les modifications apportées,
il transfère les nouveaux fichiers sur le serveur CVS, on parle alors de commit. Les autres
développeurs sont alors informés que des modifications ont été apportées et peuvent
récupérer les nouveaux fichiers mis à jour en effectuant un update.
Pour vous permettre de mieux comprendre ce point, nous allons à présent détailler la
configuration d’un serveur CVS dans un environnement Windows.
Configuration du serveur CVSNT
Sous Windows, vous devrez utiliser le serveur CVSNT. Cet outil est gratuit et peut être
téléchargé à l’adresse suivante : http://www.march-hare.com/cvspro/. Son installation est
des plus simples car il vous suffira de suivre les différentes étapes de l’assistant. Pour
configurer le serveur, suivez la procédure suivante :
1. Exécutez le programme CVSNT Control Panel (menu Démarrer>Tous les programmes>CVSNT).
2. Cliquez sur l’onglet Repository Configuration permettant de définir le répertoire dans
lequel les sources du projet à synchroniser seront enregistrées. Pour cela, cliquez sur
le bouton ADD afin d’afficher la fenêtre Server Settings (figure 4-25).
Figure 4-25
Création du répertoire de synchronisation
Configuration des utilisateurs
Les utilisateurs pouvant accéder au serveur CVSNT sont définis dans le fichier passwd situé
dans le sous-répertoire CVSROOT du répertoire de synchronisation défini précédemment.
Nous allons ajouter l’utilisateur Administrateur qui possédera tous les droits sur le répertoire de synchronisation et dont le mot de passe sera vide. Pour ce faire, éditez le fichier
passwd et ajoutez-y la ligne suivante :
Administrateur::Administrateur
69
=Flex3 FM.book Page 70 Mardi, 2. décembre 2008 3:32 15
70
Comprendre Flex 3
PARTIE I
Paramétrage du projet Flex Builder
La phase de configuration des utilisateurs terminée, il ne nous reste plus qu’à paramétrer
le travail collaboratif pour un projet Flex Builder :
1. Effectuez un clic droit sur l’icône du projet et sélectionnez Team>Share Project.
2. Dans la fenêtre qui s’affiche alors, spécifiez les différents paramètres nécessaires à la
réalisation de la connexion au serveur CVS (figure 4-26). Cliquez ensuite sur le bouton
Next.
Figure 4-26
Paramétrage de la connexion
au serveur CVS
3. Dans la fenêtre suivante, conservez l’option cochée par défaut spécifiant que le nom
du module CVS portera le nom du projet. Un répertoire du même nom que celui du
projet sera alors créé dans le dossier de synchronisation de CVS. Cliquez ensuite sur
le bouton Next > pour valider.
4. Le récapitulatif de la configuration s’affiche alors. Cliquez sur le bouton Finish pour
terminer (figure 4-27).
5. Une nouvelle fenêtre apparaît alors, vous informant que des nouveaux fichiers ont été
détectés et qu’une synchronisation est nécessaire. Cliquez sur le bouton Next.
6. Dans la fenêtre suivante, saisissez un commentaire sur la raison de la synchronisation
et validez en cliquant sur le bouton Finish (figure 4-28).
=Flex3 FM.book Page 71 Mardi, 2. décembre 2008 3:32 15
Développer des applications à l’aide de Flex Builder
CHAPITRE 4
Figure 4-27
Récapitulatif du paramétrage CVS
Figure 4-28
Première synchronisation
du projet
71
=Flex3 FM.book Page 72 Mardi, 2. décembre 2008 3:32 15
72
Comprendre Flex 3
PARTIE I
Synchronisation des sources
Si nous sélectionnons à nouveau le menu Team du projet, nous pouvons constater qu’il
comporte désormais des nouvelles entrées, dont les principales sont :
• Commit, permettant de déposer les modifications effectuées sur le serveur ;
• Update, offrant la possibilité de mettre à jour les sources du projet à partir de celles
situées sur le serveur ;
• Synchronize with repository, perspective de synchronisation du projet chargée d’analyser
les modifications effectuées et leur impact.
Nous n’allons pas nous attarder davantage sur le travail collaboratif. Cette section nous a
permis de voir que Flex Builder est capable de s’adapter à toutes les tailles de projets, du
plus petit aux projets de grande envergure développés par plusieurs personnes nécessitant
une architecture de développement bien définie.
Exporter/importer un projet
Nous venons de voir qu’il est possible de travailler en collaboration sur un même projet,
l’ensemble des développeurs partagent alors les sources. Cependant, il arrive que nous
soyons seuls à développer et que nous devions exporter notre projet afin de l’utiliser sur
un autre poste équipé du Framework Flex 3, à des fins de démonstration ou de sauvegarde.
Dans cette partie, nous allons donc voir comment il est possible d’exporter mais aussi
d’importer un projet au sein de l’environnement de développement.
Exportation
Voici la marche à suivre pour exporter un projet en vue de le déployer ou de l’archiver :
1. Effectuez un clic droit sur la vue Flex Navigator et sélectionnez Export.
2. Dans la fenêtre qui s’ouvre alors, indiquez le type d’exportation souhaité (figure 4-29) :
– Flex Project Archive, crée une archive pouvant être stockée afin de conserver, par
exemple, plusieurs versions différentes du projet ;
– Release Build, exporte le projet vers l’environnement de production, le rendant ainsi
disponible pour l’ensemble des utilisateurs concernés.
3. Cliquez ensuite sur le bouton Next afin de sélectionner le projet concerné par
l’exportation.
=Flex3 FM.book Page 73 Mardi, 2. décembre 2008 3:32 15
Développer des applications à l’aide de Flex Builder
CHAPITRE 4
Figure 4-29
Choix du type d’exportation
Importation
Pour importer un projet, suivez les étapes suivantes :
1. Effectuez un clic droit sur la vue Flex Navigator et sélectionnez Import.
2. Dans la fenêtre qui s’ouvre alors, indiquez le type de fichier à importer dans Flex
Builder. Un projet Flex Builder peut être importé à partir d’un fichier archive ou du fichier
.project présent dans le répertoire racine de chaque projet Flex Builder (figure 4-30).
Figure 4-30
Fichier .project
73
=Flex3 FM.book Page 74 Mardi, 2. décembre 2008 3:32 15
74
Comprendre Flex 3
PARTIE I
3. Cliquez sur le bouton Next. Dans la fenêtre présente à l’écran, si vous souhaitez
importer un projet archivé (zip), cliquez sur le bouton Browse situé en regard de la
ligne Archive file afin de parcourir votre disque dur et sélectionner l’archive correspondante, puis cliquez sur le bouton OK. Si vous souhaitez importer un projet non
archivé, cliquez alors le bouton Browse situé en regard de la ligne Project Folder, puis
parcourez votre disque dur jusqu’au répertoire racine du projet souhaité. Cette action
sélectionne automatiquement le fichier .project qui y est situé. Cliquez enfin sur le
bouton OK.
4. Une fois le projet sélectionné, cliquez sur le bouton Finish afin d’importer le projet
dans l’environnement de développement.
En résumé
Au cours de ce chapitre, nous avons découvert les nombreuses fonctionnalités de développement offertes par Flex Builder. Cet environnement de développement complet offre
des fonctionnalités de design, de codage, de débogage et de gestion de projets, le tout
intégré à l’outil Eclipse, ce qui rend son utilisation conviviale, contrairement au mode de
développement étudié dans le chapitre précédent. De plus, le développeur dispose de
l’ensemble des outils nécessaires au sein d’un même environnement lui permettant
d’optimiser et d’accélérer son développement.
Avant de poursuivre avec l’étude des composants graphiques proposés par le framework
Flex, nous vous conseillons de vous familiariser avec l’utilisation de Flex Builder et de
ses perspectives. Vous serez ainsi tout à fait à l’aise pour réaliser les exemples et cas
pratiques proposés dans la suite de cet ouvrage.
=Flex3 FM.book Page 75 Mardi, 2. décembre 2008 3:32 15
5
Les composants de contrôle
Comme nous le savons à présent, Flex est le framework dédié à la création de la partie
front end d’une application. Pour cela, il convient de disposer de composants permettant
de réaliser cette interface graphique.
Les composants proposés par Flex peuvent se diviser en quatre catégories :
• les composants de contrôle de type boutons, zones de texte, etc. ;
• les conteneurs comme les panneaux, canevas, etc. ;
• les composants de navigation (menus, onglets, etc.) ;
• et enfin les composants permettant de générer des graphiques et autres histogrammes
pour la visualisation de statistiques.
Au cours des trois chapitres suivants, nous n’allons pas vous présenter l’ensemble des
composants dans leurs moindres détails, car cela pourrait faire l’objet d’un ouvrage à part
entière, mais découvrir l’usage des composants les plus fréquemment utilisés dans les
applications Flex.
Nous allons donc commencer par l’étude des composants de contrôle dont le rôle est de
permettre l’interaction entre l’utilisateur et l’application. Soulignons que certains d’entre
eux permettent également de présenter des données (tableaux, images, etc.).
Les boutons et interrupteurs
Commençons notre étude des composants par la présentation des plus fréquemment
utilisés : les boutons et interrupteurs.
=Flex3 FM.book Page 76 Mardi, 2. décembre 2008 3:32 15
76
Comprendre Flex 3
PARTIE I
Button
Les boutons sont communément utilisés pour déclencher l’exécution de procédures ou de
fonctions. Voici un exemple d’implémentation :
<mx:Button
id="btn_chercher"
x="10"
y="24"
label="Rechercher"
icon="@Embed(source='../image/iconeRechercher.gif')"
click="rechercher()"/>
Le bouton correspondant à cet extrait de code possède les caractéristiques suivantes :
• un identifiant (id="btn_chercher") ;
• un label correspondant au texte affiché sur le bouton (label="Rechercher") ;
• une icône (icon="@Embed(source='../image/iconeRechercher.gif')") ;
• une action déclenchée en cliquant sur le bouton (click="rechercher()").
Dans notre exemple, lorsque l’utilisateur clique sur le bouton, la procédure rechercher()
est alors déclenchée.
ToogleButton
En ajoutant la propriété toogle="true" au composant Button, nous obtenons un bouton de
type interrupteur. Il peut être utilisé pour visualiser l’état d’une action, par exemple, le
partage d’un fichier.
<mx:Button id="btn_partager"
label="Partager Dossier"
toggle="true"
/>
Si l’utilisateur clique sur l’interrupteur, le fichier est partagé et reste dans cet état (le fond
du bouton apparaît alors en grisé, comme sur la figure 5-1). Pour annuler le partage, il
suffit de cliquer une seconde fois sur le bouton.
Figure 5-1
État « partagé »
Permettre le choix
CheckBox : les cases à cocher
Les cases à cocher permettent à l’utilisateur de réaliser plusieurs choix parmi une liste
proposée (figure 5-2).
=Flex3 FM.book Page 77 Mardi, 2. décembre 2008 3:32 15
Les composants de contrôle
CHAPITRE 5
Figure 5-2
Cases à cocher
Voici comment implémenter ce composant de contrôle :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥borderColor="#F7F9FA" themeColor="#F6F9FB" horizontalAlign="center">
<mx:Label x="15" y="74" text="Pourquoi avez-vous choisi Flex ?"/>
<mx:CheckBox x="49" y="100" label="Facilité d'utilisation" width="130" id="chbx_1"/>
<mx:CheckBox x="49" y="130" label="Complexité du code" width="156" id="chbx_2"/>
<mx:CheckBox x="49" y="160" label="Offre de nombreux composants" width="230"
➥id="chbx_3" selected="true"/>
</mx:Application>
La propriété booléenne selected permet de connaître l’état de la case à cocher. Ainsi, si
elle est égale à true, la case est cochée. Dans l’exemple ci-dessus, la troisième case est
cochée par défaut.
Grâce aux cases à cocher, il nous est possible de déclencher des exécutions de procédures
lors de la réalisation de certains événements. L’exemple ci-dessous permet de lancer la
procédure changementEtat() lors du changement d’état de la case à cocher :
<mx:CheckBox x="49" y="160" label="Age > 18 ans ?" width="230" id="chbx_4"
➥selected="true" change="changementEtat()"/>
Les listes simples et déroulantes
Les composants ListBox et ComboBox ayant un mode de fonctionnement identique, nous
avons fait le choix d’illustrer la mise en place d’une liste déroulante dont l’usage semble
être plus répandu.
Implémentation
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<!-- Liste -->
<mx:List id="maListe" x="20" y="10"></mx:List>
<!-- Liste déroulante -->
<mx:ComboBox id="maListeDeroulante" x="268" y="11"></mx:ComboBox>
</mx:Application>
77
=Flex3 FM.book Page 78 Mardi, 2. décembre 2008 3:32 15
78
Comprendre Flex 3
PARTIE I
En analysant ce code, nous voyons que l’implémentation des ListBox s’effectue à l’aide
des balises <mx:list></mx:list> et grâce aux balises <mx:ComboBox></mx:ComboBox> pour les
ComboBox. Nous profitons de cet exemple pour insister sur le fait que chaque composant
implémenté doit comporter un identifiant, soit l’attribut id. En effet, c’est grâce à cet
identifiant que le composant pourra être utilisé au sein de vos procédures ActionScript.
Par ce biais, nous pourrons modifier ses propriétés mais aussi récupérer la ou les valeurs
sélectionnées lorsque cela est nécessaire et lorsque le composant en offre la possibilité.
Alimentation en données
Considérons la liste d’enregistrements issus d’une table contenue dans une base de données
ornithologiques dont le contenu est décrit par le tableau 5-1.
Tableau 5-1
Enregistrements de base de données ornithologiques
Identifiant
Oiseau
1
Merle
2
Colibri
3
Mésange
Voyons comment alimenter une ComboBox à partir de ces éléments :
<mx:ComboBox id="combo_oiseau" x="10" y="29" selectedIndex="0">
<mx:ArrayCollection>
<mx:Object data="1" label="Merle"/>
<mx:Object data="2" label="Colibri"/>
<mx:Object data="3" label="Mésange"/>
</mx:ArrayCollection>
</mx:ComboBox>
Une collection d’objets, présentant les attributs label et data, a été créée en reprenant les
données du tableau 5-1. Cette collection est source d’alimentation pour le dataProvider
de la ComboBox car elle a été créée entre les deux balises <mx:ComboBox></mx:ComboBox> de
cette dernière.
À retenir
L’alimentation d’une liste simple ou d’une liste déroulante s’effectue toujours à l’aide de deux éléments :
• l’attribut label stipulant la donnée à afficher ;
• l’attribut data permettant d’affecter un identifiant à la donnée affichée dans la liste déroulante.
Notons également la propriété selectedIndex="0" qui indique que nous sélectionnons par
défaut le premier élément de la liste (figure 5-3).
=Flex3 FM.book Page 79 Mardi, 2. décembre 2008 3:32 15
Les composants de contrôle
CHAPITRE 5
Figure 5-3
Sélection du premier élément de la liste
Nous aurions également pu alimenter le dataProvider de la ComboBox à l’aide d’ActionScript :
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
public var listeOiseau:ArrayCollection = new ArrayCollection([
{data:"1", label:"Merle"},
{data:"2", label:"Colibri"},
{data:"3", label:"Mésange"}
])
]]>
</mx:Script>
<mx:ComboBox id="combo_oiseau" x="10" y="29" selectedIndex="1"
➥dataProvider="{listeOiseau}">
</mx:ComboBox>
Signification de la balise <![CDATA[ ]]>
<![CDATA[ ]]> est utilisée pour spécifier que le code situé à l’intérieur de celle-ci n’est pas du XML.
Dans notre cas, il s’agit d’un ensemble de lignes de code ActionScript.
Si nous observons l’alimentation du dataProvider de la ComboBox à l’aide de la collection
listeOiseau, nous notons que l’emploi de variables ActionScript au sein du code MXML
s’effectue à l’aide d’accolades ouvrante et fermante. Cette notation permet de spécifier la
relation existant entre le composant et la variable ; on parle alors de DataBinding.
Le DataBinding ou la liaison de données
Vous avez sans doute remarqué la présence de la mention [Bindable] juste avant la déclaration du
tableau d’objets listeOiseau. Nous reviendrons sur ce point en détail lors du chapitre 11 qui traite de la
gestion des données. Mais vous pouvez d’ores et déjà retenir qu’elle permet de créer une liaison entre le
tableau listeOiseau et le dataProvider de la liste déroulante. Ainsi, si le tableau listeOiseau est
mis à jour, les données contenues dans la liste déroulante le seront également.
79
=Flex3 FM.book Page 80 Mardi, 2. décembre 2008 3:32 15
80
Comprendre Flex 3
PARTIE I
Interaction avec l’utilisateur
Il est intéressant de pouvoir récupérer l’attribut data de la valeur sélectionnée par l’utilisateur afin de l’utiliser dans un traitement. Pour ce faire, il suffit d’utiliser la propriété
selectedItem du composant :
Combo_oiseau.selectedItem.data
Précisons que ce qui vient d’être énoncé pour le composant ComboBox est également valable
pour le composant ListBox :
<mx:List x="10" y="59" dataProvider="{listeOiseau}" id="liste_oiseau" selectedIndex="0">
</mx:List>
Les boutons radio
Un bouton radio seul est apparenté à une case à cocher. Utilisé dans un groupe, il permet
de contraindre l’utilisateur à ne faire qu’un seul choix parmi plusieurs propositions
(figure 5-4).
Figure 5-4
Boutons radio
Implémentation
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<!-- Groupe -->
<mx:RadioButtonGroup id="groupeRadioBoutons"/>
<!-- Boutons -->
<mx:RadioButton id="rb_1" x="55"
➥groupName="groupeRadioBoutons"
<mx:RadioButton id="rb_2" x="55"
➥groupName="groupeRadioBoutons"
y="45.0" label="Masculin"
value="M" />
y="69.0" label="Féminin"
value="F" />
</mx:Application>
Il convient tout d’abord de créer un groupe qui va contenir l’ensemble des boutons radio,
puis les boutons radio proprement dits. Chaque bouton créé devra ensuite être intégré au
groupe à l’aide de la propriété groupName.
Alimentation en données
Pour pouvoir exploiter les boutons radio dans les traitements, il est nécessaire de leur
affecter une valeur grâce à la propriété value. Attention à ne pas la confondre avec la
propriété label dont la valeur correspond au libellé du composant.
=Flex3 FM.book Page 81 Mardi, 2. décembre 2008 3:32 15
Les composants de contrôle
CHAPITRE 5
Interaction avec l’utilisateur
Pour récupérer la valeur d’un bouton radio sélectionné au sein d’un groupe, nous devons
utiliser l’écouteur d’événement ItemClickEvent de ce groupe.
En guise d’illustration, l’exemple ci-dessous permet d’afficher le choix de l’utilisateur
lors de chaque sélection (itemClick) :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.events.ItemClickEvent;
import mx.controls.Alert
public function selection(evenement:ItemClickEvent):void
{
Alert.show(String(evenement.item));
}
]]>
</mx:Script>
<mx:Label id="lab" x="10" y="19" text="Votre sexe :"/>
<mx:RadioButtonGroup id="groupeRadioBoutons" itemClick="selection(event)"/>
<mx:RadioButton id="r1" x="55" y="45.0" label="Masculin" value="M"
➥groupName="groupeRadioBoutons"/>
<mx:RadioButton id="r2" x="55" y="69.0" label="Féminin" value="F"
➥groupName="groupeRadioBoutons"/>
</mx:Application>
Lorsque l’utilisateur sélectionne un bouton radio, il déclenche l’exécution de la procédure
selection(). Cette procédure reçoit en paramètre l’événement de type ItemClickEvent qui
permet de déterminer quel bouton radio du groupe a été sélectionné. Dès lors, il nous est
possible de récupérer la valeur de celui-ci. Notez cependant que la propriété value est ici
remplacée par la propriété item.
En modifiant quelque peu le code ActionScript, il nous est possible de récupérer le libellé
du bouton radio sélectionné (label) :
<mx:Script>
<![CDATA[
import mx.events.ItemClickEvent;
import mx.controls.Alert
public function selection(evenement:ItemClickEvent):void
{
Alert.show(String(evenement.label));
}
]]>
</mx:Script>
81
=Flex3 FM.book Page 82 Mardi, 2. décembre 2008 3:32 15
82
Comprendre Flex 3
PARTIE I
Les zones de texte
L’unique moyen de communication mis à la disposition du développeur pour guider
l’utilisateur à travers son application, ou pour récolter les données saisies par ce dernier,
sont les zones de texte. Dans cette partie, nous allons voir comment utiliser ces composants.
Les libellés : Label et Text
Les libellés permettent d’afficher du texte de taille réduite (par exemple un intitulé de
champ) et non modifiable par l’utilisateur. Contrairement au champ Label, le champ Text
permet d’afficher un texte sur plusieurs lignes (figure 5-5).
<mx:Label id="lab" x="26" y="29" text="Label : Prénom de l'utilisateur" width="88"/>
<mx:Text id="txt" x="26" y="55" text="Text : Prénom de l'utilisateur" width="88"/>
Figure 5-5
Les libellés
Flex 4
Ce composant est voué à disparaître dans la version 4 du framework. Son successeur portera le nom de
TextBox.
Les zones de saisie
Permettre la saisie d’informations est l’une des fonctions principales de toute interface
homme-machine. C’est le rôle des composants TextInput et TextArea grâce auxquelles
l’utilisateur saisira des données, qui seront ensuite interprétées et traitées par l’application.
Implémentation
TextInput et TextArea permettent tous deux à l’utilisateur de saisir des informations. La différence entre ces composants réside dans la possibilité offerte par le composant TextArea de
saisir un texte sur plusieurs lignes, contrairement au composant TextInput (figure 5-6).
Figure 5-6
Les zones de texte
=Flex3 FM.book Page 83 Mardi, 2. décembre 2008 3:32 15
Les composants de contrôle
CHAPITRE 5
<mx:TextInput x="10" y="10" text="TextInput" id=”txt_ti”/>
<mx:TextArea x="10" y="40" height="128" text="TextArea : permet la saisie sur
➥plusieurs lignes" id="txt_tm" />
Alimentation en données et interaction avec l’utilisateur
La propriété text des composants TextInput et TextArea a été affectée du texte que l’on
souhaite afficher. Cette même propriété peut être utilisée en ActionScript afin de récupérer
ou d’alimenter le contenu de la zone de texte.
<!-- Récupération des données -->
public var texteEcrit:String = nomZoneTexte.text
<!-- Alimentation de la zone de texte -->
nomZoneTexte.text = "texte à afficher"
Flex 4
Grâce à la propriété withInChars, Flex 4 permettra de dimensionner automatiquement les zones de
texte en longueur, en fonction du nombre de caractères maximum que l’utilisateur pourra saisir. Pour le
composant textArea, nous aurons en plus la possibilité de définir le nombre de lignes visibles à l’écran
via la propriété heightInLines.
Les zones de texte « riches »
Les composants RichTextEditor offrent de nombreuses possibilités :
• modification de la police (choix de la police, taille, gras, souligné, italique) ;
• mise en forme du texte (modification de la couleur, aligné à gauche ou à droite, centré,
justifié) ;
• utilisation de listes à puces ;
• insertion de liens hypertextes.
Implémentation
Le code suivant montre comment alimenter la zone de texte du composant. La mise en
forme du texte (gras, italique…) est effectuée à l’aide de balises HTML alimentant la
propriété htmlText du composant. Les balises sont ensuite interprétées par le composant
qui en affiche le rendu final (figure 5-7).
<mx:Script>
<![CDATA[
public function alimenterZoneDeTexte():void
{
zoneTexteRiche.htmlText = "<TEXTFORMAT LEADING='2'>" +
"<LI>" +
"<FONT FACE='Verdana' SIZE='12' COLOR='#0B333C' LETTERSPACING=
➥'0' KERNING='0'>" +
"<B>Ceci</B>" +
83
=Flex3 FM.book Page 84 Mardi, 2. décembre 2008 3:32 15
84
Comprendre Flex 3
PARTIE I
"<FONT SIZE='10'> est <FONT FACE='Times New Roman' SIZE='14'>" +
"un lien" +
"</FONT> " +
"vers " +
"<FONT COLOR='#0000FF'>" +
"<A HREF='http://www.google.fr' TARGET='_blank'>" +
"<U>Google</U>" +
"</A>" +
"</FONT>" +
"</FONT>" +
"</FONT>" +
"</LI>" +
"</TEXTFORMAT>"
}
]]>
</mx:Script>
<mx:RichTextEditor x="10" y="10" width="354" id="zoneTexteRiche"
➥creationComplete="alimenterZoneDeTexte()">
</mx:RichTextEditor>
L’événement creationComplete appelle la fonction d’alimentation de la zone de texte une
fois le composant créé. Il peut également être utilisé pour l’ensemble des composants y
compris l’application. Ceci peut s’avérer utile si une procédure doit être exécutée après la
création de l’application.
Figure 5-7
Composant RichTextEditor
Informer l’utilisateur
Si vous souhaitez mettre en place ce composant au sein de vos interfaces, il est nécessaire d’informer
l’utilisateur sur la méthode de création des liens hypertextes, car la tâche n’est pas des plus faciles. En
effet, il devra tout d’abord sélectionner le texte faisant office de lien. La zone de texte contenant http://
s’activera alors et l’invitera à saisir le lien souhaité. Une fois la saisie effectuée, il suffira d’appuyer sur la
touche Entrée du clavier pour valider la saisie et créer le lien.
=Flex3 FM.book Page 85 Mardi, 2. décembre 2008 3:32 15
Les composants de contrôle
CHAPITRE 5
Les tableaux
DataGrid
Pour présenter des données tabulaires de façon classique, le plus simple est de recourir au
composant DataGrid. Nous verrons que malgré cet aspect simpliste, il offre tout de même
différentes fonctionnalités dont la possibilité de trier des colonnes par un simple clic sur
leur en-tête.
Implémentation et alimentation en données
Le code suivant permet d’implémenter le composant DataGrid et de l’alimenter en
données à l’aide d’une collection d’objets (figure 5-8) (ArrayCollection).
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥creationComplete="alimenterDatagrid()">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
public var tableauUtilisateurs:ArrayCollection = new ArrayCollection ([
{id:"1",prenom:"Jean",nom:"Dupont"},
{id:"2",prenom:"Annie",nom:"Lagrange"},
{id:"3",prenom:"Pierre",nom:"Jaures"}
])
public function alimenterDatagrid():void
{
dg_utilisateur.dataProvider = tableauUtilisateurs;
}
]]>
</mx:Script>
<mx:DataGrid id="dg_utilisateur" x="71" y="98" width="329" >
<mx:columns>
<mx:DataGridColumn headerText="Id" dataField="id"/>
<mx:DataGridColumn headerText="Prenom" dataField="prenom"/>
<mx:DataGridColumn headerText="Nom" dataField="nom"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
Ici, nous avons tout d’abord créé une collection d’objets ayant pour attributs id, prenom et
nom. Nous avons ensuite créé le tableau, la propriété dataField permettant de faire le lien
entre la source de données et la colonne du tableau. Ainsi, la première colonne affichera
l’attribut id de la collection d’objets. Puis, la fonction alimenterDatagrid() est appelée
85
=Flex3 FM.book Page 86 Mardi, 2. décembre 2008 3:32 15
86
Comprendre Flex 3
PARTIE I
après la création de l’application (creationCompleted) et affecte la collection d’objets au
dataProvider du DataGrid.
Il est également possible de cacher une colonne en affectant la propriété visible à false.
Figure 5-8
Le composant DataGrid
Interaction avec l’utilisateur
Comme pour les composants précédents, il est intéressant de savoir comment exploiter
l’interaction du composant DataGrid avec l’utilisateur. La question souvent posée dans ce
cas est « Comment récupérer les valeurs de la ligne sélectionnée ?». Pour y répondre,
nous allons écrire une fonction mettant en œuvre l’utilisation de la propriété selectedItem
du composant.
Voici comment procéder si nous souhaitons récupérer l’identifiant de l’individu sélectionné
dans le tableau :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥creationComplete="alimenterDatagrid()">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
public var tableauUtilisateurs:ArrayCollection = new ArrayCollection ([
{id:"1",prenom:"Jean",nom:"Dupont"},
{id:"2",prenom:"Annie",nom:"Lagrange"},
{id:"3",prenom:"Pierre",nom:"Jaures"}
])
public function alimenterDatagrid():void
{
dg_utilisateur.dataProvider = tableauUtilisateurs;
}
=Flex3 FM.book Page 87 Mardi, 2. décembre 2008 3:32 15
Les composants de contrôle
CHAPITRE 5
import mx.controls.Alert
public function infoLigneSelectionnee():void
{
Alert.show(dg_utilisateur.selectedItem.id);
}
]]>
</mx:Script>
<mx:DataGrid id="dg_utilisateur" x="71" y="98" width="329"
➥itemClick="ligneSelectionnee()" >
<mx:columns>
<mx:DataGridColumn headerText="Id" dataField="id"/>
<mx:DataGridColumn headerText="Prenom" dataField="prenom"/>
<mx:DataGridColumn headerText="Nom" dataField="nom"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
Comme pour les boutons radio, on utilise l’événement itemClick faisant appel à la procédure
infoLigneSelectionnee dont le rôle est d’afficher la valeur de l’attribut id.
Manipuler les colonnes par programmation
Toujours dans l’objectif d’offrir à l’utilisateur une part importante d’interaction avec
l’interface graphique, il est intéressant de mettre en place des fonctionnalités liées aux
colonnes du tableau et, pourquoi pas, de lui permettre de masquer ou non certaines d’entre
elles. Pour ce faire, il convient d’affecter un identifiant à chaque colonne, ce qui permettra
de les identifier et d’invoquer leur méthode dans le code ActionScript.
L’exemple de code suivant illustre la mise en place d’une procédure permettant de cacher
la colonne Id du tableau :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥creationComplete="alimenterDatagrid()">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
public var tableauUtilisateurs:ArrayCollection = new ArrayCollection ([
{id:"1",prenom:"Jean",nom:"Dupont"},
{id:"2",prenom:"Annie",nom:"Lagrange"},
{id:"3",prenom:"Pierre",nom:"Jaures"}
])
public function alimenterDatagrid():void
{
dg_utilisateur.dataProvider = tableauUtilisateurs;
87
=Flex3 FM.book Page 88 Mardi, 2. décembre 2008 3:32 15
88
Comprendre Flex 3
PARTIE I
}
// Procédure de manipulation de la colonne colIdentifiant
public function manipulerColonne():void{
if (colIdentifiant.visible == false){
colIdentifiant.visible = true
}else{
colIdentifiant.visible = false
}
}
]]>
</mx:Script>
<mx:DataGrid id="dg_utilisateur" x="71" y="98" width="329" >
<mx:columns>
<!-- Mise en place d'un identifiant -->
<mx:DataGridColumn id="colIdentifiant" headerText="Id" dataField="id"/>
<mx:DataGridColumn headerText="Prenom" dataField="prenom"/>
<mx:DataGridColumn headerText="Nom" dataField="nom"/>
</mx:columns>
</mx:DataGrid>
<!-- Bouton faisant appel à la procédure manipulerColonne() -->
<mx:Button x="71" y="276" label="cacher" id="btn_cacherColonne"
➥click="manipulerColonne()"/>
</mx:Application>
AdvancedDataGrid
Nouveauté du framework Flex 3, le composant AdvancedDataGrid apporte des nombreuses
fonctionnalités concernant la présentation des données tabulaires :
• la présentation de données hiérarchiques (sous forme d’arborescence) ;
• le regroupement de colonnes ;
• le tri sur plusieurs colonnes.
Implémentation et alimentation en données
Voici un exemple permettant de créer un tableau avancé mettant en œuvre la présentation
hiérarchique des données ainsi que le regroupement de colonnes :
=Flex3 FM.book Page 89 Mardi, 2. décembre 2008 3:32 15
Les composants de contrôle
CHAPITRE 5
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
private var tableau:ArrayCollection = new ArrayCollection([
{Pays:"Fance",
children: [
{Pays:"Importation",
children: [{matiere:"Matière A", Quantite:10, Montant:5000},
{matiere:"Matière A", Quantite:30, Montant:9000},
{matiere:"Matière B", Quantite:800, Montant:25000},
{matiere:"Matière B", Quantite:562, Montant:764},
{matiere:"Matière C", Quantite:5, Montant:25658},
]
},
{Pays:"Exportation",
children: [{matiere:"Matiere B", Quantite:58564, Montant:30000}]
}]
}
]);
]]>
</mx:Script>
<mx:AdvancedDataGrid
x="32" y="69"
id="adg1"
designViewDataType="tree"
width="634"
height="314">
<mx:dataProvider>
<mx:HierarchicalData source="{tableau}"/>
</mx:dataProvider>
<mx:groupedColumns>
<mx:AdvancedDataGridColumn headerText="Pays / Catégorie" dataField="Pays"/>
<mx:AdvancedDataGridColumn headerText="Matière" dataField="matiere"/>
<mx:AdvancedDataGridColumnGroup headerText="Quantité et montant">
<mx:AdvancedDataGridColumn headerText="Quantité" dataField="Quantite"/>
<mx:AdvancedDataGridColumn headerText="Montant en ¤" dataField=
➥"Montant"/>
</mx:AdvancedDataGridColumnGroup>
</mx:groupedColumns>
89
=Flex3 FM.book Page 90 Mardi, 2. décembre 2008 3:32 15
90
Comprendre Flex 3
PARTIE I
</mx:AdvancedDataGrid>
</mx:Application>
La figure 5-9 illustre le résultat obtenu à l’aide de ce code.
Figure 5-9
Les tableaux avancés
Par l’instanciation de la classe HierarchicalData, nous indiquons au composant Advanced
DataGrid que les données alimentant son dataProvider sont de type hiérarchiques. Notons
également la spécification du mode de visualisation des données grâce à la propriété
designViewDataType, ici affectée à tree, précisant que les données seront présentées sous
la forme d’une arborescence. Il nous est également possible de présenter les données de
la même manière que pour le composant DataGrid, c’est-à-dire de façon non hiérarchisée,
en affectant la valeur Flat à la propriété designViewDataType. Enfin, notons la présence
d’un regroupement de colonnes, obtenu grâce à la présence des balises <mx:groupedColumns>
et <mx:AdvancedDataGridColumn>. La première indique au composant AdvancedDataGrid que
certaines de ces colonnes feront l’objet d’un regroupement, la seconde balise permet de
préciser les colonnes devant être regroupées.
Interaction avec l’utilisateur
La première interaction avec l’utilisateur est la possibilité de trier le tableau sur plusieurs
colonnes. Pour ce faire, nous devons activer le mode de tri Expert du composant Advanced
DataGrid en affectant la valeur de la propriété sortExpertMode à true.
<mx:AdvancedDataGrid
x="32" y="69"
id="adg1"
designViewDataType="tree"
width="634"
=Flex3 FM.book Page 91 Mardi, 2. décembre 2008 3:32 15
Les composants de contrôle
CHAPITRE 5
height="314"
sortExpertMode="true">
</mx:AdvancedDataGrid>
Voici comment procéder si nous souhaitons trier la colonne Matière et les valeurs de la
colonne Quantité associées :
1. Sélectionnez la colonne Matière en cliquant sur son en-tête.
2. Cliquez ensuite sur la colonne Quantité tout en maintenant la touche Ctrl du clavier
enfoncée.
Les matières seront alors triées par ordre alphabétique et par quantité croissante (figure 5-10).
L’ordre du tri est spécifié par les numéros 1 et 2 apparus à droite des en-têtes des colonnes
utilisées pour le tri, et le critère croissant/décroissant est, quant à lui, indiqué par la flèche
pointant vers le haut/vers le bas.
Notons qu’il est également possible de trier le tableau sur plusieurs colonnes sans activer
le mode Expert. Voici la marche à suivre pour cela :
1. Sélectionnez la colonne Matière en cliquant sur son en-tête.
2. Choisissez une seconde colonne pour le tri.
3. En survolant avec la souris l’emplacement où se trouve le numéro d’ordre de tri,
celui-ci est alors incrémenté de un. En cliquant sur ce dernier, il est possible d’ajouter
un filtre supplémentaire.
Figure 5-10
Tri croissant sur les colonnes Matière et Quantité
Comme précédemment, si nous maintenons la touche Ctrl enfoncée et cliquons sur la
colonne Quantité, les matières seront triées par ordre alphabétique et seront regroupées
cette fois-ci par quantité décroissante (figure 5-11).
Figure 5-11
Tri croissant sur la colonne Matière et décroissant sur la colonne Quantité
91
=Flex3 FM.book Page 92 Mardi, 2. décembre 2008 3:32 15
92
Comprendre Flex 3
PARTIE I
En ce qui concerne la récupération des données de la ligne sélectionnée par l’utilisateur,
la méthode employée est identique à celle utilisée pour le composant DataGrid.
Analyser un cube OLAP avec OLAPDataGrid
L’introduction de ce composant dans la version 3 du framework ouvre les applications
Flex vers le monde décisionnel. En effet, grâce au composant OLAPDataGrid, il est possible
d’afficher les données issues de requêtes effectuées sur un cube OLAP (OnLine Analytical
Processing).
Qu’est-ce qu’un cube OLAP ?
Dans la mesure où les requêtes décisionnelles exécutées sur des bases de données relationnelles demandaient un nombre important de ressources système pour leur exécution, il
convenait d’apporter une solution aux utilisateurs cherchant une réponse à leurs besoins
tout en minimisant le temps d’exécution.
C’est dans ce but que les bases de données OLAP ont été mises au point, permettant de
stocker les données sous forme de dimensions, lesquelles représentent les axes de recherche
des utilisateurs. Il devient ainsi possible de combiner ces dimensions afin d’obtenir les
résultats voulus. Les bases de données OLAP peuvent être représentées sous forme de
cube, appelé cube OLAP. Sur la figure 5-12 illustrant ce concept de base de données,
nous pouvons distinguer trois dimensions :
• D1 : produit ;
• D2 : région ;
• D3 : montant des ventes.
Figure 5-12
Cube OLAP
=Flex3 FM.book Page 93 Mardi, 2. décembre 2008 3:32 15
Les composants de contrôle
CHAPITRE 5
Ces trois dimensions nous permettent de calculer le montant des ventes par région et par
produit, représenté par le sous-cube grisé symbolisant la rencontre des trois données. Ce
sous-cube sera appelé mesure dans le composant OLAPDataGrid. Le nombre de dimensions
étant illimité, il nous sera ainsi possible de déterminer le chiffre d’affaires (dimension 1)
d’une filiale (dimension 2) sur une période de 4 mois (dimension 3) pour un certain
produit (dimension 4) d’une certaine gamme (dimension 5). L’interrogation des données
sur un cube OLAP s’effectue donc par la combinaison de dimensions.
Aller plus loin
Si vous souhaitez en savoir davantage sur ce point, nous vous conseillons de consulter le site Internet
suivant :
http://pagesperso-orange.fr/bernard.lupin/index.htm.
Création d’un cube OLAP
Pour créer notre cube OLAP, nous allons nous baser sur une liste d’enregistrements issus
d’une base de données. Nous pourrons ainsi en déduire les dimensions du cube et procéder
à sa création.
Tableau de données
Le tableau 5-2 présente les enregistrements issus d’une base de données totalisant le
nombre skieurs annuels sur les trois stations de ski S1, S2 et S3.
Tableau 5-2
Données à analyser avec un cube OLAP
Station
Année
Nombre de skieurs
S1
2008
12 000
S1
2007
11 000
S1
2006
18 000
S1
2005
17 444
S2
2008
1 200
S2
2007
4 500
S2
2006
8 000
S2
2005
500
S3
2008
12 500
S3
2007
40 000
S3
2006
8 550
S3
2005
6 000
93
=Flex3 FM.book Page 94 Mardi, 2. décembre 2008 3:32 15
94
Comprendre Flex 3
PARTIE I
Ce tableau peut être dès à présent implémenté en ActionScript comme suit :
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
private var donnees:ArrayCollection = new ArrayCollection(
[
{station:"S1", skieurs:12000, annee:"2008"},
{station:"S1", skieurs:11000, annee:"2007"},
{station:"S1", skieurs:18000, annee:"2006"},
{station:"S1", skieurs:17444, annee:"2005"},
{station:"S2",
{station:"S2",
{station:"S2",
{station:"S2",
skieurs:1200, annee:"2008"},
skieurs:4500, annee:"2007"},
skieurs:8000, annee:"2006"},
skieurs:500, annee:"2005"},
{station:"S3",
{station:"S3",
{station:"S3",
{station:"S3",
skieurs:12500, annee:"2008"},
skieurs:40000, annee:"2007"},
skieurs:8550, annee:"2006"},
skieurs:6000, annee:"2005"}
]);
]]>
Pour l’instant, nous n’avons fait que réaliser l’implémentation d’un tableau de données.
Nous allons à présent voir comment l’utiliser afin de créer les dimensions du cube OLAP.
Mise en place des dimensions
Grâce au tableau que nous venons de créer, nous pouvons déduire la composition du
cube. Celui-ci contiendra ainsi trois dimensions et un champ qui nous servira de mesure :
• dimension 1 : le champ station ;
• dimension 2 : le champ skieurs ;
• dimension 3 : le champ annee ;
• champ de mesure : skieurs, dont nous calculerons la somme.
Voyons comment créer le cube et ses dimensions :
<mx:OLAPCube name="cubeOLAP"
dataProvider="{donnees}"
id="id_cube"
>
<mx:OLAPDimension name="dim_station">
<mx:OLAPAttribute name="att_station" dataField="station"/>
<mx:OLAPHierarchy name="hier_station" hasAll="true">
<mx:OLAPLevel attributeName="att_station"/>
=Flex3 FM.book Page 95 Mardi, 2. décembre 2008 3:32 15
Les composants de contrôle
CHAPITRE 5
</mx:OLAPHierarchy>
</mx:OLAPDimension>
<mx:OLAPDimension name="dim_skieurs">
<mx:OLAPAttribute name="att_skieurs" dataField="skieurs"/>
<mx:OLAPHierarchy name="hier_skieurs" hasAll="true">
<mx:OLAPLevel attributeName="att_skieurs"/>
</mx:OLAPHierarchy>
</mx:OLAPDimension>
<mx:OLAPDimension name="dim_annee">
<mx:OLAPAttribute name="att_annee" dataField="annee"/>
<mx:OLAPHierarchy name="hier_annee" hasAll="true">
<mx:OLAPLevel attributeName="att_annee"/>
</mx:OLAPHierarchy>
</mx:OLAPDimension>
<mx:OLAPMeasure name="SommeSkieurs"
dataField="skieurs"
aggregator="SUM"/>
</mx:OLAPCube>
Notre cube OLAP est créé à l’aide de la balise <mx:OLAPCube>. Les dimensions, quant à
elles, sont créées à l’aide de la balise <mx:OLAPDimension>. Chaque dimension est définie
par un attribut (<mx:OLAPAttribut>) et un niveau de hiérarchie (<mx:OLAPHierarchy> et
<mx:OLAPLevel>). Une hiérarchie représente, de façon simplifiée, le nombre de champs
contenus dans la dimension. Dans notre exemple, chaque dimension possède une hiérarchie
à un seul niveau.
Enfin, nous devons créer une mesure, c’est-à-dire une valeur que nous pourrons visualiser
lorsque nous effectuerons des opérations sur le cube. Nous avons ici choisi comme
mesure la somme du nombre de skieurs (<mx:OLAPMeasure>). Le cube sera alimenté en
données à l’aide de sa propriété dataProvider qui doit être liée à au tableau. Notre cube
est à présent créé et nous pouvons désormais effectuer notre première requête.
Requête sur le cube
La requête que nous allons effectuer nous permettra de visualiser le nombre de skieurs
par station et par année. Le résultat obtenu sera affiché dans le composant OLAPDataGrid.
La liste des stations s’affichera en lignes et la liste des années en colonnes. À chaque
intersection, nous retrouverons notre mesure spécifiée lors de la création du cube, c’està-dire la somme du nombre de skieurs.
Le code suivant correspond au code complet de l’application. Nous l’avons commenté
pour vous permettre de comprendre la méthode de création d’une requête sur un cube
OLAP afin d’en afficher le résultat.
95
=Flex3 FM.book Page 96 Mardi, 2. décembre 2008 3:32 15
96
Comprendre Flex 3
PARTIE I
Important
Le composant OLAPDataGrid sert uniquement à afficher le résultat d’une requête réalisée sur un cube
OLAP. Il est donc impossible d’afficher les données du cube dans le composant OLAPDataGrid. En effet,
un cube possédant plusieurs dimensions, il serait très difficile de les représenter dans un composant ne
présentant que deux dimensions (lignes et colonnes) !
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="afficherOLAPDataGrid();">
<mx:Script>
<![CDATA[
import mx.rpc.AsyncResponder;
import mx.rpc.AsyncToken;
import mx.olap.OLAPQuery;
import mx.olap.OLAPSet;
import mx.olap.IOLAPQuery;
import mx.olap.IOLAPQueryAxis;
import mx.olap.IOLAPCube;
import mx.olap.OLAPResult;
import mx.events.CubeEvent;
import mx.controls.Alert;
import mx.collections.ArrayCollection;
[Bindable]
private var donnees:ArrayCollection = new ArrayCollection(
[
{station:"S1", skieurs:12000, annee:"2008"},
{station:"S1", skieurs:11000, annee:"2007"},
{station:"S1", skieurs:18000, annee:"2006"},
{station:"S1", skieurs:17444, annee:"2005"},
{station:"S2",
{station:"S2",
{station:"S2",
{station:"S2",
skieurs:1200, annee:"2008"},
skieurs:4500, annee:"2007"},
skieurs:8000, annee:"2006"},
skieurs:500, annee:"2005"},
{station:"S3",
{station:"S3",
{station:"S3",
{station:"S3",
skieurs:12500, annee:"2008"},
skieurs:40000, annee:"2007"},
skieurs:8550, annee:"2006"},
skieurs:6000, annee:"2005"}
]);
/*****************************
* 1 : CRÉATION DE LA REQUÊTE
* ***************************/
=Flex3 FM.book Page 97 Mardi, 2. décembre 2008 3:32 15
Les composants de contrôle
CHAPITRE 5
private function creerRequete(cube:IOLAPCube):IOLAPQuery {
// Instanciation de la classe OLAPQUery permettant de créer un objet requête
var requete:OLAPQuery = new OLAPQuery;
// Création de "l’axe" des lignes
var ligne:IOLAPQueryAxis =
requete.getAxis(OLAPQuery.ROW_AXIS);
// Création de "l’axe" des colonnes
var colonne:IOLAPQueryAxis =
requete.getAxis(OLAPQuery.COLUMN_AXIS);
// --- AJOUT DES STATIONS DANS L’AXE DES LIGNES --var lg_stations:OLAPSet = new OLAPSet;
lg_stations.addElements(cube.findDimension("dim_station").
➥findAttribute("att_station").children);
ligne.addSet(lg_stations);
// --- AJOUT DES ANNÉES DANS L’AXE DES COLONNES --var col_annee:OLAPSet= new OLAPSet;
col_annee.addElements(
cube.findDimension("dim_annee").findAttribute("att_annee").children);
colonne.addSet(col_annee);
// Envoi de la requête pour être exécutée par la procédure
➥executerRequête()
return requete;
}
/*****************************
* 2 : EXÉCUTION DE LA REQUÊTE
* ***************************/
private function executerRequete(event:CubeEvent):void {
// Chargement du cube
var cube:IOLAPCube = IOLAPCube(event.currentTarget);
// Réception de la requête par la fonction creerRequete() précédemment
➥créée
var requete:IOLAPQuery = creerRequete(cube);
// Exécution de la requête
var execution:AsyncToken = cube.execute(requete);
// Exécution des procédures afficherResultat ou afficherErreur en
97
=Flex3 FM.book Page 98 Mardi, 2. décembre 2008 3:32 15
98
Comprendre Flex 3
PARTIE I
➥fonction du résultat d’exécution de la requête
execution.addResponder(new AsyncResponder(afficherResultat,
➥afficherErreur));
}
/*****************************
* 3 : AFFICHAGE DU RÉSULTAT
* ***************************/
private function afficherErreur(result:Object, token:Object):void {
Alert.show("Erreur d’exécution de la requête");
}
private function afficherResultat(result:Object, token:Object):void {
if (!result) {
Alert.show("Aucun résultat à afficher");
return;
}
// Mise à jour du composant OLAPDataGrid
OLAPDg.dataProvider= result as OLAPResult;
}
/*********************************************
* 4 : MISE À JOUR DU COMPOSANT OLAPDATAGRID
* Dès la fin de la création de l’application
* (creationCompleted)
* *******************************************/
private function afficherOLAPDataGrid():void
{
// On rafraîchit le cube qui va exécuter la requête
// L’exécution de la procédure executerRequete est appelée
// Après création du cube : complete="executerRequete(event)"
id_cube.refresh();
}
]]>
</mx:Script>
<mx:OLAPCube name="cubeOLAP"
dataProvider="{donnees}"
id="id_cube"
complete="executerRequete(event)">
<mx:OLAPDimension name="dim_station">
<mx:OLAPAttribute name="att_station" dataField="station"/>
=Flex3 FM.book Page 99 Mardi, 2. décembre 2008 3:32 15
Les composants de contrôle
CHAPITRE 5
<mx:OLAPHierarchy name="hier_station" hasAll="true">
<mx:OLAPLevel attributeName="att_station"/>
</mx:OLAPHierarchy>
</mx:OLAPDimension>
<mx:OLAPDimension name="dim_skieurs">
<mx:OLAPAttribute name="att_skieurs" dataField="skieurs"/>
<mx:OLAPHierarchy name="hier_skieurs" hasAll="true">
<mx:OLAPLevel attributeName="att_skieurs"/>
</mx:OLAPHierarchy>
</mx:OLAPDimension>
<mx:OLAPDimension name="dim_annee">
<mx:OLAPAttribute name="att_annee" dataField="annee"/>
<mx:OLAPHierarchy name="hier_annee" hasAll="true">
<mx:OLAPLevel attributeName="att_annee"/>
</mx:OLAPHierarchy>
</mx:OLAPDimension>
<mx:OLAPMeasure name="TotSkieurs"
dataField="skieurs"
aggregator="SUM"/>
</mx:OLAPCube>
<!-- IMPLÉMENTATION DU COMPOSANT OLAPDATAGRID -->
<mx:OLAPDataGrid id="OLAPDg" width="100%" height="275"/>
</mx:Application>
La figure 5-13 illustre le résultat obtenu lors de l’exécution de la requête sur le cube OLAP.
Les lignes correspondent comme convenu aux stations et les années s’affichent en colonnes.
À l’intersection de ces lignes et colonnes, nous pouvons voir la valeur de la mesure.
Figure 5-13
Utilisation du composant OLAPDataGrid
99
=Flex3 FM.book Page 100 Mardi, 2. décembre 2008 3:32 15
100
Comprendre Flex 3
PARTIE I
Tri des colonnes
Le composant OLAPDataGrid ne permet pas de tri sur les colonnes affichées alors que c’est le cas avec
le composant AdvancedDataGrid.
Insérer des images, des animations et vidéos Flash
Intégrer des animations Flash
Grâce au composant SWFLoader, il est possible d’intégrer des animations ou tout autre
programme Flash dans les applications Flex.
<mx:SWFLoader width="148" height="133" id="animation_flash"
scaleContent="true"
autoLoad="true"
source="animation.swf">
</mx:SWFLoader>
L’attribut scaleContent permet d’adapter la taille de l’animation par rapport à celle du
composant. La propriété autoLoad sert, quant à elle, à spécifier si l’animation doit être lue
automatiquement (true) ou non (false). Pour charger une animation par programmation,
il convient donc de spécifier la source et d’exécuter la procédure load() du composant :
public function chargerSWF():void
{
animation_flash.source = "animation.swf";
animation_flash.load();
}
Insérer des images
L’insertion d’images est possible par l’utilisation du composant Image.
L’implémentation de ce composant est identique à celle du composant SWFLoader. Nous
retrouvons donc les propriétés source et scaleContent.
<mx:Image width="128" height="73"
id="img_image"
scaleContent="false"
source="image.gif"
/>
Conseil
Afin que vos images et animations Flash soient prises en compte lors de la compilation de votre projet,
nous vous conseillons de créer un dossier images dans le répertoire src du projet et d’y ajouter l’ensemble
de vos images ou animations Flash.
=Flex3 FM.book Page 101 Mardi, 2. décembre 2008 3:32 15
Les composants de contrôle
CHAPITRE 5
101
Lecteur vidéo Flash
Le composant VideoDisplay permet de lire des vidéos Flash (fichiers .flv), comme le
propose par exemple le site de YouTube.
Le code suivant illustre l’utilisation du composant VideoDisplay et de ses méthodes Play()
et Stop() permettant respectivement de démarrer et de stopper la lecture d’une vidéo
(figure 5-14) :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:VideoDisplay x="28" y="31" width="292" height="263" source="DSCF1311.flv"
➥id="cpVideo" autoPlay="false"/>
<mx:Button x="28" y="302" label="Jouer" click="cpVideo.play();" id="btn_play"/>
<mx:Button x="94" y="302" label="Stop" id="btn_stop" click="cpVideo.stop();"/>
</mx:Application>
La propriété source permet de définir le chemin de la vidéo qui doit être lue par le composant. La lecture de la vidéo s’effectue par l’appel de la méthode Play() de la classe Video
Display.L’arrêt passe par l’emploi de la méthode Stop(). Notez qu’il est également possible de lire automatiquement la vidéo en affectant la valeur true à la propriété autoPlay du
composant.
Figure 5-14
Lecture d’une vidéo Flash
=Flex3 FM.book Page 102 Mardi, 2. décembre 2008 3:32 15
102
Comprendre Flex 3
PARTIE I
Afficher la progression du chargement de la vidéo
Le composant VideoDisplay ne dispose pas d’une barre de progression intégrée. Pour l’afficher, il
convient de développer cette fonctionnalité en utilisant la méthode progress du composant qui tout au
long du chargement exécutera une procédure permettant de calculer le nombre d’octets chargés.
L’exemple de code suivant montre comment procéder pour afficher le pourcentage du chargement de la
vidéo dans une zone de texte :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
// Procédure d’affichage de la barre de progression du chargement de la vidéo
[Bindable]
public var texte:String
public function afficherProgression(e:ProgressEvent):void
{
// Affichage de la barre de progression
txt_progression.visible = true;
// Taille de la vidéo
var tailleVideo:Number = e.bytesTotal;
// Nombre d’octets chargés:
var nbOctets:Number = e.bytesLoaded;
// Calcul du pourcentage de chargement
var pourcentage:Number = Math.round((nbOctets/tailleVideo)*100)
// Affichage du texte
texte = "Chargement de la vidéo : "+ String(pourcentage)+"%";
}
]]>
</mx:Script>
<mx:VideoDisplay progress="afficherProgression(event)" x="28" y="31" width="292"
➥height="263" source="DSCF1311.flv" id="cpVideo" autoPlay="false"/>
<mx:Button x="28" y="302" label="Jouer" click="cpVideo.play();" id="btn_play"/>
<mx:Button x="94" y="302" label="Stop" id="btn_stop" click="cpVideo.stop();"/>
=Flex3 FM.book Page 103 Mardi, 2. décembre 2008 3:32 15
Les composants de contrôle
CHAPITRE 5
103
<!-- AFFICHAGE DE LA PROGRESSION DU CHARGEMENT -->
<mx:Label text="{texte}"
fontWeight="bold"
fontSize="12"
x="28"
y="330"
width="325" id="txt_progression"
visible="false">
</mx:Label>
</mx:Application>
Choisir une couleur dans une palette avec ColorPicker
Ce composant trouve sa place dans une application à vocation graphique. En effet, il
permet de choisir une couleur dans une palette par défaut ou définie par le développeur
(figure 5-15).
Figure 5-15
Composant ColorPicker
Prenons comme exemple de travail un jeu de Mastermind où l’utilisateur peut choisir une
couleur parmi les suivantes (figure 5-16) :
Couleur
Code correspondant
Bleu
0x0033CC
0x33CC00
0xFF0000
0xFFFF00
0xFF9900
0x9900CC
0xFF00FF
Vert
Rouge
Jaune
Orange
Violet
Fuchsia
=Flex3 FM.book Page 104 Mardi, 2. décembre 2008 3:32 15
104
Comprendre Flex 3
PARTIE I
Figure 5-16
Exemple d’utilisation du composant
ColorPicker dans le jeu Mastermind
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
[Bindable]
public var tableauCouleurs:Array = ['0x0033CC','0x33CC00',
➥'0xFF0000','0xFFFF00','0xFF9900','0x9900CC','0xFF00FF'
];
]]>
</mx:Script>
<mx:ColorPicker id="selecteurCouleur" x="86" y="75" dataProvider="{tableauCouleurs}" />
</mx:Application>
La liste des couleurs est contenue dans un tableau servant à alimenter le dataProvider du
composant. Pour récupérer le code couleur sélectionné, on utilisera la propriété selected
Item du composant, comme nous l’aurions fait pour une simple liste.
Contrôler le format de date avec DateChooser et DateField
Afin de faciliter la saisie et d’éviter les erreurs de format de date, Flex met à votre disposition deux composants :
• Le composant dateChooser qui se présente sous la forme d’un calendrier grâce auquel
l’utilisateur peut sélectionner la date souhaitée. Notez néanmoins que la date ainsi
choisie n’est pas présente sous forme littérale (par exemple : 16 octobre 2008).
• Le composant dateField qui se présente sous la forme d’une zone de texte contenant la
date au format littéral et dont le contenu ne peut être modifié qu’en sélectionnant une
date dans le calendrier associé.
=Flex3 FM.book Page 105 Mardi, 2. décembre 2008 3:32 15
Les composants de contrôle
CHAPITRE 5
105
De nombreux paramétrages peuvent être effectués sur ces composants. Dans l’exemple
suivant, nous avons choisi de les « franciser » en affichant les mois en français dans les
calendriers et la date au format jour/mois/année dans le composant dateField.
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
[Bindable]
public var moisFrancais:Array = ['Janvier','Février','Mars','Avril',
➥'Mai','Juin','Juillet','Août','Septembre','Octobre','Novembre','Décembre'];
]]>
</mx:Script>
<mx:DateChooser id="calendrier" x="35" y="31" monthNames="{moisFrancais}"/>
<mx:DateField id="zoneDeTexte" x="35" y="219" formatString="DD/MM/YYYY"
➥monthNames="{moisFrancais}"/>
</mx:Application>
Il est possible de connaître la date sélectionnée à l’aide de la propriété selectedDate
accompagnée de la donnée choisie. Prenons pour exemple la date 02/03/2008, sélectionnée
dans le composant Calendrier :
• Calendrier.selectedDate.date renverra la valeur 2.
• Calendrier.selectedDate.month retournera la valeur 2 étant donné que le premier mois
de l’année porte le numéro 0.
• Calendrier.selectedDate.fullYear retournera la valeur 2008.
Ajouter un curseur avec HSlider et VSlider
L’intérêt de ces composants est qu’ils permettent à l’utilisateur de sélectionner une valeur
dans un intervalle défini en déplaçant simplement un curseur sur une barre horizontale
(HSlider) ou verticale (VSlider). Voyons comment implémenter ce composant à travers
les quelques lignes suivantes :
<mx:HSlider id=”intervalHorizontal” x="10" y="21"
tickInterval="2"
minimum="0"
snapInterval="2"
maximum="20" labels="[0,2,4,6,8,10,12,14,16,18,20]"
width="270"/>
=Flex3 FM.book Page 106 Mardi, 2. décembre 2008 3:32 15
106
Comprendre Flex 3
PARTIE I
Figure 5-17
Composant HSlider
Comme le montre la figure 5-17, le composant créé pour le code précédent est de type
horizontal et propose un intervalle de valeurs comprises entre 0 et 20 avec un pas de 2
(tickInterval). Le déplacement du curseur sera également effectué à l’aide d’un pas de 2
grâce à la propriété snapInterval portée à cette valeur. Par ailleurs, les libellés ont été
définis manuellement afin de rendre l’utilisation du composant plus conviviale, car les
libellés ne sont pas spécifiés par défaut lors de la mise en place de ces deux composants.
Enfin, la valeur sur laquelle est positionné le curseur peut aisément être récupérée grâce
à la propriété value du composant.
L’incrémentation avec NumericStepper
Le composant NumericStepper est semblable aux composants HSlider et Vslider à la seule
différence que l’utilisateur utilise dans ce cas un ascenseur et non un curseur (figure 5-18).
Figure 5-18
Composant NumericStepper
<mx:NumericStepper id="numStepper" x="10" y="28"
minimum="0"
maximum="20"
stepSize="2"/>
Au titre des différences, soulignons également l’emploi la propriété stepSize (au lieu de
tickInterval pour les composants Hslider et Vslider) qui permet de définir le pas.
Présentation de données avec HorizontalList et TileList
Ces composants permettent de présenter des données en combinant aspect graphique et
données. En d’autres termes, si nous considérons une application spécifique au domaine
du e-commerce, ces composants peuvent êtres utilisés afin de visualiser l’image d’un
produit ainsi que ses caractéristiques (prix, description, etc.).
Dans un autre domaine, nous pouvons utiliser ces composants dans le milieu médical afin
d’afficher la liste des lits hospitaliers occupés ou non avec le nom du patient le cas échéant
(figure 5-19). Pour cela, il convient de placer deux images dans le répertoire images
préalablement créé dans le répertoire src du projet.
=Flex3 FM.book Page 107 Mardi, 2. décembre 2008 3:32 15
Les composants de contrôle
CHAPITRE 5
107
Figure 5-19
Composant HorizontalList
<mx:HorizontalList id="hzliste" x="10" y="28" width="381">
<mx:dataProvider>
<mx:Array>
<mx:Object label="M. Dupont" icon="@Embed(source='images/litOccupe
➥.jpg')"/>
<mx:Object label="--" icon="@Embed(source='images/litVide.jpg')"/>
<mx:Object label="Mme Lesage" icon="@Embed(source='images/litOccupe
➥.jpg')"/>
</mx:Array>
</mx:dataProvider>
</mx:HorizontalList>
Cet exemple permet d’introduire la méthode d’alimentation du dataProvider de notre
composant ; elle est bien évidemment identique pour l’ensemble des composants utilisant
un dataProvider. Il s’agit d’illustrer en MXML le ArrayCollection du langage ActionScript.
On retrouve la balise Array, contenant l’ensemble des objets (object) possédant les attributs
label et icon.
Réaliser des hyperliens grâce à LinkButton
Ce composant permet à l’utilisateur d’ouvrir la page web associée à un hyperlien après
avoir cliqué dessus (figure 5-20), grâce à la méthode navigateToUrl.
Figure 5-20
Composant LinkButton
<mx:LinkButton x="21" y="37"
label="Lien vers les éditions Eyrolles"
click="navigateToURL(new URLRequest('http://www.eyrolles.com'))" />
=Flex3 FM.book Page 108 Mardi, 2. décembre 2008 3:32 15
108
Comprendre Flex 3
PARTIE I
Cette portion de code provoque l’ouverture d’une nouvelle fenêtre dans le navigateur
web. Notez que l’affichage de cette fenêtre peut être bloqué en fonction des paramètres
de sécurité spécifiés sur votre poste de travail.
Afficher des données sous forme d’arborescence
Le composant Tree est très souvent utilisé pour afficher des données organisées de façon
hiérarchique (listing des fichiers d’un répertoire, e-mails contenus dans la boîte de réception
d’un logiciel de messagerie électronique…).
Implémentation et alimentation en données
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
[Bindable]
public var listeXML:XML = new XML(
<fichiers>
<niveau1 label='N1'>
<niveau2 label='N2'>
<element id='1' label='Fichier 1'/>
</niveau2>
</niveau1>
<niveau1 label='N1'>
<niveau2 label='N2'>
<element id='2' label='Fichier 2'/>
</niveau2>
</niveau1>
<niveau1 label='N1'>
<niveau2 label='N2'>
<element id='3' label='Fichier 3'/>
</niveau2>
</niveau1>
</fichiers>
);
]]>
</mx:Script>
<mx:Tree x="10" y="10" width="258" height="376" id="arbre"
dataProvider="{listeXML.niveau1}"
labelField="@label">
</mx:Tree>
</mx:Application>
=Flex3 FM.book Page 109 Mardi, 2. décembre 2008 3:32 15
Les composants de contrôle
CHAPITRE 5
109
Un arbre (figure 5-21) ayant pour vocation d’afficher des données hiérarchiques telles
que celles contenues dans un fichier XML, nous avons donc tout naturellement créé une
variable XML contenant un ensemble de données. Cette variable va alimenter le dataProvider du composant Tree en prenant soin de sélectionner le niveau1 comme premier
niveau hiérarchique.
Il faut également spécifier les libellés pour assurer la présentation des données (labelField).
Pour cela que nous faisons appel à la propriété label (@label) de chaque nœud.
Figure 5-21
Affichage de données hiérarchiques
à l’aide du composant Tree
Interaction avec l’utilisateur
La principale interaction consiste à récupérer la valeur d’un nœud de l’arbre sélectionné
par l’utilisateur afin de l’exploiter dans un traitement. Voici comment procéder :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.events.ListEvent;
import mx.controls.Alert
[Bindable]
public var listeXML:XML = new XML(
<fichiers>
<niveau1 label='N1'>
=Flex3 FM.book Page 110 Mardi, 2. décembre 2008 3:32 15
110
Comprendre Flex 3
PARTIE I
<niveau2 label='N2'>
<element id='1' label='Fichier 1'/>
</niveau2>
</niveau1>
<niveau1 label='N1'>
<niveau2 label='N2'>
<element id='2' label='Fichier 2'/>
</niveau2>
</niveau1>
<niveau1 label='N1'>
<niveau2 label='N2'>
<element id='3' label='Fichier 3'/>
</niveau2>
</niveau1>
</fichiers>
);
public function afficherLabel(e:ListEvent):void
{
Alert.show(e.currentTarget.selectedItem.@label);
}
]]>
</mx:Script>
<mx:Tree x="10" y="10" width="258" height="376" id="arbre"
dataProvider="{listeXML.niveau1}"
labelField="@label"
itemClick="afficherLabel(event)">
</mx:Tree>
</mx:Application>
Lorsque l’utilisateur clique sur un élément de l’arbre (itemClick), cela déclenche l’exécution
de la procédure afficherLabel() dont l’événement de type ListeEvent est passé en paramètre, permettant ainsi de déterminer l’élément de l’arbre sélectionné et d’en extraire sa
propriété label (@label)
En résumé
Dans ce chapitre, nous avons étudié les composants permettant une interaction avec
l’utilisateur de l’application. Nous sommes à présent en mesure de créer des listes déroulantes, de déclencher des actions à l’aide de boutons, de présenter des données sous
forme tabulaire, etc. L’étape suivante va consister à étudier les composants qui vont nous
permettre de positionner ces composants de contrôle.
=Flex3 FM.book Page 111 Mardi, 2. décembre 2008 3:32 15
6
Les composants conteneurs
Grâce à la lecture du chapitre précédent, vous connaissez maintenant les principaux
composants de contrôle. Nous allons désormais vous présenter les différents composants
chargés de jouer le rôle de « conteneur de composants » et permettant d’agencer et
d’organiser ces derniers.
Créer une barre de menus avec ApplicationControlBar
Le composant ApplicationControlBar permet de créer une barre de menus utile à la navigation dans laquelle diverses actions, comme un champ de recherche, peuvent être
proposées.
Le code suivant permet de créer une barre de menus contenant une zone de texte et un
bouton Rechercher afin que l’utilisateur puisse effectuer une recherche dans un champ
d’une base de données (figure 6-1).
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:ApplicationControlBar x="10" y="10" dock="true">
<mx:Label text="Rechercher :" id="lab_rechercher"/>
<mx:TextInput id="txt_rechercher"/>
<mx:Button label="Ok" width="42" id="btn_ok"/>
</mx:ApplicationControlBar>
</mx:Application>
=Flex3 FM.book Page 112 Mardi, 2. décembre 2008 3:32 15
112
Comprendre Flex 3
PARTIE I
En affectant la valeur true à la propriété dock, nous indiquons que nous souhaitons que la
barre de menus soit positionnée en haut de l’application. Pour la placer à un autre endroit
dans l’application, il suffit de passer cette valeur à false.
Figure 6-1
Utilisation du composant ApplicationControlBar
Le composant Canvas
Ce composant conteneur Canvas permet de placer d’autres composants à l’intérieur de
celui-ci à l’aide de leurs coordonnées x et y.
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Canvas id="cn1" x="54" y="48" width="200" height="200">
<mx:Button x="51" y="93" label="Valider" id="btn_valider"/>
</mx:Canvas>
</mx:Application>
Nous constatons que le composant Button est positionné à l’intérieur du canevas à l’aide
de ses propriétés x et y (figure 6-2). Exactement comme en algèbre, les coordonnées (x,y)
des éléments situés dans le canevas ont pour coordonnées relatives le coin supérieur
gauche du canevas. Ainsi, notre bouton est espacé de 51 pixels sur l’axe horizontal et de
93 pixels sur l’axe vertical du coin supérieur gauche du canevas.
Figure 6-2
Utilisation du
composant Canvas
=Flex3 FM.book Page 113 Mardi, 2. décembre 2008 3:32 15
Les composants conteneurs
CHAPITRE 6
113
Aligner verticalement ou horizontalement les composants
Nous allons à présent voir comment aligner automatiquement les composants selon un
axe horizontal ou vertical.
Les composants HBox et VBox
Le composant HBox permet d’aligner automatiquement les composants sur l’axe horizontal (les uns à côté des autres), alors que le composant VBox permet de les aligner sur l’axe
vertical (les uns en dessous des autres).
À l’aide du code suivant, nous avons illustré l’implémentation des composants HBox et
VBox via l’organisation horizontale (HBox) et ou verticale (VBox) de trois boutons.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Label id="lab" x="10" y="5" text="HBox" width="151" fontWeight="bold"/>
<mx:HBox id="hb" x="10" y="29" width="151">
<mx:Button label="B1" id="btn_1"/>
<mx:Button label="B2" id="btn_2"/>
<mx:Button label="B3" id="btn_3"/>
</mx:HBox>
<mx:Label id="lab2" x="220" y="5" text="VBox" width="151" fontWeight="bold"/>
<mx:VBox id="vb" x="220" y="29" height="116">
<mx:Button label="B4" id="btn_4"/>
<mx:Button label="B5" id="btn_5"/>
<mx:Button label="B6" id="btn_6"/>
</mx:VBox>
</mx:Application>
La figure 6-3 présente le résultat ainsi obtenu.
Figure 6-3
Composants HBox et VBox
Les composants HDividedBox et VDividedBox
Ces composants ont le même rôle que les composants HBox et VBox à la seule différence
qu’ils permettent d’afficher un séparateur mobile.
=Flex3 FM.book Page 114 Mardi, 2. décembre 2008 3:32 15
114
Comprendre Flex 3
PARTIE I
Le code suivant illustre un exemple d’implémentation de ces deux composants :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Label id="lab" x="10" y="17" text="HDividedBox" fontWeight="bold"/>
<mx:HDividedBox id="hdb" x="10" y="43" width="540" height="116">
<mx:Canvas id="cv1" width="200" height="115" backgroundColor="#BCB8B8">
</mx:Canvas>
<mx:Canvas id="cv2" width="230" height="115" backgroundColor="#F9F8F8">
</mx:Canvas>
</mx:HDividedBox>
<mx:Label id="lab2" x="10" y="172" text="VDividedBox" fontWeight="bold"/>
<mx:VDividedBox id="vdb" x="10" y="198" height="312" width="540">
<mx:Canvas id="cv3" width="539" height="200" backgroundColor="#BCB8B8">
</mx:Canvas>
<mx:Canvas id="cv4" width="541" height="200" backgroundColor="#FBFBFB">
</mx:Canvas>
</mx:VDividedBox>
</mx:Application>
La figure 6-4 illustre le résultat obtenu après exécution de ce code. On constate la
présence d’un séparateur pouvant être déplacé vers la gauche ou vers la droite pour le
composant HDividedBox, et vers le haut ou vers le bas pour le composant VdividedBox.
L’utilisateur peut ainsi agrandir ou réduire la zone de son choix en sélectionnant ce séparateur et en déplaçant sa souris de droite à gauche ou de haut en bas.
Figure 6-4
Implémentation
des composants
HDividedBox et
VDividedBox
=Flex3 FM.book Page 115 Mardi, 2. décembre 2008 3:32 15
Les composants conteneurs
CHAPITRE 6
115
Créer des formulaires avec Form, FormHeading et FormItem
Les composants Form, FormHeading et FormItem sont les plus communément utilisés au sein
des applications Flex car ils permettent de créer des formulaires de saisie.
Le code suivant permet de créer un formulaire d’inscription intitulé « Nouvel utilisateur : » (FormHeading) ainsi que les trois items de formulaire (FormItem) suivants :
• l’item Prénom, dont la saisie est obligatoire (required="true") ;
• l’item Nom ;
• le bouton Valider.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Form x="10" y="19" width="269" height="168">
<mx:FormHeading label="Nouvel utilisateur :"/>
<mx:FormItem id="fit1" label="Prénom :" required="true">
<mx:TextInput id="txt_prenom"/>
</mx:FormItem>
<mx:FormItem id="fit2" label="Nom :">
<mx:TextInput id="txt_nom"/>
</mx:FormItem>
<mx:FormItem id="fit3">
<mx:Button label="Valider" id="btn_valider"/>
</mx:FormItem>
</mx:Form>
</mx:Application>
La figure 6-5 illustre le résultat obtenu.
Figure 6-5
Création d’un formulaire
=Flex3 FM.book Page 116 Mardi, 2. décembre 2008 3:32 15
116
Comprendre Flex 3
PARTIE I
Créer une grille grâce à Grid
Le composant Grid permet d’organiser les composants selon une grille. Le code suivant
illustre son implémentation constitué de trois lignes et de trois colonnes dont certaines
doivent contenir un chiffre.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Grid id="gd" x="10" y="10" width="212" height="198">
<mx:GridRow width="100%" height="100%">
<mx:GridItem width="100%" height="43">
<mx:Label text="1" fontWeight="bold" fontSize="28" height="39" width="65"
➥textAlign="center" id="l1"/>
</mx:GridItem>
<mx:GridItem width="100%" height="100%">
<mx:Label text="3" fontWeight="bold" fontSize="28" height="39" width="65"
➥textAlign="center" id="l2"/>
</mx:GridItem>
<mx:GridItem width="100%" height="100%">
</mx:GridItem>
</mx:GridRow>
<mx:GridRow width="100%" height="100%">
<mx:GridItem width="100%" height="100%">
</mx:GridItem>
<mx:GridItem width="100%" height="100%">
<mx:Label text="2" fontWeight="bold" fontSize="28" height="39" width="65"
➥textAlign="center" id="l3"/>
</mx:GridItem>
<mx:GridItem width="100%" height="100%">
<mx:Label text="1" fontWeight="bold" fontSize="28" height="39" width="65"
➥textAlign="center" id="l4"/>
</mx:GridItem>
</mx:GridRow>
<mx:GridRow width="100%" height="100%">
<mx:GridItem width="100%" height="100%">
<mx:Label text="3" fontWeight="bold" fontSize="28" height="39" width="65"
➥textAlign="center" id="l5"/>
</mx:GridItem>
<mx:GridItem width="100%" height="100%">
<mx:Label text="1" fontWeight="bold" fontSize="28" height="39" width="65"
➥textAlign="center" id="l6"/>
</mx:GridItem>
<mx:GridItem width="100%" height="100%">
</mx:GridItem>
</mx:GridRow>
</mx:Grid>
</mx:Application>
=Flex3 FM.book Page 117 Mardi, 2. décembre 2008 3:32 15
Les composants conteneurs
CHAPITRE 6
117
Chaque ligne est créée grâce à la balise <mx:GridRow> et le nombre de cellules qu’elle
contient est spécifié par la balise <mx:GridItem>.
La figure 6-6 illustre le résultat obtenu après exécution du code.
Figure 6-6
Utilisation du
composant Grid
Les panneaux : Panel
Le composant Panel est l’un des composants de type conteneur les plus utilisés. Il permet
en effet de disposer les composants à l’aide de leur coordonnées x et y, tout comme le
composant Canvas mais en offrant un aspect graphique plus intéressant comme la
présence d’un titre ou la possibilité d’ajouter une icône.
Le code suivant met en place un composant Panel contenant un formulaire d’identification et
une icône.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Panel x="10" y="10" width="355" height="182" titleIcon="@Embed('login.jpg')"
➥layout="absolute" title="Identification" id="panel_identification">
<mx:Form id="form" x="10" y="10" width="315" height="117">
<mx:FormItem id="fit1" label="Identifiant :">
<mx:TextInput id="id_txt"/>
</mx:FormItem>
<mx:FormItem id="fit2" label="Mot de passe :">
<mx:TextInput displayAsPassword="true" id="mdp_txt" text=”1234”/>
</mx:FormItem>
<mx:FormItem id="fit3">
<mx:Button label="OK" id="btn_ok"/>
</mx:FormItem>
</mx:Form>
</mx:Panel>
</mx:Application>
=Flex3 FM.book Page 118 Mardi, 2. décembre 2008 3:32 15
118
Comprendre Flex 3
PARTIE I
Par l’utilisation de la propriété titleIcon, il nous est possible d’affecter une icône au
composant Panel. Notez également que nous avons affecté la valeur true à la propriété
displayPassword du composant mdp_txt. Ceci a pour effet de remplacer le texte en cours de
saisie par des astérisques, permettant ainsi de cacher le mot de passe.
Le résultat obtenu après exécution de ce code est représenté à la figure 6-7.
Figure 6-7
Composant Panel
Créer des fenêtres pop-ups avec TitleWindow
La création d’une fenêtre pop-up s’effectue en deux temps : la première étape consiste à
créer le pop-up et la seconde, à faire appel à ce dernier dans la fenêtre de l’application
principale. Nous allons voir cela en détail.
Création du pop-up
Pour réaliser un pop-up, il convient tout d’abord de créer un projet que nous nommerons
projetPopUp, dans lequel nous créerons un nouveau fichier composant MXML, nommé
popUp.mxml, via le menu File>New>MXML Component. Ce fichier doit être basé sur le
composant TitleWindow, et va décrire l’interface graphique du pop-up grâce au code suivant :
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
width="248" height="204"
title="Fenêtre pop-up"
showCloseButton="true"
close="fermerPopUp()" >
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager
public function fermerPopUp():void
{
PopUpManager.removePopUp(this);
}
]]>
=Flex3 FM.book Page 119 Mardi, 2. décembre 2008 3:32 15
Les composants conteneurs
CHAPITRE 6
119
</mx:Script>
<mx:TextInput id="txt_message"/>
<mx:Button label="Ok" id="btn_ok"/>
</mx:TitleWindow>
Ici, nous avons implémenté une procédure faisant appel à la classe PopUpManager qui
permet de gérer les pop-ups. Cette classe propose deux méthodes principales pour cela :
• createPopUp(fenêtre chargée de contenir le pop-up, Nom du pop-up, pop-up modal
(true/false)) permet de créer et d’afficher le pop-up ;
• removePopUp(nom du pop-up) supprime le pop-up.
Grâce à ces méthodes, nous avons créé une procédure déclenchant la fermeture du popup lorsque l’utilisateur clique sur la croix de fermeture située en haut à droite du pop-up,
dont nous avons spécifié la présence en affectant la valeur true à la propriété showCloseButton (figure 6-8).
Figure 6-8
Création de la
fenêtre pop-up
Appel du pop-up
Maintenant que nous avons créé le pop-up, nous allons voir comment l’utiliser au sein
de notre application. Plaçons-nous à présent dans le fichier principal de l’application
(projetPopUp.mxml) et saisissons le code suivant :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;
public function ouvrirPopUp():void{
=Flex3 FM.book Page 120 Mardi, 2. décembre 2008 3:32 15
120
Comprendre Flex 3
PARTIE I
PopUpManager.createPopUp(this,popUp,true);
}
]]>
</mx:Script>
<mx:Button x="32" y="32" label="Afficher pop-up" click="ouvrirPopUp()"
➥id="btn_ouvrirpopup"/>
</mx:Application>
Dans cet exemple, le bouton btn_ouvrirpopup déclenche l’exécution de la procédure
ouvrirPopUp() qui crée un nouveau pop-up à partir du fichier popUp.mxml que nous venons
d’enregistrer (figure 6-9). La création de cette fenêtre pop-up est réalisée à l’aide de la
méthode createPopUp de la classe PopUpManager. Voyons sa syntaxe en détail :
• This = fenêtre parent (dans notre cas, il s’agit de la fenêtre principale de l’application).
• popUp = nom du fichier MXML implémentant le composant TitleWindow.
• true = spécifie si le pop-up doit être modal (c’est-à-dire s’il doit être fermé pour
permettre l’utilisation de la fenêtre parent) ou non.
Figure 6-9
Ouverture d’un pop-up
Communiquer avec le pop-up
Créer un pop-up c’est bien, mais pouvoir communiquer avec lui c’est encore mieux !
Nous allons, à travers le code suivant, montrer comment envoyer des données au pop-up.
Ces dernières seront ensuite affichées dans une zone de texte du pop-up.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;
=Flex3 FM.book Page 121 Mardi, 2. décembre 2008 3:32 15
Les composants conteneurs
CHAPITRE 6
121
public function ouvrirPopUp():void{
<!-- Création d’un objet de type pop-up issu du fichier popUp.mxml -->
var objetPopUp:popUp = popUp(PopUpManager.createPopUp(this,popUp,true));
<!-- Modification de la propriété text du champ txt_message de l’objet
➥objetPopUp -->
objetPopUp.txt_message.text = "Message transferé !";
}
]]>
</mx:Script>
<mx:Button x="32" y="32" label="Afficher pop-up" click="ouvrirPopUp()"
➥id="btn_ouvrirpopup"/>
<mx:TextInput x="32" y="71" id="txt_messageapplication"/>
</mx:Application>
En premier lieu, nous avons ajouté une zone de texte dans le fichier MXML de l’application,
afin que les données transmises puissent y être affichées :
<mx:TextInput x="32" y="71" id="txt_messageapplication"/>
Nous avons ensuite modifié le code du pop-up comme suit :
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
width="248" height="204"
title="Fenêtre pop-up"
showCloseButton="true"
close="fermerPopUp()" >
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager
public function fermerPopUp():void
{
PopUpManager.removePopUp(this);
}
public function envoyerMessage():void
{
parentApplication.txt_messageapplication.text = "Message reçu !";
}
]]>
</mx:Script>
<mx:TextInput id="txt_message"/>
<mx:Button label="Ok" id="btn_ok" click="envoyerMessage()"/>
</mx:TitleWindow>
=Flex3 FM.book Page 122 Mardi, 2. décembre 2008 3:32 15
122
Comprendre Flex 3
PARTIE I
Lorsque l’utilisateur cliquera sur le bouton btn_ok, la propriété text du champ
txt_messageapplication de l’application parente (celle contenant le pop-up) sera mise à
jour. C’est donc en utilisant la propriété parentApplication reprenant la notion de parenté
qu’il devient possible de communiquer à partir du pop-up vers l’application qui le
contient.
La figure 6-10, illustre les résultats obtenus par la communication de l’application avec le
pop-up et inversement.
Figure 6-10
Communication
de l’application
vers le pop-up puis
du pop-up vers
l’application
En résumé
Au cours de ce chapitre, nous avons découvert les principaux composants conteneurs qui
vont nous permettre d’agencer les différents composants de contrôle au sein de nos interfaces. Nous avons également vu qu’il est possible de créer un pop-up et de communiquer
avec lui. Ce dernier point nous a permis d’aborder la notion de composant que nous
étudierons en détail au chapitre 10 de cet ouvrage. Nous pouvons à présent poursuivre
notre apprentissage en découvrant les composants qui vont nous permettre de naviguer à
travers nos applications et ceux dédiés à la notion de reporting : les composants graphiques.
=Flex3 FM.book Page 123 Mardi, 2. décembre 2008 3:32 15
7
Les composants
de navigation et de reporting
Nous voici à présent au dernier chapitre consacré aux différents composants contenus
dans le framework Flex. Après les composants de contrôle et les composants conteneurs,
nous allons à nous concentrer sur les composants chargés de la navigation au sein de
notre application (onglets, menus en accordéon…), ainsi que ceux permettant de créer
des applications de reporting (analyse statistique) : les composants de graphiques.
Les composants de navigation
Au cours de cette section, nous allons étudier les composants proposant aux utilisateurs
des options de navigation dans l’application. Nous allons ici décrire les trois composants
les plus utilisés : TabNavigator, ViewStack et Accordion.
Navigation par onglets avec TabNavigator
Lorsque le nombre de composants devient trop important pour que l’ensemble soit
contenu dans un seul panneau, il est préférable d’utiliser des onglets, ce que permet le
composant TabNavigator.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:TabNavigator x="10" y="10" width="516" height="400" id="tbn">
<mx:Canvas label="Onglet 1" width="100%" height="100%" >
</mx:Canvas>
=Flex3 FM.book Page 124 Mardi, 2. décembre 2008 3:32 15
124
Comprendre Flex 3
PARTIE I
<mx:Canvas label="Onglet 2" width="100%" height="100%">
</mx:Canvas>
</mx:TabNavigator>
</mx:Application>
Cette portion de code permet de créer deux onglets. Si nous observons attentivement ces
quelques lignes, nous voyons qu’un onglet n’est rien d’autre qu’un composant Canvas
dont le libellé servira à définir le titre de l’onglet (figure 7-1).
Figure 7-1
Exemple d’implémentation
de deux onglets
Le libellé du composant Canvas ne s’affichera pas si ce dernier n’est pas contenu dans un
composant TabNavigator.
Vues empilées avec ViewStack
Ce type de navigation s’apparente à la navigation par onglets. Cependant, à l’inverse du
composant TabNavigator, le composant ViewStack utilise un système de vues empilées et
la navigation entre chacune de ces vues peut être réalisée à l’aide des composants
suivants :
• LinkBar ;
• TabBar ;
• ButtonBar ;
• ToggleButtonBar.
En alimentant le dataProvider de chacun de ces composants avec le nom du composant
ViewStack, ces derniers sont alors capables de récupérer les libellés des vues et de les afficher.
Voici un exemple utilisant le composant ViewStack couplé au composant ToggleButtonBar.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:ToggleButtonBar x="10" y="10" width="503" dataProvider="ensembleVues"
➥id="tg_barre">
</mx:ToggleButtonBar>
=Flex3 FM.book Page 125 Mardi, 2. décembre 2008 3:32 15
Les composants de navigation et de reporting
CHAPITRE 7
125
<mx:ViewStack x="10" y="38" id="ensembleVues" width="497" height="327">
<mx:Canvas label="Vue 1" width="100%" height="100%" id="Vue_1"
➥backgroundColor="#E0BCBC">
</mx:Canvas>
<mx:Canvas label="Vue 2" width="100%" height="100%" id="Vue_2"
➥backgroundColor="#444697">
</mx:Canvas>
<mx:Canvas label="Vue 3" width="100%" height="100%" id="Vue_3"
➥backgroundColor="#A254B5">
</mx:Canvas>
</mx:ViewStack>
</mx:Application>
Chaque vue n’est autre qu’un composant Canvas. Nous pouvons également observer que
le composant ViewStack alimente le dataProvider du composant ToggleButtonBar, permettant
ainsi l’affichage du libellé de chaque vue dans ce dernier (figure 7-2).
Figure 7-2
Utilisation des composants ViewStack et ToggleButtonBar
=Flex3 FM.book Page 126 Mardi, 2. décembre 2008 3:32 15
126
Comprendre Flex 3
PARTIE I
Si nous souhaitons sélectionner une vue par défaut, il suffit d’affecter son numéro d’index
à la méthode selectedIndex du composant ToogleButtonBar :
< !-- Sélection de la vue 2 ayant pour numéro d’index 1 -->
<mx:ToggleButtonBar x="10" y="10" width="503" dataProvider="ensembleVues"
➥id="tg_barre" selectedIndex="1">
</mx:ToggleButtonBar>
Attention
Le premier élément du composant ViewStack a pour numéro d’index la valeur 0, le deuxième le numéro 1,
et ainsi de suite. Il en va de même pour les éléments de type tabulaire en ActionScript (ArrayList,
ArrayCollection…).
Navigation « en accordéon » : Accordion
Grâce au composant Accordion, il est possible de proposer une navigation entre chaque
écran sous la forme d’un accordéon (menu empilé).
Pour vous faire une idée de ce type de navigation, nous vous invitons à saisir ces quelques
lignes de code au sein d’une nouvelle application Flex et à tester l’application.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Accordion x="10" y="10" width="483" height="301" id="acn">
<mx:Canvas label="Partie A" width="100%" height="100%">
<mx:Panel x="115.5" y="10" width="250" height="200" layout="absolute"
➥title="Panel Partie A">
</mx:Panel>
</mx:Canvas>
<mx:Canvas label="Partie B" width="100%" height="100%">
<mx:Panel x="115.5" y="23" width="250" height="200" layout="absolute"
➥title="Panel Partie B">
</mx:Panel>
</mx:Canvas>
</mx:Accordion>
</mx:Application>
La figure 7-3 illustre le résultat obtenu après exécution du code.
=Flex3 FM.book Page 127 Mardi, 2. décembre 2008 3:32 15
Les composants de navigation et de reporting
CHAPITRE 7
127
Figure 7-3
Exemple de navigation « en accordéon »
Nous constatons que nos panneaux (panels) sont positionnés dans des parties mobiles,
permettant un gain de place important sur l’interface graphique principale de l’application. Le composant Accordion est souvent utilisé pour la création de menus car il permet
d’obtenir un aspect graphique assez intéressant et prisé par les utilisateurs.
=Flex3 FM.book Page 128 Mardi, 2. décembre 2008 3:32 15
128
Comprendre Flex 3
PARTIE I
Les composants de graphique
Ces composants servant pour la génération de graphiques sont uniquement disponibles
dans la version professionnelle de Flex Builder 3. Le tableau 7-1 en dresse la liste exhaustive :
Tableau 7-1
Nom du composant
Les composants à vocation statistiques
Icône
Utilisation
AreaChart
Représentation sous forme d’aires
BarChart
Représentation sous forme d’histogramme horizontal
ColumnChart
Représentation sous forme d’histogramme vertical
BubbleChart
Graphique sous forme de bulles
CandlestickChart
Représentation sous forme de chandelles
LineChart
Graphique linéaire
PieChart
Graphique en secteurs
PlotChart
Représentation sous forme d’un nuage de points
HLOCChart (HLOC (Hight, Low,
Open, Close))
Graphique boursier
Implémentation
L’implémentation de chacun de ces composants étant plus ou moins semblable, nous avons
choisi de présenter l’utilisation du composant PieChart, car c’est le plus fréquemment
utilisé dans les applications de reporting. Dans la portion de code suivante, nous représentons le nombre de dossiers médicaux non clôturés au sein d’un service hospitalier :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
=Flex3 FM.book Page 129 Mardi, 2. décembre 2008 3:32 15
Les composants de navigation et de reporting
CHAPITRE 7
129
public var etatDossiers:ArrayCollection = new ArrayCollection([
{Dossier:"Clôturés", nombre:1500},
{Dossier:"Ouverts", nombre:200},
{Dossier:"En attente", nombre:30},
]);
]]>
</mx:Script>
<mx:PieChart id="graphique"
dataProvider="{etatDossiers}"
showDataTips="true"
width="203" height="140" x="10" y="5">
<mx:series>
<mx:PieSeries
field="nombre"
nameField="Dossier"
/>
</mx:series>
</mx:PieChart>
</mx:Application>
Les données présentées dans le graphique sont obtenues grâce au tableau etatDossier
venant alimenter le dataProvider du composant. La valeur du champ Dossier est alors
extraite, ce qui permet de générer le graphique. La propriété showDataTips affectée de la
valeur true affiche les légendes de chaque quartier lorsque l’utilisateur les survole. La
figure 7-4 illustre le résultat obtenu après exécution du code.
Figure 7-4
Implémentation du
composant PieChart
Les légendes (dataTip) sont automatiquement créées par le composant PieChart : « Clôturés :
86,7 % (1 500) ». Si nous souhaitons personnaliser cet affichage, nous devrons utiliser la
méthode dataTipFunction comme suit :
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
=Flex3 FM.book Page 130 Mardi, 2. décembre 2008 3:32 15
130
Comprendre Flex 3
PARTIE I
public var etatDossiers:ArrayCollection = new ArrayCollection([
{Dossier:"Clôturés", nombre:1500},
{Dossier:"Ouverts", nombre:200},
{Dossier:"En attente", nombre:30},
]);
import mx.charts.HitData
public function modifierDataTip(e:HitData):String{
var etiquette:String;
etiquette= "Nombre de dossiers :"+e.item.nombre;
return etiquette;
}
]]>
</mx:Script>
<mx:PieChart id="graphique"
dataProvider="{etatDossiers}"
showDataTips="true"
width="203" height="140" x="10" y="5"
dataTipFunction="modifierDataTip">
<mx:series>
<mx:PieSeries
field="nombre"
nameField="Dossier"
/>
</mx:series>
</mx:PieChart>
</mx:Application>
Si nous exécutons ce code, nous notons que les légendes ont à présent la valeur « Nombre
de dossiers : valeur du quartier survolé par la souris ».
En pratique : création d’un outil de reporting
En guise de synthèse, réalisons une petite application permettant d’afficher le reporting
des ventes par produit pour un mois donné, sélectionné par l’utilisateur.
Le graphique utilisé est un histogramme BarChart et les données visualisées correspondront
au mois sélectionné par l’utilisateur à l’aide du composant HSlider étudié au chapitre 5.
Étape 1 : création des données
La première étape (outre la création d’un nouveau projet Flex) va consister à créer les
tableaux de données. Nous avons ici choisi de créer trois tableaux contenant la somme
des ventes réalisées pour trois produits aux mois de janvier, février et mars.
=Flex3 FM.book Page 131 Mardi, 2. décembre 2008 3:32 15
Les composants de navigation et de reporting
CHAPITRE 7
131
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
// Tableaux de données
[Bindable]
private var Janvier:ArrayCollection = new ArrayCollection([
{produit:"P1", vente:500},
{produit:"P2", vente:700},
{produit:"P3", vente:2000}]);
private var Fevrier:ArrayCollection = new ArrayCollection([
{produit:"P1", vente:2500},
{produit:"P2", vente:800},
{produit:"P3", vente:4000}]);
private var Mars:ArrayCollection = new ArrayCollection([
{produit:"P1", vente:800},
{produit:"P2", vente:1200},
{produit:"P3", vente:1500}]);
]]>
</mx:Script>
</mx:Application>
Étape 2 : mise en place de l’histogramme
Nous souhaitons afficher par défaut les données du mois de janvier. Pour cela, nous affectons le dataProvider de l’histogramme du tableau Janvier créé précédemment.
<mx:ColumnChart x="10" y="67" id="histogramme" dataProvider="{Janvier}">
<mx:horizontalAxis>
<mx:CategoryAxis id="donneesGraphiques"
dataProvider="{Janvier}"
categoryField="produit"
/>
</mx:horizontalAxis>
<mx:series>
<mx:ColumnSeries
xField="produit"
yField="vente"
/>
</mx:series>
</mx:ColumnChart>
Sur l’axe horizontal (HorizontalAxis), qui sera alimenté en données, nous allons afficher
les libellés des produits, soit P1, P2 et P3. À partir des données contenues sur cet axe,
=Flex3 FM.book Page 132 Mardi, 2. décembre 2008 3:32 15
132
Comprendre Flex 3
PARTIE I
nous allons créer une série qui nous permettra d’extraire les valeurs devant être affichées
sur l’axe vertical (yField) et sur l’axe horizontal (xField).
À ce stade, si nous exécutons le projet, nous pouvons visualiser les données du mois de
janvier. Cependant nous souhaitons donner la possibilité à l’utilisateur de choisir le mois
de visualisation à l’aide du composant HSlider.
Étape 3 : utilisation du composant HSlider
Nous ajoutons un composant HSlider afin de mettre à jour le dataProvider du graphique
en fonction du mois sélectionné. Pour cela, il convient tout d’abord d’implémenter notre
composant :
<mx:HSlider
id="choixDuMois"
x="38"
y="23"
width="372"
minimum="1"
maximum="3"
tickInterval="1"
snapInterval="1"
liveDragging="true"
labels="[Janvier,Février,Mars]"
showDataTip="false"
change="afficherGraphique()"
/>
HSlider va donc comporter les libellés Janvier, Février et Mars. Chaque mois va corres-
pondre à un numéro précis correspondant à l’indice sélectionné dans le composant :
1 = Janvier, 2 = Février et 3 = Mars. À partir de cette information, il sera aisé de déterminer le mois sélectionné et de mettre à jour les données contenues dans l’histogramme.
Remarquez également la suppression des infobulles par l’utilisation de la propriété
showDataTip portée à false.
Il ne nous reste plus qu’à mettre en place la partie dynamique de l’application en écrivant
le code de la fonction afficherGraphique() qui sera déclenchée à chaque changement de
valeur du composant HSlider :
// Affichage des données en fonction du mois sélectionné
// dans le HSlider
import mx.controls.Alert;
public function afficherGraphique():void
{
switch (choixDuMois.value){
case 1 : histogramme.dataProvider = Janvier;
break;
case 2 : histogramme.dataProvider = Fevrier;
break;
=Flex3 FM.book Page 133 Mardi, 2. décembre 2008 3:32 15
Les composants de navigation et de reporting
CHAPITRE 7
133
case 3 : histogramme.dataProvider = Mars;
break;
}
// Mise à jour du dataProvider du composant HorizontalAxis
donneesGraphiques.dataProvider = histogramme.dataProvider;
}
Ainsi, lorsque l’utilisateur sélectionne un mois dans le composant HSlider, sa valeur est
récupérée et le tableau de données correspondant est chargé dans le dataProvider de
l’histogramme et de l’axe horizontal (donneesGraphiques.dataProvider = histogramme.dataProvider).
La figure 7-5 illustre le résultat obtenu après exécution de l’application.
Figure 7-5
Outil de reporting
En résumé
Après la lecture des chapitres 5 à 7, vous connaissez à présent les principaux composants
que Flex met à votre disposition pour créer les interfaces de vos applications. Vous savez
donc résoudre les problèmes les plus fréquemment rencontrés lors de la phase de développement : comment alimenter une liste déroulante ? Comment en récupérer la valeur
sélectionnée ? et bien d’autres…
Pour poursuivre notre apprentissage du framework Flex, nous allons à présent étudier les
méthodes qui vont nous permettre d’agencer ces composants au sein d’une interface
graphique.
=Flex3 FM.book Page 134 Mardi, 2. décembre 2008 3:32 15
=Flex3 FM.book Page 135 Mardi, 2. décembre 2008 3:32 15
8
Réaliser le design
des interfaces
Au cours de ce chapitre, vous allez apprendre à personnaliser le design des interfaces
graphiques grâce au framework Flex et à Flex Builder. Nous découvrirons tout d’abord
comment positionner et dimensionner les composants de Flex, puis nous aborderons la notion
de style et nous terminerons par la réalisation de nos propres habillages de composants.
Dimensionner et positionner les composants
L’une des premières étapes dans la conception d’interfaces graphiques consiste à agencer
les composants au sein de cette interface. Le designer devra trouver la taille et la disposition
adéquates pour les différents composants de l’application afin d’obtenir une certaine
harmonie dans l’interface, ce qui la rendra conviviale. Nous allons donc dans un premier
temps nous attarder sur les méthodes permettant de définir les dimensions des composants
et de les positionner.
Spécifier les dimensions des composants
Il existe plusieurs méthodes permettant de définir les dimensions des composants au sein
d’une interface graphique :
• Vous pouvez laisser cette tâche au framework Flex qui vous proposera alors une taille
par défaut pour chaque composant inséré dans l’interface.
• Vous pouvez préciser manuellement la taille en pixels de chaque composant.
• Enfin, vous pouvez spécifier les dimensions des composants en pourcentage des dimensions de leur conteneur.
=Flex3 FM.book Page 136 Mardi, 2. décembre 2008 3:32 15
136
Comprendre Flex 3
PARTIE I
La spécification des dimensions d’un composant consiste ni plus ni moins à modifier
certaines des propriétés présentées dans le tableau 8-1.
Tableau 8-1
Propriétés permettant de déterminer la taille des composants
Propriété
Rôle
Height
Hauteur du composant exprimée en pixels.
Width
Largeur du composant exprimée en pixels.
minHeight
Hauteur minimale du composant exprimée en pixels.
minWidth
Largeur minimale du composant exprimée en pixels.
maxHeight
Hauteur maximale du composant exprimée en pixels.
maxWidth
Largeur maximale du composant exprimée en pixels.
percentHeigth
Hauteur du composant exprimée en pourcentage de la hauteur de son conteneur.
percentWidth
Largeur du composant exprimée en pourcentage de la largeur de son conteneur.
Quelques exemples
Les exemples suivants vous permettront de voir comment implémenter les différentes
propriétés présentées au tableau 8-1 et les résultats obtenus pour chaque type de dimensionnement.
Dimensionnement par défaut
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<!-- Conteneur : VBox -->
<mx:VBox x="20" y="27" height="70" width="289">
<!-- Composant : Button -->
<mx:Button id="btn" label="Button"/>
</mx:VBox>
</mx:Application>
Dans cet exemple de code, aucune dimension n’a été spécifiée pour le bouton. Le composant Button aura donc les dimensions spécifiées par défaut par Flex (figure 8-1).
Figure 8-1
Dimensionnement
par défaut
=Flex3 FM.book Page 137 Mardi, 2. décembre 2008 3:32 15
Réaliser le design des interfaces
CHAPITRE 8
137
Spécification des dimensions
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<!-- Conteneur : VBox -->
<mx:VBox x="20" y="27" height="70" width="289">
<!-- Composant : Button -->
<mx:Button id="btn" label="Button" width="223" height="35"/>
</mx:VBox>
</mx:Application>
Dans cet exemple, une largeur et une hauteur ont été précisées pour le bouton. Le résultat
obtenu est illustré par la figure 8-2.
Figure 8-2
Spécification des dimensions
Utilisation des pourcentages
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<!-- Conteneur : VBox -->
<mx:VBox x="20" y="27" height="70" width="289">
<!-- Composant : Button -->
<mx:Button id="btn" label="Button" width="50%" height="80%"/>
</mx:VBox>
</mx:Application>
Dans cet exemple de code, nous avons spécifié les dimensions du bouton en fonction de
la taille de son conteneur. Ainsi, la largeur du composant est égale à 50 % de la largeur de
son conteneur et sa hauteur correspond à 80 % de la hauteur de son conteneur.
Pour vous aider dans la compréhension de cette notion parfois difficile à saisir, nous vous
invitons à étudier la figure 8-3 présentant le résultat obtenu après exécution du code.
=Flex3 FM.book Page 138 Mardi, 2. décembre 2008 3:32 15
138
Comprendre Flex 3
PARTIE I
Figure 8-3
Dimensionnement à l’aide des pourcentages
À noter que nous aurions également pu utiliser les propriétés percentWidth et percentHeight
comme suit :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:VBox x="20" y="27" height="70" width="289" borderStyle="inset">
<!-- Composant : Button -->
<mx:Button id="btn" label="Button" percentHeight="80" percentWidth="50"/>
</mx:VBox>
</mx:Application>
Cependant, la méthode la plus communément utilisée consiste à spécifier des pourcentages
pour les propriétés width et height.
Nous savons à présent définir la taille d’un composant selon trois méthodes distinctes.
Voyons maintenant comment disposer ce dernier au sein d’une interface.
Positionner les composants
Pour placer un composant à un endroit précis de l’interface, nous disposons également de
trois méthodes :
• le positionnement automatique ;
• le positionnement absolu ;
• le positionnement à l’aide de contraintes (ancrages).
Le positionnement automatique
Par défaut, Flex place les composants de façon automatique en fonction des règles de
positionnement de leur conteneur. Par exemple, un composant intégré dans le conteneur
HBox sera automatiquement positionné en haut à gauche, aux coordonnées x = 0 et y = 0.
=Flex3 FM.book Page 139 Mardi, 2. décembre 2008 3:32 15
Réaliser le design des interfaces
CHAPITRE 8
139
Nous pouvons néanmoins intervenir sur ce positionnement en modifiant certaines
propriétés du conteneur. Le tableau 8-2 présente les propriétés les plus communément
modifiées.
Tableau 8-2
Propriétés de positionnement automatique
Propriété
Rôle
horizontalAlign
Aligne les composants par rapport à l’axe horizontal du conteneur :
Center : centre le composant.
Left : place le composant à gauche.
Right : place le composant à droite.
verticalAlign
Aligne les composants par rapport à l’axe vertical du conteneur :
Bottom : place le composant en bas.
Middle : place le composant au centre.
Top : place le composant en haut.
layout : applicable à l’application
et aux composants Panel et Canvas.
Permet de modifier la disposition des composants :
Absolute : positionne les composants en fonction de leur coordonnées x et y.
Vertical : positionne les composants les uns en dessous des autres.
Horizontal : positionne les composants côte à côte.
paddingBottom
Marge inférieure du conteneur.
paddingLeft
Marge gauche du conteneur.
paddingRight
Marge droite du conteneur.
paddingTop
Marge supérieure du conteneur.
La propriété horizontalAlign
L’exemple de code suivant implémente les trois positions d’alignement horizontal illustrées par la figure 8-4.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<!-- CENTRE -->
<mx:Label x="10" y="17" text="Centre" width="250"/>
<mx:HBox x="10" y="43" width="250" height="74" horizontalAlign="center">
<mx:Button id="btn1" label="Button"/>
</mx:HBox>
<!-- DROITE -->
<mx:Label x="10" y="129" text="Droite" width="250"/>
<mx:HBox x="10" y="153" width="250" height="74" horizontalAlign="right">
<mx:Button id="btn2" label="Button"/>
</mx:HBox>
<!-- GAUCHE -->
<mx:Label x="10" y="247" text="Gauche" width="250"/>
=Flex3 FM.book Page 140 Mardi, 2. décembre 2008 3:32 15
140
Comprendre Flex 3
PARTIE I
<mx:HBox x="10" y="271" width="250" height="74" horizontalAlign="left">
<mx:Button id="btn3" label="Button"/>
</mx:HBox>
</mx:Application>
Figure 8-4
Positionnement à l’aide
de la propriété horizontalAlign
La propriété verticalAlign
Voici à présent un exemple de code illustrant le positionnement des composants dont la
propriété verticalAlign du conteneur a été modifiée. Le résultat obtenu est représenté à la
figure 8-5.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<!-- MILIEU -->
<mx:Label x="10" y="17" text="Milieu" width="250"/>
<mx:HBox x="10" y="43" width="250" height="74" verticalAlign="middle">
<mx:Button id="btn1" label="Button"/>
</mx:HBox>
<!-- HAUT -->
<mx:Label x="10" y="129" text="Haut" width="250"/>
<mx:HBox x="10" y="153" width="250" height="74" verticalAlign="top">
<mx:Button id="btn2" label="Button"/>
</mx:HBox>
=Flex3 FM.book Page 141 Mardi, 2. décembre 2008 3:32 15
Réaliser le design des interfaces
CHAPITRE 8
141
<!-- BAS -->
<mx:Label x="10" y="247" text="Bas" width="250"/>
<mx:HBox x="10" y="271" width="250" height="74" verticalAlign="bottom">
<mx:Button id="btn3" label="Button"/>
</mx:HBox>
</mx:Application>
Figure 8-5
Positionnement des composants
à l’aide de la propriété verticalAlign
La propriété layout
Dans l’exemple de code suivant, nous voyons que l’application possède une mise en
forme de type absolute. Les composants qu’elle contient seront donc placés à l’aide de
leurs coordonnées. Nous pouvons observer ce positionnement pour les composants Panel,
pour lesquels des valeurs ont été affectées aux propriétés x et y.
Le résultat obtenu après exécution de ce code est représenté à la figure 8-6.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<!-- Positionnement de type "absolute" -->
<mx:Panel title="Absolute" x="31" y="10" width="250" height="120" layout="absolute" >
<mx:Button id="btn" x="10" y="10" label="Button"/>
<mx:Button id="btn2" x="133" y="37" label="Button"/>
</mx:Panel>
<!-- Positionnement de type "vertical" -->
<mx:Panel title="Vertical" x="31" y="138" width="250" height="120" layout="vertical" >
<mx:Button id="btn3" label="Button"/>
=Flex3 FM.book Page 142 Mardi, 2. décembre 2008 3:32 15
142
Comprendre Flex 3
PARTIE I
<mx:Button id="btn4" label="Button"/>
</mx:Panel>
<!-- Positionnement de type "horizontal" -->
<mx:Panel title="Horizontal" x="31" y="266" width="250" height="120"
➥layout="horizontal" >
<mx:Button id="btn5" label="Button"/>
<mx:Button id="btn6" label="Button"/>
</mx:Panel>
</mx:Application>
Figure 8-6
Utilisations de la propriété layout
La propriété padding
L’exemple de code suivant illustre le positionnement des composants à l’aide des marges.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:HBox x="10" y="10" width="250" height="158"
paddingLeft="50"
paddingTop="20"
>
<mx:Button id="btn" label="Button"/>
</mx:HBox>
</mx:Application>
=Flex3 FM.book Page 143 Mardi, 2. décembre 2008 3:32 15
Réaliser le design des interfaces
CHAPITRE 8
143
Les marges gauche et supérieure du conteneur HBox ont été définies, impliquant le positionnement du bouton à une distance de 20 pixels par rapport à la ligne supérieure du
conteneur et à 50 pixels de son bord gauche (figure 8-7).
Figure 8-7
Utilisation des marges
pour le positionnement
du composant
Le positionnement absolu
Ce type de positionnement est appliqué par défaut à l’application ainsi qu’aux composants Panel et Canvas. Comme mentionné précédemment, ce type de positionnement
s’effectue en affectant la valeur absolute à la propriété layout des composants concernés.
Cette méthode permet de positionner les composants au sein du conteneur selon les axes
de coordonnées x et y et, si besoin, d’effectuer des superpositions de composants.
Le positionnement à l’aide de contraintes
Ce type de positionnement est également appelé positionnement par ancrage. Il peut
s’effectuer de deux façons :
• en modifiant les propriétés de positionnement par ancrage (voir tableau 8-3) ;
• en utilisant la perspective de design et plus particulièrement la vue layout de celle-ci
(cette vue est activée lorsqu’on sélectionne un composant et elle se situe en bas à droite
de la perspective de design (figure 8-8)).
Ancrage du conteneur ou du composant ?
Jusqu’à présent, nous avons modifié les propriétés du conteneur afin de positionner les composants à
l’intérieur de celui-ci. L’ancrage concerne le composant. C’est donc sur ce dernier que les modifications
devront être effectuées. Ceci peut se résumer par : « Le composant est ancré par rapport à son conteneur ».
=Flex3 FM.book Page 144 Mardi, 2. décembre 2008 3:32 15
144
Comprendre Flex 3
PARTIE I
Tableau 8-3
Propriétés de positionnement par ancrage
Propriété
Rôle
horizontalCenter
Distance exprimée en pixels entre le centre de l’axe horizontal du composant et
celui de son conteneur.
verticalCenter
Distance exprimée en pixels entre le centre de l’axe vertical du composant et
celui de son conteneur.
top
Distance exprimée en pixels entre le bord supérieur du composant et celui de son
conteneur.
bottom
Distance exprimée en pixels entre le bord inférieur du composant et celui de son
conteneur.
left
Distance exprimée en pixels entre le bord gauche du composant et celui de son
conteneur.
right
Distance exprimée en pixels entre le bord droit du composant et celui de son conteneur.
Figure 8-8
Vue d’ancrage de la perspective design
=Flex3 FM.book Page 145 Mardi, 2. décembre 2008 3:32 15
Réaliser le design des interfaces
CHAPITRE 8
145
Exemple d’application
Considérons une application servant de conteneur à un composant Panel correspondant
au code suivant :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Panel width="250" layout="absolute"
horizontalCenter="0"
top="175"
bottom="275">
</mx:Panel>
</mx:Application>
Dans cet exemple de code, nous remarquons que des contraintes de positionnement ont
été spécifiées pour le composant Panel :
• il doit se situer au centre de l’application : horizontalCenter="0" ;
• il doit se situer à 175 pixels du bord supérieur de l’application : top="175" ;
• il doit se situer à 275 pixels du bord inférieur de l’application : bottom="275".
Ces caractéristiques sont reprises dans la vue de positionnement des contraintes, comme
l’illustre la figure 8-9.
Figure 8-9
Répercussions du code sur la vue spécifique aux ancrages
=Flex3 FM.book Page 146 Mardi, 2. décembre 2008 3:32 15
146
Comprendre Flex 3
PARTIE I
Le positionnement des composants à l’aide d’ancrages présente l’avantage de permettre
un ajustement de l’interface en fonction de la résolution d’écran de l’utilisateur en adaptant
la taille et la disposition des composants (figure 8-10).
Figure 8-10
Adaptation de l’interface graphique en fonction de la résolution du navigateur
Gestion des ascenseurs
Dans certaines configurations (lorsque la taille du composant est sensiblement identique ou supérieure à
celle du conteneur), les ascenseurs verticaux et horizontaux du conteneur peuvent s’afficher. Pour pallier
cela, il suffit de passer la valeur des propriétés horizontalScrollPolicy et verticalScrollPolicy
du conteneur à off (figure 8-11).
=Flex3 FM.book Page 147 Mardi, 2. décembre 2008 3:32 15
Réaliser le design des interfaces
CHAPITRE 8
147
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Panel id="pan" x="10" y="10" width="250" height="86" layout="absolute"
horizontalScrollPolicy="off"
verticalScrollPolicy="off">
<mx:Button id="btn" x="0" y="14" label="Button" width="240"/>
</mx:Panel>
</mx:Application>
Figure 8-11
Gestion des ascenseurs horizontaux et verticaux
Utiliser les styles
Selon les goûts de chacun, le style proposé par défaut dans une application Flex peut
parfaitement convenir, alors que d’autres y ajouteraient bien un peu de couleur. Au-delà
de cela, il convient de garder à l’esprit qu’une application doit respecter une charte
graphique éditée par l’entreprise dont il est très difficile de déroger. C’est pourquoi Flex
permet de personnaliser le style d’une application au moyen du langage CSS (Cascading
Style Sheet).
Le CSS de Flex supporte quelques propriétés du langage CSS standardisé dont voici la
liste exhaustive :
• color ;
• fontFamily ;
• fontSize ;
• fontStyle ;
• fontWeight ;
• paddingBottom ;
• paddingLeft ;
=Flex3 FM.book Page 148 Mardi, 2. décembre 2008 3:32 15
148
Comprendre Flex 3
PARTIE I
• paddingRight ;
• paddingTop ;
• textAlign ;
• textDecoration ;
• textIndent.
Bien entendu, le CSS de Flex ne se limite pas à ces quelques propriétés standardisées,
mais englobe un ensemble de propriétés propres à chacun de ses composants.
Visualiser les propriétés de style d’un composant
Pour visualiser l’ensemble des propriétés de style d’un composant, il suffit de le placer sur l’interface et de
le sélectionner. Dans la vue Flex Properties, il est alors possible de cliquer sur le bouton Category view,
lequel permet d’afficher la liste des propriétés du composant sous la forme d’un treeview. Dans cette
représentation hiérarchique, nous pouvons apercevoir un nœud nommé Style qui reprend l’ensemble des
propriétés stylistiques du composant.
Étudions en détail l’implémentation de ce langage au sein d’une application Flex.
La balise Style
La première méthode d’implémentation du langage CSS consiste à utiliser la balise
<mx:Style> du langage MXML, comme illustré dans l’exemple de code suivant :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Style>
.classePersonnalisee{
fontSize: 10;
color:red;
}
Button {
fontSize: 20;
}
</mx:Style>
<mx:Button id="btn" x="10" y="10" label="Button"/>
<mx:Label id="lab" x="10" y="53" text="Label" styleName="classePersonnalisee"/>
</mx:Application>
L’analyse de ces quelques lignes de code permet de comprendre aisément la notion de
classes CSS. Le sélecteur Button permet de définir le style de l’ensemble des composants
de type bouton de l’interface. La classe personnalisée (classePersonnalisee) ne fait référence à aucune classe de composant et doit donc être appelée à l’aide de la propriété
styleName du composant concerné. Cela permet de définir des styles différents pouvant
=Flex3 FM.book Page 149 Mardi, 2. décembre 2008 3:32 15
Réaliser le design des interfaces
CHAPITRE 8
149
alors être appliqués pour un même type de composant (un bouton rouge, vert, bleu, etc.).
Notez que l’utilisation de styles ne se limite pas au composant de type Button mais peut
également être appliquée à l’ensemble de composants du framework.
Figure 8-12
Emploi de la balise <mx:Style>
Le fichier CSS externe
La seconde méthode d’implémentation consiste à faire appel à un fichier CSS externe.
Pour ce faire, nous utiliserons de nouveau la balise <mx:Style> mais en lui précisant le
chemin d’accès du fichier CSS à utiliser.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Style source="feuilleDeStyle.css"></mx:Style>
<mx:Button id="btn" x="10" y="10" label="Button"/>
<mx:Label id="lab" x="10" y="53" text="Label" styleName="classePersonnalisee"/>
</mx:Application>
Le fichier CSS (ici, feuilleDeStyle.css) peut être édité à l’aide de la perspective de développement en choisissant la création d’un nouveau fichier CSS, ou en utilisant l’application Flex Style Explorer développée par l’éditeur.
Le Flex Style Explorer vous permet de modifier les propriétés de chaque composant de façon
graphique. Le code correspondant est alors automatiquement généré et vous pouvez
ensuite l’exporter et l’utiliser dans votre application Flex (figure 8-13). Si vous souhaitez
utiliser cette application, rendez-vous sur la page web suivante : http://weblogs.macromedia.com/mc/archives/FlexStyleExplorer.html.
Utilisation des images
Pour utiliser des images, il convient de faire appel à la méthode Embed(). Dans l’exemple de code suivant,
l’image monImage.jpg est employée comme arrière-plan de l’application.
backgroundImage : Embed('monImage.jpg')
=Flex3 FM.book Page 150 Mardi, 2. décembre 2008 3:32 15
150
Comprendre Flex 3
PARTIE I
Figure 8-13
Application Flex Style Explorer
CSS et ActionScript
La troisième méthode d’implémentation consiste à créer le style CSS à l’aide du langage
ActionScript. Ceci est possible grâce à la classe StyleManager qui permet de définir de
nouveaux styles et de les appliquer aux composants de l’application. Voyons ceci de plus
près à travers un exemple :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥creationComplete="appliquerStyle()" >
<mx:Script>
<![CDATA[
// Importation de la classe StyleManager
import mx.styles.StyleManager;
// Définition du style
private var styleActionScript:CSSStyleDeclaration;
private function appliquerStyle():void{
=Flex3 FM.book Page 151 Mardi, 2. décembre 2008 3:32 15
Réaliser le design des interfaces
CHAPITRE 8
151
// Instanciation de la classe CSSStyleDeclaration;
styleActionScript = new CSSStyleDeclaration('styleActionScript');
// Création des propriétés
styleActionScript.setStyle('fontSize',20);
// Affectation des propriétés à la classe Label
StyleManager.setStyleDeclaration("Label",styleActionScript,true);
}
]]>
</mx:Script>
<mx:Label id="lab" x="10" y="10" text="Étiquette"/>
</mx:Application>
La première étape consiste à instancier la classe CSSStyleDeclaration permettant de déclarer un nouveau style. Nous y ajoutons ensuite des propriétés CSS grâce à la méthode
setStyle(). Enfin, nous affectons ce style à la classe Label en employant la méthode
setStyleDeclaration(nom de la classe CSS, style, mise à jour (true/false)). À noter
que l’ensemble de ces instructions est contenu dans la fonction appliquerStyle(), exécutée
à la fin de la création de l’application.
Grâce à la classe StyleManager, il devient possible de manipuler le style CSS de notre
application. Ceci nous ouvre la voie vers une multitude de possibilités, notamment celle
du dynamisme applicatif, c’est-à-dire le changement de style en fonction de l’utilisateur
connecté ou lors d’un déclenchement d’événement…
Habiller les composants : skinning
Une autre particularité de Flex est de permettre l’habillage des composants au moyen
d’images, de fichiers SWF (animations Flash) ou de classes contenant des instructions de
design.
Les habillages (skins) sont généralement appliqués sur les états d’un composant. Ainsi, nous
pouvons, par exemple, définir huit skins différents pour les composants de type bouton :
• un skin pour l’état relâché : upSkin ;
• un skin pour l’état cliqué : downSkin ;
• un skin pour l’état survolé : overSkin ;
• un skin pour l’état désactivé : disabledSkin ;
• un skin pour la prise de focus : focusSkin ;
• un skin pour l’état cliqué d’un bouton de type interrupteur : selectedDownSkin ;
• un skin pour l’état relâché d’un bouton de type interrupteur : selectedUpSkin ;
• un skin pour l’état survolé d’un bouton de type interrupteur : selectedOverSkin.
=Flex3 FM.book Page 152 Mardi, 2. décembre 2008 3:32 15
152
Comprendre Flex 3
PARTIE I
Utiliser des images
Pour implémenter un habillage sur un composant, il est possible d’utiliser la balise
<mx:Style>, tout comme nous l’aurions fait pour créer un nouveau style CSS ou pour
modifier directement les propriétés souhaitées au sein du composant. L’exemple de code
suivant illustre l’utilisation de cette balise :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" >
<mx:Style>
Button {
downSkin: Embed('monImage.jpg');
}
</mx:Style>
<mx:Button id="btn" x="50" y="42" label="Button"/>
</mx:Application>
Dans l’exemple suivant, vous notez que l’habillage a été modifié à l’aide des propriétés
du composant :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" >
<mx:Button id="btn" x="50" y="42" label="Button"
downSkin="@Embed(source='monImage.jpg')"/>
</mx:Application>
Utiliser des fichiers SWF
L’habillage des composants est réalisé de la même façon qu’à l’aide d’une image, c’està-dire en utilisant la balise <mx:Style> ou en modifiant les propriétés du composant. Cela
est illustré par le code suivant :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" >
<mx:Style>
Button {
downSkin: Embed('monSWF.swf');
}
</mx:Style>
<mx:Button id="btn" x="50" y="42" label="Button"/>
</mx:Application>
=Flex3 FM.book Page 153 Mardi, 2. décembre 2008 3:32 15
Réaliser le design des interfaces
CHAPITRE 8
153
Dans l’exemple suivant, les propriétés du composant ont été modifiées :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" >
<mx:Button id="btn" x="50" y="42" label="Button"
downSkin="Embed(source='monSWF.swf')"/>
</mx:Application>
L’habillage par programmation
Dans cette section, nous allons aborder la programmation de skins à l’aide d’Action
Script à travers un exemple d’application, ce qui est le meilleur moyen pour en comprendre les rouages.
L’objectif est de créer un habillage pour le composant VBox en redessinant son contour
afin d’obtenir le résultat illustré par la figure 8-14.
Figure 8-14
Skin personnalisé pour le composant VBox
Pour cela, la première étape va consister à créer une classe, dans un package que nous
nommerons com.test.skin, qui définira notre skin personnalisé :
Package com.test.skin
{
import mx.skins.RectangularBorder;
=Flex3 FM.book Page 154 Mardi, 2. décembre 2008 3:32 15
154
Comprendre Flex 3
PARTIE I
public class SkinPersonnalise extends RectangularBorder
{
// Constructeur
public function SkinPersonnalise(){}
// Redéfinition de la méthode updateDisplayList
override protected function updateDisplayList(unscaledWidth:Number,
➥unscaledHeight:Number):void{
// Récupération de la taille du skin composant
super.updateDisplayList(unscaledWidth, unscaledHeight);
// Nettoyage de la forme
graphics.clear();
// Dessin de la bordure
drawRoundRect(0,0,unscaledWidth,unscaledHeight,{tl:50,tr:10,bl:10,br:30}
➥,0xCCCC99,0.8);
}
}
}
Analysons un peu ce code. Tout d’abord, nous importons la classe RectangularBorder qui
nous permettra de manipuler les bordures du composant. Notons au passage que notre
classe SkinPersonnalise hérite de cette classe. Puis, nous spécifions le constructeur et
redéfinissons la méthode updateDisplayList. Pour faire très simple, nous dirons que cette
méthode permet de gérer l’affichage de tout composant au sein d’une interface graphique
(positionnement et dimensionnement des composants ainsi que leur représentation (bordure,
couleurs…)). En modifiant quelque peu cette méthode, nous serons en mesure de redessiner les contours de notre VBox. Par ailleurs, nous remarquons la présence des paramètres
unscaleWidth et unscaleHeight qui contiennent les valeurs des propriétés width et heigth du
composant afin d’en connaître la largeur et la hauteur.
Passons à présent aux choses sérieuses. Les contours de notre composant seront redessinés à l’aide de la méthode drawRoundRect qui permet de dessiner un rectangle aux bords
arrondis. Les deux premiers paramètres passés à cette méthode correspondent aux coordonnées x et y du composant, les deux suivants à sa largeur et à sa hauteur. Vient ensuite
un tableau contenant les dimensions des arcs de cercle redessinant les arrondis de chaque
angle du composant :
• tl (pour top left) : en haut à gauche ;
• tr (pour top right) : en haut à droite ;
• bl (pour bottom left) : en bas à gauche ;
• br (pour bottom right) : en bas à droite.
Enfin, les deux derniers paramètres spécifient la couleur et la transparence du composant.
=Flex3 FM.book Page 155 Mardi, 2. décembre 2008 3:32 15
Réaliser le design des interfaces
CHAPITRE 8
155
Notre skin est à présent terminé, il est temps de passer à la seconde étape qui consiste à
appeler le skin personnalisé en affectant la propriété borderSkin du composant VBox avec
le nom de la classe précédemment créée :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:VBox id="vb" x="29" y="20" height="173" width="259"
borderSkin="com.test.skin.SkinPersonnalise" >
</mx:VBox>
</mx:Application>
Voilà, c’est terminé ! À noter que dans notre exemple, nous avons utilisé la méthode
drawRoundRect, mais il en existe d’autres telles que :
• curveTo() qui permet de créer des courbes ;
• drawCircle() qui permet de dessiner des cercles ;
• drawRect() qui permet de dessiner des rectangles ;
• lineTo() qui permet de dessiner une ligne, etc.
La création de skins à l’aide du langage ActionScript n’est pas des plus aisées. Néanmoins, tout comme pour la création de styles CSS grâce à ce langage, il nous est maintenant possible de conférer une part de dynamisme aux habillages de nos composants,
offrant un réel plus à nos interfaces graphiques.
En résumé
Au cours de ce chapitre, nous avons abordé les concepts de base utiles à la création
d’interfaces graphiques. Nous sommes à présent en mesure de positionner et de dimensionner les composants afin qu’ils répondent à l’ergonomie souhaitée de l’application.
Nous savons également personnaliser les interfaces à l’aide du langage CSS et de l’utilisation de skins.
Si nous avions pour habitude d’utiliser le langage HTML pour générer nos interfaces
web nous pourrions nous contenter de ce qui vient d’être énoncé, mais nous perdrions la
notion de richesse des interfaces proposée par Flex. En effet, ce qui différencie Flex du
langage HTML, c’est la possibilité d’ajouter un dynamisme visuel aux interfaces. Cette
différence se traduit par la mise en place d’effets, de mouvements, de transitions, etc.
C’est ce dynamisme que nous allons aborder dans le chapitre suivant en traitant les
notions d’états, de transitions et d’effets.
=Flex3 FM.book Page 156 Mardi, 2. décembre 2008 3:32 15
=Flex3 FM.book Page 157 Mardi, 2. décembre 2008 3:32 15
9
Le dynamisme applicatif
à l’aide des états,
des transitions et des effets
Dans le chapitre précédent, nous avons vu comment agencer les composants au sein d’une
interface. Nous allons à présent aborder les notions d’états, de transitions et d’effets
permettant d’ajouter dynamisme et convivialité à nos applications Flex.
Les états ou view states
Comme nous le savons, une application Flex est composée d’un fichier MXML décrivant
son interface graphique. Sur cette dernière, nous pouvons disposer des composants selon
un agencement précis répondant aux besoins d’ergonomie et de fonctionnalité de l’application. Il n’est pas faux d’affirmer qu’une interface graphique doit être « vivante », dans
le sens où un événement peut déclencher l’ouverture d’une interface spécifique, cacher
certains composants ou parties de l’interface, en modifier totalement l’apparence… En
HTML, ceci s’obtient aisément en combinant les langages CSS et JavaScript ou bien en
créant une nouvelle page. Néanmoins, n’oublions pas que nous ne possédons qu’un seul
fichier de description d’interface, alors comment procéder ?
C’est la notion d’état qui va nous apporter la réponse. Cette notion repose sur l’interface
de base d’une application Flex, que l’on nommera état de base (base state). Cet état peut
par ailleurs donner naissance à des états enfants ayant les mêmes caractéristiques que
leur parent, mais pour lesquels il est possible d’ajouter ou de supprimer des composants
ou encore de modifier les comportements et événements qui leur sont associés.
=Flex3 FM.book Page 158 Mardi, 2. décembre 2008 3:32 15
158
Comprendre Flex 3
PARTIE I
La compréhension de la notion d’état n’est pas facile. C’est pourquoi nous allons nous
appuyer sur une étude de cas qui va nous permettre de mieux comprendre le mécanisme
de ce concept.
Vers une première définition
Pour introduire la notion d’état, nous pouvons l’assimiler au changement de page d’un site web. Un état
correspond alors à une nouvelle page web.
Étude de cas
Imaginons une interface graphique permettant d’effectuer des recherches sur des patients
dans une base de données médicale. Deux types de recherche sont possibles :
• la recherche simple contenant quelques critères de base (numéro de patient, prénom et
nom) ;
• la recherche avancée comportant davantage de critères (numéro de chambre, date
d’admission…).
La recherche basique sera proposé par défaut à l’utilisateur, mais il lui sera possible de
basculer vers la recherche avancée en sélectionnant cette option.
Création de l’état de base
La première étape va consister à créer l’interface de base proposant la recherche simple :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<!-- GROUPE DE BOUTONS RADIO -->
<mx:RadioButtonGroup id="radioBoutons"/>
<mx:RadioButton x="34" y="21" label="Recherche simple" groupName="radioBoutons"
➥id="btn_simple" selected="true"/>
<mx:RadioButton x="166" y="21" label="Recherche avancée" groupName="radioBoutons"
➥id="btn_avance"/>
<!-- CRITÈRES DE RECHERCHE -->
<mx:Panel id="panel1" x="34" y="51" width="339" height="198" layout="absolute"
➥title="Critères de recherche" >
<mx:Form id="form1"x="10" y="10" height="108" width="302"
➥horizontalScrollPolicy="off" verticalScrollPolicy="off">
<mx:FormItem label="N° patient :">
<mx:TextInput id="numPatient"/>
</mx:FormItem>
<mx:FormItem label="Prénom :">
<mx:TextInput id="Prenom"/>
</mx:FormItem>
=Flex3 FM.book Page 159 Mardi, 2. décembre 2008 3:32 15
Le dynamisme applicatif à l’aide des états, des transitions et des effets
CHAPITRE 9
159
<mx:FormItem label="Nom :">
<mx:TextInput id="Nom"/>
</mx:FormItem>
</mx:Form>
<mx:Button id="button1"x="221" y="126" label="Rechercher"/>
</mx:Panel>
</mx:Application>
Cet exemple de code permet de sélectionner le type de recherche souhaité à l’aide du
composant RadioButton (figure 9-1). Le bouton radio proposant la recherche simple est
sélectionné par défaut (selected="true"). S’en suit la mise en place d’un Panel contenant
un formulaire, composé de trois champs correspondant aux trois critères de base. Enfin,
un bouton avec un intitulé clair quant à sa fonction est inséré dans le composant Panel.
Notre interface de base, ou état de base, est à présent créé.
Figure 9-1
Interface de
recherche simple
Comme le sous-entend le cahier des charges de ce cas pratique, le type de recherche
avancée doit inclure les champs de recherche de base tout en proposant des critères
supplémentaires. Nous allons donc créer un état enfant qui héritera de l’état de base
auquel nous ajouterons d’autres critères.
Création de l’état enfant
Pour créer ce nouvel état, nous allons ajouter le code suivant dans le fichier MXML de
notre application :
<mx:states>
<mx:State name="rechercheAvancee"/>
</mx:states>
La balise <mx:states> a pour fonction de lister l’ensemble des états contenus dans l’application. Par ailleurs, une balise <mx:State> y a été ajoutée, cette dernière permettant d’indiquer
la création d’un nouvel état nommé rechercheAvancee. Notre état enfant est désormais créé.
=Flex3 FM.book Page 160 Mardi, 2. décembre 2008 3:32 15
160
Comprendre Flex 3
PARTIE I
Il convient à présent de modifier quelques propriétés afin de proposer les nouveaux critères de recherche :
• agrandissement du panel ;
• agrandissement du formulaire, occasionnant le déplacement du bouton Rechercher ;
• ajout des critères de recherche supplémentaires.
Pour cela, nous agrémentons le code précédemment saisi :
<mx:states>
<mx:State name="rechercheAvancee">
<mx:SetProperty target="{panel1}" name="height" value="267"/>
<mx:SetProperty target="{button1}" name="x" value="218"/>
<mx:SetProperty target="{button1}" name="y" value="195"/>
<mx:SetProperty target="{form1}" name="height" value="177"/>
<mx:AddChild relativeTo="{form1}" position="lastChild">
<mx:FormItem label="N° chambre :">
<mx:TextInput id="num_chambre"/>
</mx:FormItem>
</mx:AddChild>
<mx:AddChild relativeTo="{form1}" position="lastChild">
<mx:FormItem label="Date admission :">
<mx:DateField id="dateAdmission" />
</mx:FormItem>
</mx:AddChild>
</mx:State>
</mx:states>
Quelques explications s’imposent. Grâce à la balise <mx:SetProperty>, il nous est possible
de modifier les propriétés du composant dont l’identifiant est précisé dans la propriété
target.
Ainsi, la première ligne de code consiste à modifier la hauteur (name="height") du composant panel1, en passant la valeur de cette propriété à 267 pixels. Avec ce décryptage en
tête, nous vous laissons le soin d’analyser les trois autres lignes de code concernant le
déplacement du bouton (lignes 2 et 3) et l’agrandissement du formulaire (ligne 4).
Passons à présent à la suite du code :
<mx:AddChild relativeTo="{form1}" position="lastChild">
<mx:FormItem label="N° chambre :">
<mx:TextInput id="num_chambre"/>
</mx:FormItem>
</mx:AddChild>
<mx:AddChild relativeTo="{form1}" position="lastChild">
<mx:FormItem label="Date admission :">
<mx:DateField id="dateAdmission" />
</mx:FormItem>
</mx:AddChild>
=Flex3 FM.book Page 161 Mardi, 2. décembre 2008 3:32 15
Le dynamisme applicatif à l’aide des états, des transitions et des effets
CHAPITRE 9
161
Vous l’avez certainement deviné, ce code permet d’ajouter les nouveaux critères de
recherche. Cela est réalisé à l’aide de la balise <mx:AddChild>, qu’il faut comprendre
comme suit : « Ajouter à la suite des champs déjà présents (position="lastChild") dans le
formulaire form1 (relativeTo="{form1}"), un nouveau champ de formulaire (<mx:FormItem>)
dont le label est N° chambre et dont le type est une zone de saisie (<mx:TextInput>) ». Cette
traduction est également applicable au champ dateAdmission ajouté à l’aide de la seconde
balise <mx:AddChild>.
Notre état enfant est à présent terminé. Pour visualiser le résultat obtenu, placez-vous
dans la perspective Design de Flex Builder. En haut à droite de cette perspective, vous
trouverez la vue States. Si le code a été correctement saisi, vous devriez visualiser le
nouvel état héritant de l’état de base (<Base State>), comme l’illustre la figure 9-2. Vous
pouvez également naviguer entre les différents états en cliquant dessus, ce qui permet
d’en visualiser les différences (figure 9-3).
Figure 9-2
Visualisation de l’état
rechercheAvancee
dans Flex Builder
Figure 9-3
Visualisation des états
=Flex3 FM.book Page 162 Mardi, 2. décembre 2008 3:32 15
162
Comprendre Flex 3
PARTIE I
La dernière tâche qui nous incombe consiste à mettre en place l’aspect dynamique de
l’application, c’est-à-dire permettre à l’utilisateur de passer d’un état à un autre en sélectionnant l’option de recherche de son choix.
Mise en place de l’interactivité
Le passage d’un état à un autre sera effectué lors de la sélection du type de recherche à
l’aide des boutons radio. C’est donc sur l’événement click de ceux-ci que nous ferons
appel à l’état correspondant à l’option sélectionnée.
La sélection d’un état s’effectue grâce à la méthode currentState à laquelle nous passons
en paramètre l’état à afficher :
<!-- GROUPE DE BOUTONS RADIO -->
<mx:RadioButtonGroup id="radioBoutons"/>
<mx:RadioButton x="34" y="21" label="Recherche simple" groupName="radioBoutons"
➥id="btn_simple" selected="true" click="currentState=''"/>
<mx:RadioButton x="166" y="21" label="Recherche avancée" groupName="radioBoutons"
➥id="btn_avance" click="currentState='rechercheAvancee'"/>
Cet exemple de code présente la méthode d’appel de l’état à afficher lors de l’événement
click du bouton radio. À noter qu’aucun paramètre n’a été défini pour la méthode
currentState du bouton btn_simple, l’état appelé sera donc l’état de base.
N’oublions pas que l’état enfant doit hériter de l’état parent, sauf volonté contraire du
développeur. Dans notre cas, nous souhaitons que le changement d’état s’effectue également sur l’état enfant. Il convient donc d’ajouter ces deux événements à l’état rechercheAvancee :
<mx:SetEventHandler target="{btn_simple}" name="click" handler="currentState=''"/>
<mx:SetEventHandler target="{btn_avance}" name="click" handler=
➥"currentState='rechercheAvancee'"/>
Vous l’aurez compris, la balise <mx:SetEventHandler> permet d’ajouter des événements
sur des composants des états enfants.
Pour plus de clarté, voici le code complet de l’état de recherche avancée :
<mx:State name="rechercheAvancee">
<mx:SetProperty target="{panel1}" name="height" value="267"/>
<mx:SetProperty target="{button1}" name="x" value="218"/>
<mx:SetProperty target="{button1}" name="y" value="195"/>
<mx:SetProperty target="{form1}" name="height" value="177"/>
<mx:AddChild relativeTo="{form1}" position="lastChild">
<mx:FormItem label="N° chambre :">
<mx:TextInput id="num_chambre"/>
</mx:FormItem>
</mx:AddChild>
<mx:AddChild relativeTo="{form1}" position="lastChild">
<mx:FormItem label="Date admission :">
<mx:DateField id="dateAdmission"/>
</mx:FormItem>
=Flex3 FM.book Page 163 Mardi, 2. décembre 2008 3:32 15
Le dynamisme applicatif à l’aide des états, des transitions et des effets
CHAPITRE 9
163
</mx:AddChild>
<mx:SetEventHandler target="{btn_simple}" name="click" handler="currentState=''"/>
<mx:SetEventHandler target="{btn_avance}" name="click" handler="currentState=
➥'rechercheAvancee'"/>
</mx:State>
Grâce à cette étude de cas, nous avons pu apprécier la notion d’état. Les états permettent
de définir l’architecture de l’application en fonction des actions de l’utilisateur. Vous
pouvez ainsi modifier l’apparence de l’interface ou d’un composant en fonction d’un
événement déclenché par l’utilisateur. Cette nouvelle notion peut être un peu difficile à
assimiler pour celles et ceux habitués à développer des applications web classiques, mais
ils en apprécieront pleinement les avantages par la suite.
Nous allons à présent aborder la notion de transition qui, comme vous allez le voir, représente une partie très importante de la notion d’interface cliente riche en nous permettant
d’ajouter du dynamisme à nos états.
Les transitions
Un peu à la manière d’un logiciel de montage vidéo, Flex permet d’effectuer des transitions entre chaque changement d’état. Vous pourrez ainsi obtenir des applications à
l’aspect visuel très intéressant et attractif.
La création d’une transition s’effectue en définissant les quatre paramètres de base
suivants :
• l’identifiant de la transition ;
• l’état de départ ;
• l’état d’arrivée ;
• l’effet de transition exécuté.
En explorant la documentation du package mx.effects , nous pouvons dresser la liste des
effets de transition disponibles, repris dans le tableau 9-1, ainsi que leur description.
Tableau 9-1
Liste des effets de transition disponibles
Effet
Description
Blur
Exécution d’un effet de flouté.
Dissolve
Passe de l’état transparent à l’état opaque ou inversement.
Fade
Effet semblable à celui de
composant.
Glow
Applique un effet de surbrillance sur le composant.
Iris
Utilise un masque rectangulaire centré sur la cible afin de dévoiler petit à petit le contenu
de celle-ci.
Move
Modifie la position d’un composant.
Dissolve en jouant sur la valeur de la propriété alpha du
=Flex3 FM.book Page 164 Mardi, 2. décembre 2008 3:32 15
164
Comprendre Flex 3
PARTIE I
Tableau 9-1
Liste des effets de transition disponibles (suite)
Effet
Description
Rezise
Modifie la hauteur et la largeur d’un composant.
Rotate
Effectue la rotation d’un objet suivant un angle spécifique.
WipeDown
Effet de « baisser de rideau ».
WipeLeft
Effet de « tirer de rideau » vers la gauche.
WipeUp
Effet de « lever de rideau ».
WipeRight
Effet de « tirer de rideau » vers la droite.
Zoom
Effet de zoom sur le composant concerné.
Voyons à présent comment implémenter une transition à travers l’exemple de code suivant :
<mx:transitions>
<mx:Transition id="transition" fromState="*" toState="*">
<mx:WipeDown duration="1000" target="{panel1}"> </mx:WipeDown>
</mx:Transition>
</mx:transitions>
La première étape consiste à mettre en place la balise <mx:transitions> qui va contenir
l’ensemble des transitions de l’application. Vient ensuite la création de la transition
proprement dite qui, comme mentionné précédemment, est définie par :
• son identifiant : id="transition" ;
• l’état de départ : fromState="*" ;
• l’état d’arrivée : toState="*" ;
• l’effet : <mx:WipeDown duration="1000" target="{panel1}">.
En analysant attentivement les quelques lignes de code précédentes, nous pouvons observer quelques subtilités. La première concerne le nom des états. En effet, leur nom a été
remplacé une astérisque (*), signifiant que la transition concerne l’ensemble des changements d’états de l’application. L’expression littérale de notre transition est la suivante :
« Pour chaque changement d’état effectué dans l’application, appliquer l’effet WipeDown,
ayant une durée de 1000 millisecondes, au composant panel1 ». Si nous avions souhaité
créer une transition entre deux états particuliers, nous aurions remplacé les astérisques
par l’identifiant de ces états :
<mx:transitions>
<mx:Transition id="transition" fromState="nomEtat1" toState="nomEtat2">
<mx:WipeDown duration="1000" target="{panel1}"> </mx:WipeDown>
</mx:Transition>
</mx:transitions>
La seconde subtilité concernera l’emploi de la balise <mx:sequence>, dont la signification
sera détaillée à la section suivante « Combiner des effets ».
=Flex3 FM.book Page 165 Mardi, 2. décembre 2008 3:32 15
Le dynamisme applicatif à l’aide des états, des transitions et des effets
CHAPITRE 9
165
Effet et cible (target)
Chaque effet doit être appliqué sur une cible, dont l’identifiant est passé en paramètre de la propriété
target de l’effet à l’aide d’accolades ouvrante et fermante. Pour appliquer l’effet à plusieurs cibles, il
convient d’utiliser la propriété targets, à laquelle nous passons en paramètre la liste des identifiants des
cibles concernées :
<mx:WipeDown duration="1000" targets="{[panel1,numPatient]}"> </mx:WipeDown>
Combiner des effets
Chaque effet a une durée d’exécution déterminée dans le temps. Cette durée, exprimée en
millisecondes, est précisée à l’aide de la propriété duration. Pour bien comprendre, revenons sur la notion de transition. Nous avons vu qu’une transition peut comporter un effet,
mais elle peut également en comporter plusieurs ! Dans ce cas, comment ordonner leur
exécution ? La réponse réside dans l’utilisation des balises <mx:Sequence> et <mx:Parallel>
dont nous allons à présent étudier le fonctionnement.
Exécution en séquence
La balise <mx:Sequence> va nous permettre d’exécuter les effets de façon successive
(figure 9-4). Si la transition comporte deux effets, l’effet 1 sera exécuté, puis l’effet 2, à
condition que l’exécution du premier effet soit terminée.
Figure 9-4
Séquence d’effets
<mx:transitions>
<mx:Transition id="transition" fromState="*" toState="*">
<mx:Sequence target="{panel1}">
<mx:WipeDown duration="1000"> </mx:WipeDown>
<mx:Blur duration="1500"> </mx:Blur>
</mx:Sequence>
</mx:Transition>
</mx:transitions>
Dans cet exemple de code, les effets WipeDown et Blur seront exécutés l’un après l’autre.
Voyons à présent les particularités de la balise <mx:Parallel>.
=Flex3 FM.book Page 166 Mardi, 2. décembre 2008 3:32 15
166
Comprendre Flex 3
PARTIE I
Exécution en parallèle
Comme vous l’avez sans doute deviné, la balise <mx:Parallel> permet l’exécution d’effets
de façon simultanée (figure 9-5). Ainsi, si la transition comporte deux effets, l’effet 1 et
l’effet 2 sont exécutés en même temps.
<mx:transitions>
<mx:Transition id="transition" fromState="*" toState="*">
<mx:Parallel target="{panel1}">
<mx:WipeDown duration="1000"> </mx:WipeDown>
<mx:Blur duration="1500"> </mx:Blur>
</mx:Parallel>
</mx:Transition>
</mx:transitions>
Dans cet exemple de code, les effets WipeDown et Blur sont exécutés de façon simultanée.
Il est temps à présent de mettre en pratique de ce que vous venez d’apprendre sur les transitions et les effets associés. Pour cela, nous vous proposons de reprendre l’étude de cas
précédente afin d’y ajouter une transition.
Figure 9-5
Effets exécutés
en parallèle
Mise en pratique
La transition que nous souhaitons implémenter sera jouée à chaque changement d’état de
l’application. Nous y ajouterons deux effets exécutés de façon simultanée et ayant pour
cible commune le composant Panel contenant le formulaire. Les effets choisis sont :
• une rotation complète du panneau (figure 9-6) ;
• un effet « d’Iris », c’est-à-dire la découverte progressive du panneau (figure 9-7).
L’implémentation de la transition se résume à l’ajout des quelques lignes de code suivantes :
<!-- TRANSITIONS -->
<mx:transitions>
<mx:Transition id="transition" fromState="*" toState="*">
<mx:Parallel target="{panel1}">
<mx:Rotate angleFrom="0" angleTo="360" duration="1000"> </mx:Rotate>
<mx:Iris duration="1000"> </mx:Iris>
</mx:Parallel>
</mx:Transition>
</mx:transitions>
=Flex3 FM.book Page 167 Mardi, 2. décembre 2008 3:32 15
Le dynamisme applicatif à l’aide des états, des transitions et des effets
CHAPITRE 9
Figure 9-6
Effet de rotation
Figure 9-7
Effet « d’Iris »
167
=Flex3 FM.book Page 168 Mardi, 2. décembre 2008 3:32 15
168
Comprendre Flex 3
PARTIE I
Notre transition est donc jouée à chaque changement d’état grâce à la valeur * affectée
aux propriétés fromState et toState. Comme nous souhaitons que l’exécution des effets
soit simultanée, nous utilisons la balise <mx:Parallel> ayant pour cible principale le
panneau portant l’identifiant panel1.
Le premier effet est une rotation complète du panneau (angleFrom="0" angleTo="360") sur
une durée de 1000 millisecondes. Quant au second, il s’agit de l’effet Iris ayant une
durée équivalente à l’effet précédent.
La transition est à présent mise en place. Nous vous laissons le soin de l’apprécier en
exécutant le projet. Pour plus de clarté, voici le code complet de l’application qui pourra
vous aider en cas d’éventuels dysfonctionnements :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<!-- TRANSITIONS -->
<mx:transitions>
<mx:Transition id="transition" fromState="*" toState="*">
<mx:Parallel target="{panel1}">
<mx:Rotate angleFrom="0" angleTo="360" duration="1000"> </mx:Rotate>
<mx:Iris duration="1000"> </mx:Iris>
</mx:Parallel>
</mx:Transition>
</mx:transitions>
<!-- GROUPE DE BOUTONS RADIO -->
<mx:RadioButtonGroup id="radioBoutons"/>
<mx:RadioButton x="34" y="21" label="Recherche simple" groupName="radioBoutons"
➥id="btn_simple" selected="true" click="currentState=''"/>
<mx:RadioButton x="166" y="21" label="Recherche avancée" groupName="radioBoutons"
➥id="btn_avance" click="currentState='rechercheAvancee'"/>
<!-- CRITÈRES DE RECHERCHE -->
<mx:Panel x="34" y="51" width="339" height="198" layout="absolute" title="Critères de
➥recherche" id="panel1">
<mx:Form x="10" y="10" height="108" width="302" horizontalScrollPolicy="off"
➥verticalScrollPolicy="off" id="form1">
<mx:FormItem label="N° patient :">
<mx:TextInput id="numPatient"/>
</mx:FormItem>
<mx:FormItem label="Prénom :">
<mx:TextInput id="Prenom"/>
</mx:FormItem>
<mx:FormItem label="Nom :">
<mx:TextInput id="Nom"/>
</mx:FormItem>
</mx:Form>
<mx:Button x="221" y="126" label="Rechercher" id="button1"/>
</mx:Panel>
=Flex3 FM.book Page 169 Mardi, 2. décembre 2008 3:32 15
Le dynamisme applicatif à l’aide des états, des transitions et des effets
CHAPITRE 9
169
<!-- ÉTATS -->
<mx:states>
<mx:State name="rechercheAvancee">
<mx:SetProperty target="{panel1}" name="height" value="267"/>
<mx:SetProperty target="{button1}" name="x" value="218"/>
<mx:SetProperty target="{button1}" name="y" value="195"/>
<mx:SetProperty target="{form1}" name="height" value="177"/>
<mx:AddChild relativeTo="{form1}" position="lastChild">
<mx:FormItem label="N° chambre :">
<mx:TextInput id="num_chambre"/>
</mx:FormItem>
</mx:AddChild>
<mx:AddChild relativeTo="{form1}" position="lastChild">
<mx:FormItem label="Date admission :">
<mx:DateField id="dateAdmission"/>
</mx:FormItem>
</mx:AddChild>
<mx:SetEventHandler target="{btn_simple}" name="click"
➥handler="currentState=''"/>
<mx:SetEventHandler target="{btn_avance}" name="click"
➥handler="currentState='rechercheAvancee'"/>
</mx:State>
</mx:states>
</mx:Application>
Écrire des transitions en ActionScript
Comme nous l’avons vu au chapitre 2, tout ce qui est réalisé en MXML peut l’être grâce
à ActionScript. C’est donc tout naturellement que nous allons recréer l’effet de transition
précédent à l’aide du langage ActionScript.
Pour cela, il convient tout d’abord d’effacer toute notion de transition dans l’application
en supprimant le code suivant :
<!-- TRANSITIONS -->
<mx:transitions>
<mx:Transition id="transition" fromState="*" toState="*">
<mx:Parallel target="{panel1}">
<mx:Rotate angleFrom="0" angleTo="360" duration="1000"> </mx:Rotate>
<mx:Iris duration="1000"> </mx:Iris>
</mx:Parallel>
</mx:Transition>
</mx:transitions>
Ensuite, nous allons devoir créer un nouveau fichier ActionScript dans le répertoire src
du projet, que nous nommerons TransitionAS3.as. Attention à ne pas oublier de créer le
lien entre l’application et ce fichier en utilisant la balise <mx:Script> :
<mx:Script source="TransitionAS3.as"> </mx:Script>
=Flex3 FM.book Page 170 Mardi, 2. décembre 2008 3:32 15
170
Comprendre Flex 3
PARTIE I
Passons à présent à l’écriture du code de notre transition :
// Importation des classes nécessaires
import mx.effects.Iris;
import mx.effects.Parallel;
import mx.effects.Rotate;
import mx.states.Transition;
public function creationTransition ():void{
// Création de la transition
var transitionAS:Transition = new Transition;
transitionAS.fromState = "*";
transitionAS.toState = "*";
// Création de la notion de parallélisme d’effets
var parallelisme:Parallel = new Parallel;
parallelisme.target = panel1;
// Création de l’effet de rotation
var rotation:Rotate = new Rotate();
rotation.angleFrom = 0;
rotation.angleTo = 360
rotation.duration = 1000;
// Création de l’effet d’Iris
var iris:Iris = new Iris();
iris.duration = 1000;
// Ajout des effets au conteneur d’effets
parallelisme.addChild(rotation);
parallelisme.addChild(iris);
// Ajout du conteneur à la transition
transitionAS.effect = parallelisme;
// Ajout de la transition à la balise <mx:transitions> de l’application
application.transitions = [transitionAS];
}
La lecture de ce code parle d’elle-même. Nous importons tout d’abord l’ensemble des
classes nécessaires à la réalisation de la transition, puis nous construisons petit à petit
l’ensemble des éléments la composant. Le tableau 9-2 présente la correspondance entre le
code MXML utilisé précédemment pour la création de la transition et le code ActionScript.
Souvenez-vous, les effets de rotation et d’Iris sont dans le conteneur d’effets définissant
leur mode d’exécution :
<mx:Parallel target="{panel1}">
<mx:Rotate angleFrom="0" angleTo="360" duration="1000"> </mx:Rotate>
<mx:Iris duration="1000"> </mx:Iris>
</mx:Parallel>
=Flex3 FM.book Page 171 Mardi, 2. décembre 2008 3:32 15
Le dynamisme applicatif à l’aide des états, des transitions et des effets
CHAPITRE 9
Tableau 9-2
171
Correspondances entre le code MXML et le code ActionScript
Étape
MXML
Actionscript
Création de la transition.
<mx:Transition id="transition"
fromState="*" toState="*">
var transitionAS:Transition = new
Transition;
transitionAS.fromState = "*";
transitionAS.toState = "*";
Définition du mode
d’exécution des effets
et de la cible concernée.
<mx:Parallel
target="{panel1}">
var parallelisme:Parallel = new
Parallel;
parallelisme.target = panel1;
Création de l’effet
de rotation.
<mx:Rotate angleFrom="0"
angleTo="360" duration="1000">
</mx:Rotate>
var rotation:Rotate = new Rotate();
rotation.angleFrom = 0;
rotation.angleTo = 360
rotation.duration = 1000;
Création de l’effet d’Iris.
<mx:Iris duration="1000">
</mx:Iris>
var iris:Iris = new Iris();
iris.duration = 1000;
Bien entendu, MXML étant un langage basé sur XML, la notion d’inclusion d’élément se
fait tout naturellement :
// L’élément B est contenu dans l’élément A
<ElementA>
<ElementB> </ElementB>
</ElementA>
En ActionScript, cela n’est possible que si la classe utilisée permet de réaliser cette inclusion via l’une de ses méthodes. Si nous analysons la classe Parallel, nous constatons la
présence de la méthode addChild(childEffect:IEffect) permettant d’ajouter à notre
conteneur les deux effets créés :
parallelisme.addChild(rotation);
parallelisme.addChild(iris);
Il convient ensuite d’inclure notre transition dans la propriété transitions (<mx:transitions>) de l’application chargée de contenir dans un tableau l’ensemble des transitions de
l’application :
application.transitions = [transitionAS];
La dernière étape consiste tout simplement à faire appel à notre procédure creationTransition() dans notre application et à vérifier par l’exécution du projet que le résultat
obtenu est identique à celui obtenu par l’usage du langage MXML.
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥creationComplete="creationTransition ()">
=Flex3 FM.book Page 172 Mardi, 2. décembre 2008 3:32 15
172
Comprendre Flex 3
PARTIE I
En résumé
Dans ce chapitre, nous avons vu comment il est possible d’organiser l’interface graphique de
nos applications à l’aide des états et comment réaliser des transitions « animées ». Ces
dernières permettent de réaliser des interfaces graphiques plus conviviales, avec un pouvoir
commercial indéniable : si l’application est agréable à l’œil l’utilisateur aimera s’en
servir et en parlera autour de lui. Attention toutefois à ne pas abuser des animations car en
trop grand nombre, elles pourraient être gênantes pour les utilisateurs, qui la rejetteraient
alors très rapidement, anéantissant ainsi votre dur labeur.
Comme nous l’avons vu, Flex offre un éventail de fonctionnalités très large, couvrant la
majeure partie de nos besoins. Néanmoins, il peut s’avérer que le composant nécessaire
ne soit pas présent dans la bibliothèque de Flex. Nous allons donc voir dans le chapitre
suivant comment créer nos propres composants.
=Flex3 FM.book Page 173 Mardi, 2. décembre 2008 3:32 15
10
Créer des composants
personnalisés
Par définition, un composant est un objet faisant partie d’un système. Une application
Flex contient un ensemble de composants ayant chacun un rôle précis :
• un bouton qui déclenche l’exécution d’une action ;
• un DataGrid qui offre la possibilité de présenter les données sous forme tabulaire ;
• une zone de saisie, lieu de l’interaction avec l’utilisateur : elle lui offre la possibilité
d’alimenter le système d’information, etc.
Cependant, ces composants ne sont pas toujours entièrement satisfaisants, car leurs
possibilités sont parfois limitées. Fort heureusement, le framework Flex nous permet de
remédier à cela en créant nos propres composants.
Penser composant
Avant d’entrer dans le cœur du sujet, il est souhaitable de bien comprendre la notion de
composant.
Un composant est un élément autonome offrant un ensemble de fonctionnalités et
pouvant être utilisé de façon similaire dans plusieurs applications. Il doit donc être capable de s’adapter à l’environnement applicatif dans lequel il est utilisé, tout en assurant
une continuité de ses services. Prenons l’exemple du composant Button. Vous pouvez
l’adapter à l’environnement applicatif en changeant son libellé ou son design (couleur,
=Flex3 FM.book Page 174 Mardi, 2. décembre 2008 3:32 15
174
Comprendre Flex 3
PARTIE I
police…), il assurera toujours sa fonctionnalité principale, qui est le déclenchement d’une
action lorsque l’utilisateur clique dessus.
Pour pouvoir être considéré comme tel, un composant doit offrir une ou plusieurs fonctionnalités qui pourront être invoquées quelle que soit l’application dans lequel il sera utilisé,
ainsi qu’un certain nombre de paramètres lui permettant de s’adapter à son environnement.
Tout ceci dans le but d’être réutilisable.
Comme mentionné précédemment, une application Flex est constituée d’un ensemble de
composants. Par ailleurs, un composant peut lui aussi comprendre d’autres composants.
Par exemple, un composant permettant de suivre des flux RSS devra être constitué d’un
composant permettant de saisir l’URL du flux à lire et d’un composant DataGrid présentant les articles de ce flux sous forme tabulaire. Un tel composant pourrait être qualifié de
complexe mais nous lui préférons le nom de module.
Ainsi, une application peut facilement être découpée en modules réutilisables dans d’autres
applications. L’intérêt de développer des modules réside dans le fait qu’ils peuvent être
développés et maintenus séparément, ne remettant pas en cause la stabilité de l’application
dans laquelle ils sont intégrés.
Qu’est–ce qu’un composant ?
Un composant est un fichier portant l’extension .swc, obtenu grâce à la compilation
d’autres fichiers, écrits à l’aide des langages ActionScript et/ou MXML.
MXML ou ActionScript ?
La première question que nous sommes en droit de nous poser est : faut il créer le
composant à l’aide du langage MXML ou ActionScript ? Il n’existe pas de règle réellement établie à ce sujet. Pour les composants simples, c’est-à-dire ayant peu de fonctionnalités (un composant de présentation d’images par exemple), le MXML peut suffire.
Pour un composant demandant la mise en place d’une logique complexe, la combinaison
des langages ActionScript et MXML est à préférer, mais rien ne vous empêche d’utiliser
exclusivement ActionScript. C’est d’ailleurs cette méthode que nous allons privilégier ici
afin d’illustrer au mieux la mise en place d’un composant. Libre à vous d’opter pour
l’une ou l’autre de ces méthodes en fonction de vos affinités avec les langages ActionScript et MXML, et de la complexité du composant à développer.
Le compilateur compc
Maintenant que le choix de la méthode de développement a été effectué, nous pouvons
passer à la réalisation du composant. Une fois ce dernier créé, il nous faut le compiler
afin de le rendre utilisable dans d’autres applications Flex. C’est le rôle du compilateur
compc.
=Flex3 FM.book Page 175 Mardi, 2. décembre 2008 3:32 15
Créer des composants personnalisés
CHAPITRE 10
175
Le compilateur de composants compc s’exécute en ligne de commande. Il permet de créer
un fichier SWC à partir de fichiers MXML et ActionScript passés en paramètres. Sa
syntaxe d’exécution est la suivante :
compc [options] -include-classes class [...]
compc -o monComposant.swc
-root monComposant.mxml
Dans cet exemple de code, nous compilons le fichier monComposant.mxml donnant naissance (-o = output) au fichier monComposant.swc. Nous ne nous attarderons pas davantage
sur ce compilateur dont le fonctionnement sera détaillé à la section « Compilation avec
compc » de ce chapitre.
Créer un composant
Un exemple valant souvent mieux qu’un long discours, nous vous proposons à présent de
créer un composant que vous réutiliserez sans doute dans un grand nombre de vos futures
applications Flex, qui vous permettra de filtrer un tableau en fonction d’une donnée saisie
dans une zone de texte.
Description du composant
Le composant que nous allons créer permettra de filtrer le contenu d’un tableau sur une
colonne donnée en fonction des informations saisies par l’utilisateur dans un champ
prévu à cet effet.
Le fonctionnement du composant est synthétisé par la figure 10-1 qui nous permet de définir
les étapes suivantes :
Étape ➊ : le composant reçoit des données sous la forme d’une collection d’objets
(ArrayCollection).
Étape ➋ : les données reçues sont affichées dans le DataGrid du composant.
Étape ➌ : l’utilisateur saisit son critère de recherche dans la zone de texte prévue à cet
effet.
Étape ➍ : à chaque modification de la zone de saisie, le filtre est effectué sur la colonne
du DataGrid concerné selon la règle suivante : « Afficher les éléments de la colonne
contenant la valeur de l’expression saisie dans la zone de texte », ce qui entraîne la mise
à jour du DataGrid.
Étape ➎ : la sélection d’une ligne du DataGrid permet d’extraire la valeur servant d’identifiant pour la donnée cliquée, valeur qui peut alors être exploitée dans un autre traitement.
=Flex3 FM.book Page 176 Mardi, 2. décembre 2008 3:32 15
176
Comprendre Flex 3
PARTIE I
Figure 10-1
Fonctionnement
du composant
Compte tenu de ce que nous venons d’énoncer, les éléments faisant partie intégrante du
composant sont donc :
• un composant TextInput qui permettra à l’utilisateur de saisir des données ;
• un composant Label précédant la zone de saisie et permettant d’indiquer à l’utilisateur
la colonne du tableau concernée par le filtre ;
• un composant DataGrid représentant les données sous forme tabulaire ;
• un composant Canvas servant de conteneur principal.
Comme nous l’avons vu précédemment, un composant doit être réutilisable et s’adapter
à toutes les situations. Pour que cette adaptation soit effective, certaines propriétés du
composant doivent être paramétrables. La plupart des paramétrages sont liés à l’aspect
graphique (couleur, libellés…). Pour que notre composant soit réutilisable, nous devons
offrir la possibilité de paramétrer les éléments suivants :
• le nombre de colonnes du DataGrid ;
• les propriétés des colonnes (nom, taille, visibilité…) ;
• le texte du composant Label précédant la zone de texte.
=Flex3 FM.book Page 177 Mardi, 2. décembre 2008 3:32 15
Créer des composants personnalisés
CHAPITRE 10
177
Les paramètres liés aux traitements ne peuvent que très rarement être spécifiés car ils
obéissent à des règles précises énoncées dans le code du composant. Dans notre cas, nous
allons demander à ce que la collection d’objets transmise au composant (ArrayCollection)
ait une structure particulière :
• le champ sur lequel portera le filtre devra être nommé champFiltre ;
• le champ contenant l’identifiant de la donnée devra porter le nom idt.
Si l’on considère l’exemple illustré par la figure 10-1, la collection d’objets (ArrayCollection)
s’apparente au code suivant :
<mx:ArrayCollection id="sourceDonnees">
<mx:Object idt="1" champFiltre="Tucano Flylab"/>
<mx:Object idt="2" champFiltre="Pou du ciel"/>
<mx:Object idt="3" champFiltre="Skyranger"/>
<mx:Object idt="4" champFiltre="A22 Vision"/>
<mx:Object idt="5" champFiltre="Storch"/>
</mx:ArrayCollection>
Le fonctionnement général du composant étant à présent défini, il est temps de se lancer
dans sa réalisation.
Méthodologie de création
La création de notre composant se déroule en six phases que allons découvrir ensemble :
1. création du projet ;
2. création du composant ;
3. mise en place des éléments graphiques du composant ;
4. alimentation du DataGrid (tableau de données) ;
5. gestion des événements ;
6. compilation.
Phase 1 – Création du projet
Bien que nous allons créer un élément aussi important, il n’existe pas de projet de ce type au
sein de Flex Builder. Il faut donc procéder comme si nous allions créer un projet Flex standard.
Fichier MXML Component
Il est possible de créer un composant au sein d’une application Flex en créant un nouveau fichier MXML
Component.
1. Ouvrez Flex Builder et sélectionnez le menu File>New>Flex Project.
2. Dans la fenêtre qui s’ouvre alors, saisissez le nom du projet (compFiltreTableau pour
notre exemple) et indiquez que vous souhaitez créer une application de type web
(option Web application).
=Flex3 FM.book Page 178 Mardi, 2. décembre 2008 3:32 15
178
Comprendre Flex 3
PARTIE I
3. Conservez les options de configuration proposées par défaut et cliquez sur le bouton
Finish.
Phase 2 − Création du composant
La phase suivante consiste à créer la classe ActionScript du composant et à l’insérer dans
l’interface graphique du projet afin de pouvoir tester son bon fonctionnement.
Dans l’arborescence du projet, nous allons tout d’abord créer un package que l’on
nommera com.composants et qui contiendra la classe du composant :
1. Effectuez un clic droit sur le répertoire src et sélectionnez New>Folder.
2. Nommez ce nouveau répertoire com
3. Répétez l’étape 1 avec le répertoire com nouvellement créé et nommez le nouveau sousrépertoire composants.
4. Créez ensuite la classe du composant en effectuant un clic droit sur le répertoire
composants et en sélectionnant ActionScript Class>New dans le menu contextuel.
5. Dans la fenêtre qui s’affiche alors, vous constatez que le package com.composants est
renseigné de façon automatique.
6. Spécifiez ensuite le nom de la classe, soit FiltreTableau. Le composant étant avant
tout un Canvas comportant différents éléments (TextInput, DataGrid), la classe FiltreTableau devra hériter de la classe mx.containers.Canvas. Cet héritage est à spécifier
dans le champ Superclass de la fenêtre de configuration (figure 10-2).
Convention de nommage
Pour respecter la convention de nommage du langage ActionScript, le nom de la classe doit obligatoirement commencer par une majuscule.
7. Cliquez sur le bouton Finish.
Si vous observez l’arborescence du projet, vous notez la présence de la classe FiltreTableau créée dans le répertoire composants et contenant le code suivant :
package com.composants
{
import mx.containers.Canvas;
public class FiltreTableau extends Canvas
{
public function FiltreTableau()
{
super();
}
}
}
=Flex3 FM.book Page 179 Mardi, 2. décembre 2008 3:32 15
Créer des composants personnalisés
CHAPITRE 10
179
Figure 10-2
Création de la
classe FiltreTableau
Nous observons que la classe Canvas (import mx.containers.Canvas) a été importée et que
notre classe hérite de cette dernière (extends Canvas). Nous notons aussi la présence du
constructeur FiltreTableau(), appelé lors de l’instanciation de la classe. À l’intérieur de
ce constructeur, on remarque également la présence du mot-clé super. Celui-ci doit être
obligatoirement spécifié car notre composant hérite de la classe Canvas et de ce fait, le
constructeur de cette classe doit être appelé avant toute autre instruction.
Il faut ensuite mettre en place le composant dans l’interface graphique du projet en modifiant le fichier comFiltreTableau.mxml créé lors de la phase d’initialisation du projet. Pour
ce faire, activez le mode Source et apportez les modifications suivantes au code déjà
présent :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥xmlns:compFT="com.composants.*">
<compFT:FiltreTableau
id="ComposantFiltreTableau"
width="420"
=Flex3 FM.book Page 180 Mardi, 2. décembre 2008 3:32 15
180
Comprendre Flex 3
PARTIE I
height="420"
x="10"
y="10">
</compFT:FiltreTableau>
</mx:Application>
La première chose à faire est de préciser l’espace de noms du composant à l’aide de xmlns
(pour XML Name Space). C’est grâce à cet espace de noms que le compilateur est en
mesure de trouver les classes ActionScript correspondant à notre composant. L’espace de
noms utilisé est com.composant.* préfixé par la valeur compFT. C’est ce préfixe qui sera
utilisé dans l’interface graphique, Flex étant alors en mesure de faire la relation entre le
préfixe et la classe spécifiée dans l’espace de noms. Nous pourrons ainsi faire appel aux
méthodes du composant. Vient ensuite la mise en place du composant en faisant appel à
son constructeur (<compFT:FiltreTableau>). Étant donné qu’il hérite de la classe Canvas,
nous pouvons lui affecter les propriétés id, width, height, x et y. À présent, si nous activons
le mode Design, nous remarquons la présence de notre composant sous la forme d’un
Canvas comme l’illustre la figure 10-3.
Figure 10-3
Mise en place du composant
Phase 3 − Mise en place des éléments
Nous allons à présent modifier la classe FiltreTableau pour que les éléments TextInput,
Label et DataGrid soient créés dynamiquement.
package com.composants
{
import mx.containers.Canvas;
import mx.controls.DataGrid;
=Flex3 FM.book Page 181 Mardi, 2. décembre 2008 3:32 15
Créer des composants personnalisés
CHAPITRE 10
181
import mx.controls.Label;
import mx.controls.TextInput;
public class FiltreTableau extends Canvas
{
private var _libelle:Label = new Label();
private var _zoneTexte:TextInput = new TextInput;
private var _datagrid:DataGrid = new DataGrid();
public function FiltreTableau()
{
super();
// Ajout du libellé
_libelle.x=10
_libelle.y=10
_libelle.width = 100;
this.addChild(_libelle);
// Ajout de la zone de texte
_zoneTexte.x = 110;
_zoneTexte.y = 10;
this.addChild(_zoneTexte);
// Ajout du DataGrid
_datagrid.x=10;
_datagrid.y=40;
this.addChild(_datagrid);
}
}
}
Après avoir importé les classes relatives à chaque élément, nous devons les instancier en
créant les objets _libelle, _zoneTexte et _datagrid. Chaque objet pourra alors être ajouté
au Canvas de notre composant grâce à sa méthode addChild(). La figure 10-4 illustre le
résultat obtenu après l’ajout de ces quelques lignes de code.
Figure 10-4
Mise en place des éléments
=Flex3 FM.book Page 182 Mardi, 2. décembre 2008 3:32 15
182
Comprendre Flex 3
PARTIE I
Vous aurez sans doute remarqué que le libellé ne semble pas être présent sur l’interface.
Cette impression est due au fait que la propriété text du libellé n’a pas été renseignée,
mais rassurez-vous, le libellé est bien présent. Nous verrons par la suite comment il est
possible de le personnaliser.
Phase 4 − Alimentation du DataGrid
Le DataGrid du composant sera alimenté via une collection d’objets (ArrayCollection)
passée en paramètre. La première étape va donc consister à créer ce paramètre en déclarant un attribut _tableauDonnees de type ArrayCollection ainsi que les méthodes set et get
qui lui seront associées. Dans la méthode set, on affectera le dataProvider de l’objet
_datagrid avec la valeur reçue en paramètre, permettant l’affichage des données dans le
DataGrid.
import mx.collections.ArrayCollection;
public class FiltreTableau extends Canvas
{
[…]
private var _tableauDonnees:ArrayCollection = new ArrayCollection();
public function FiltreTableau()
{
super();
[…]
}
public function set tableauDonnees(t:ArrayCollection):void{
_datagrid.dataProvider = t;
_tableauDonnees = t;
}
public function get tableauDonnees():ArrayCollection{
return _tableauDonnees;
}
}
Modifions à présent le code du fichier FiltreTableau.mxml en créant une nouvelle collection d’objets (ArrayCollection) qui sera passée en paramètre de notre composant.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥xmlns:compFT="com.composants.*">
<mx:ArrayCollection id="sourceDonnees">
<mx:Object idt="1" champFiltre="Tucano Flylab"/>
<mx:Object idt="2" champFiltre="Pou du ciel"/>
<mx:Object idt="3" champFiltre="Skyranger"/>
<mx:Object idt="4" champFiltre="A22 Vision"/>
<mx:Object idt="5" champFiltre="Storch"/>
</mx:ArrayCollection>
=Flex3 FM.book Page 183 Mardi, 2. décembre 2008 3:32 15
Créer des composants personnalisés
CHAPITRE 10
183
<compFT:FiltreTableau
id="ComposantFiltreTableau"
width="420"
height="420"
x="10"
y="10"
tableauDonnees="{sourceDonnees}"
>
</compFT:FiltreTableau>
</mx:Application>
Exécutons ensuite l’application et vérifions que tout se déroule bien correctement
(figure 10-5).
Figure 10-5
Alimentation du DataGrid
Nous pourrions nous contenter du résultat obtenu, mais n’oublions pas qu’un composant
n’est réutilisable que s’il peut s’adapter à une multitude de situations. Dans notre cas, il
serait préférable que les colonnes du DataGrid soient paramétrables, c’est-à-dire qu’il soit
au moins possible de définir leur libellé, leur taille et leur visibilité. Pour cela, nous allons
procéder de la même manière que pour la création du paramètre tableauDonnees. Les
colonnes seront décrites dans une ArrayCollection qui sera ensuite analysée, modifiant
ainsi les colonnes du DataGrid.
import mx.controls.dataGridClasses.DataGridColumn;
public class FiltreTableau extends Canvas
{
[…]
private var _colonnes:ArrayCollection = new ArrayCollection();
[…]
public function set colonnes(col:ArrayCollection):void{
_colonnes = col;
ajouterColonnes()
}
=Flex3 FM.book Page 184 Mardi, 2. décembre 2008 3:32 15
184
Comprendre Flex 3
PARTIE I
public function get colonnes():ArrayCollection{
return _colonnes;
}
public function ajouterColonnes():void
{
var listeColonnes:Array = new Array();
for (var i:int=0; i<_colonnes.length;i++)
{
var colonne:DataGridColumn = new DataGridColumn();
colonne.headerText = _colonnes[i].entete;
colonne.dataField = _colonnes[i].champ;
colonne.visible = _colonnes[i].visible;
colonne.width = _colonnes[i].longueur;
listeColonnes.push(colonne);
}
_datagrid.columns = listeColonnes;
}
}
Nous devons tout d’abord créer l’objet _colonne et ses méthodes set et get associées.
Dans la méthode set, nous faisons appel à la méthode ajouterColonnes() qui, pour chaque
élément trouvé dans l’ArrayCollection _colonnes, instancie la classe mx.controls.dataGridClasses.DataGridColumn.
Cette instanciation a pour résultat la création d’un objet colonne dont les attributs sont
affectés par les données présentes dans l’objet _colonnes. Nous pouvons donc modifier
les attributs suivants :
• headerText, qui correspond à l’en-tête de la colonne ;
• visible, qui indique si la colonne sera visible ou non ;
• width, qui permet de spécifier la taille de la colonne ;
• DataField, qui correspond au nom de l’attribut présent dans l’objet _tableauDonnees
devant être affiché dans cette colonne.
Chaque nouvelle colonne est ensuite mise dans un tableau servant à alimenter l’attribut
columns de l’objet _datagrid.
Voyons à présent comment implémenter tout ceci dans l’interface graphique de notre
application.
<mx:ArrayCollection id="colonnes">
<mx:Object entete="IDT" champ="idt" visible="false" longueur="10"/>
<mx:Object entete="Nom des appareils" champ="champFiltre" visible="true"
➥longueur="300"/>
</mx:ArrayCollection>
=Flex3 FM.book Page 185 Mardi, 2. décembre 2008 3:32 15
Créer des composants personnalisés
CHAPITRE 10
185
<compFT:FiltreTableau
id="ComposantFiltreTableau"
width="420"
height="420"
x="10"
y="10
tableauDonnees="{sourceDonnees}"
colonnes="{colonnes}"
>
</compFT:FiltreTableau>
Chaque objet de l’ArrayCollection possède les attributs entete, champ, visible et longueur
qui seront repris lors de l’ajout de colonnes dans le DataGrid. Il suffit ensuite de passer
cette collection d’objets en paramètre à l’attribut colonnes de notre composant et d’observer
le résultat obtenu (figure 10-6).
Figure 10-6
Paramétrage des colonnes
Le paramétrage de notre composant touche à sa fin, il ne nous reste plus qu’à créer le
paramètre servant à afficher le texte dans le label. Pour ce faire, il convient de créer la
méthode set de l’objet libelle qui modifie la propriété text de ce dernier :
public function set libelle(texte:String):void{
_libelle.text = texte;
}
L’étape finale consiste à affecter ce nouveau paramètre dans l’interface graphique
(figure 10-7) :
<compFT:FiltreTableau
id="ComposantFiltreTableau"
width="420"
height="420"
x="10"
y="10"
tableauDonnees="{sourceDonnees}"
colonnes="{colonnes}"
libelle="Appareil ULM :"
>
=Flex3 FM.book Page 186 Mardi, 2. décembre 2008 3:32 15
186
Comprendre Flex 3
PARTIE I
Figure 10-7
Composant paramétré
Voici le code complet de la classe FiltreTableau et du fichier compFiltreTableau.mxml, qui
vous permettra de vérifier votre bonne compréhension de ce qui vient d’être énoncé et
que vous n’avez rien oublié.
Classe FiltreTableau
package com.composants
{
import mx.containers.Canvas;
import mx.collections.ArrayCollection;
import mx.controls.DataGrid;
import mx.controls.Label;
import mx.controls.TextInput;
import mx.controls.dataGridClasses.DataGridColumn;
public class FiltreTableau extends Canvas
{
private var _libelle:Label = new Label();
private var _zoneTexte:TextInput = new TextInput;
private var _datagrid:DataGrid = new DataGrid();
private var _tableauDonnees:ArrayCollection = new ArrayCollection();
private var _colonnes:ArrayCollection = new ArrayCollection();
public function FiltreTableau()
{
super();
// Ajout du libellé
_libelle.x=10
_libelle.y=10
_libelle.width = 100;
this.addChild(_libelle);
=Flex3 FM.book Page 187 Mardi, 2. décembre 2008 3:32 15
Créer des composants personnalisés
CHAPITRE 10
// Ajout de la zone de texte
_zoneTexte.x = 110;
_zoneTexte.y = 10;
this.addChild(_zoneTexte);
// Ajout du DataGrid
_datagrid.x=10;
_datagrid.y=40;
this.addChild(_datagrid);
}
public function set tableauDonnees(t:ArrayCollection):void{
_datagrid.dataProvider = t;
_tableauDonnees = t;
}
public function get tableauDonnees():ArrayCollection{
return _tableauDonnees;
}
public function set colonnes(col:ArrayCollection):void{
_colonnes = col;
ajouterColonnes()
}
public function get colonnes():ArrayCollection{
return _colonnes;
}
public function ajouterColonnes():void
{
var listeColonnes:Array = new Array();
for (var i:int=0; i<_colonnes.length;i++)
{
var colonne:DataGridColumn = new DataGridColumn();
colonne.headerText = _colonnes[i].entete;
colonne.dataField = _colonnes[i].champ;
colonne.visible = _colonnes[i].visible;
colonne.width = _colonnes[i].longueur;
listeColonnes.push(colonne);
}
_datagrid.columns = listeColonnes;
}
public function set libelle(texte:String):void{
_libelle.text = texte;
}
}
}
187
=Flex3 FM.book Page 188 Mardi, 2. décembre 2008 3:32 15
188
Comprendre Flex 3
PARTIE I
Fichier compFiltreTableau.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥xmlns:compFT="com.composants.*">
<mx:ArrayCollection id="sourceDonnees">
<mx:Object idt="1" champFiltre="Tucano Flylab"/>
<mx:Object idt="2" champFiltre="Pou du ciel"/>
<mx:Object idt="3" champFiltre="Skyranger"/>
<mx:Object idt="4" champFiltre="A22 Vision"/>
<mx:Object idt="5" champFiltre="Storch"/>
</mx:ArrayCollection>
<mx:ArrayCollection id="colonnes">
<mx:Object entete="IDT" champ="idt" visible="false" longueur="10"/>
<mx:Object entete="Noms des appareils" champ="champFiltre" visible="true"
➥longueur="300"/>
</mx:ArrayCollection>
<compFT:FiltreTableau
id="ComposantFiltreTableau"
width="420"
height="420"
x="10"
y="10"
tableauDonnees="{sourceDonnees}"
colonnes="{colonnes}"
libelle="Appareil ULM :"
>
</compFT:FiltreTableau>
</mx:Application>
Phase 5 − Gestion des événements
Nous allons à présent mettre en place toute la logique applicative de notre composant.
Nous souhaitons tout d’abord que lorsque l’utilisateur saisit une information dans la zone
de texte prévue à cet effet, cela entraîne un filtre sur l’attribut champFiltre de l’objet
_tableaudonnee et la mise à jour du DataGrid en fonction du résultat de ce filtre. Ensuite,
l’événement déclenché en cliquant sur un item du DataGrid doit permettre de récupérer la
valeur de la colonne idt afin que son exploitation soit possible dans un autre traitement.
Mise en place du filtre
Avant de programmer tout événement, nous devons importer les classes nécessaires :
import flash.events.Event;
import mx.events.ListEvent;
=Flex3 FM.book Page 189 Mardi, 2. décembre 2008 3:32 15
Créer des composants personnalisés
CHAPITRE 10
189
Par ailleurs, le filtre doit être effectué lors de chaque modification de la zone de saisie, ce
qui signifie que nous devons ajouter un écouteur d’événement qui se chargera d’exécuter
une méthode lorsque le contenu de la zone de texte sera modifié :
_zoneTexte.addEventListener(Event.CHANGE,evenementModification);
Voyons à présent le contenu de la méthode evenementModification :
public function evenementModification(e:Event):void
{
var texteSaisi:String = _zoneTexte.text;
_tableauDonnees.filterFunction = filtrageDonnees;
_tableauDonnees.refresh();
_datagrid.dataProvider = _tableauDonnees;
}
public function filtrageDonnees(item:Object):Boolean
{
return !item.champFiltre.length || item.champFiltre.toUpperCase().indexOf
➥(_zoneTexte.text.toUpperCase()) >= 0;
}
La méthode filterFunction de l’attribut _tableauDonnees est appelée. Cette méthode de la
classe ArrayCollection va permettre de filtrer le contenu de l’attribut à l’aide de la fonction filtrageDonnees. Le principe de ce filtre est le suivant :
1. L’utilisateur saisit la première lettre de l’élément recherché.
2. Pour chaque item de l’ArrayCollection, la fonction FiltrageDonnees est exécutée. Si
l’item, passé en paramètre de la fonction, correspond aux critères saisis dans la zone
de texte, la valeur true est renvoyée, ce qui permet d’indiquer à l’ArrayCollection que
l’item pourra être affiché.
3. Le contenu de l’attribut _tableauDonnees est ensuite actualisé. Les données de l’ArrayCollection ne correspondant pas au filtre ne sont pas supprimées mais simplement
masquées.
4. L’attribut est ensuite affecté au dataProvider du DataGrid ce qui permet d’afficher les
éléments correspondant au filtre saisi par l’utilisateur.
Nous pouvons de nouveau exécuter le projet et vérifier que tout fonctionne correctement.
Passons à présent à la mise en place de l’événement qui nous permettra de récupérer la
valeur du champ idt lorsque l’utilisateur cliquera sur un item du DataGrid.
Récupération de la valeur de l’identifiant
Pour commencer, nous allons ajouter une zone de texte sur notre interface graphique
dans laquelle sera affiché l’identifiant de l’item sélectionné dans le DataGrid.
<mx:TextInput x="10" y="457" width="198" id="idITem"/>
=Flex3 FM.book Page 190 Mardi, 2. décembre 2008 3:32 15
190
Comprendre Flex 3
PARTIE I
Comme nous l’avons fait pour le filtrage des données, nous ajoutons un écouteur
d’événement sur le DataGrid qui déclenchera l’exécution d’une méthode à chaque fois
que l’utilisateur cliquera sur l’un des items du DataGrid :
_datagrid.addEventListener(ListEvent.ITEM_CLICK,renvoyerIdentifiant)
L’identifiant sera stocké dans un attribut que l’on nommera _valeurRenvoyee, dont les
méthodes set et get devront être spécifiées. Le rôle de la méthode renvoyerIdentifiant
sera de récupérer la valeur du champ idt de la ligne du DataGrid sélectionnée et de
l’affecter à l’attribut _valeurRenvoyee.
public class FiltreTableau extends Canvas
{
[...]
private var _valeurRenvoyee:String;
[...]
}
public function set valeurRenvoyee(valeur:String):void{
_valeurRenvoyee = valeur;
}
public function get valeurRenvoyee():String {
return _valeurRenvoyee;
}
public function renvoyerIdentifiant(e:Event):void
{
_valeurRenvoyee = String(e.currentTarget.selectedItem.idt);
}
Modifions également la zone de texte précédemment créée afin qu’elle affiche le résultat
obtenu par la méthode get valeurRenvoyee.
<mx:TextInput x="10" y="457" width="198" id="idITem" text="{ComposantFiltreTableau
➥.valeurRenvoyee}"/>
Si nous exécutons à présent le projet, nous voyons que cela ne fonctionne pas. Le débogueur de Flex nous indique le message d’alerte suivant : Data Binding will not be able to
detect assignments to « ValeurRenvoyee ». Que se passe-t-il ? Tout semblait pourtant être
correct !
Souvenez-vous, nous avons vu dans le chapitre 5 que lorsqu’une variable est utilisée à
des fins d’association de données (DataBinding), nous devons lui affecter la mention
[Bindable]. Ceci est très souvent utilisé lorsqu’une variable sert à alimenter le dataProvider d’un DataGrid ou d’une liste déroulante. Cette mention permet l’exécution d’un
événement lors du changement de valeur de la variable, indiquant à Flex que la valeur de
la variable a été modifiée et qu’il faut la réassigner.
Si on analyse le message affiché dans le débogueur de Flex, il semblerait que la méthode
get ValeurRenvoyee ait besoin d’être affectée de la mention [Bindable]. Cela semble tout à
fait logique. En effet, nous modifions bien la valeur de l’attribut _valeurRenvoyée grâce à
=Flex3 FM.book Page 191 Mardi, 2. décembre 2008 3:32 15
Créer des composants personnalisés
CHAPITRE 10
191
la méthode set ValeurRetournee(valeur:String) mais Flex nous alerte qu’il n’est pas en
mesure d’afficher la nouvelle valeur prise par cet attribut étant donné que la méthode get
ValeurRetournee ne possède pas d’événement permettant à Flex de l’appeler.
Pour résoudre ce problème, nous allons donc modifier les méthodes set et get de l’attribut _valeurRetournee :
public function set valeurRenvoyee(valeur:String):void{
_valeurRenvoyee = valeur;
dispatchEvent(new Event("changementValeurRenvoyee"));
}
[Bindable("changementValeurRenvoyee")]
public function get valeurRenvoyee():String{
return _valeurRenvoyee;
}
La méthode get valeurRenvoyee est affectée de la mention [Bindable("changementValeurRenvoyee")]. Lors de l’exécution de la méthode set ValeurRenvoyee, ceci permet d’effectuer un dispatch (ou appel) à l’événement changementValeurRenvoyee exécutant la méthode
get ValeurRenvoyee() et a pour conséquence, dans notre cas, la mise à jour de la zone de
texte chargée de contenir l’identifiant de l’élément sélectionné dans le DataGrid.
Nous pouvons à présent tester le bon fonctionnement de notre composant en exécutant le
projet. Pour plus de clarté, voici le code complet de la classe FiltreTableau et du fichier
compFiltreTableau.mxml.
Classe FiltreTableau
package com.composants
{
import mx.containers.Canvas;
import mx.collections.ArrayCollection;
import mx.controls.DataGrid;
import mx.controls.Label;
import mx.controls.TextInput;
import mx.controls.dataGridClasses.DataGridColumn;
import flash.events.Event;
import mx.events.ListEvent;
public class FiltreTableau extends Canvas
{
private var _tableauDonnees:ArrayCollection = new ArrayCollection();
private var _datagrid:DataGrid = new DataGrid();
private var _libelle:Label = new Label();
private var _zoneTexte:TextInput = new TextInput;
private var _colonnes:ArrayCollection = new ArrayCollection();
private var _champRecherche:String;
private var _valeurRenvoyee:String;
=Flex3 FM.book Page 192 Mardi, 2. décembre 2008 3:32 15
192
Comprendre Flex 3
PARTIE I
public function FiltreTableau()
{
super();
// Ajout d’un libellé
_libelle.x=10
_libelle.y=10
_libelle.width = 100;
this.addChild(_libelle);
// Ajout de la zone de texte
_zoneTexte.x = 110;
_zoneTexte.y = 10;
_zoneTexte.addEventListener(Event.CHANGE,evenementModification);
this.addChild(_zoneTexte);
//Ajout du DataGrid
_datagrid.x=10;
_datagrid.y=40;
_datagrid.addEventListener(ListEvent.ITEM_CLICK,renvoyerIdentifiant)
this.addChild(_datagrid);
}
// Méthodes Setters (affection de valeur aux attributs) et Getters (récupération
➥des valeurs affectées aux attributs)
public function set valeurRenvoyee(valeur:String):void{
_valeurRenvoyee = valeur;
dispatchEvent(new Event("changementValeurRenvoyee"));
}
[Bindable("changementValeurRenvoyee")]
public function get valeurRenvoyee():String{
return _valeurRenvoyee;
}
public function set libelle(texte:String):void{
_libelle.text = texte;
}
public function get libelle():String{
return _libelle.text;
}
public function set tableauDonnees(t:ArrayCollection):void{
_datagrid.dataProvider = t;
_tableauDonnees = t;
}
public function get tableauDonnees():ArrayCollection{
return _tableauDonnees;
}
public function set champRecherche(champ:String):void{
_champRecherche = champ;
}
=Flex3 FM.book Page 193 Mardi, 2. décembre 2008 3:32 15
Créer des composants personnalisés
CHAPITRE 10
public function get champRecherche():String{
return _champRecherche;
}
public function set colonnes(col:ArrayCollection):void{
_colonnes = col;
ajouterColonnes()
}
public function get colonnes():ArrayCollection{
return _colonnes;
}
// Méthode d’ajout des colonnes
public function ajouterColonnes():void
{
var listeColonnes:Array = new Array();
for (var i:int=0; i<_colonnes.length;i++)
{
var colonne:DataGridColumn = new DataGridColumn();
colonne.headerText = _colonnes[i].entete;
colonne.dataField = _colonnes[i].champ;
colonne.visible = _colonnes[i].visible;
colonne.width = _colonnes[i].longueur;
listeColonnes.push(colonne);
}
_datagrid.columns = listeColonnes;
}
public function evenementModification(e:Event):void
{
var texteSaisi:String = _zoneTexte.text;
_tableauDonnees.filterFunction = filtrageDonnees;
_tableauDonnees.refresh();
_datagrid.dataProvider = _tableauDonnees;
}
public function filtrageDonnees(item:Object):Boolean
{
return !item.champFiltre.length || item.champFiltre.toUpperCase()
➥.indexOf(_zoneTexte.text.toUpperCase()) >= 0;
}
public function renvoyerIdentifiant(e:Event):void
{
_valeurRenvoyee = String(e.currentTarget.selectedItem.idt);
}
}
}
193
=Flex3 FM.book Page 194 Mardi, 2. décembre 2008 3:32 15
194
Comprendre Flex 3
PARTIE I
Fichier ComFiltreTableau.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥xmlns:compFT="com.composants.*">
<mx:ArrayCollection id="sourceDonnees">
<mx:Object idt="1" champFiltre="Tucano Flylab"/>
<mx:Object idt="2" champFiltre="Pou du ciel"/>
<mx:Object idt="3" champFiltre="Skyranger"/>
<mx:Object idt="4" champFiltre="A22 Vision"/>
<mx:Object idt="5" champFiltre="Storch"/>
</mx:ArrayCollection>
<mx:ArrayCollection id="colonnes">
<mx:Object entete="IDT" champ="idt" visible="false" longueur="10"/>
<mx:Object entete="Nom des appareils" champ="champFiltre" visible="true"
➥longueur="300"/>
</mx:ArrayCollection>
<compFT:FiltreTableau id="ComposantFiltreTableau"
x="10"
y="10"
width="420"
height="320"
libelle ="Appareil ULM : "
tableauDonnees="{sourceDonnees}"
colonnes="{colonnes}"
>
</compFT:FiltreTableau>
<mx:TextInput x="10" y="457" width="198" id="idITem"
➥text="{ComposantFiltreTableau.valeurRenvoyee}"/>
</mx:Application>
Notre composant est à présent terminé. Nous avons vu qu’il était primordial d’offrir au
composant un minimum de possibilités de paramétrage afin qu’il puisse s’adapter à
l’application dans lequel il doit être intégré. Cette partie nous a également permis de
compléter nos connaissances sur la notion de DataBinding, largement employée dans de
nombreuses applications comme celles que nous aurons l’occasion de découvrir dans les
chapitres suivants. Voyons à présent comment compiler notre composant et vérifions
qu’il est bien possible de le réutiliser dans une autre application.
=Flex3 FM.book Page 195 Mardi, 2. décembre 2008 3:32 15
Créer des composants personnalisés
CHAPITRE 10
195
Phase 6 − Compilation
Convention de nommage
Afin de faciliter l’ensemble des explications qui vont suivre, nous utiliserons une convention de nommage
pour l’ensemble des répertoires qui seront utilisés :
RootProjetFlex : répertoire contenant les sources du projet ;
RootFlexBuilder : répertoire d’installation de Flex Builder.
Nous allons à présent compiler notre composant à l’aide du compilateur compc en mode
MS-DOS. Comme nous l’avons vu au chapitre 3, il convient d’utiliser le compilateur
compc pour compiler des composants. L’exécutable compc.exe se situe dans le répertoire bin
du kit Flex SDK ou dans le répertoire RootFlexBuilder\sdks\3.0.0\bin de Flex Builder.
Pour réaliser la compilation, placez-vous dans le répertoire approprié et saisissez la
commande suivante :
compc -o "c:/librairieComposants/compFiltreTableau.swc" -source-path="RootProjetFlex/
➥\src" -include-classes="com.composants.FiltreTableau"
L’instruction compc fait appel au compilateur compc.exe. L’option –o (output) spécifie le
répertoire où sera créé le fichier SWC. Nous vous conseillons d’ailleurs de créer un
répertoire sur votre disque dur destiné à accueillir l’ensemble de vos composants, ce qui
vous permettra de les retrouver plus rapidement. La seconde option, -source-path, sert à
indiquer le chemin d’accès aux sources du projet Flex. Veillez à ne pas oublier le répertoire src car sinon, la classe FiltreTableau ne sera pas trouvée. Enfin, l’option -includeclasses permet de définir le package et la classe de notre composant. Nous pouvons à
présent appuyer sur la touche Entrée du clavier pour vérifier la bonne compilation du
projet par la création du fichier compFiltreTableau.swc.
Réemploi du composant
Nous allons à présent voir comment réemployer notre composant dans une autre application.
1. Créez un nouveau projet Flex que vous nommerez orchidees et qui traitera de la
gestion des orchidées.
2. Vient ensuite l’étape d’importation du composant dans le projet. Pour ce faire, effectuez un clic droit sur le nom du projet nouvellement créé et sélectionnez Properties.
3. Cliquez ensuite sur Flex Build Path, sélectionnez l’onglet Library path et cliquez sur
le bouton Add SWC…
4. Dans la fenêtre qui s’ouvre alors (figure 10-8), sélectionnez le fichier comFiltreTableau
.swc se trouvant dans le répertoire de stockage de vos composants (ici, c:\librairie
Composants\compFiltreTableau.swc). Cliquez ensuite sur le bouton OK pour terminer
la procédure d’importation du composant.
=Flex3 FM.book Page 196 Mardi, 2. décembre 2008 3:32 15
196
Comprendre Flex 3
PARTIE I
Figure 10-8
Importation du fichier compFiltreTableau.swc
Modifions à présent le code du fichier orchidee.mxml. Saisissons les cinq premiers caractères : <comp pour voir apparaître, par le biais de l’autocomplétion, la proposition de notre
composant, soit <composants:FiltreTableau>. Notons l’importation automatique de l’espace
de noms xmlns:composants="com.composants.*" après validation de la saisie précédente.
Nous venons, en quelques instructions, d’importer notre composant au sein de notre
application.
Voici un exemple d’implémentation de notre composant à travers une collection d’objets
listant les orchidées disponibles à la vente sur un site d’une jardinerie :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
➥layout="absolute" xmlns:composants="com.composants.*">
=Flex3 FM.book Page 197 Mardi, 2. décembre 2008 3:32 15
Créer des composants personnalisés
CHAPITRE 10
197
<mx:ArrayCollection id="sourceDonnees">
<mx:Object idt="1" champFiltre="Aerides" couleur="Bleu" prix="19 €"/>
<mx:Object idt="2" champFiltre="Bulbophyllum" couleur="Rouge / Blanc" prix="17 €"/>
<mx:Object idt="3" champFiltre="Masdevallia" couleur="Rose" prix="40 €"/>
<mx:Object idt="4" champFiltre="Miltoniopsis" couleur="Vert / Jaune" prix="6 €"/>
<mx:Object idt="5" champFiltre="Phalaenopsis" couleur="Rose" prix="21 €"/>
</mx:ArrayCollection>
<mx:ArrayCollection id="colonnes">
<mx:Object entete="IDT" champ="idt" visible="false" longueur="10"/>
<mx:Object entete="Espèce" champ="champFiltre" visible="true" longueur="100"/>
<mx:Object entete="Couleur" champ="couleur" visible="true" longueur="100"/>
<mx:Object entete="Prix" champ="prix" visible="true" longueur="60"/>
</mx:ArrayCollection>
<composants:FiltreTableau
id="listeOrchidees"
width="480"
height="370"
libelle="Orchidée :"
tableauDonnees="{sourceDonnees}"
colonnes="{colonnes}">
</composants:FiltreTableau>
</mx:Application>
Nous pouvons alors remarquer que des nouvelles colonnes ont été ajoutées et sont parfaitement gérées par notre composant (figure 10-9), ce qui démontre que ce dernier offre un
niveau de paramétrage suffisant pour être utilisé dans de nombreuses applications.
Figure 10-9
Mise en place du composant
Vous constaterez que la méthode de récupération de l’identifiant n’est pas utilisée dans
cette application. Libre à vous de l’implémenter en créant une zone de texte dont la
propriété text serait affectée de la valeur {listeOrchidees.valeurRenvoyee}.
=Flex3 FM.book Page 198 Mardi, 2. décembre 2008 3:32 15
198
Comprendre Flex 3
PARTIE I
En résumé
Ce chapitre a montré l’intérêt de développer vos applications par composants. Vous
pouvez à présent combiner les fonctionnalités de plusieurs composants afin d’en créer un
qui corresponde à vos besoins. Il a également mis en valeur le caractère réutilisable des
composants. Vous devrez donc toujours veiller à les rendre paramétrables afin qu’ils
puissent être utilisés dans de nombreuses applications.
Ce chapitre clôt l’étude de la partie graphique du framework Flex. Nous allons à présent
nous consacrer à l’étude de l’utilisation des données et découvrir les méthodes d’accès
aux services de la couche métier.
=Flex3 FM.book Page 199 Mardi, 2. décembre 2008 3:32 15
11
Gérer les données
Au cours de ce chapitre, nous allons découvrir les moyens mis à notre disposition par le
framework Flex pour assurer la gestion des données. Nous approfondirons la notion de
DataBinding, très utilisée dans les applications Flex et déjà mentionnée de nombreuses
fois dans cet ouvrage. Nous verrons ensuite comment implémenter le modèle de l’architecture MVC présentée au chapitre 2, puis nous étudierons les méthodes de validation
des données permettant de conserver la qualité de ces dernières dans le système d’information mais également d’interagir avec l’utilisateur en lui indiquant les zones de saisie
obligatoires et les formats de saisie incorrects. Nous terminerons enfin par le formatage
des données. À l’issue de ce chapitre, vous serez en mesure de gérer l’interaction des
données entre composants, mais également de vérifier leur validité avant l’exécution de
tout traitement.
Lier des données
La notion de DataBinding est l’une des plus importantes du framework Flex. Son rôle est
d’assurer la communication des données entre un objet source et un objet de destination.
Ainsi, toute modification des données de l’objet source entraîne la modification des
données de l’objet de destination. Illustrons ceci par un exemple :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:NumericStepper x="10" y="22" width="78" id="objet_source"/>
<mx:TextInput x="106" y="22" id="objet_destination" text="{objet_source.value}"/>
</mx:Application>
=Flex3 FM.book Page 200 Mardi, 2. décembre 2008 3:32 15
200
Comprendre Flex 3
PARTIE I
Dans cette portion de code, deux composants sont présents :
• le composant NumericStepper, qui représente l’objet source ;
• le composant TextInput, qui correspond à l’objet de destination.
La valeur mentionnée entre les accolades de la propriété text du composant TextInput
précise la liaison de données : « pour tout changement de la valeur du NumericStepper,
recopier la valeur dans la propriété text du composant TextInput ». Le procédé alors
utilisé est le suivant :
1. La valeur du composant NumericStepper est modifiée par l’utilisateur (figure 11-1, ➊).
2. Flex vérifie la présence de la liaison et constate que la valeur de la propriété text de la
zone de saisie est liée à la valeur de la propriété value du NumericStepper (figure 11-1, ➋).
3. Dans la mesure où ces deux objets sont liés, la valeur de la propriété text de l’objet
de destination s’en trouve modifiée (figure 11-1, ➌).
Figure 11-1
Principe du DataBinding
Définition
Le DataBinding est l’action consistant à copier des données d’un objet source vers un objet de destination
lors de l’exécution d’un événement déclenchant l’action de copie.
Cet exemple illustre l’une des méthodes d’implémentation du DataBinding mais il en
existe d’autres, que nous allons étudier à présent.
=Flex3 FM.book Page 201 Mardi, 2. décembre 2008 3:32 15
Gérer les données
CHAPITRE 11
201
Utilisation de la balise <mx:Binding>
La balise <mx:Binding> a pour but de remplacer la notation par accolades vue précédemment.
Elle permet également de remplir le rôle du contrôleur dans une application ayant un
type d’architecture MVC en détachant la vue du modèle et en attribuant plusieurs objets
de destination à un seul objet source (nous reviendrons sur ce point un peu plus loin dans
ce chapitre). Voyons comment utiliser cette balise dans l’exemple de code précédent :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:NumericStepper x="10" y="22" width="78" id="objet_source"/>
<mx:TextInput x="234" y="22" id="objet_destination"/>
<mx:Binding
source="String(objet_source.value)"
destination="objet_destination.text">
</mx:Binding>
</mx:Application>
Cette balise nous permet, par l’emploi des propriétés source et destination, de mieux
comprendre la notion de DataBinding. Une conversion de type numérique vers chaîne a
été nécessaire pour que la liaison soit effective. Sans cela, il nous était impossible
d’affecter une valeur de type numérique vers une propriété de type chaîne de caractères.
Conversion de type
Pour convertir un type de données vers un autre type, il suffit de faire appel à la méthode de conversion du
type souhaité. Ainsi, pour convertir un numérique en une chaîne de caractères, il convient de saisir le code
suivant :
String(valeurNumerique)
Le DataBinding en ActionScript
Grâce au langage ActionScript, il est non seulement possible de programmer nos propres
liaisons, mais également de définir des variables en tant que sources de données.
Programmation de la liaison
La programmation des liaisons de données entre objets passe par l’emploi de la classe
BindingUtils. Située dans le package mx.binding.utils, elle met à notre disposition la
méthode BindingUtils.bindProperty dont les paramètres sont les suivants :
BindingUtils.bindProperty(identifiant de l’objet de destination, propriété de l’objet
de destination faisant l’objet de la modification, identifiant de l’objet source,
propriété de l’objet source faisant l’objet de la synchronisation).
=Flex3 FM.book Page 202 Mardi, 2. décembre 2008 3:32 15
202
Comprendre Flex 3
PARTIE I
Reprenons notre exemple précédent et adaptons-le afin d’illustrer ce qui vient d’être
énoncé :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥creationComplete="creationLiaison()">
<mx:Script>
<![CDATA[
import mx.binding.utils.BindingUtils;
public function creationLiaison():void
{
BindingUtils.bindProperty(objet_destination, "text", objet_source,
➥"value");
}
]]>
</mx:Script>
<mx:NumericStepper x="10" y="22" width="78" id="objet_source"/>
<mx:TextInput x="234" y="22" id="objet_destination"/>
</mx:Application>
La programmation des liaisons est assez simple. Pour obtenir une résultat concluant, il
suffit en effet d’importer la classe nécessaire et de créer une procédure utilisant la
méthode bindProperty, dont les paramètres correspondent aux identifiants et propriétés de
nos objets. N’oubliez pas d’exécuter cette fonction à la fin de l’initialisation ou de la
création de l’application sans quoi l’application ne prendra pas la liaison en compte.
Utilisation de l’étiquette [Bindable]
Au cours des chapitres précédents, vous avez sans doute remarqué l’utilisation par
endroits de l’étiquette [Bindable]. Jusqu’à présent, la liaison de données a été établie
entre deux objets MXML. Mais si nous combinons les langages ActionScript et MXML
dans notre application, ne serait-il pas intéressant de pouvoir déclarer des variables
ActionScript en tant que sources de données pour un objet MXML ? C’est ce que permet
de réaliser l’étiquette [Bindable].
Pour permettre à une variable d’être source de données dans une liaison, sa déclaration
doit être précédée de l’étiquette [Bindable]. Dans le cas contraire, la liaison souhaitée
sera impossible et un avertissement apparaîtra dans la vue Problems de FlexBuilder
(figure 11-2).
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
=Flex3 FM.book Page 203 Mardi, 2. décembre 2008 3:32 15
Gérer les données
CHAPITRE 11
203
<mx:Script>
<![CDATA[
[Bindable]
private var variableSource:String;
public function afficherValeur():void
{
variableSource = "Valeur du NumericStepper : "+ String(numericStepper
➥.value);
}
]]>
</mx:Script>
<mx:NumericStepper x="10" y="22" width="78" id="numericStepper
➥change="afficherValeur()"/>
<mx:TextInput x="182" y="22" id="objet_destination" text="{variableSource}"
➥width="360"/>
</mx:Application>
Figure 11-2
Oubli de l’étiquette [Bindable]
La variable variableSource est considérée comme source de données du fait que sa déclaration est précédée de l’étiquette [Bindable]. La procédure afficherValeur() est appelée à
chaque modification de la valeur du NumericStepper et a pour fonction de modifier la
=Flex3 FM.book Page 204 Mardi, 2. décembre 2008 3:32 15
204
Comprendre Flex 3
PARTIE I
variable source. La liaison de données est effectuée sur la propriété text du composant
TextInput, ce qui signifie qu’à chaque modification de la variable source, la valeur de la
propriété text sera modifiée en conséquence. Pour plus de clarté, la figure 11-3 schématise le principe de ce processus.
Figure 11-3
Utilisation de l’étiquette [Bindable]
Nous pouvons alors distinguer quatre étapes :
➊ La valeur du composant NumericStepper est modifiée par l’utilisateur, ce qui déclenche
l’exécution de la procédure afficherValeur().
➋ La procédure modifie alors la valeur de la variable variableSource.
➌ Flex vérifie l’existence d’une liaison.
➍ Étant donné qu’une liaison a été établie entre la variable ActionScript et la propriété
text du composant TextInput, la valeur de cette propriété est mise à jour.
Spécification d’un événement
Par défaut, la synchronisation s’effectue sur la modification de la valeur source, mais il
est possible de modifier ce comportement en permettant la synchronisation sur le déclenchement d’un événement précis.
Pour ce faire, nous devons définir un événement de synchronisation et l’affecter à
l’étiquette [Bindable] précédant la variable source. Lorsque le dispatch de l’événement
sera exécuté, l’étiquette [Bindable] concernée en sera avertie et procédera à la synchronisation des données.
=Flex3 FM.book Page 205 Mardi, 2. décembre 2008 3:32 15
Gérer les données
CHAPITRE 11
205
Dans le code suivant, nous allons faire en sorte que la synchronisation des données ne
s’effectue que si la valeur du composant NumericStepper est supérieure ou égale à 5.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
[Bindable(event="siSupOuEgalA5")]
private var variableSource:String;
public function afficherValeur():void
{
if (numericStepper.value >= 5)
{
variableSource = "Valeur du NumericStepper : "+ String(numericStepper
➥.value);
// Déclaration de l’événement
var evenement:Event = new Event("siSupOuEgalA5");
// Action de dispatch
dispatchEvent(evenement);
}
}
]]>
</mx:Script>
<mx:NumericStepper x="10" y="22" width="78" id="numericStepper"
➥change="afficherValeur()"/>
<mx:TextInput x="182" y="22" id="objet_destination" text="{variableSource}"
➥width="360"/>
</mx:Application>
L’expression [Bindable(event="siSupOuEgalA5")] précise que l’action de synchronisation
ne peut se produire que lorsque l’événement siSupOuEgalA5 est déclenché. Par ailleurs, cet
événement n’est déclaré dans la procédure afficherValeur() que lorsque la valeur du
NumericStepper répond aux conditions fixées. Vient ensuite l’envoi de l’ordre de mise à
jour de la variable à l’étiquette [Bindable], par l’exécution du dispatch de l’événement.
La valeur de variable est alors immédiatement mise à jour et modifiée.
Flex 4 et le DataBinding bi-directionnel
Le DataBinding consiste à mettre à jour une donnée source, qui répercute cette modification à une
donnée destination. Dans l’autre sens, cette action est impossible. Ce problème est résolu dans la version
4 du framework par l’apparition de la notion de DataBinding bi-directionnel.
=Flex3 FM.book Page 206 Mardi, 2. décembre 2008 3:32 15
206
Comprendre Flex 3
PARTIE I
Stocker des données grâce au modèle
Comme nous l’avons vu au chapitre 2, la partie graphique d’une application peut être
divisée en trois couches distinctes (modèle, vue et contrôleur) selon l’architecture MVC.
Au cours de la section précédente, nous avons également vu que la balise <mx:Binding>
peut jouer le rôle du contrôleur. Nous allons maintenant découvrir comment le modèle
peut être implémenté à l’aide des langages MXML et ActionScript.
Un modèle a pour fonction principale de stocker des données. Ce stockage précède le
stockage persistant réalisée par la base de données. L’utilisation d’un modèle permet
donc un stockage temporaire des données afin de les manipuler avant leur enregistrement
définitif. Dans cette section, nous vous proposons d’étudier les différentes méthodes de
déclaration d’un modèle ainsi que son utilité à travers un exemple concret.
Implémenter le modèle à l’aide de la balise <mx:Model>
Imaginons une petite application dont le but est d’enregistrer les nouvelles admissions
dans un centre hospitalier. Une admission consiste à enregistrer les données caractéristiques
d’un patient, à savoir son identifiant, son prénom et son nom.
La première étape va donc consister à créer un modèle capable de stocker ces informations.
Pour cela, nous recourons à la balise <mx:Model> du langage MXML.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<!-- LE MODÈLE -->
<mx:Model id="ModelePatient">
<patient>
<id/>
<prenom/>
<nom/>
</patient>
</mx:Model>
</mx:Application>
En analysant ce code, nous voyons tout d’abord qu’un modèle se caractérise par un identifiant qui lui est propre. À l’intérieur de ce modèle, nous spécifions ce qui peut être
considéré comme la classe patient et ses trois attributs id, prenom et nom.
Afin d’étudier l’utilisation du modèle, nous devons ajouter un formulaire de saisie, qui
nous permettra d’alimenter le modèle en données
<!-- LE FORMULAIRE -->
<mx:Panel x="10" y="10" width="344" height="315" layout="absolute" title="Patient">
<mx:Form x="10" y="10" height="115" width="295">
<mx:FormItem label="Id :">
<mx:TextInput id="id_txt"/>
</mx:FormItem>
<mx:FormItem label="Prénom :">
<mx:TextInput id="prenom_txt"/>
=Flex3 FM.book Page 207 Mardi, 2. décembre 2008 3:32 15
Gérer les données
CHAPITRE 11
207
</mx:FormItem>
<mx:FormItem label="Nom :">
<mx:TextInput id="nom_txt"/>
</mx:FormItem>
</mx:Form>
<mx:Button x="240" y="145" label="Ajouter" click=”ajouterPatient()”/>
</mx:Panel>
Il convient ensuite d’implémenter une procédure qui va utiliser notre modèle pour stocker les informations. Cette procédure sera appelée lorsque l’utilisateur cliquera sur le
bouton Ajouter.
<!-- LE SCRIPT D’AJOUT -->
<mx:Script>
<![CDATA[
import mx.controls.Alert;
public function ajouterPatient():void
{
ModelePatient.id = id_txt.text;
ModelePatient.prenom = prenom_txt.text;
ModelePatient.nom = nom_txt.text;
Alert.show (ModelePatient.id +" - "+ModelePatient.prenom+" ➥"+ModelePatient.nom);
}
]]>
</mx:Script>
La procédure affecte les attributs du modèle à partir des champs du formulaire pour
ensuite afficher la valeur de ces attributs dans une fenêtre d’alerte (figure 11-4).
Figure 11-4
Interaction avec le modèle
=Flex3 FM.book Page 208 Mardi, 2. décembre 2008 3:32 15
208
Comprendre Flex 3
PARTIE I
Pour plus de clarté, voici le code complet de cet exemple :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<!-- LE MODÈLE -->
<mx:Model id="ModelePatient">
<patient>
<id/>
<prenom/>
<nom/>
</patient>
</mx:Model>
<!-- LE SCRIPT D’AJOUT -->
<mx:Script>
<![CDATA[
import mx.controls.Alert;
public function ajouterPatient():void
{
ModelePatient.id = id_txt.text;
ModelePatient.prenom = prenom_txt.text;
ModelePatient.nom = nom_txt.text;
Alert.show (ModelePatient.id +" - "+ModelePatient.prenom+" ➥"+ModelePatient.nom);
}
]]>
</mx:Script>
<!-- LE FORMULAIRE -->
<mx:Panel x="10" y="10" width="344" height="315" layout="absolute" title="Patient">
<mx:Form x="10" y="10" height="115" width="295">
<mx:FormItem label="Id :">
<mx:TextInput id="id_txt"/>
</mx:FormItem>
<mx:FormItem label="Prénom :">
<mx:TextInput id="prenom_txt"/>
</mx:FormItem>
<mx:FormItem label="Nom :">
<mx:TextInput id="nom_txt"/>
</mx:FormItem>
</mx:Form>
<mx:Button x="240" y="145" label="Button" click="ajouterPatient()"/>
</mx:Panel>
</mx:Application>
Il aurait également été possible d’utiliser le DataBinding. L’objet source de la liaison
aurait alors été la zone de saisie et l’objet de destination, l’attribut du modèle correspondant à cette zone de saisie.
=Flex3 FM.book Page 209 Mardi, 2. décembre 2008 3:32 15
Gérer les données
CHAPITRE 11
209
<mx:Model id="ModelePatient">
<patient>
<id>{id_txt.text} </id>
<prenom>{prenom_txt.text} </prenom>
<nom>{nom_txt.text} </nom>
</patient>
</mx:Model>
Nous venons de réaliser notre première application faisant usage d’un modèle, nous
donnant aussi l’occasion de faire nos premiers pas dans l’architecture MVC à l’aide de
Flex. Néanmoins, l’usage de la balise <mx:Model> ne se limite qu’à la description du
modèle en lui-même et ne nous permet pas d’y inclure la logique métier. Pour faire cela,
nous devrons utiliser le langage ActionScript.
Les modèles et ActionScript
La première alternative à l’usage de la balise <mx:Model> est son implémentation à l’aide
du langage ActionScript :
public var ModelePatient:Object={
id:null, // Affecte la valeur nulle à l’identifiant...
prenom:null,
nom:null
}
Néanmoins, ceci ne procure guère plus d’avantages que l’emploi de la balise <mx:Model>,
car il est toujours impossible d’implémenter la logique métier et d’y typer nos variables.
La solution va donc consister à créer des classes ActionScript dont le rôle est de décrire
le modèle et de typer les attributs (chaîne, entier…).
La figure 11-5 illustre la conceptualisation de la classe Patient. Cette classe comporte les
trois attributs id, prenom et nom dont la portée est privée, c’est-à-dire que leur accès est
strictement réservé à la classe Patient. Trois méthodes publiques d’affectation de valeur
aux attributs sont ensuite créées (set) ainsi que trois méthodes publiques récupérant la
valeur des attributs (get).
Figure 11-5
La classe Patient
=Flex3 FM.book Page 210 Mardi, 2. décembre 2008 3:32 15
210
Comprendre Flex 3
PARTIE I
Cette classe sera retranscrite dans un fichier ActionScript distinct du fichier MXML de
l’application en créant un fichier de type ActionScript Class (menu File>New de Flex
Builder).
Le code de la classe est le suivant :
package
{
public class Patient
{
// Déclaration des attributs
private var _id:int;
private var _prenom:String;
private var _nom:String;
// Méthodes d’affectation
public function set id(param:int):void{
_id = param;
}
public function set prenom(param:String):void{
_prenom = param;
}
public function set nom (param:String):void{
_nom = param;
}
// Méthodes de récupération des valeurs
public function get id():int{
return _id
}
public function get prenom():String{
return _prenom;
}
public function get nom():String{
return _nom
}
}
}
Passons à présent à l’utilisation de cette classe dans notre application. Commençons par
importer notre classe en procédant comme nous l’avons fait pour l’importation des
composants personnalisés (chapitre 10), c’est-à-dire en ajoutant la syntaxe suivante au
code déclaratif de l’application :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
xmlns:Modele="*"
>
=Flex3 FM.book Page 211 Mardi, 2. décembre 2008 3:32 15
Gérer les données
CHAPITRE 11
211
Étant donné que notre classe joue le rôle de modèle, il convient de lui affecter un identifiant afin de pouvoir y faire référence dans les différents scripts qui pourront être développés ultérieurement :
<Modele:Patient id="ModelePatient"/>
Attention
La syntaxe <Modele:Patient> n’est pas fortuite. En effet, Patient correspond au nom de la classe à
employer.
Notre classe est à présent intégrée dans l’interface graphique. Elle remplit sa fonction de
modèle, comme le montrent ces quelques lignes de code :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
xmlns:Modele="*"
>
<!-- APPEL DU MODÈLE -->
<Modele:Patient id="ModelePatient"/>
<!-- LE SCRIPT D’AJOUT -->
<mx:Script>
<![CDATA[
import mx.controls.Alert;
public function ajouterPatient():void
{
ModelePatient.id = int(id_txt.text);
ModelePatient.prenom = prenom_txt.text;
ModelePatient.nom = nom_txt.text;
Alert.show (ModelePatient.id +" - "+ModelePatient.prenom+" ➥"+ModelePatient.nom);
}
]]>
</mx:Script>
<!-- LE FORMULAIRE -->
<mx:Panel x="10" y="10" width="344" height="315" layout="absolute" title="Patient">
<mx:Form x="10" y="10" height="115" width="295">
<mx:FormItem label="Id :">
<mx:TextInput id="id_txt"/>
</mx:FormItem>
<mx:FormItem label="Prénom :">
<mx:TextInput id="prenom_txt"/>
</mx:FormItem>
<mx:FormItem label="Nom :">
<mx:TextInput id="nom_txt"/>
=Flex3 FM.book Page 212 Mardi, 2. décembre 2008 3:32 15
212
Comprendre Flex 3
PARTIE I
</mx:FormItem>
</mx:Form>
<mx:Button x="240" y="145" label="Ajouter" click="ajouterPatient()" />
</mx:Panel>
</mx:Application>
Le résultat auquel nous aboutissons est identique à celui obtenu avec la balise <mx:Model>
(figure 11-4).
Grâce aux classes, nous pouvons implémenter la logique métier en y développant des
méthodes spécifiques, ce qui était jusque-là impossible à l’aide des méthodes traditionnelles d’implémentation de modèle. Dans notre exemple, nous aurions pu développer une
méthode calculant le nombre de lettres contenues dans le nom de famille saisi, lequel
aurait alors été concaténé à ce même nom :
[…]
public function set nom (param:String):void{
_nom = param + " NB Lettres -> "+String(calculNbLettres(param));
}
[…]
// Méthode de calcul du nombre de lettres contenues dans le nom de famille
public function calculNbLettres(param:String):int{
return param.length;
}
Ceci ne présente, certes, que peu d’intérêt ici, mais vous voyez ainsi que l’utilisation des
classes nous offre de nombreuses possibilités, notamment celle de manipuler les données
stockées dans le modèle avant de les transférer à la couche de persistance de données.
Nous pourrions nous arrêter là mais il nous a semblé important de poursuivre avec les
méthodes de validation des données. En effet, qui n’a jamais été confronté au codage
parfois fastidieux d’une vérification d’une adresse e-mail ? Eh bien ce temps est révolu
grâce aux composants Validator qui réalisent ce travail pour vous !
Valider des données
Valider les données, c’est s’assurer de la cohérence et de la qualité des informations
contenues dans le système. Pour une entreprise de marketing, par exemple, il serait
inconcevable que le format des adresses e-mail des clients ne soit pas correct, de même
que celui du code postal ou du numéro de carte bancaire. Jusqu’à présent, ces vérifications de format devaient être implémentées par le développeur de l’application. Tout cela
est désormais de l’histoire ancienne grâce au composant Validator de Flex. Flex permet
de vérifier le format des éléments suivants :
• carte de crédit (en fonction du type : Visa, MasterCard…) ;
• valeur monétaire ;
• date ;
• adresse e-mail ;
=Flex3 FM.book Page 213 Mardi, 2. décembre 2008 3:32 15
Gérer les données
CHAPITRE 11
•
•
•
•
•
•
213
nombre ;
numéro de téléphone ;
numéro de Sécurité sociale ;
code postal ;
chaîne de caractères ;
expression régulière.
Nous n’allons pas ici décrire tous ces formats de validation, mais nous nous concentrerons sur un type en particulier, très largement utilisé dans les applications : la validation
du format de l’adresse e-mail.
Pour commencer, créons un formulaire contenant une zone de texte dédiée à la saisie de
l’adresse e-mail :
<mx:Panel x="10" y="10" width="344" height="159" layout="absolute" title="E-mail">
<mx:Form x="10" y="10" height="62" width="295">
<mx:FormItem label="Votre e-mail :">
<mx:TextInput id="mail_txt"/>
</mx:FormItem>
</mx:Form>
<mx:Button x="235" y="80" label="Valider" id=”btn_valider” />
</mx:Panel>
Rendre la saisie obligatoire
Pour cet exemple, le champ mail_txt doit obligatoirement être renseigné. Dans une application web classique (non développée à l’aide d’un framework), il nous faudrait éventuellement développer une fonction JavaScript qui vérifierait la présence ou non de
caractères spécifiques dans la zone (point, arobase…). Les choses sont beaucoup plus
simples grâce au framework Flex, car il suffit de lui préciser que ce champ est obligatoire
grâce à la propriété required du composant FormItem.
<mx:FormItem label="Votre e-mail :" required="true">
En passant à true la valeur de la propriété required du composant FormItem, nous indiquons à Flex que la saisie de ce champ est obligatoire. Un astérisque apparaît alors après
le libellé du champ (figure 11-6).
Figure 11-6
Saisie obligatoire
=Flex3 FM.book Page 214 Mardi, 2. décembre 2008 3:32 15
214
Comprendre Flex 3
PARTIE I
Il ne nous reste plus qu’à mettre en place le validateur comme suit :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<!-- VALIDATION -->
<mx:Validator id="validation_saisie" source="{mail_txt}" property="text">
➥</mx:Validator>
<!-- LE FORMULAIRE -->
<mx:Panel x="10" y="10" width="344" height="159" layout="absolute" title="E-mail">
<mx:Form x="10" y="10" height="62" width="295">
<mx:FormItem label="Votre email :" required="true">
<mx:TextInput id="mail_txt"/>
</mx:FormItem>
</mx:Form>
<mx:Button x="235" y="80" label="Valider" id=”btn_valider” />
</mx:Panel>
</mx:Application>
Le fonctionnement de la validation est basé sur la notion de DataBinding. La source du
Validator est le champ mail_txt. Lorsque sa propriété text est modifiée, l’action de validation est alors déclenchée.
Nous vous laissons à présent le soin d’exécuter cette application et de vérifier que lorsque
l’on clique sur le bouton Valider sans avoir saisi d’adresse e-mail, le contour du champ
devient rouge et un message d’erreur s’affiche (figure 11-7) au survol du champ.
Figure 11-7
Contrôle de la saisie obligatoire
=Flex3 FM.book Page 215 Mardi, 2. décembre 2008 3:32 15
Gérer les données
CHAPITRE 11
215
Vérification du format
Pour qu’une adresse e-mail soit valide, elle doit obligatoirement être composée :
• d’un nom d’utilisateur (par exemple, jean.dupont) ;
• d’une arobase (@) ;
• d’un nom de domaine (par exemple, domaine.fr).
La vérification de la présence de ces trois éléments est chose complexe à développer.
Grâce à Flex, elle se résume à une simple ligne de code grâce au composant <mx:EmailValidator> qui se charge d’effectuer l’ensemble des vérifications nécessaires. Voyons
ceci en détail.
Pour commencer, nous devons remplacer le composant de validation présent dans notre
application par celui-ci :
<mx:EmailValidator id="validation_email" source="{mail_txt}" property="text">
</mx:EmailValidator>
Ce composant fonctionne de la même façon que le précédent, à la seule différence qu’il
vérifie également, en plus de la saisie obligatoire, la syntaxe de l’adresse e-mail.
Si vous testez de nouveau l’application, vous verrez que tous les critères sont correctement vérifiés et ce, grâce à une simple ligne de code. Néanmoins, il reste un petit
problème qu’en tant que lecteur attentif vous avez certainement remarqué : les messages
d’erreur sont en anglais ! Mais rassurez-vous, il est possible de personnaliser ces messages,
ce que nous allons voir à présent.
Personnalisation des messages d’erreur
Chaque composant de validation possède sa propre bibliothèque de textes à afficher en
fonction du type d’erreur rencontré. Il est possible de personnaliser ces messages. Voyons
comment procéder pour notre composant :
<mx:EmailValidator id="validation_email" source="{mail_txt}" property="text"
requiredFieldError="Ce champ est obligatoire"
missingAtSignError="Votre adresse e-mail ne comporte pas d’arobase"
missingUsernameError="Le nom d’utilisateur n’a pas été spécifié"
missingPeriodInDomainError="Le nom de domaine n’a pas été spécifié">
</mx:EmailValidator>
En exécutant à nouveau l’application, vous notez que les messages d’erreur affichés
correspondent désormais à ceux qui ont été spécifiés suivant le cas de figure concerné.
Les événements de validation
Par défaut, l’événement de validation de format correspond à la notification de changement de la valeur source du composant de validation. Il nous est possible de modifier ce
comportement à l’aide des propriétés trigger et triggerEvent du composant de validation.
=Flex3 FM.book Page 216 Mardi, 2. décembre 2008 3:32 15
216
Comprendre Flex 3
PARTIE I
La propriété trigger sert à spécifier qu’un composant de l’interface déclenchera l’action
de validation. Quant à la propriété triggerEvent, elle précise l’action qui devra être réalisée sur notre composant. Ainsi, si nous souhaitons déclencher la validation d’un champ
lorsque l’utilisateur clique sur le bouton btn_verifier de l’interface, la propriété trigger
de l’élément de validation devra porter la valeur btn_verifier et il faudra affecter la
propriété triggerEvent de la valeur click. Appliquons ceci à notre exemple en définissant
la règle suivante : « L’action de validation doit être effectuée à chaque fois que l’utilisateur
clique sur le bouton Valider ».
<mx:EmailValidator id="validation_email" source="{mail_txt}" property="text"
trigger="{btn_valider}"
triggerEvent="click">
</mx:EmailValidator>
Gestion de la validation en ActionScript
Maintenant que nous sommes en mesure de valider le format des données de nos formulaires, il est important d’étudier l’interaction entre la validation et les traitements
ActionScript. En effet, il serait bien regrettable que le traitement d’enregistrement ait lieu
malgré l’erreur de format détectée par le composant de validation.
Pour cela, nous avons recours à la méthode validate() du composant de validation. Grâce
à lui, nous vérifierons le résultat des différentes validations et permettrons ou non l’exécution
de traitements applicatifs :
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.ValidationResultEvent;
public function ajouterAdresseEmail():void{
// Résultat de la validation
var resultatValidation:ValidationResultEvent = validation_email.validate()
if (resultatValidation.type == ValidationResultEvent.VALID)
{
Alert.show ("Enregistrement effectué")
}
}
]]>
</mx:Script>
Le type de résultat retourné par la méthode validate() est VALID si la validation s’est
correctement déroulée, et INVALID si la validation a échoué.
Un simple test sur la valeur de la variable resultatValidation permet d’exécuter ou non le
traitement d’ajout.
=Flex3 FM.book Page 217 Mardi, 2. décembre 2008 3:32 15
Gérer les données
CHAPITRE 11
217
Voici le code de l’exemple dans son intégralité :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<!-- TRAITEMENT -->
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.ValidationResultEvent;
public function ajouterAdresseEmail():void{
// Résultat de la validation
var resultatValidation:ValidationResultEvent = validation_email.validate()
if (resultatValidation.type == ValidationResultEvent.VALID)
{
Alert.show ("Enregistrement effectué")
}
}
]]>
</mx:Script>
<!-- VALIDATION -->
<mx:EmailValidator id="validation_email" source="{mail_txt}" property="text"
trigger="{btn_valider}"
triggerEvent="click">
</mx:EmailValidator>
<!-- LE FORMULAIRE -->
<mx:Panel x="10" y="10" width="344" height="159" layout="absolute" title="E-mail">
<mx:Form x="10" y="10" height="62" width="295">
<mx:FormItem label="Votre e-mail :" required="true">
<mx:TextInput id="mail_txt"/>
</mx:FormItem>
</mx:Form>
<mx:Button x="235" y="80" label="Valider" id="btn_valider"
➥click="ajouterAdresseEmail()" />
</mx:Panel>
</mx:Application>
Ainsi se termine cette section sur la validation des formats de données. Grâce aux
composants de validation, vous êtes à présent en mesure de fournir des données cohérentes à votre système d’information. Dans la mesure où nous ne pouvons pas dans cet
ouvrage définir toutes les possibilités offertes par ces composants, nous les utiliserons
par la suite au travers d’exemples grâce auxquels vous pourrez notamment apprécier les
méthodes de création de composant de validation personnalisés. Pour l’heure nous allons
aborder un autre sujet tout aussi intéressant : le formatage des données.
=Flex3 FM.book Page 218 Mardi, 2. décembre 2008 3:32 15
218
Comprendre Flex 3
PARTIE I
Validation complète d’un formulaire
Si un formulaire comporte de nombreux champs, la méthode que nous venons de voir deviendra rapidement fastidieuse à implémenter. La classe Validator pallie ce problème grâce à sa méthode
validateAll([composants de validation séparés par une virgule]).
<mx:Script>
<![CDATA[
import mx.validators.Validator;
import mx.controls.Alert
public function ajouterAdresseEmail():void{
// Stockage des erreurs de validation dans un tableau
var tableau_validation:Array = Validator.validateAll([validation_email]);
// Si le tableau ne contient aucun élément, le traitement peut être
➥effectué
if(tableau_validation.length == 0) {
Alert.show ("Enregistrement effectué")
}
}
]]>
</mx:Script>
Formater des données
Nous ne pouvions pas écrire un chapitre sur la gestion des données sans aborder la notion
de formatage. Cette opération consiste à transformer une donnée en une chaîne dont le
format aura préalablement été précisé. L’application la plus commune est le formatage
du numéro de téléphone, ce que nous allons voir à travers l’exemple suivant.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<!-- SPÉCIFICATION DU FORMAT -->
<mx:PhoneFormatter
id="formatTelephone"
formatString="##.##.##.##.##">
</mx:PhoneFormatter>
<!-- LE FORMULAIRE -->
<mx:Panel x="10" y="10" width="344" height="210" layout="absolute" title="Formatage">
<mx:Form x="10" y="10" height="62" width="295">
<mx:FormItem label="Téléphone :" >
<mx:TextInput id="tel_txt"/>
</mx:FormItem>
</mx:Form>
=Flex3 FM.book Page 219 Mardi, 2. décembre 2008 3:32 15
Gérer les données
CHAPITRE 11
219
<mx:Form x="10" y="97" width="295" height="63">
<mx:FormItem label="Téléphone : ">
<mx:TextInput id="telFormate_txt" text="{formatTelephone.format
➥(tel_txt.text)}"/>
</mx:FormItem>
</mx:Form>
</mx:Panel>
</mx:Application>
Nous commençons l’écriture de l’application par la spécification d’un composant de
formatage propre aux données téléphoniques et qui nous permet de formater les données
à notre convenance. Nous affectons ainsi la propriété formatString de la valeur
##.##.##.##.##. Vient ensuite l’écriture de l’interface graphique qui sera composée d’un
panneau et de deux zones de texte. La première servira à saisir le numéro de téléphone, la
seconde affichera le résultat du formatage. Attardons-nous quelques instants sur la
propriété text de la seconde zone de texte :
text="{formatTelephone.format(tel_txt.text)}"
Ces quelques instructions signifient que le formatage est exécuté sur la propriété text de la
zone tel_txt lorsque celle-ci est mise à jour (nous retrouvons ici la notion de DataBinding).
Le résultat obtenu est illustré par la figure 11-8.
Figure 11-8
Formatage de
données
téléphoniques
Les composants de formatage proposés par Flex sont les suivants :
• composant de formatage monétaire (<mx:CurrencyFormatter>) ;
• composant de formatage de date (<mx:DateFormatter>) ;
• composant de formatage de numéro de téléphone (<mx:PhoneFormatter>) ;
• composant de formatage de nombre (<mx:NumberFormatter>) ;
• Composant de formatage de code postal (<mx:ZipCodeFormatter>).
Intéressons-nous à présent au composant de formatage de date dont la particularité est de
proposer un système de notation particulier pour le formatage des années, mois, jours…
=Flex3 FM.book Page 220 Mardi, 2. décembre 2008 3:32 15
220
Comprendre Flex 3
PARTIE I
Le système proprement dit est basé sur une notation par lettres, lesquelles sont présentées
dans le tableau 11-1, ainsi que leur signification afin de vous aider dans la manipulation
de ce champ très spécial qu’est le champ date :
Tableau 11-1
Formatage des différents éléments d’une date
Lettre
Description
Y
Permet de formater l’année. Par exemple :
YY = 08
YYYY = 2008.
M
Permet de formater le mois. Par exemple :
M = 7
MM = 07
MMM = jul
MMMM =july
D
Permet de formater le jour. Par exemple :
D = 1
DD = 01
E
Permet de format le jour de la semaine. Par exemple :
E = 1
EE = 01
EEE = mon
EEEE = monday
A
Permet d’ajouter l’indicateur Matin/Après midi.
J
Permet de formater l’heure de 0 à 23.
H
Permet de formater l’heure de 1 à 24.
K
Permet de formater l’heure au format AM/PM (0-1).
L
Permet de formater l’heure au format AM/PM (1-12).
N
Permet de formater les minutes.
S
Permet de formater les secondes.
Le tableau 11-2 contient quelques exemples de formatage.
Tableau 11-2
Exemples de formatage
Formatage
Résultat obtenu
YYYY.MM.DD
2008.05.15
H:NN
9:05 AM
EEE, DD MMMM YYYY
Thu, 15 May 2008
L’exemple de code suivant montre comment formater la date du jour à l’aide de l’expression
EEE, DD MMMM YYYY.
=Flex3 FM.book Page 221 Mardi, 2. décembre 2008 3:32 15
Gérer les données
CHAPITRE 11
221
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
[Bindable]
public var date:Date = new Date(); //new Date() = date du jour
]]>
</mx:Script>
<mx:DateFormatter
id="formatDate"
formatString="EEE, DD MMMM YYYY">
</mx:DateFormatter>
<mx:TextInput id="date_txt" text="{formatDate.format(date)}" x="10" y="50"/>
</mx:Application>
En résumé
Grâce à ce chapitre, vous êtes désormais en mesure de créer des liaisons de données
grâce à la notion de DataBinding qui permet d’éviter l’écriture de procédures de recopie
de données comme c’est le cas dans d’autres langages.
Vous avez également pu découvrir les méthodes utilisées afin de mettre en place la notion
de modèle de l’architecture MVC qui permet un stockage temporaire des données avant
leur enregistrement définitif dans la base de données.
Par ailleurs, vous êtes à présent en mesure de vérifier le format des données afin de vous
assurer de la qualité des données insérées dans le système d’information, et de formater
les données afin de les présenter conformément aux attentes de l’utilisateur.
À ce stade, vous savez donc comment faire pour fournir des données de qualité à votre
système d’information. La question que nous sommes maintenant en droit de nous poser
est la suivante : Comment insérer ces données dans le système d’information ? Le
contenu du chapitre 2 nous apporte déjà un élément de réponse en nous indiquant que
Flex n’est pas capable de communiquer directement avec la couche de persistance de
données. En effet, cette communication est réservée à la couche métier qui, en offrant ses
services à l’application Flex, permet la manipulation des données. L’étape suivante va
donc consister à étudier les différentes méthodes qui nous permettront de communiquer
avec cette couche.
=Flex3 FM.book Page 222 Mardi, 2. décembre 2008 3:32 15
=Flex3 FM.book Page 223 Mardi, 2. décembre 2008 3:32 15
12
Accéder aux services
de la couche métier
Dans la mesure où Flex ne peut accéder aux informations contenues dans une base de
données en raison de son appartenance à la couche graphique, il va demander à un tiers,
la couche métier, de réaliser ce travail, exactement comme nous demandons parfois à une
personne de notre entourage de nous rendre un service.
Pour communiquer avec cette couche, Flex dispose de trois composants RPC (Remote
Procedure Call) :
• HTTPService, également dénommé REST-Style webservice ;
• WebService ;
• RemoteObject.
Ce chapitre sera donc consacré à l’étude de ces composants
Employer les requêtes HTTP avec HTTPService
ou REST-Style webservice
L’emploi de ce composant dépend du langage utilisé pour la création et le développement
des services. Si ce dernier accepte de recevoir des données à l’aide des méthodes POST et
GET (ce qui est le cas des langages PHP, JSP, ColdFusion, ASP.NET, Ruby on Rails ou
encore Servlet Java), il conviendra alors d’utiliser le composant HTTPService.
Le principe est le suivant :
1. Le composant appelle le service grâce à son URL.
=Flex3 FM.book Page 224 Mardi, 2. décembre 2008 3:32 15
224
Comprendre Flex 3
PARTIE I
2. Lors de cet appel, des données peuvent être transférées au service via les méthodes
POST ou GET.
3. Le service exécute la tâche qui lui a été confiée (connexion à la base de données,
exécution de requêtes…).
4. Il renvoie la réponse préalablement formatée au format XML.
L’exemple suivant illustre l’interaction d’une application Flex avec un service écrit en
PHP. Précisons que pour réaliser cet exemple, vous devez disposer sur votre machine
d’un environnement PHP correctement configuré.
Environnement PHP
Si vous ne connaissez pas du tout le langage PHP, nous vous invitons à consulter son site officiel
(http://www.php.net/), qui répondra sans doute à une grande partie des questions que vous pourriez
vous poser.
Nous vous conseillons d’installer soit EasyPHP qui contient l’ensemble des composants nécessaires à
l’utilisation de PHP (http://www.easyphp.org/), soit WampServer (http://www.wampserver.com/).
L’interface graphique de l’application sera composée de trois zones de texte. Les deux
premières permettront à l’utilisateur de saisir son prénom et son nom, la troisième sera
chargée d’afficher le résultat du traitement réalisé par le service PHP. Ce traitement
consistera à récupérer les données saisies par l’utilisateur et à les exploiter pour créer la
phrase « Bonjour prénom nom ». Le résultat du traitement sera ensuite envoyé à l’application.
Pour commencer, il convient donc de créer un formulaire (figure 12-1) :
<!-- FORMULAIRE -->
<mx:Panel x="10" y="10" width="337" height="220" layout="absolute"
➥title="HTTPService">
<mx:Form x="10" y="10" width="297" height="80" horizontalScrollPolicy="off"
➥verticalScrollPolicy="off">
<mx:FormItem label="Prénom :" width="272">
<mx:TextInput width="200" id="prenom_txt"/>
</mx:FormItem>
<mx:FormItem label="Nom :" width="272">
<mx:TextInput width="200" id="nom_txt"/>
</mx:FormItem>
</mx:Form>
<mx:Button x="242" y="96" label="Valider" id="btn_valider"
➥click="executerService()"/>
<mx:TextInput x="10" y="141" width="297" id="resultat_txt"/>
</mx:Panel>
=Flex3 FM.book Page 225 Mardi, 2. décembre 2008 3:32 15
Accéder aux services de la couche métier
CHAPITRE 12
225
Ce formulaire ressemble en tous points à ceux que vous avez désormais l’habitude de
créer.
Figure 12-1
Interface de saisie
La deuxième étape va consister à implémenter et paramétrer le composant <mx:HTTPService> :
<!-- DÉCLARATION DU SERVICE -->
<mx:HTTPService id="service"
url="http://localhost/PHP/HHTPService/HTTPService.php"
result="reponseOK(event)"
fault="reponseKO(event)"
resultFormat="e4x"
method="POST">
<!—AFFECTATION DES PARAMÈTRES -->
<mx:request xmlns="*">
<prenom>{prenom_txt.text}</prenom>
<nom>{nom_txt.text}</nom>
</mx:request>
</mx:HTTPService>
<mx:HTTPService> étant un composant, il n’échappe pas à la règle de base consistant à lui
affecter un identifiant. Vient ensuite la phase de spécification de certains paramètres :
• url : adresse web du service ;
• result : action à réaliser si le service s’exécute correctement ;
• fault : action à réaliser si l’exécution du service échoue ;
• resultFormat : format de réception du message de réponse ;
• method : méthode de transmission des données.
=Flex3 FM.book Page 226 Mardi, 2. décembre 2008 3:32 15
226
Comprendre Flex 3
PARTIE I
Pour terminer cette phase de paramétrage, vous devrez ensuite définir les paramètres qui
seront envoyés et leurs sources de données via la balise <mx:request>.
Le proxy de Flex
Le Flash Player dispose d’un espace de sécurité (proxy) qui limite les requêtes d’appels aux services au
domaine de chargement du fichier SWF. Pour faire appel à des services web situés en dehors de ce
domaine, il convient d’outrepasser cette sécurité en affectant à la propriété useProxy du composant
d’accès au service la valeur false (valeur attribuée par défaut si l’attribut useProxy n’est pas utilisé, ce
qui est le cas dans l’exemple décrit précédemment).
E4X (ECMAScript for XML)
E4X est une extension du langage de programmation ECMAScript facilitant l’exploitation des fichiers XML.
Considérons le fichier XML suivant stocké dans la variable listeAvions de type XML :
var listeAvions = <avions>
<appareil id=1>Storch</appareil>
<appareil id=2>Cesna</appareil>
</avions>
Pour accéder à l’identifiant du premier élément, il suffit d’employer la syntaxe suivante :
listeAvions.appareil[0].@id
En spécifiant le format du résultat du composant HTTPService en tant que E4X dans l’attribut result
Format, vous pourrez exploiter le résultat obtenu, tout comme nous venons de le faire.
La troisième étape va ensuite consister à écrire service PHP :
<?php
//--- SERVICE PHP ----// Récupération des paramètres
$prenom = $_POST["prenom"];
$nom = $_POST["nom"];
// Traitement
$traitement = "Bonjour ".$prenom." ".$nom;
// Formatage de la réponse
$reponse = "<HTTPService>";
$reponse .= "<reponse>";
$reponse .= "<resultat>".$traitement."</resultat>";
$reponse .= "</reponse>";
$reponse .= "</HTTPService>";
// Envoi de la réponse
print $reponse;
?>
=Flex3 FM.book Page 227 Mardi, 2. décembre 2008 3:32 15
Accéder aux services de la couche métier
CHAPITRE 12
227
Le service ainsi défini récupère les valeurs des paramètres prenom et nom spécifiés dans
notre composant <mx:HTTPService>. Ces valeurs sont ensuite stockées dans des variables
afin d’être utilisées dans le traitement. Une fois le traitement terminé, la réponse est
formatée à l’aide du langage XML afin d’obtenir le format de réponse suivant :
<HTTPService>
<reponse>
<resultat> bonjour prenom nom </resultat>
</reponse>
<HTTPService>
La réponse est ensuite envoyée à l’application Flex :
print $reponse;
La quatrième étape consistera ensuite à implémenter les procédures ActionScript chargées
d’appeler le service et d’interpréter le résultat reçu.
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
// Exécution du service
public function executerService():void{
service.send();
}
public function reponseOK(event:ResultEvent):void{
var reponseXML:XML = event.result as XML;
resultat_txt.text = String(reponseXML.reponse.resultat);
}
public function reponseKO(event:FaultEvent):void{
Alert.show ("Erreur ! : "+event.fault.message)
}
]]>
</mx:Script>
La procédure executerService() a pour fonction de réaliser la requête d’appel du service
(service.send()) lorsque l’utilisateur clique sur le bouton Valider. La procédure reponseOK
(event) interprète le résultat reçu et l’affiche dans la zone de texte resultat_txt. Enfin, la
procédure reponseKO(event) intercepte l’erreur d’exécution du service et en affiche la cause.
Tous nos fichiers sont à présent complets et nous pouvons donc tester notre application.
Pour faciliter la compréhension du fonctionnement général, ce dernier est illustré par la
figure 12-2.
=Flex3 FM.book Page 228 Mardi, 2. décembre 2008 3:32 15
228
Comprendre Flex 3
PARTIE I
Figure 12-2
Utilisation du composant HTTPService
=Flex3 FM.book Page 229 Mardi, 2. décembre 2008 3:32 15
Accéder aux services de la couche métier
CHAPITRE 12
229
Étape ➊ : l’utilisateur saisit les informations demandées, ce qui entraîne la mise à jour
des paramètres grâce au DataBinding (voir chapitre 11).
Étape ➋ : lorsque l’utilisateur clique sur le bouton Valider, la requête d’exécution du
service est déclenchée ainsi que l’envoi des paramètres au service.
Étape ➌ : le service récupère les données envoyées via la méthode POST et exécute le
traitement.
Étape ➍ : le résultat du traitement est formaté en XML.
Étape ➎ : le résultat est envoyé à l’application.
Étape ➏ : puisque le composant reçoit un résultat, il exécute la procédure reponseOK(event).
Étape ➐ : cette procédure extrait le résultat et met à jour l’interface graphique.
Nous pouvons ainsi conclure que l’emploi du composant HTTPService est similaire à celui
de la majorité des applications web. Il sera donc tout naturellement utilisé dans la plupart
des cas.
Format des valeurs renvoyées
Les valeurs retournées sont au format texte. De ce fait, si la valeur renvoyée comporte des erreurs (par
exemple, </message>Bonjour</message>), cela provoquera une erreur de parsing et la valeur ne
pourra pas être interprétée et affichée dans l’application Flex. Il est donc préférable d’utiliser des outils tels
que SimpleXML proposé par PHP (http://fr.php.net/simplexml), qui vous permettra d’éviter ce
genre de désagréments en « échappant » les caractères spéciaux.
Le composant WebService
Un service web (Web Service dans la langue de Shakespeare) est un mécanisme de
communication entre deux applications distantes. La communication est réalisée à l’aide
du protocole HTTP dans lequel l’échange des données et l’appel des différentes fonctions
sont réalisés à l’aide du langage XML.
De nombreux services web sont disponibles sur Internet, tels que :
• les services météorologiques ;
• les services boursiers ;
• les services d’informations, etc.
Néanmoins, pour accéder à un service, il faut en connaître l’adresse ainsi que les méthodes
d’interrogation.
L’implémentation d’un service web s’effectue à l’aide du composant <mx:WebService>. Pour
vous permettre de bien appréhender l’utilisation de ce composant, nous allons implémenter
un service choisi parmi ceux mis à notre disposition sur le site Internet http://www.web
servicex.net. Pour notre exemple, nous avons sélectionné le service permettant de convertir
la température exprimée en degrés Celsius en une température exprimée en degrés
Fahrenheit.
=Flex3 FM.book Page 230 Mardi, 2. décembre 2008 3:32 15
230
Comprendre Flex 3
PARTIE I
Le service web en détail
Pour commencer, étudions le service web que nous allons utiliser à titre d’exemple. La
description du service web est disponible à l’adresse suivante : http://www.webservicex.net
/ConvertTemperature.asmx?WSDL. Elle va nous permettre de comprendre le fonctionnement
du service :
<?xml version="1.0" encoding="utf-8" ?>
-<wsdl:definitions
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:s="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://www.webserviceX.NET/"
xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
targetNamespace="http://www.webserviceX.NET/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
- <wsdl:types>
- <s:schema elementFormDefault="qualified" targetNamespace=
➥"http://www.webserviceX.NET/">
- <s:element name="ConvertTemp">
- <s:complexType>
- <s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="Temperature"
➥type="s:double" />
<s:element minOccurs="1" maxOccurs="1" name="FromUnit"
➥type="tns:TemperatureUnit" />
<s:element minOccurs="1" maxOccurs="1" name="ToUnit"
➥type="tns:TemperatureUnit" />
</s:sequence>
</s:complexType>
</s:element>
- <s:simpleType name="TemperatureUnit">
- <s:restriction base="s:string">
<s:enumeration value="degreeCelsius" />
<s:enumeration value="degreeFahrenheit" />
<s:enumeration value="degreeRankine" />
<s:enumeration value="degreeReaumur" />
<s:enumeration value="kelvin" />
</s:restriction>
</s:simpleType>
- <s:element name="ConvertTempResponse">
- <s:complexType>
- <s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="ConvertTempResult"
➥type="s:double" />
</s:sequence>
</s:complexType>
</s:element>
=Flex3 FM.book Page 231 Mardi, 2. décembre 2008 3:32 15
Accéder aux services de la couche métier
CHAPITRE 12
<s:element name="double" type="s:double" />
</s:schema>
</wsdl:types>
- <wsdl:message name="ConvertTempSoapIn">
<wsdl:part name="parameters" element="tns:ConvertTemp" />
</wsdl:message>
- <wsdl:message name="ConvertTempSoapOut">
<wsdl:part name="parameters" element="tns:ConvertTempResponse" />
</wsdl:message>
- <wsdl:message name="ConvertTempHttpGetIn">
<wsdl:part name="Temperature" type="s:string" />
<wsdl:part name="FromUnit" type="s:string" />
<wsdl:part name="ToUnit" type="s:string" />
</wsdl:message>
- <wsdl:message name="ConvertTempHttpGetOut">
<wsdl:part name="Body" element="tns:double" />
</wsdl:message>
- <wsdl:message name="ConvertTempHttpPostIn">
<wsdl:part name="Temperature" type="s:string" />
<wsdl:part name="FromUnit" type="s:string" />
<wsdl:part name="ToUnit" type="s:string" />
</wsdl:message>
- <wsdl:message name="ConvertTempHttpPostOut">
<wsdl:part name="Body" element="tns:double" />
</wsdl:message>
- <wsdl:portType name="ConvertTemperatureSoap">
- <wsdl:operation name="ConvertTemp">
<wsdl:input message="tns:ConvertTempSoapIn" />
<wsdl:output message="tns:ConvertTempSoapOut" />
</wsdl:operation>
</wsdl:portType>
- <wsdl:portType name="ConvertTemperatureHttpGet">
- <wsdl:operation name="ConvertTemp">
<wsdl:input message="tns:ConvertTempHttpGetIn" />
<wsdl:output message="tns:ConvertTempHttpGetOut" />
</wsdl:operation>
</wsdl:portType>
- <wsdl:portType name="ConvertTemperatureHttpPost">
- <wsdl:operation name="ConvertTemp">
<wsdl:input message="tns:ConvertTempHttpPostIn" />
<wsdl:output message="tns:ConvertTempHttpPostOut" />
</wsdl:operation>
</wsdl:portType>
- <wsdl:binding name="ConvertTemperatureSoap" type="tns:ConvertTemperatureSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
➥style="document" />
- <wsdl:operation name="ConvertTemp">
<soap:operation soapAction="http://www.webserviceX.NET/ConvertTemp"
➥style="document" />
- <wsdl:input>
<soap:body use="literal" />
231
=Flex3 FM.book Page 232 Mardi, 2. décembre 2008 3:32 15
232
Comprendre Flex 3
PARTIE I
</wsdl:input>
- <wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
- <wsdl:binding name="ConvertTemperatureHttpGet"
➥type="tns:ConvertTemperatureHttpGet">
<http:binding verb="GET" />
- <wsdl:operation name="ConvertTemp">
<http:operation location="/ConvertTemp" />
- <wsdl:input>
<http:urlEncoded />
</wsdl:input>
- <wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
- <wsdl:binding name="ConvertTemperatureHttpPost"
➥type="tns:ConvertTemperatureHttpPost">
<http:binding verb="POST" />
- <wsdl:operation name="ConvertTemp">
<http:operation location="/ConvertTemp" />
- <wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
- <wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
- <wsdl:service name="ConvertTemperature">
- <wsdl:port name="ConvertTemperatureSoap"
➥binding="tns:ConvertTemperatureSoap">
<soap:address location="http://www.webservicex.net/
➥ConvertTemperature.asmx" />
</wsdl:port>
- <wsdl:port name="ConvertTemperatureHttpGet"
➥binding="tns:ConvertTemperatureHttpGet">
<http:address location="http://www.webservicex.net/
➥ConvertTemperature.asmx" />
</wsdl:port>
- <wsdl:port name="ConvertTemperatureHttpPost"
➥binding="tns:ConvertTemperatureHttpPost">
<http:address location="http://www.webservicex.net/
➥ConvertTemperature.asmx" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
=Flex3 FM.book Page 233 Mardi, 2. décembre 2008 3:32 15
Accéder aux services de la couche métier
CHAPITRE 12
233
Cela peut paraître très complexe à première vue mais décortiquons ce fichier afin d’en
comprendre le fonctionnement.
La première étape consiste à définir la méthode d’utilisation de ce service web. Pour cela,
nous savons que le protocole HTTP est utilisé pour le transport des données et que les
méthodes d’envoi des données via ce protocole sont POST ou GET. En parcourant le fichier,
nous remarquons les lignes suivantes :
- <wsdl:message name="ConvertTempHttpGetIn">
<wsdl:part name="Temperature" type="s:string" />
<wsdl:part name="FromUnit" type="s:string" />
<wsdl:part name="ToUnit" type="s:string" />
</wsdl:message>
- <wsdl:message name="ConvertTempHttpPostIn">
<wsdl:part name="Temperature" type="s:string" />
<wsdl:part name="FromUnit" type="s:string" />
<wsdl:part name="ToUnit" type="s:string" />
</wsdl:message>
Cela signifie que notre service attend trois paramètres :
• Le premier s’intitule Temperature et reçoit des données numériques (type="s:double").
• Le deuxième, nommé FromUnit, sert à définir l’unité de conversion de base.
• Le troisième, nommé ToUnit, permet de définir l’unité de conversion.
Il est également important de souligner que ces trois paramètres sont de type chaîne
(type="s:string"). Pour faire appel à ce service, nous devons donc lui fournir ces trois
paramètres, en respectant cet ordre précis et en veillant au format des données transmises.
Nous avons déterminé les paramètres requis et leur type, mais qu’en est-il du format de
la réponse fournie par le service ? Continuons notre lecture du fichier et observons les
lignes suivantes :
<s:element name="double" type="s:double" />
- <wsdl:message name="ConvertTempHttpGetOut">
<wsdl:part name="Body" element="tns:double" />
</wsdl:message>
- <wsdl:message name="ConvertTempHttpPostOut">
<wsdl:part name="Body" element="tns:double" />
</wsdl:message>
Ces lignes de code indiquent que le format de la réponse sera de type décimal numérique
(double).
La dernière étape va consister à trouver le nom de la méthode, également appelée opération,
qui va être invoquée pour réaliser le traitement. Pour cela, recherchons la balise operation
correspondant à notre protocole d’envoi (HTTP).
=Flex3 FM.book Page 234 Mardi, 2. décembre 2008 3:32 15
234
Comprendre Flex 3
PARTIE I
- <wsdl:portType name="ConvertTemperatureHttpGet">
- <wsdl:operation name="ConvertTemp">
<wsdl:input message="tns:ConvertTempHttpGetIn" />
<wsdl:output message="tns:ConvertTempHttpGetOut" />
</wsdl:operation>
</wsdl:portType>
- <wsdl:portType name="ConvertTemperatureHttpPost">
- <wsdl:operation name="ConvertTemp">
<wsdl:input message="tns:ConvertTempHttpPostIn" />
<wsdl:output message="tns:ConvertTempHttpPostOut" />
</wsdl:operation>
</wsdl:portType>
Nous retrouvons les deux éléments propres à notre protocole : ConvertTemperatureHttpGet
et ConvertTemperatureHttpPost. Nous remarquons également la présence de la balise
operation définissant le nom de la méthode devant être invoquée (ConvertTemp) et l’appel
aux paramètres d’entrée (input) et de sortie (output).
Ceci termine l’analyse de notre service web qui, avouons-le, n’est pas des plus simples.
L’étape suivante va consister à créer une application Flex faisant appel à ce service.
Création de l’interface graphique
L’interface graphique de notre application comprend seulement deux zones de texte et un
bouton permettant l’appel du service web (figure 12-3).
Figure 12-3
Interface graphique de conversion de températures
<mx:Panel x="10" y="10" width="379" height="183" layout="absolute" title="WebService
: Conversion de température">
<mx:Button x="10" y="105" label="Convertir" id="btn_executer"
➥click="executerWebService()" width="339"/>
<mx:Form x="10" y="10" width="339" height="87" horizontalScrollPolicy="off"
➥verticalScrollPolicy="off">
<mx:FormItem label="Température en degrés Celsius :">
<mx:TextInput width="79" id="degresC_txt"/>
=Flex3 FM.book Page 235 Mardi, 2. décembre 2008 3:32 15
Accéder aux services de la couche métier
CHAPITRE 12
235
</mx:FormItem>
<mx:FormItem label="Température en degrés Fahrenheit :">
<mx:TextInput width="81" editable="false" enabled="true" id="degresF_txt"/>
</mx:FormItem>
</mx:Form>
</mx:Panel>
Appel du service web
Le service web sera appelé grâce au composant <mx:WebService>, comme suit :
<mx:WebService
id="serviceConversion"
wsdl="http://www.webservicex.net/ConvertTemperature.asmx?WSDL">
<mx:operation name="ConvertTemp" resultFormat="object"
fault="resultatKO(event)"
result="resultatOK(event)"/>
</mx:WebService>
L’URL du service est spécifiée dans la propriété wsdl. Vient ensuite l’appel de l’opération
ConvertTemp dont le résultat est ici spécifié comme un objet. On trouve ensuite les procédures
resultatOK(event) et resultatKO(event) exécutées en fonction du résultat de l’exécution
du service.
La configuration de l’appel de notre service web terminée, passons maintenant à l’écriture
des procédures d’appel et d’analyse du résultat.
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
// Procédure affichant l’erreur d’exécution
public function resultatKO(e:FaultEvent):void{
Alert.show("ERREUR "+e.fault.faultString);
}
// Récupération du résultat envoyé par le service web
public function resultatOK(e:ResultEvent):void
{
degresF_txt.text=String(e.result);
}
// Exécution du service
public function executerWebService():void
{
var temperature:String = degresC_txt.text;
var uniteSource:String = "degreeCelsius";
=Flex3 FM.book Page 236 Mardi, 2. décembre 2008 3:32 15
236
Comprendre Flex 3
PARTIE I
var uniteConversion:String = "degreeFahrenheit";
// Appel du service
serviceConversion.ConvertTemp(temperature,uniteSource,uniteConversion);
}
]]>
</mx:Script>
Les commentaires insérés dans cette portion de code parlent d’eux-mêmes. Nous aimerions
tout de même attirer votre attention sur la méthode d’appel du service. Cette méthode se
résume en l’appel de l’opération appropriée et en la transmission des paramètres requis :
serviceConversion.ConvertTemp(temperature,uniteSource,uniteConversion);
Soulignons également que l’ordre et le type des paramètres transmis doivent coïncider
avec ceux établis en phase d’étude du service web, sous peine d’un dysfonctionnement
de celui-ci. Nous pouvons à présent exécuter notre application afin de vérifier qu’elle
fonctionne correctement (figure 12-4).
Figure 12-4
Appréciation du bon fonctionnement de l’application
Analyse du fonctionnement de l’application
Au cours de cette section, nous allons analyser le fonctionnement global de notre application afin de synthétiser la notion de service web et son mode d’interaction avec les
applications Flex.
Sept étapes jalonnent le processus de communication :
Étape ➊ : l’utilisateur saisit la température en degrés Celsius et clique sur le bouton
Convertir.
Étape ➋ : l’action sur le bouton entraîne l’appel du service via son URL et la transmission
des paramètres à l’opération de traitement concerné.
Étape ➌ : le service reçoit les informations et les transmet à un programme chargé
d’exécuter la conversion. À noter que nous n’avons pas accès à ce programme et il nous
est impossible d’en déterminer les procédures de calcul.
=Flex3 FM.book Page 237 Mardi, 2. décembre 2008 3:32 15
Accéder aux services de la couche métier
CHAPITRE 12
Figure 12-5
Fonctionnement du composant WebService
237
=Flex3 FM.book Page 238 Mardi, 2. décembre 2008 3:32 15
238
Comprendre Flex 3
PARTIE I
Étape ➍ : le programme retourne le résultat du traitement au service web.
Étape ➎ : le service web communique à son tour le résultat à l’application Flex.
Étape ➏ : la procédure liée à l’événement de retour positif du service est alors exécutée.
Étape ➐ : l’interface graphique est mise à jour.
Cet exemple nous a permis de démontrer que l’emploi des services web est assez fastidieux.
La phase la plus complexe est sans doute l’analyse du service web, car la méthode d’appel
du service reste très simple grâce à l’utilisation du composant <mx:WebService>.
Flex nous propose enfin une troisième et dernière méthode de communication que nous
allons nous empresser de découvrir au cours de la section suivante.
Accéder aux classes distinctes grâce à RemoteObject
Comprendre RemoteObject
Le composant RemoteObject se distingue des composants HTTPService et WebService par son
mode d’accès aux services. En effet, alors que nous devions préciser le mode d’envoi des
données avec le composant HTTPService ou choisir l’opération adéquate avec WebService,
le composant RemoteObject nous offre la possibilité d’accéder directement à la classe
métiers souhaitée.
Cette connexion directe n’est possible qu’à l’aide du langage ColdFusion ou de l’applicatif
LiveCycle Data Service d’Adobe, souvent utilisé pour les environnements J2EE. Pour les
services écrits en PHP et .NET, le composant RemoteObject ne peut accéder directement aux
classes métiers, nous devons donc recourir à une passerelle qui effectuera cette connexion.
Elle est réalisé au moyen d’applicatifs tels que AMFPHP (http://amfphp.sourceforge.net/),
SabreAMF (http://www.osflash.org/sabreamf) ou encore WebORB de Midnight Coders
(http://www.themidnightcoders.com/). Nous vous invitons à visiter les sites web de ces
outils pour de plus amples informations à leur sujet.
Implémentation de RemoteObject
L’implémentation du composant RemoteObject à l’aide du langage MXML s’effectue comme
suit :
<mx:RemoteObject id="identifiant"
source="classe à utiliser" endpoint="URL de la classe">
<mx:method name="nom de la méthode de la classe à exécuter" result="procédure à
➥exécuter en cas de succès d’exécution de la méthode" fault="procédure à exécuter en
➥cas d’échec d’exécution de la méthode"></mx:method>
</mx:RemoteObject>
=Flex3 FM.book Page 239 Mardi, 2. décembre 2008 3:32 15
Accéder aux services de la couche métier
CHAPITRE 12
239
Voyons maintenant comment utiliser la classe RemoteObject en ActionScript :
import mx.rpc.remoting.mxml.RemoteObject;
var service:RemoteObject = new RemoteObject();
service.endpoint = adresse de la classe à utiliser;
service.source="classe à utiliser";
service.nom_de_la_methode();
service.nom_de_la_methode.addEventListener("result", procédure à exécuter en cas de
➥succès d’exécution de la méthode);
service.nom_de_la_methode.addEventListener("fault", procédure à exécuter en cas
➥d’échec d’exécution de la méthode)
À ce stade, nous ne nous attarderons pas d’avantage sur l’utilisation de ce composant, car
nous étudierons son application en détail au cours du chapitre suivant. Néanmoins, penchonsnous sur le schéma de son fonctionnement dans le cadre d’une utilisation avec le langage
PHP couplé à la passerelle AMFPHP (figure 12-6). Ce schéma nous permet de distinguer
les différentes étapes suivantes :
Figure 12-6
Fonctionnement du composant RemoteObject avec AMFPHP et PHP
=Flex3 FM.book Page 240 Mardi, 2. décembre 2008 3:32 15
240
Comprendre Flex 3
PARTIE I
Étape ➊ : le composant établit la connexion avec AMFPHP et lui transmet la classe et la
méthode recherchées.
Étape ➋ : AMFPHP recherche la classe et la méthode.
Étape ➌ : une fois la méthode trouvée, celle-ci est exécutée.
Étape ➍ : le résultat de l’exécution de la méthode est transmis à AMFPHP.
Étape ➎ : la procédure resultatOK(event) est exécutée afin de présenter le résultat obtenu.
En résumé
Au cours de ce chapitre, nous avons abordé les différentes méthodes de connexion aux
services proposés par la couche métier. La méthode à employer dépend de la nature du
service et du type de résultat souhaité (XML ou non). Néanmoins, dans la plupart des
cas, le composant HTTPService est le plus communément utilisé car il se rapproche des
méthodes de communication traditionnelles.
Le chapitre suivant va nous permettre d’approfondir nos connaissances en matière de
communication avec la couche métier en détaillant l’interaction avec les services écrits
en PHP.
=Flex3 FM.book Page 241 Mardi, 2. décembre 2008 3:32 15
13
Flex et PHP
L’utilisation du langage PHP est très répandue pour la création de sites web. En effet, il
représente aujourd’hui le langage utilisé par 80 % des sites Internet. C’est pourquoi, il est
indispensable de comprendre comment il interagit avec le framework Flex.
Accès aux services PHP
PHP est un langage serveur dont le fonctionnement est basé sur l’interprétation et
l’exécution de requêtes HTTP. La transmission des données entre le client et le script
PHP s’effectue le plus communément à l’aide des méthodes POST ou GET. À première vue,
le composant du framework Flex répondant à ces critères de communication est le
composant HTTPService. Néanmoins, ce dernier présente un petit inconvénient : la réponse
doit obligatoirement être formatée sous forme de balise XML (voir chapitre 12).
Une autre solution consiste alors à utiliser le composant RemoteObject. En effet, grâce à ce
composant, il est inutile de formater la réponse, car celle-ci peut être utilisée dans son
format originel (chaîne, tableau, entier…). Cependant, RemoteObject ne peut interagir
directement avec les objets PHP comme nous aurions pu l’envisager avec le langage
ColdFusion. Il va donc falloir utiliser une passerelle capable de réaliser la communication
entre l’application Flex et les services PHP. Nous avons ici choisi de vous présenter la
passerelle AMFPHP (Action Message Format PHP).
Installation et fonctionnement de la passerelle AMFPHP
AMFPHP est une bibliothèque PHP sous licence Open Source permettant la communication entre des applications Flash (et par extension Flex) et le langage PHP. Elle joue le
rôle de passerelle entre l’application et les services PHP.
=Flex3 FM.book Page 242 Mardi, 2. décembre 2008 3:32 15
242
Comprendre Flex 3
PARTIE I
Le principal avantage de cette bibliothèque est de ne pas modifier les types des données
transmises. Par exemple, si nous transmettons un objet via l’application Flex, PHP reçoit
un objet et inversement.
Le protocole AMF
La libraire AMFPHP utilise le protocole AMF, mis au point par Adobe. Il s’agit d’un protocole binaire de
transfert de données entre le client et le serveur, ce qui permet de réduire la taille des paquets échangés
entre ces deux entités et, par conséquent, de diminuer la part de la bande passante utilisée par l’application
qui le met en œuvre. Il présente également l’avantage d’augmenter la rapidité d’exécution des applications
en raison de la diminution des paquets échangés.
Pour installer la bibliothèque AMFPHP, il suffit de la télécharger à l’adresse suivante :
http://sourceforge.net/project/showfiles.php?group_id=72483#files, et de décompresser
l’archive ainsi obtenue à la racine de votre serveur web.
Attention
Pour que l’interaction avec le composant RemoteObject soit effective, vous devez disposer au minimum
de la version amfphp-1.9.beta.20070513.
En explorant les différents répertoires de la bibliothèque AMFPHP, nous notons la présence
du répertoire services. C’est ici que nous allons déposer l’ensemble de nos services PHP.
Rappelons qu’un service PHP est une méthode contenue dans une classe PHP dont le
nom doit être rigoureusement identique au nom du fichier PHP qui la contient. En effet,
c’est à partir de ce nom de fichier qu’AMFPHP va pouvoir effectuer la corrélation entre
la classe et le service appelé.
À la racine de la bibliothèque AMFPHP, nous notons également la présence du fichier
gateway.php. Ce fichier va être le point d’entrée entre notre application Flex et les services
PHP.
Les différentes étapes de communication entre une application Flex et les services PHP
sont les suivantes (figure 13-1) :
Étape 1 : l’application Flex effectue une demande d’exécution de service en se connectant
au fichier gateway.php de la bibliothèque AMFPHP et en lui spécifiant la classe et le
service (méthode) recherchés.
Étapes 2, 3 et 4 : le fichier gateway.php vérifie la présence de la classe, en fonction des
noms de fichiers PHP présents dans le répertoire service, et si la méthode demandée est
bien implémentée dans la classe.
Étape 5 : la méthode renvoie un résultat au fichier gateway.php.
Étape 6 : le fichier gateway.php transmet à l’application Flex le résultat fourni par la
méthode. Notez que la sérialisation/désérialisation des données est effectuée par AMFPHP,
=Flex3 FM.book Page 243 Mardi, 2. décembre 2008 3:32 15
Flex et PHP
CHAPITRE 13
243
ce qui permet de ne pas modifier le type de données transmises et reçues. De ce fait, si le
service retourne un tableau, c’est un tableau qui sera reçu par l’application Flex et si
l’application Flex transmet un tableau au service, c’est sous cette forme qu’il sera
réceptionné par le service.
Figure 13-1
Processus d’échange entre une application Flex et les services PHP
Pour plus de clarté, nous avons choisi d’illustrer l’ensemble des notions abordées jusqu’à
présent à travers un exemple dans lequel les composants HTTPService et RemoteObject sont
utilisés.
=Flex3 FM.book Page 244 Mardi, 2. décembre 2008 3:32 15
244
Comprendre Flex 3
PARTIE I
Cas pratique : gestion d’un magasin informatique
En guise d’exemple, nous vous proposons de développer une petite application permettant
de gérer l’ensemble des produits d’un magasin informatique. Le but n’étant pas ici de
développer un cas pratique complet (ceci sera abordé dans la seconde partie de cet ouvrage),
nous allons plutôt illustrer l’ensemble des concepts et observer les différences entre les
composants HTTPService et RemoteObject. Afin d’observer ces différences, nous réaliserons
le listing des produits à l’aide de ces deux composants.
Préparation
Avant d’entrer dans le vif du sujet, il convient tout d’abord de créer le projet Flex et la
base de données qui contiendra les produits du magasin informatique, sans oublier de
satisfaire à certains prérequis techniques.
Prérequis
Pour mener à bien cet exemple, vous devez impérativement disposer d’un environnement PHP correctement
installé et configuré sur votre machine. Pour plus de facilité, nous vous conseillons d’utiliser EasyPHP,
pack logiciel contenant l’ensemble des éléments requis (PHP, MySQL et le serveur Apache). Vous trouverez
toutes les informations nécessaires sur cette application à l’adresse suivante :
http://www.easyphp.org/.
Création de la base de données
Le schéma de la base de données MySQL découle du diagramme de classes représenté à
la figure 13-2. La base de données contient donc deux tables : la première synthétise les
catégories de produits (carte mère, disque dur, etc.), la seconde permet de stocker les
composants informatiques mis en vente.
Figure 13-2
Diagramme de classes
Voici le script de création de la base de données, issue de la transcription du diagramme
précédemment décrit.
--- SCHÉMA DE LA BASE DE DONNÉES db_configurateur
=Flex3 FM.book Page 245 Mardi, 2. décembre 2008 3:32 15
Flex et PHP
CHAPITRE 13
-CREATE DATABASE IF NOT EXISTS db_configurateur;
USE db_configurateur;
--- CRÉATION DE LA TABLE tb_categorie
-CREATE TABLE `tb_categorie` (
`idCategorie` int(10) unsigned NOT NULL auto_increment,
`nomCategorie` varchar(45) NOT NULL default '',
PRIMARY KEY (`idCategorie`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--- INSERTION DE DONNÉES DANS LA TABLE tb_categorie
-INSERT INTO `tb_categorie` (`idCategorie`,`nomCategorie`) VALUES
(1,'Disques durs'),
(2,'Mémoires'),
(3,'Cartes graphiques'),
(4,'Processeurs'),
(5,'Cartes mères'),
(6,'Graveurs & Lecteurs'),
(7,'Boîtiers & Alimentations');
--- CRÉATION DE LA TABLE tb_composant liée à la table tb_categorie par le biais de la
➥clé étrangère fkCategorie
-CREATE TABLE `tb_composant` (
`idComposant` int(10) unsigned NOT NULL auto_increment,
`nomComposant` varchar(45) NOT NULL default '',
`prixComposant` float NOT NULL default '0',
`fkCategorie` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`idComposant`),
KEY `FK_tb_composant` (`fkCategorie`),
CONSTRAINT `FK_tb_composant` FOREIGN KEY (`fkCategorie`) REFERENCES `tb_categorie`
➥(`idCategorie`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--- INSERTION DE DONNÉES DANS LA TABLE tb_composant
-INSERT INTO `tb_composant` (`idComposant`,`nomComposant`,`prixComposant`,
➥`fkCategorie`) VALUES
(1,'SATA - 160 Go, 8 Mo, S-ATA/II, 7200 trs/min',48.99,1),
(2,'SATA - 80 Go, 8 Mo, S-ATA/II, 7200 trs/min',38.52,1),
(3,'SATA - 400 Go, 16 Mo, S-ATA/II, 7200 trs/min',154.25,1),
(4,'IDE - 160 Go, 8 Mo',59,1),
(5,'IDE - 320 Go, 8 Mo',72.5,1),
(6,'IDE - 400 Go, 16 Mo',150,1),
245
=Flex3 FM.book Page 246 Mardi, 2. décembre 2008 3:32 15
246
Comprendre Flex 3
PARTIE I
(7,'1024 Mo, PC3200 (400 MHz)',60.42,2),
(8,'512 Mo, PC133',54.12,2),
(9,'2048 Mo, PC4200 (533 MHz)',118.99,2),
(10,'512 Mo, PC3200 (400 MHz)',32.75,2),
(11,'256 Mo, PC133',22.15,2),
(12,'512 Mo, PC4200 (533 MHz)',25.89,2),
(13,'Radeon X1600 Pro, PCI-Express 16x, 256 Mo',124.52,3),
(14,'GeForce 7600 GS, PCI-Express 16x, 256 Mo',98,3),
(15,'GeForce 7800 GS, AGP 8x, 256 Mo',300.41,3),
(16,'Radeon X1950 Pro, PCI-Express 16x, 256 Mo',174.98,3),
(17,'Quadro FX 3500, PCI-Express 16x, 256 Mo',1200.58,3),
(18,'GeForce 7300 GS, PCI-Express 16x, 256 Mo',70.25,3),
(19,'2,67 GHz, 256 Ko, 533 MHz',35,4),
(20,'3,00 GHz, 4 Mo, 800 MHz',125.36,4),
(21,'1,86 GHz, 4 Mo, 1066 MHz',41.73,4);
INSERT INTO `tb_composant` (`idComposant`,`nomComposant`,`prixComposant`,
➥`fkCategorie`) VALUES
(22,'3,33 GHz, 512 Ko, 533 MHz',60.81,4),
(23,'2,00 GHz, 2 Mo, 800 MHz',132.84,4),
(24,'2,93 GHz, 4 Mo, 1066 MHz',978.68,4),
(25,'VIA PT880 Ultra',31.69,5),
(26,'NVIDIA nForce Dual PCI-E x 16',254.94,5),
(27,'Intel P965',154,5),
(28,'NVIDIA nForce 680i SLI',500.84,5),
(29,'Intel 946GZ Express',85.24,5),
(30,'Intel 975X',100,5),
(31,'GRAVEUR DVD - S-ATA, noir',50,6),
(32,'GRAVEUR DVD - USB 2.0, aluminium',125.41,6),
(33,'LECTEUR DVD - BLANC',19.99,6),
(34,'LECTEUR DVD - NOIR',19.99,6),
(35,'GRAVEUR DVD - IDE Noir',45,6),
(36,'GRAVEUR DVD - IDE Beige',54.26,6),
(37,'Digital-B - 480 w',52,7),
(38,'NSK6000 - 380 w',98,7),
(39,'P160 - 430 w',114.83,7),
(40,'Vague 8609B - 500 w',81.23,7),
(41,'Nine Hundred - 400 w',100.14,7),
(42,'Oxygen 8611B',95.24,7);
Passons à présent à la création de l’interface graphique de notre application.
Création de l’interface graphique
Après avoir créé un nouveau projet Flex, nous vous invitons à saisir les quelques lignes
de code suivantes afin d’obtenir l’interface graphique capable de lister l’ensemble des
produits de notre magasin (figure 13-3).
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
=Flex3 FM.book Page 247 Mardi, 2. décembre 2008 3:32 15
Flex et PHP
CHAPITRE 13
247
<mx:DataGrid id="grilleComposants" x="10" y="10" width="700" rowCount="10">
<mx:columns>
<mx:DataGridColumn headerText="Catégorie" dataField="nomCategorie"
➥width="200"/>
<mx:DataGridColumn headerText="Composant" dataField="nomComposant"
➥width="400"/>
<mx:DataGridColumn headerText="Prix" dataField="prixComposant" width="100"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
Figure 13-3
Interface graphique
Nous disposons désormais de l’ensemble des éléments nécessaires au bon déroulement
de notre application. Voyons maintenant comment utiliser les composants HTTPService et
RemoteObject.
Implémentation du composant HTTPService en ActionScript
Au cours du chapitre précédent, nous avions vu un exemple mettant en évidence l’utilisation
du composant HTTPService pour accéder aux services PHP. Nous allons l’utiliser également dans notre cas pratique, mais cette fois, nous l’implémenterons à l’aide du langage
ActionScript.
Pour cela, la première étape va consister à créer le service PHP devant se connecter à la
base de données et lister les produits qu’elle contient. Il ne faudra pas omettre de transformer le résultat en langage XML, afin qu’il soit exploitable par notre application. Voici
le code du fichier listerProduits.php, qui va nous permettre d’obtenir la liste des
produits de notre magasin et de la transmettre à l’application Flex sous forme XML :
=Flex3 FM.book Page 248 Mardi, 2. décembre 2008 3:32 15
248
Comprendre Flex 3
PARTIE I
<?php
// Connexion à la base de données MySQL grâce au nom d’hôte, au login et au mot de
➥passe
$db = mysql_connect("localhost","root","mysql");
// Sélection de la base de données
mysql_select_db("db_configurateur", $db);
// Requête
$Requete = "select CP.idComposant, CP.nomComposant, CP.prixComposant,
➥CAT.nomCategorie, CAT.idCategorie
From tb_composant CP, tb_categorie CAT
where CP.fkCategorie = CAT.idCategorie";
// Résultat de la requête
$Resultat = mysql_query( $Requete );
// Transformation du résultat en XML
$ExportXML = "<composants>";
while ($Composants = mysql_fetch_object ($Resultat))
{
$ExportXML .="<composant>";
$ExportXML .="<idComposant>".$Composants->idComposant."</idComposant>";
$ExportXML .="<nomComposant>".$Composants->nomComposant."</nomComposant>";
$ExportXML .="<prixComposant>".$Composants->prixComposant."</prixComposant>";
$ExportXML .="<idCategorie>".$Composants->idCategorie."</idCategorie>";
$ExportXML .="<nomCategorie>".$Composants->nomCategorie."</nomCategorie>";
$ExportXML .="</composant>";
}
$ExportXML .= "</composants>";
mysql_free_result($Resultat);
print ($ExportXML)
?>
Nous devons ensuite créer la procédure alimentant notre tableau. Pour cela, nous vous
conseillons de créer un fichier ActionScript nommé httpService.as, que nous lierons par
la suite au fichier MXML. Dans la portion de code suivante, nous avons commenté
l’ensemble des lignes devant être insérées dans ce fichier afin que vous puissiez apprécier
la signification et le rôle de chacune :
// Importation des classes nécessaires
import mx.controls.Alert;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.http.HTTPService;
// Procédure déclenchée à la fin de la création de l’application
public function listerComposants():void{
=Flex3 FM.book Page 249 Mardi, 2. décembre 2008 3:32 15
Flex et PHP
CHAPITRE 13
249
var serviceHttp:HTTPService = new HTTPService;
// Spécification de l’URL
serviceHttp.url = "http://localhost/PHP/httpServices/listerProduits.php"
// Spécification du format des données reçues
serviceHttp.resultFormat = "e4x";
// Type de méthode d’envoi des données
serviceHttp.method = "POST";
// Procédure à exécuter en cas de succès
serviceHttp.addEventListener(ResultEvent.RESULT,resultatOk)
// Procédure a exécuter en cas d’erreur
serviceHttp.addEventListener(FaultEvent.FAULT,resultatKo)
// Exécution du service
serviceHttp.send()
}
// Procédure exécutée en cas de réception du résultat
public function resultatOk(e:ResultEvent):void
{
// Récupération du résultat
var resultatXML:XML = e.result as XML;
// Alimentation du dataProvider du DataGrid
grilleComposants.dataProvider = resultatXML.composant;
}
// Procédure exécutée en cas d’erreur
public function resultatKo(e:FaultEvent):void
{
// Message d’erreur
Alert.show("Erreur !");
}
L’implémentation du composant HTTPService en ActionScript est identique à celle utilisée
en MXML (voir chapitre 12) :
• spécification de l’URL ;
• spécification de la méthode d’envoi des données ;
• indication des procédures à exécuter en cas de succès ou d’erreur ;
=Flex3 FM.book Page 250 Mardi, 2. décembre 2008 3:32 15
250
Comprendre Flex 3
PARTIE I
• indication du format des données récupérées.
À présent, il ne nous reste plus qu’à lier notre fichier ActionScript au fichier MXML principal et faire appel à l’exécution de la procédure listerComposants() après la création de
l’application :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥creationComplete="listerComposants()">
<mx:Script source="httpService.as"></mx:Script>
Nous pouvons maintenant tester notre application et observer que le résultat obtenu est
bien concluant (figure 13-4).
Figure 13-4
Résultat obtenu à l’aide du composant HTTPService
Nous allons réitérer cette procédure, mais en utilisant le composant remoteObject couplé
à AMFPHP.
RemoteObject en pratique
Nous allons à présent voir le couple RemoteObject et AMFPHP en action.
Création du service PHP
Avant toute chose, il convient de créer le service PHP. Pour cela, nous allons nous placer
dans le répertoire services de la bibliothèque AMFPHP et créer un fichier nommé
servComposants.php qui va contenir l’ensemble des services accessibles pour notre
application :
<?php
class servComposants
{
=Flex3 FM.book Page 251 Mardi, 2. décembre 2008 3:32 15
Flex et PHP
CHAPITRE 13
function servComposants ()
{
/******************************************
/*
LISTE DES SERVICES
*
/******************************************/
$this->methodTable = array(
"serviceListerComposants" => array(
"description" => "Liste des composants",
"access" => "remote"
)
);
}
//-------------------------//-SERVICE
-//-------------------------function serviceListerComposants ()
{
// Connexion à la base de données MySQL grâce au nom d’hôte, au login et au
➥mot de passe
$db = mysql_connect("localhost","root","mysql");
// Sélection de la base de données
mysql_select_db("db_configurateur", $db);
// Requête
$Requete = "select CP.idComposant, CP.nomComposant, CP.prixComposant,
➥CAT.nomCategorie, CAT.idCategorie
From tb_composant CP, tb_categorie CAT
where CP.fkCategorie = CAT.idCategorie";
// Résultat de la requête
$Resultat = mysql_query( $Requete );
// Alimentation d’un tableau avec la liste des composants
while ($Composant = mysql_fetch_object ($Resultat))
{
$tableauComposants[] = $Composant;
}
// Envoi du tableau
return( $tableauComposants);
}
}
?>
251
=Flex3 FM.book Page 252 Mardi, 2. décembre 2008 3:32 15
252
Comprendre Flex 3
PARTIE I
Ce fichier comporte une classe nommée servComposants. Nous insistons sur le fait que le
nom de la classe doit obligatoirement comporter le nom du fichier PHP car ces deux entités
sont liées.
Le fichier est ensuite découpé en deux parties. La première permet de créer, dans le
constructeur de la classe, un tableau contenant la liste des services disponibles :
function servComposants ()
{
/******************************************
/*
LISTE DES SERVICES
*
/******************************************/
$this->methodTable = array(
"serviceListerComposants" => array(
"description" => "Liste des composants",
"access" => "remote"
)
);
}
La seconde partie contient les services proprement dits :
function serviceListerComposants ()
{
[…]
// Alimentation d’un tableau avec la liste des composants
while ($Composant = mysql_fetch_object ($Resultat))
{
$tableauComposants[] = $Composant;
}
// Envoi du tableau
return( $tableauComposants);
}
Notre service serviceListerComposants() va donc rechercher les informations dans la base
de données et pour chaque ligne trouvée, il va les stocker dans une ligne d’un tableau qui
sera ensuite transmis à l’application Flex en suivant les étapes décrites à la section précédente « Installation et fonctionnement » de ce chapitre.
Test du service
Avant de se lancer dans le codage du fichier MXML de notre application, il convient de
s’assurer que notre service fonctionne correctement. Pour cela, nous allons utiliser l’interface prévue à cet effet située dans le répertoire browser de la bibliothèque AMFPHP. Pour
tester le service :
1. Dans la partie gauche de l’interface, sélectionnez votre fichier php (ServComposant)
contenant la liste des services.
=Flex3 FM.book Page 253 Mardi, 2. décembre 2008 3:32 15
Flex et PHP
CHAPITRE 13
253
2. Dans la partie droite de l’interface s’affiche alors la liste des services contenus dans
ce fichier PHP. Sélectionnez le service serviceListerComposant.
3. Cliquez sur le bouton Call qui déclenche l’appel du service. Vous obtenez alors le
résultat illustré à la figure 13-5.
Figure 13-5
Test du service dans l’interface Service Browser
Première exécution du service browser d’AMFPHP
Pour accéder à l’interface de test des services, il faut appeler le fichier index.html du répertoire browser
de la bibliothèque AMFPHP via votre navigateur (par exemple, http://localhost/amfphp/browser).
Au premier lancement de cette application, une fenêtre vous indique les paramètres utilisés :
• le chemin d’accès au fichier gateway.php ;
• le type d’encodage :
– AMF0 (à utiliser si l’application a été développée à l’aide d’ActionScript 1.0 ou 2.0) ;
– AMF3.
• les onglets de résultat visibles après l’exécution d’un service :
– l’onglet Info, qui permet de visualiser les temps de traitement du service ;
– l’onglet Results, qui permet d’afficher le résultat sous forme de trace de log ;
– l’onglet Tree view, qui permet de visualiser les résultats sous forme d’arborescence, un nœud étant
caractérisé par un objet.
=Flex3 FM.book Page 254 Mardi, 2. décembre 2008 3:32 15
254
Comprendre Flex 3
PARTIE I
Conseil
Pour une prise en main de cette interface, nous vous conseillons de conserver les paramètres spécifiés
par défaut, qui sont généralement les plus utilisés.
Si vous visualisez la liste des composants informatiques dans l’onglet Results, cela signifie
que notre service s’est exécuté correctement. Dans le cas contraire, cela signifie que le
fichier PHP contient une erreur.
Il est important de noter que seule cette interface vous permettra de déboguer vos services
PHP. En effet, dans la mesure où l’application Flex et les services PHP sont séparés par
la notion de couche métier, il est impossible de remonter dans l’application les erreurs
rencontrées dans les services. Le seul indice nous indiquant un éventuel dysfonctionnement
du service est une erreur de connexion au service, ou parfois aucune erreur…, mais dans
tous les cas nous n’obtiendrons aucun résultat.
Implémentation en MXML
Dans un premier temps, nous allons étudier la mise en place du composant RemoteObject
à l’aide du langage MXML. Pour cela, analysons les lignes de code suivantes :
<mx:RemoteObject id="servRO"
source="ServComposants" endpoint="http://localhost/amfphp/gateway.php"
➥destination="amfphp" showBusyCursor="true">
<mx:method name="serviceListerComposants" result="resultatOK(event)"
➥fault="resultatKO(event)"></mx:method>
</mx:RemoteObject>
Comme nous l’avons vu au chapitre précédent, le composant RemoteObject nécessite
quelques paramétrages :
• source : sert à spécifier le nom de la classe contenant la méthode à exécuter ;
• endPoint : contient l’URL du fichier gateway.php de la bibliothèque AMFPHP ;
• destination : permet de faire le lien avec le sous-répertoire amfphp du répertoire services,
ce dernier contenant le fichier DiscoveryService.php qui va permettre à AMFPHP de
connaître les fichiers PHP contenant l’ensemble des services ;
• showBusyCursor : affiche le curseur « Occupé » pendant l’exécution de la méthode ;
• method name : précise le nom de la méthode à exécuter ;
• result : contient le nom de l’action à réaliser lorsque la méthode retourne un résultat ;
• fault : déclare le nom de l’action à réaliser lorsque la méthode a provoqué une erreur.
Nous faisons ici appel à la méthode serviceListerComposants de la classe servComposants.
Si la méthode retourne un résultat, la procédure resultatOk() est exécutée. Dans le cas
contraire, la procédure resultatKO() est exécutée.
=Flex3 FM.book Page 255 Mardi, 2. décembre 2008 3:32 15
Flex et PHP
CHAPITRE 13
255
Afin de pouvoir réaliser l’appel à notre méthode, nous allons ajouter un bouton comme suit :
<mx:Button x="10" y="242" label="Appeler service" id="btn_ro"
➥click="executerService()"/>
Notre composant est à présent configuré, il ne reste plus qu’à écrire les procédures
ActionScript.
<mx:Script>
<![CDATA[
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.controls.Alert;
public function executerService():void
{
servRO.getOperation('serviceListerComposants').send();
}
public function resultatOK(e:ResultEvent):void
{
grilleComposants.dataProvider = e.result as Array;
}
public function resultatKO(e:FaultEvent):void
{
Alert.show(e.fault.faultString, e.fault.faultCode.toString());
}
]]>
</mx:Script>
Observons en détail comment l’appel de l’exécution de la méthode serviceListerComposants
est réalisé . En effet, cet appel s’effectue par la combinaison des méthodes getOperation()
et send() du composant RemoteObject. La traduction littérale de ceci serait alors : « Recherche l’opération serviceListerComposant(getOperation('serviceListerComposants')) et exécute
la méthode send() ».
Notre composant est à présent configuré et fonctionnel. Soulignons également le travail
réalisé par la bibliothèque AMFPHP : le résultat tabulaire renvoyé par la méthode est
directement exploitable sous cette forme par le composant RemoteObject, ce qui facilite
ainsi son exploitation ultérieure.
=Flex3 FM.book Page 256 Mardi, 2. décembre 2008 3:32 15
256
Comprendre Flex 3
PARTIE I
Implémentation en ActionScript
Nous allons de nouveau appeler le service serviceListerComposants, mais cette fois-ci
avec le langage ActionScript. Pour cela, il convient de modifier quelque peu la procédure
executerService() :
public function executerService():void
{
var servRO:RemoteObject = new RemoteObject;
// Paramétrage
servRO.source = "ServComposants"
servRO.destination = "amfphp"
servRO.endpoint = "http://localhost/amfphp/gateway.php"
// Événements si succès ou erreur
servRO.serviceListerComposants.addEventListener("result", resultatOK);
servRO.serviceListerComposants.addEventListener("fault", resultatKO)
// Exécution de la méthode
servRO.serviceListerComposants()
}
Nous n’utilisons pas ici les méthodes getOperation() et send() pour exécuter le service
serviceListerComposants. En effet, nous préférons utiliser la syntaxe servRO.serviceLister
Composants (). Pour passer des paramètres au service, il suffit alors de les spécifier à
l’intérieur des parenthèses, comme suit :
servRO.serviceListerComposants(parametre1, parametre2)
Vous pouvez à présent tester l’application afin de vérifier que tout fonctionne correctement
(figure 13-6).
Figure 13-6
Résultat obtenu à l’aide du composant RemoteObject
=Flex3 FM.book Page 257 Mardi, 2. décembre 2008 3:32 15
Flex et PHP
CHAPITRE 13
257
Le générateur d’application de Flex Builder
L’une des grandes nouveautés de Flex Builder 3 est la possibilité de générer automatiquement l’interface graphique et le service PHP associés à une table d’une base de données.
Voici la marche à suivre pour cela :
1. Créez un nouveau projet nommé listerComposant et sélectionnez PHP pour le paramètre Application server type (figure 13-7).
Figure 13-7
Création d’un nouveau projet utilisant la technologie PHP
2. Spécifiez le répertoire racine de votre serveur web (pour EasyPHP, il s’agit du chemin
d’accès au répertoire www) ainsi que son URL (généralement http://localhost).
Cliquez ensuite sur le bouton Validate Configuration (figure 13-8).
3. Le nouveau projet est désormais créé et il faut à présent le connecter à une source de
données. Pour cela, sélectionnez le menu Data de Flex Builder et choisissez l’option
Create application from database… Dans la fenêtre qui s’ouvre alors, sélectionnez le
projet précédemment créé et spécifiez la connexion à la base de données souhaitée à
l’aide du champ Connection. Après avoir testé la connexion (en cliquant sur le bouton
Test Connexion), renseignez le champ Table en indiquant le nom de la table de la
base de données qui fera l’objet du développement. Pour notre exemple, nous avons
choisi la table tb_composant (figure 13-9). Le champ Primary key permet de spécifier
le champ de la table servant de clé primaire.
=Flex3 FM.book Page 258 Mardi, 2. décembre 2008 3:32 15
258
Comprendre Flex 3
PARTIE I
Figure 13-8
Configuration des paramètres du serveur web
Figure 13-9
Paramétrage de la base de données et sélection de la table
=Flex3 FM.book Page 259 Mardi, 2. décembre 2008 3:32 15
Flex et PHP
CHAPITRE 13
259
4. Cliquez ensuite sur le bouton Next. Une nouvelle fenêtre apparaît alors, vous permettant de définir le nom et le lieu de stockage du fichier PHP contenant les services
nécessaires (figure 13-10).
Figure 13-10
Paramétrage du fichier PHP
5. Cliquez à nouveau sur le bouton Next et dans la nouvelle fenêtre qui s’ouvre, spécifiez
éventuellement un critère de filtre sur une colonne précise de la table (figure 13-11).
6. Cliquez enfin sur le bouton Finish. Flex Builder va alors générer les interfaces et
services nécessaires à la gestion des données contenues dans la table :
– Liste des données ;
– Ajout ;
– Suppression ;
– Modification ;
– Recherche de données.
À première vue, tout semble parfait. Nous disposons d’une interface dans laquelle nous
pouvons visualiser la liste des composants et procéder aux opérations de base : ajout,
suppression et modification (figure 13-12).
=Flex3 FM.book Page 260 Mardi, 2. décembre 2008 3:32 15
260
Comprendre Flex 3
PARTIE I
Figure 13-11
Spécification d’un critère de filtre sur une colonne de la table
Figure 13-12
Interface générée par Flex Builder
=Flex3 FM.book Page 261 Mardi, 2. décembre 2008 3:32 15
Flex et PHP
CHAPITRE 13
261
Si nous naviguons dans le composant ViewStack de l’application, nous remarquons la
présence d’un formulaire permettant la saisie des informations nécessaires à la création
d’un composant informatique (figure 13-13).
Figure 13-13
Formulaire d’ajout d’un composant informatique
Pour le moment, tout cela est assez satisfaisant. Analysons à présent le code. La première
chose que l’on peut remarquer en sélectionnant le mode source pour le fichier MXML,
est l’abondance de commentaires au début du fichier, lesquels favorisent une bonne
compréhension de ce qui a été réalisé par le générateur. Si nous nous aventurons dans le
fichier ActionScript tb_composant.as, nous voyons également de nombreux commentaires
expliquant le rôle et le fonctionnement de chaque procédure et fonction.
Si le code présenté ici n’est pas très complexe pour les néophytes en ActionScript, il
demande tout de même quelques précisions. L’emploi du composant HTTPService permet
de réaliser l’appel des services PHP décrits dans le fichier tb_composant.php situé dans le
répertoire bin-debug de l’application. C’est à partir d’ici que les choses se compliquent
car pour les non-initiés au langage PHP, le fichier tb_composant.php est assez difficile à
comprendre.
Si nous faisons la synthèse de tout cela, nous pouvons dire que le générateur est assez
simple d’utilisation mais que le code généré demande tout de même certaines connaissances et une certaine maîtrise des langages ActionScript et PHP. Cette complexité du
code peut dérouter les utilisateurs débutants et c’est l’un des points négatifs que nous
pouvons soulever.
=Flex3 FM.book Page 262 Mardi, 2. décembre 2008 3:32 15
262
Comprendre Flex 3
PARTIE I
Par ailleurs, le résultat final est concluant. Nous disposons en effet d’une application
fonctionnelle, réalisée en quelques clics de souris seulement, même si elle ne concerne
qu’une seule table de notre base de données. Pour les autres tables, il faudra procéder de
la même manière et créer une nouvelle connexion à une source de données en choisissant
une autre table de la base. La fusion de plusieurs tables n’est donc pas possible au sein
d’une même interface, ce qui est tout de même assez gênant.
En résumé
Au cours de ce chapitre, nous avons vu qu’il est assez aisé de combiner des services PHP
avec une application Flex grâce aux composants HTTPService et RemoteObject. Nous avons
ouvert une porte sur la réécriture d’applications PHP existantes vers une application plus
dynamique grâce au framework Flex. Flex Builder propose certes un générateur automatique d’interface homme-machine et de services PHP, mais nous vous conseillons de
développer vous-même ces éléments. En effet, vous en connaîtrez ainsi les subtilités et
cela vous permettra de prévenir tout dysfonctionnement, dont la maîtrise vous échapperait
en utilisant la génération automatique.
Dans le chapitre suivant, nous allons mettre de côté PHP pour nous consacrer à l’étude du
projet BlazeDS d’Adobe, dédié à la communication entre une application Flex et les
services Java, ainsi qu’à l’utilisation de données en temps réel (une application de tchat
par exemple).
=Flex3 FM.book Page 263 Mardi, 2. décembre 2008 3:32 15
14
BlazeDS :
ouverture Open Source
vers le monde J2EE
et la communication
d’applications
Dans ce chapitre, nous allons faire connaissance avec l’un des produits Open Source
d’Adobe : le projet BlazeDS. Grâce à lui, nous pourrons, entre autres, faire appel à des
méthodes J2EE de la couche métier et réaliser des échanges de données en temps « réel »
entre deux applications Flex.
Le projet BlazeDS
Pour accéder aux méthodes Java et réaliser l’échange de données en temps « réel » entre
deux applications RIA (data push), nous devions jusqu’à présent utiliser la solution
serveur LiveCycle Data Service ES d’Adobe dont le prix d’acquisition nécessitait un
investissement supplémentaire à l’utilisation de la plate-forme de développement Flex. Il
existe certes une version gratuite de cet applicatif, la version LiveCycle Data Service ES
Express, mais elle ne peut être utilisée sur un environnement de production.
C’est pourquoi le projet BlazeDS a vu le jour, offrant au développeur Flex la possibilité
d’utiliser les briques de communication avec les méthodes Java et le push de données du
LiveCyle Data Service ES sous licence Open Source (LGPL v3).
=Flex3 FM.book Page 264 Mardi, 2. décembre 2008 3:32 15
264
Comprendre Flex 3
PARTIE I
La technologie de communication utilisée par le serveur BlazeDS est le protocole AMF
(Action Message Format) permettant l’échange de données au format binaire, jugé plus
rapide que l’échange de données au format texte (XML).
Les différentes versions du serveur BlazeDS
Le serveur BlazeDS est disponible sous deux versions : la version BlazeDS Turnkey et
une version binaire.
La version BlazeDS Turnkey
Pour être fonctionnel, BlazeDS doit être déployé sur le serveur web conteneur de servlets
bien connu des développeurs J2EE : le serveur Tomcat.
La version BlazeDS Turnkey propose aux utilisateurs le téléchargement d’une version
« prête à l’emploi » contenant le serveur Tomcat et les services BlazeDS déjà déployés et
configurés sur ce serveur.
La version binaire
Cette version est à privilégier si vous disposez déjà d’un serveur Tomcat sur votre
machine. En effet, la version binaire consiste à télécharger l’archive BlazeDS.war pouvant
ainsi être déployée sur votre serveur Tomcat.
Dans notre cas, nous allons privilégier l’usage de la version BlazeDS Turnkey proposant
une facilité d’installation non négligeable et permettant une meilleure approche du
serveur BlazeDS. Néanmoins, si vous souhaitez déployer vous-même l’archive du
serveur BlazeDS sur votre serveur Tomcat, nous vous conseillons de consulter le lien
suivant, qui vous apportera toute les précisions nécessaires pour mener à bien son
déploiement : http://opensource.adobe.com/wiki/display/blazeds/Installation+Guide.
Installation
Avant de procéder à l’installation du serveur BlazeDS, il convient de vérifier certains
prérequis.
Prérequis
Pour que le serveur BlazeDS Turnkey soit fonctionnel, Java SDK (Software Development
Kit) doit être installé et correctement configuré sur votre machine. Par ailleurs, la variable
d’environnement JAVA_HOME doit être spécifiée.
Installation du SDK
Pour plus de détails sur l’installation de Java SDK, nous vous invitons à vous reporter au chapitre 3 de cet
ouvrage ou à consulter le site web de Sun Microsytems à l’adresse suivante : http://java.sun.com/
javase/downloads/index.jsp.
=Flex3 FM.book Page 265 Mardi, 2. décembre 2008 3:32 15
BlazeDS : ouverture Open Source vers le monde J2EE et la communication d’applications
CHAPITRE 14
265
Afin de nous assurer que notre environnement est correctement configuré, nous allons
procéder à la saisie de quelques lignes de commande MS-DOS. Voici celle à saisir pour
vérifier la présence de Java :
java –version
Nous obtenons alors le résultat suivant. Notez que l’affichage de ce résultat peut être
différent en fonction de la version de Java installée sur votre système :
java version version de java « 1.6.0_05 »
Java™ SE Runtime Environnement (build 1.6.0_05-b13)
Java HotSpot™ Vlient VM (build 10.0-b19, mixed mode, sharing)
Pour vérifier la présence de la variable d’environnement JAVA_HOME, nous saisissons
ensuite la ligne de commande suivante :
Echo %JAVA_HOME%
La valeur spécifiée dans la variable d’environnement doit s’afficher à l’écran. Dans le cas
contraire, ajoutez-la comme nous l’avons vu au chapitre 3.
Si ces tests sont concluants, vous pouvez passer à l’installation du serveur BlazeDS.
L’installation pas à pas
L’installation du serveur BlazeDS Turnkey comprend trois phases distinctes :
1. Le téléchargement de l’archive du serveur à partir du site d’Adobe : http://open
source.adobe.com/wiki/display/blazeds/Release+Builds.
2. La décompression de l’archive sur votre disque dur.
3. Le renommage du répertoire issu de la décompression en blazeds.
Dans la mesure où le répertoire d’installation peut être différent en fonction de la configuration de votre machine, nous nommerons par convention {blazeds} le répertoire
racine du serveur BlazeDS correspondant au chemin d’installation que vous avez choisi.
Le serveur Tomcat
Tomcat est un conteneur d’applications Java également appelées servlets. Souvent associé
au serveur web Apache faisant office de serveur de présentation, Tomcat est chargé de gérer
la partie dynamique de l’application J2EE par la prise en charge des requêtes effectuées
sur les servlets.
Nous ne détaillerons pas davantage l’étude de ce serveur dans cet ouvrage. Si vous
souhaitez en savoir plus, nous vous conseillons de consulter le site de l’éditeur (http://
jakarta.apache.org/tomcat) ou de vous référer à l’ouvrage Java – (1) Premières applications
professionnelles en Java d’Emmanuel Puybaret publié aux éditions Eyrolles.
=Flex3 FM.book Page 266 Mardi, 2. décembre 2008 3:32 15
266
Comprendre Flex 3
PARTIE I
Configuration
Avant de démarrer le serveur Tomcat , il convient de créer une variable d’environnement
CATALINA_HOME pointant vers le répertoire racine de Tomcat, c’est-à-dire le répertoire
{blazeds}\tomcat. Cette variable d’environnement doit être spécifiée afin d’indiquer au
système l’endroit où se situent les fichiers nécessaires à la bonne exécution du serveur
Tomcat. Pour cela, suivez les indications fournies au chapitre 3 dans la section des prérequis
et saisissez les paramètres suivants (figure 14-1) :
• Nom de la variable : CATALINA_HOME ;
• Valeur de la variable : répertoire racine de Tomcat.
Terminez ensuite en cliquant sur le bouton OK et fermez la fenêtre de propriété du poste
de travail.
Figure 14-1
Création de la variable d’environnement CATALINA_HOME
Démarrage du serveur
Avant de lancer le serveur Tomcat, vous devez démarrer le serveur de base de données
HSQLDB. Il a été installé avec le serveur BlazeDS, et est indispensable au bon fonctionnement de certaines applications de démonstration livrées avec le serveur BlazeDS Turnkey.
Pour cela, placez-vous dans le répertoire sampledb du répertoire racine de BlazeDS et
double-cliquez sur le script startdb.bat pour l’exécuter (figure14-2).
=Flex3 FM.book Page 267 Mardi, 2. décembre 2008 3:32 15
BlazeDS : ouverture Open Source vers le monde J2EE et la communication d’applications
CHAPITRE 14
267
Figure 14-2
Démarrage du server HSQLDB
Pour exécuter à présent le serveur Tomcat, placez-vous dans le sous-répertoire bin de son
répertoire racine et exécutez le script startup.bat (figure 14-3).
Figure 14-3
Démarrage du serveur Tomcat
Arrêt du serveur
Pour arrêter le serveur Tomcat, il faut tout d’abord exécuter le script shutdown.bat situé
dans le sous-répertoire bin de Tomcat. Une fois ceci fait, stoppez le serveur de base de
données HSQLDB en exécutant le script stopdb.bat situé dans le répertoire {blazeds}/
sampledb.
=Flex3 FM.book Page 268 Mardi, 2. décembre 2008 3:32 15
268
Comprendre Flex 3
PARTIE I
Test d’installation
Après avoir démarré le serveur Tomcat, il est possible de vérifier le bon fonctionnement
de BlazeDS en saisissant l’URL suivante dans la barre d’adresse du navigateur web
(figure 14-4) : http://localhost:8400/samples/.
Cette adresse nous donne accès à une multitude d’applications de tests situées dans le
répertoire webapps/samples de Tomcat. Nous vous laissons le soin de les découvrir avant
d’entrer dans le détail de l’interaction entre le serveur BlazeDs et les méthodes de classe
J2EE.
Figure 14-4
Applications de tests
Interaction avec les méthodes J2EE
Étudions à présent le processus d’exécution d’une méthode J2EE ainsi qu’un exemple
d’application qui vous permettra de mieux comprendre l’interaction entre une application
Flex et cette classe Java.
=Flex3 FM.book Page 269 Mardi, 2. décembre 2008 3:32 15
BlazeDS : ouverture Open Source vers le monde J2EE et la communication d’applications
CHAPITRE 14
269
Processus d’exécution
Pour pouvoir exécuter une méthode J2EE (contenue dans une classe J2EE) à l’aide de
BlazeDS, elle doit être connue du serveur. Pour cela, il convient de respecter une certaine
organisation :
Figure 14-5
Processus d’exécution d’une méthode J2EE
=Flex3 FM.book Page 270 Mardi, 2. décembre 2008 3:32 15
270
Comprendre Flex 3
PARTIE I
• Les classes J2EE doivent être déployées dans le répertoire {blazeds}\tomcat\webapps\
blazeDS\webapps\classes.
• Les classes J2EE doivent ensuite être spécifiées dans le fichier remoting-config.xml,
situé dans le répertoire {blazeds}\tomcat\webapps\blazeDS\WEB-INF\flex, qui joue le
rôle de routeur vers les classes J2EE.
Ce fichier contient ce que l’on appelle des destinations, pointant vers chaque classe présente
sur le serveur BlazeDS. Le fichier remoting-config.xml est donc le point d’entrée de
chaque requête de demande d’exécution de méthodes. Pour exécuter une méthode, il faut
en quelque sorte montrer patte blanche en fournissant le nom de la destination ainsi que
le nom de la méthode J2EE à exécuter.
La présence de la destination dans le fichier remoting-config.xml est ensuite vérifiée. Si
elle est bien détectée, la requête est redirigée vers la classe liée pour permettre la recherche
et l’exécution de la méthode. La figure 14-5 résume ce processus.
Exemple d’application
Illustrons à présent ce concept, en créant notre propre méthode J2EE et en l’appelant dans
un projet Flex. Le but de cette méthode sera d’additionner deux entiers et d’en retourner
le résultat.
Important
Avant tout développement, nous vous conseillons d’arrêter les serveurs Tomcat et HSQLDB. En effet, ceci
permet de faciliter le déploiement des applications. Même si le serveur est capable de déployer une application alors qu’il est toujours en fonctionnement, il est conseillé de l’arrêter, afin que le déploiement se
réalise proprement.
Création de la classe J2EE
La première étape consiste à créer un fichier Java nommé ClasseJ2ee.java contenant la
logique applicative de la méthode. Nous vous suggérons de créer ce fichier à la racine de
votre disque dur à l’aide du Bloc-notes de Windows si vous ne disposez pas d’un environnement de développement Java. Néanmoins, si vous désirez utiliser Java et Flex de
manière plus poussée, nous vous recommandons fortement d’installer sur votre poste un
IDE tel que Eclipse ou NetBeans, car ils contiennent un ensemble de fonctionnalités
propres au développement Java. Voici le code du fichier ClasseJ2ee.java :
public class ClasseJ2ee{
// Méthode
public int calculer (int a, int b)
{
return (a + b);
}
}
=Flex3 FM.book Page 271 Mardi, 2. décembre 2008 3:32 15
BlazeDS : ouverture Open Source vers le monde J2EE et la communication d’applications
CHAPITRE 14
271
Une fois ce fichier créé, il convient de le compiler afin d’obtenir un fichier binaire portant
l’extension .class, lequel sera ensuite déployé sur le serveur BlazeDS.
1. Ouvrez l’invite de commandes MS-DOS.
2. Placez-vous dans le répertoire du fichier Java précédemment créé.
3. Saisissez ensuite la commande de compilation suivante :
javac ClasseJ2ee.java
Le résultat de cette compilation est la création du fichier ClasseJ2ee.class. Notre classe
créée, nous allons à présent procéder à la configuration du serveur BlazeDS.
Configuration du serveur BlazeDS
La configuration du serveur se déroule en deux étapes : la configuration du fichier
« passerelle » remote-config.xml permettant d’orienter la requête d’exécution d’une
méthode J2EE vers la classe Java la contenant, et le déploiement de la classe J2EE.
Le fichier remoting-config.xml
Comme nous l’avons vu, ce fichier, situé dans le répertoire {blazeds}\tomcat\webapps\
blazeds\WEB-INF\flex, permet de rediriger la requête de demande d’exécution de la
méthode J2EE vers la classe qui la contient.
<?xml version="1.0" encoding="UTF-8"?>
<service id="remoting-service"
class="flex.messaging.services.RemotingService">
<adapters>
<adapter-definition id="java-object" class="flex.messaging.services
➥.remoting.adapters.JavaAdapter" default="true"/>
</adapters>
<default-channels>
<channel ref="my-amf"/>
</default-channels>
<destination id="destJ2ee">
<properties>
<source>ClasseJ2ee</source>
<scope>application</scope>
</properties>
</destination>
</service>
Une nouvelle destination (destJ2ee) pointant vers notre classe ClasseJ2ee.class a été créée
en spécifiant le nom de la classe dans la balise <source> des propriétés de la destination.
=Flex3 FM.book Page 272 Mardi, 2. décembre 2008 3:32 15
272
Comprendre Flex 3
PARTIE I
Déploiement de la classe J2EE
Le déploiement de la classe J2EE consiste tout simplement à copier le fichier ClasseJ2ee
.class dans le répertoire {blazeds}\tomcat\webapps\blazeds\WEB-INF\classes.
Vous pouvez à présent redémarrer le serveur Tomcat afin de vous assurer qu’aucune erreur
n’est survenue lors du chargement de la classe.
Création du projet Flex
Nous allons maintenant nous pencher sur la création du projet Flex. Il sera chargé de
réaliser le front end de l’application et de faire appel à méthode J2EE :
1. Créez un nouveau projet Flex que vous nommerez BzJ2ee.
2. Dans la fenêtre qui s’ouvre alors (figure 14-6), sélectionnez la technologie serveur
J2EE, puisque nous allons faire appel à une méthode J2EE. Activez également
l’option LiveCycle Data Services, car BlazeDS se substitue à ce serveur. Cliquez sur
le bouton Next.
Figure 14-6
Configuration du projet
=Flex3 FM.book Page 273 Mardi, 2. décembre 2008 3:32 15
BlazeDS : ouverture Open Source vers le monde J2EE et la communication d’applications
CHAPITRE 14
273
3. Précisez ensuite le chemin d’installation du serveur BlazeDS. Dans la mesure où
nous n’allons pas utiliser LiveCycle Data Services, désactivez l’option Use default
location for local LiveCycle Data Services Server et spécifiez les différents paramètres
du serveur (figure 14-7) :
– Root folder : {blazeds}\tomcat\webapps\blazeds ;
– Root URL : http://localhost:8400/blazeds ;
– Context root : /blazeds.
Répertoire
Le répertoire de compilation sera situé dans le répertoire {blazeds}\tomcat\webapps\blazeds et non
dans le répertoire de l’application, comme c’est le cas habituellement.
Figure 14-7
Configuration du serveur J2EE
4. Cliquez enfin sur le bouton Finish pour terminer la création du projet Flex.
Notre projet créé, nous mettons en place l’interface graphique (figure 14-8).
=Flex3 FM.book Page 274 Mardi, 2. décembre 2008 3:32 15
274
Comprendre Flex 3
PARTIE I
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Panel x="10" y="10" width="250" height="200" layout="absolute" title="Addition">
<mx:Form x="10" y="10" height="107" width="210" horizontalScrollPolicy="off"
➥verticalScrollPolicy="off">
<mx:FormItem label="Entier A: ">
<mx:TextInput width="78" id="txt_entiera"/>
</mx:FormItem>
<mx:FormItem label="Entier B:">
<mx:TextInput width="78" id="txt_entierb"/>
</mx:FormItem>
<mx:FormItem label="Résultat :">
<mx:TextInput width="79" id="txt_resultat"/>
</mx:FormItem>
</mx:Form>
<mx:Button x="10" y="128" label="Calculer" width="210" />
</mx:Panel>
</mx:Application>
Figure 14-8
Interface graphique du projet
La tâche suivante va consister à configurer le composant RemoteObject afin de réaliser
l’appel de la méthode J2EE.
Exécution de la méthode J2EE
Maintenant que notre interface graphique est terminée, la dernière étape va consister à
configurer le composant RemoteObject afin d’exécuter la méthode Java :
<mx:RemoteObject id="roMethodeJ2ee"
destination="destJ2ee"
result="resultatOK(event)"
fault="resultatKO(event)" showBusyCursor="true">
</mx:RemoteObject>
=Flex3 FM.book Page 275 Mardi, 2. décembre 2008 3:32 15
BlazeDS : ouverture Open Source vers le monde J2EE et la communication d’applications
CHAPITRE 14
275
La propriété destination du composant RemoteObject doit prendre la valeur de la balise
destination spécifiée dans le fichier remote-config.xml. En effet, c’est à partir de la
concordance des deux propriétés que la méthode Java sera exécutée.
La touche finale consiste à écrire les procédures ActionScript permettant de réaliser l’appel
de la méthode Java :
<mx:Script>
<![CDATA[
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.controls.Alert;
public function executerMethodeJ2ee():void
{
var a:int = int(txt_entiera.text);
var b:int = int(txt_entierb.text);
roMethodeJ2ee.calculer(a,b);
}
public function resultatOK(e:ResultEvent):void
{
txt_resultat.text = e.result.toString();
}
public function resultatKO(e:FaultEvent):void
{
Alert.show(e.fault.faultString);
}
]]>
</mx:Script>
Il convient par ailleurs de ne pas oublier de déclencher la procédure executerMethode
J2ee() lorsque l’utilisateur clique sur le bouton Calculer :
<mx:Button x="10" y="128" label="Calculer" width="210" click="executerMethodeJ2ee()"/>
Test de l’application
Pour tester l’application, assurez-vous tout d’abord que le serveur Tomcat est démarré,
puis saisissez l’URL suivante dans la barre d’adresse de votre navigateur web :
http://localhost:8400/blazeds/BzJ2ee-debug/BzJ2ee.html.
Vous constatez que l’application est bien appelée et s’exécute correctement (figure 14-9).
Nous venons de réaliser une première application faisant appel à une méthode Java. Le
plus compliqué est de créer correctement la classe Java et la méthode et de configurer le
serveur BlazeDS. L’appel du service via l’utilisation du composant RemoteObject reste,
quant à lui, identique à ce que nous avons pu réaliser au chapitre précédent avec PHP.
=Flex3 FM.book Page 276 Mardi, 2. décembre 2008 3:32 15
276
Comprendre Flex 3
PARTIE I
Figure 14-9
Test de l’application
Nous allons à présent aborder un autre aspect du serveur BlazeDS qui nous permet de
créer des applications « communicantes ».
Échanger des données en temps réel
L’exemple le plus communément développé pour illustrer le mécanisme d’échange de
données en temps réel avec le serveur BlazeDS est une application de messagerie instantanée (chat). Pour nous démarquer un peu, nous allons utiliser ce procédé, mais en en
détourner l’usage, afin de réaliser une application capable de piloter un « robot » virtuel.
Il sera matérialisé par un petit carré rouge au centre de l’interface graphique. L’utilisateur
disposera de quatre boutons, représentant les quatre directions, qui lui permettront de
déplacer le carré.
Comme nous vous l’avons indiqué, nous allons utiliser le procédé de la messagerie
instantanée pour piloter notre robot. Pour qu’une communication soit définie comme
telle, la présence de deux interlocuteurs est nécessaire. Nous devons donc exécuter deux
instances d’applications. Nous allons à nouveau utiliser une destination qui servira ici de
point d’échange entre les deux applications. Chaque application sera connectée à cette
destination afin d’en être à l’écoute et d’être informée des modifications apportées par
chacune d’entre elles. L’échange est donc réalisé selon le principe suivant :
1. Une destination d’échange est créée sur le serveur.
2. Chaque application se connecte à cette destination et se met à son écoute.
3. L’application A envoie un message à la destination.
4. La destination reçoit le message.
5. L’application B, à l’écoute de la destination, est informée de la notification de réception
d’un nouveau message et le récupère.
6. L’application B traite le message.
C’est sur ce principe que nous allons offrir la possibilité à une application A de piloter le
robot d’une application B et inversement. Chaque direction correspondra à une lettre :
=Flex3 FM.book Page 277 Mardi, 2. décembre 2008 3:32 15
BlazeDS : ouverture Open Source vers le monde J2EE et la communication d’applications
CHAPITRE 14
277
• Haut : « H » ;
• Bas : « B » ;
• Droite : « D » ;
• Gauche : « G ».
Par ailleurs, nous devrons créer une destination sur le serveur et mettre à l’écoute les deux
applications. Bien entendu, chaque application aura également la possibilité d’envoyer
un message à la destination afin de faire bouger le robot. Ainsi, si l’application A envoie
le message « H » à la destination, l’application B interceptera le message, l’analysera
grâce à procédure d’analyse et déterminera que « H » signifie « déplacer le robot vers le
haut ».
Création du projet
Pour commencer, nous allons créer un nouveau projet nommé robot. Nous procéderons
de la même manière que pour créer un projet faisant appel à l’exécution d’une méthode
J2EE, car nous allons avoir besoin du serveur BlazeDS pour permettre l’échange de
données entre les applications. La première étape va consister à créer l’interface graphique :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Panel x="10" y="10" width="250" height="335" layout="absolute">
<mx:Canvas x="10" y="10" width="210" height="200" backgroundColor="#BFB5B5">
<!-- ROBOT -->
<mx:Canvas x="90" y="81" width="30" height="30" backgroundColor="#F90101"
➥cornerRadius="5" borderStyle="solid" id="irobot">
</mx:Canvas>
</mx:Canvas>
<mx:Button
<mx:Button
<mx:Button
<mx:Button
x="82.5" y="218" label="Haut" width="70" id="btn_haut"/>
x="82.5" y="263" label="Bas" width="70" id="btn_bas"/>
x="153" y="241" label="Droite" width="70" id="btn_droite"/>
x="10" y="241" label="Gauche" width="70" id="btn_gauche"/>
</mx:Panel>
</mx:Application>
La composition de cette interface est assez simple (figure 14-10) :
• un Canvas définissant le périmètre de déplacement du robot ;
• un Canvas représentant le robot ;
• quatre boutons représentant les quatre directions.
=Flex3 FM.book Page 278 Mardi, 2. décembre 2008 3:32 15
278
Comprendre Flex 3
PARTIE I
Figure 14-10
Interface de pilotage du robot
Configuration du serveur
La configuration du serveur consiste à créer dessus une destination. Pour cela, placez-vous
tout d’abord dans le répertoire {blazeds}\tomcat\webapps\blazeds\WEB-INF\flex et ouvrez
le fichier service-config.xml, fichier de configuration principal du serveur BlazeDS. Il
fait appel au fichier messaging-config.xml :
<services>
<service-include file-path="remoting-config.xml"/>
<service-include file-path="proxy-config.xml"/>
<service-include file-path="messaging-config.xml"/>
</services>
C’est ce fichier qui va particulièrement nous intéresser, car c’est à cet endroit que nous
allons créer notre destination. Avant d’en visualiser le contenu, poursuivons notre lecture
du fichier service-config.xml et attardons-nous sur les lignes de code suivantes :
<channel-definition id="my-polling-amf" class="mx.messaging.channels.AMFChannel">
<endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/
➥amfpolling" class="flex.messaging.endpoints.AMFEndpoint"/>
<properties>
<polling-enabled>true</polling-enabled>
<polling-interval-seconds>4</polling-interval-seconds>
</properties>
</channel-definition>
Vous remarquez la présence du canal my-polling-amf. C’est lui qui sera utilisé pour
l’échange de données en temps réel, car il est spécifié comme service par défaut dans le
fichier messaging-config.xml. Notons que le temps de consultation de la destination est
défini à 4 secondes. Pour plus de réactivité d’échange, il est possible de réduire cette valeur.
=Flex3 FM.book Page 279 Mardi, 2. décembre 2008 3:32 15
BlazeDS : ouverture Open Source vers le monde J2EE et la communication d’applications
CHAPITRE 14
279
Intéressons-nous à présent au fichier messaging-config.xml. Comme nous venons de le
spécifier, le canal utilisé par défaut est my-polling-amf. Notre travail va donc se résumer à
créer une destination, que nous nommerons bougerrobot, et qui fera appel à ce canal de
communication comme suit :
<?xml version="1.0" encoding="UTF-8"?>
<service id="message-service"
class="flex.messaging.services.MessageService">
<adapters>
<adapter-definition id="actionscript" class="flex.messaging.services
➥.messaging.adapters.ActionScriptAdapter" default="true" />
<!-- <adapter-definition id="jms" class="flex.messaging.services
➥.messaging.adapters.JMSAdapter"/> -->
</adapters>
<default-channels>
<channel ref="my-polling-amf"/>
</default-channels>
<destination id="bougerrobot"/>
</service>
Le serveur est à présent correctement configuré. L’étape suivante consiste à implémenter
les méthodes d’écoute et d’échange avec la destination.
<mx:Producer> et <mx:Consumer> : les composants émetteurs
et récepteurs
Le composant <mx:Consumer> permet à l’application de se connecter à une destination afin
d’en être à l’écoute et de réceptionner les messages qu’elle reçoit. À l’inverse, le composant
<mx:Producer> permet de transmettre des messages à la destination.
Nous allons donc utiliser ces composants pour nous connecter à la destination bougerrobot,
afin de détecter d’une part tout message qui pourrait nous être transmis via une application
distante, et d’autre part de communiquer avec elle. La communication sera donc bidirectionnelle : nous pourrons transmettre et recevoir des informations, ce qui nous permettra de
piloter le robot de l’application distante, et l’utilisateur de cette application pourra à son
tour piloter notre robot. Voici le code d’implémentation de l’écouteur :
<mx:Consumer id="ecouteur" destination="bougerrobot" message="receptionner
➥(event.message)"/>
Nous avons spécifié la destination d’écoute et une action à réaliser en cas de réception
d’un message. Cette action permettra d’interpréter le message reçu et de déplacer le robot
en conséquence.
=Flex3 FM.book Page 280 Mardi, 2. décembre 2008 3:32 15
280
Comprendre Flex 3
PARTIE I
Il convient également d’initialiser l’écoute dès la fin de la création de l’application en
faisant appel à la méthode subscribe() du composant Consumer :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥creationComplete="emetteur.subscribe()">
Voyons à présent la mise en place de l’émetteur qui nous permettra de déplacer le robot
de l’application distante :
<mx:Producer id="emetteur" destination="bougerrobot"/>
Nous avons simplement connecté l’émetteur à la destination bougerrobot. L’envoi du
message sera réalisé grâce à la méthode send() du composant Producer dont nous allons
voir de suite l’utilisation.
Les procédures de communication
Nous allons à présent mettre en place les procédures permettant de réaliser l’échange de
données et d’interpréter le message reçu.
Envoyer un message
Comme nous venons de l’évoquer, l’envoi d’un message s’effectue via la méthode send()
du composant Producer. Nous allons donc écrire une procédure, que nous nommerons
envoyer(), qui transmettra à la destination bougerrobot la lettre correspondant à la direction
de déplacement du robot choisi par l’utilisateur :
<mx:Script>
<![CDATA[
import mx.messaging.messages.AsyncMessage;
import mx.messaging.messages.IMessage;
private function envoyer(direction:String):void{
var messageAsynchrone:IMessage = new AsyncMessage();
messageAsynchrone.body.chatMessage = direction;
emetteur.send(messageAsynchrone);
}
]]>
</mx:Script>
Cette procédure crée un message asynchrone dont la propriété body.chatMessage contient
la direction à transmettre à la destination. Cette dernière est alors avertie de la transmission
d’un nouveau message. Voyons à présent comment récupérer ce message.
Recevoir un message
Lors de la mise en place du composant <mx:Consumer>, nous avons spécifié une action à
réaliser à chaque réception d’un message de la part de la destination. Le code de cette
action est le suivant :
=Flex3 FM.book Page 281 Mardi, 2. décembre 2008 3:32 15
BlazeDS : ouverture Open Source vers le monde J2EE et la communication d’applications
CHAPITRE 14
281
private function receptionner(messageDestination:IMessage):void{
var directionRecue:String = messageDestination.body.chatMessage;
switch (directionRecue) {
case "G" : gauche();
break;
case "D" : droite();
break;
case "H" : haut();
break;
case "B" : bas();
break;
}
}
Nous récupérons la propriété body.chatMessage du message reçu et nous exécutons une
procédure de déplacement en fonction de la lettre reçue.
Pour terminer, voici le code des quatre procédures permettant de déplacer le robot :
public function gauche():void
{
irobot.x = irobot.x-5
}
public function droite():void
{
irobot.x = irobot.x+5
}
public function haut():void
{
irobot.y = irobot.y-5
}
public function bas():void
{
irobot.y = irobot.y+5
}
Pour chaque destination, nous récupérons la position actuelle à laquelle nous ajoutons ou
soustrayons 5 pixels. Libre à vous de modifier cette valeur en fonction de vos préférences.
=Flex3 FM.book Page 282 Mardi, 2. décembre 2008 3:32 15
282
Comprendre Flex 3
PARTIE I
Test de l’application
Le moment est venu de tester notre application. Pour cela, exécutez-la deux fois dans votre
navigateur web, afin de créer deux interlocuteurs. En cliquant sur les différents boutons
de l’interface, nous voyons que l’échange des données s’effectue correctement (figure 14-11).
Figure 14-11
Exécution de l’application
En résumé
Dans ce chapitre, nous avons abordé les deux principales opérations pouvant être réalisées
à l’aide du serveur BlazeDS, à savoir l’appel de méthodes Java et l’échange de données
entre plusieurs applications. Adobe mise beaucoup sur ce serveur en nous le proposant en
Open Source malgré son offre de distribution du serveur LiveCycle Data Service ES.
Néanmoins, BlazeDS ne permet pas d’effectuer l’ensemble des fonctionnalités proposées
par son concurrent payant (citons par exemple la génération de fichiers PDF ou la présence
d’options de déploiement avancées…).
Vous êtes désormais en mesure de créer des applications dynamiques capables d’interagir
avec la couche métier développée en Java, ce qui améliorera l’interactivité de vos applications en offrant la possibilité d’interaction entre deux applications Flex.
=Flex3 FM.book Page 283 Mardi, 2. décembre 2008 3:32 15
BlazeDS : ouverture Open Source vers le monde J2EE et la communication d’applications
CHAPITRE 14
283
Ce chapitre nous également permis d’approfondir notre étude des méthodes de communication avec la couche métier. Nous avons vu au chapitre précédent que pour communiquer
avec la couche métier PHP, il convenait d’utiliser le protocole AMF couplé au composant
RemoteObject afin d’obtenir des résultats plus concluants (rapidité, sérialisation des
données…). Pour accéder aux méthodes Java, nous observons le même mode opératoire.
Par conséquent, nous pouvons en déduire que le couple RemoteObject/AMF semble être le
mode le plus approprié pour communiquer avec la couche métier à condition que celle-ci
le permette.
=Flex3 FM.book Page 284 Mardi, 2. décembre 2008 3:32 15
=Flex3 FM.book Page 285 Mardi, 2. décembre 2008 3:32 15
15
Créer des applications
modulaires
Au cours de ce chapitre, vous allez utiliser des modules applicatifs afin de les intégrer au
sein d’une application Flex.
La notion de module
Un module est une application (fichier .swf) proposant un certain nombre de fonctionnalités
pouvant être intégrées à une autre application. En d’autres termes, si nous considérons
qu’une application Flex est un puzzle, un module est une pièce le constituant.
Les modules ne sont pas indépendants : ils ont impérativement besoin d’une application
pour pouvoir être exécutés. Il existe de nombreux avantages à l’utilisation de modules :
• une diminution de la taille de l’application principale ;
• une diminution du temps de chargement de l’application ;
• un découpage applicatif (module de comptabilité, module de vente en ligne…) ;
• une meilleure maintenance de l’application : chaque module étant indépendant, il est
possible d’y apporter des modifications sans remettre en cause la stabilité complète de
l’application ;
• une optimisation de la performance d’exécution de l’application : le module peut être
chargé et déchargé à volonté.
Un module se crée à partir d’un fichier MXML, tout comme une application Flex standard,
à la différence que la balise <mx:Application> est remplacée par la balise <mx:Module>.
=Flex3 FM.book Page 286 Mardi, 2. décembre 2008 3:32 15
286
Comprendre Flex 3
PARTIE I
C’est le seul élément qui différencie un module d’une application. Il est ensuite possible
d’y placer des composants et d’y décrire des procédures ActionScript, tout comme nous
le ferions pour une application Flex.
Créer un module
Afin de mieux comprendre la notion de module, nous vous proposons d’en créer un qui
soit capable de déterminer le nombre de caractères d’une chaîne saisie dans une zone de
texte. Voici la marche à suivre pour cela :
1. Créez un nouveau projet Flex à l’aide de Flex Builder 3 nommé module.
2. Dans ce projet, créez ensuite un fichier de type MXML Module, que vous nommerez
modLettre, en effectuant un clic droit sur le nom du projet et en sélectionnant New.
3. Dans la fenêtre qui s’ouvre alors, assurez-vous que l’option Do not optimize (module
can be loaded by multiple applications) est bien cochée afin que le module puisse
s’exécuter sur plusieurs applications (figure 15-1).
Figure 15-1
Création d’un module
=Flex3 FM.book Page 287 Mardi, 2. décembre 2008 3:32 15
Créer des applications modulaires
CHAPITRE 15
287
Notre module est désormais créé. Il convient à présent d’implémenter les composants et
procédures nécessaires à la réalisation de la tâche demandée (figure 15-2) :
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="400"
➥height="300">
<mx:Panel x="10" y="11" width="380" height="141" layout="absolute" title="Nombre de
➥lettres">
<mx:TextInput x="10" y="10" width="340" id="chaine_txt"/>
<mx:TextInput x="190" y="40" id="resultat_txt"/>
<mx:Button x="10" y="40" label="Calculer" click="resultat_txt.text =
➥String(chaine_txt.length)" id="btn_calculer"/>
</mx:Panel>
</mx:Module>
Figure 15-2
Interface graphique du module
Ainsi, quelques clics de souris et lignes de code suffisent pour créer un module entièrement
fonctionnel et prêt à être utilisé. Mais, avant cela, il convient de le compiler et de créer
une version de déploiement.
1. Effectuez un clic droit sur le nom du projet et sélectionnez Export.
2. Dans la fenêtre qui s’ouvre alors, indiquez que vous souhaitez réaliser une version de
déploiement (build release) en veillant à ne pas modifier les options spécifiées par
défaut.
=Flex3 FM.book Page 288 Mardi, 2. décembre 2008 3:32 15
288
Comprendre Flex 3
PARTIE I
À l’issue de l’exportation, vous pouvez voir qu’un nouveau dossier bin-release est
apparu dans l’arborescence du projet. Il contient le fichier modLettre.swf correspondant à
la version de déploiement du module.
Voyons à présent comment intégrer ce module dans une nouvelle application.
Intégrer un module dans une application
Nous allons ici créer un nouveau projet puis ajouter, dans son répertoire src, un dossier
modules qui contiendra l’ensemble des modules de notre application. Nous copierons
ensuite dans ce dossier le module du répertoire bin-release du précédent projet, puis
nous l’intégrerons à notre projet.
Charger les modules à l’aide du composant ModuleLoader
Pour charger un module dans une application, la première méthode consiste à utiliser le
composant ModuleLoader comme suit :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:ModuleLoader id="module" url="modules/modLettre.swf" >
</mx:ModuleLoader>
</mx:Application>
Grâce à la propriété url, nous spécifions le chemin du module permettant de le charger
automatiquement. Cependant, il est possible de gérer de façon plus poussée le chargement
des modules grâce à ActionScript, ce que nous allons voir dans la section suivante.
Gestion des modules avec ActionScript
Nous allons ici aborder la gestion du chargement/déchargement de modules à l’aide du
langage ActionScript.
Charger un module
Le chargement d’un module s’effectue très simplement à l’aide de la méthode loadModule()
du composant ModuleLoader :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
=Flex3 FM.book Page 289 Mardi, 2. décembre 2008 3:32 15
Créer des applications modulaires
CHAPITRE 15
289
import mx.modules.*;
public function chargerModule(adresse:String):void{
// Adresse du module
chargeurModule.url = adresse;
// Chargement du module
chargeurModule.loadModule();
}
]]>
</mx:Script>
<mx:ModuleLoader id="chargeurModule"> </mx:ModuleLoader>
<mx:Button x="427" y="10" label="Charger" id="btn_chargerModule"
➥click="chargerModule('modules/modLettre.swf')"/>
</mx:Application>
Décharger un module
Pour décharger un module, il suffit d’utiliser la méthode unload() du composant Module
Loader comme suit :
public function dechargerModule():void{
// Déchargement du module
chargeurModule.unloadModule();
}
Gérer les erreurs de chargement
La plupart des erreurs surviennent lors du chargement du module. Nous allons voir
comment les intercepter afin d’en avertir l’utilisateur et de prévenir tout désagrément.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.modules.*;
import mx.events.ModuleEvent;
import mx.controls.Alert;
public function chargerModule(adresse:String):void{
=Flex3 FM.book Page 290 Mardi, 2. décembre 2008 3:32 15
290
Comprendre Flex 3
PARTIE I
// Adresse du module
chargeurModule.url = adresse;
// Chargement du module
chargeurModule.loadModule();
}
public function interceptionErreur(e:ModuleEvent):void{
Alert.show ("Erreur lors du chargement du module : "+e.errorText);
}
]]>
</mx:Script>
<mx:ModuleLoader id="chargeurModule" error="interceptionErreur(event)">
</mx:ModuleLoader>
<mx:Button x="427" y="10" label="Charger" id="btn_chargerModule"
➥click="chargerModule('modules/modLettres.swf')"/>
</mx:Application>
L’exécution de la procédure interceptionErreur() n’est déclenchée que lorsque le
composant ModuleLoader rencontre une erreur (grâce au paramètre error du ModuleLoader).
La procédure reçoit alors en paramètre l’événement qui déclenche l’erreur et nous
permet d’en afficher la description (figure 15-3).
Figure 15-3
Interception des erreurs de chargement
Afficher la progression du chargement
Quoi de plus désagréable pour un utilisateur que d’attendre devant une page blanche sans
savoir ce qui se passe ? Pour lui éviter cela, il est possible de déterminer l’état d’avancement du chargement du module en se « connectant », par l’usage du terme [Bindable]
(voir le chapitre 11), à la propriété progress du composant ModuleLoader :
=Flex3 FM.book Page 291 Mardi, 2. décembre 2008 3:32 15
Créer des applications modulaires
CHAPITRE 15
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.modules.*;
import mx.events.ModuleEvent;
import mx.controls.Alert;
public function chargerModule(adresse:String):void{
// Adresse du module
chargeurModule.url = adresse;
// Chargement du module
chargeurModule.loadModule();
}
[Bindable]
public var texte:String
public function afficherProgression(e:ProgressEvent):void
{
// Taille du module
var tailleModule:Number = e.bytesTotal;
// Nombre d’octets chargés
var nbOctets:Number = e.bytesLoaded;
// Calcul du pourcentage de chargement
var pourcentage:Number = Math.round((nbOctets/tailleModule)*100)
// Affichage du texte
texte = String(pourcentage)+"%";
}
]]>
</mx:Script>
<mx:ModuleLoader id="chargeurModule" progress="afficherProgression(event)">
</mx:ModuleLoader>
<mx:Button x="427" y="10" label="Charger" id="btn_chargerModule"
➥click="chargerModule('modules/modLettre.swf')"/>
<mx:Panel x="10" y="226" width="401" height="97" layout="absolute" title="Affichage
➥du chargement" id="panel_1">
<mx:Text x="98" y="23" width="222" id="progression_txt" text="{texte}"/>
<mx:Label x="10" y="23" text="% Chargé :" width="80"/>
</mx:Panel>
</mx:Application>
291
=Flex3 FM.book Page 292 Mardi, 2. décembre 2008 3:32 15
292
Comprendre Flex 3
PARTIE I
La procédure afficherProgression() est déclenchée à chaque fois que le taux de chargement
du module augmente. Par ailleurs, l’événement ProgressEvent nous permet de capturer le
nombre d’octets chargés, nous pouvons ainsi déterminer le pourcentage de chargement
du module et l’afficher dans une zone de texte (figure 15-4).
Figure 15-4
Affichage de la progression du chargement
Interagir avec le module
Pour pouvoir interagir avec le module depuis l’application, nous devons utiliser une
interface qui servira de passerelle permettant l’accès aux méthodes du module. Cet accès
est possible car l’interface elle-même connaît l’ensemble des méthodes. La figure 15-5
illustre le processus de communication entre une application et un module :
Figure 15-5
Notion d’interface
1. L’application fait appel à une procédure du module. Pour cela elle s’adresse à l’interface qui est liée au module.
2. L’interface recherche l’existence de la procédure parmi celles contenues dans sa liste.
Si la procédure est trouvée, l’interface demande son exécution au module.
3. Le module exécute la procédure demandée.
Nous allons à présent modifier le module pour y implanter une procédure chargée
d’alimenter le champ chaine_txt. Notez que toutes les modifications à apporter devront être
effectuées dans le projet module car une nouvelle compilation du module sera nécessaire.
=Flex3 FM.book Page 293 Mardi, 2. décembre 2008 3:32 15
Créer des applications modulaires
CHAPITRE 15
293
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="400"
➥height="300">
<mx:Script>
<![CDATA[
[Bindable]
public var texte:String
public function set chaine(param:String):void
{
texte = param;
}
]]>
</mx:Script>
<mx:Panel x="10" y="11" width="380" height="141" layout="absolute" title="Nombre de
➥lettres">
<mx:TextInput x="10" y="10" width="340" id="chaine_txt" text="{texte}"/>
<mx:TextInput x="190" y="40" id="resultat_txt"/>
<mx:Button x="10" y="40" label="Calculer" click="resultat_txt.text =
➥String(chaine_txt.length)" id="btn_calculer"/>
</mx:Panel>
</mx:Module>
La propriété text du champ chaine_txt est liée à la variable texte. Cette dernière est mise
à jour à l’aide de la méthode set chaine(param:String):void impliquant une actualisation
du champ chaine_txt par la notion de DataBinding reliant la propriété text de ce champ
à la variable texte.
L’étape suivante consiste à créer l’interface permettant de réaliser la communication
entre l’application et le module. Pour cela, il suffit de créer un nouveau fichier ActionScript Interface, nommé InterfaceModule, héritant de la classe IEventDispatcher, et d’y
insérer le code suivant :
package
{
import flash.events.IEventDispatcher;
public interface InterfaceModule extends IEventDispatcher
{
function set chaine(param:String):void;
}
}
L’héritage de la classe IEventDispatcher est utile afin d’intercepter les appels aux procédures
du module et de les dispatcher correctement. Cette répartition est effectuée parmi les
=Flex3 FM.book Page 294 Mardi, 2. décembre 2008 3:32 15
294
Comprendre Flex 3
PARTIE I
procédures spécifiées dans l’interface, dont la déclaration doit être identique à celle
effectuée dans le module (en excluant leur visibilité publique/privée, figure 15-6).
Figure 15-6
Similitude des déclarations de procédure
Enfin, il nous reste à établir la liaison entre l’interface et le module en modifiant la
propriété implements de ce dernier :
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="400"
➥height="300" implements="InterfaceModule">
La première étape est terminée, il convient à présent de recompiler le module et d’en
réaliser une version de déploiement, comme expliqué précédemment.
1. Créez un nouveau projet Flex.
2. Après avoir copié les fichiers modLettre.swf, modLettre.mxml et interfaceModule.as du
projet module dans le répertoire src de notre nouveau projet, éditez le fichier MXML
comme suit :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.events.ModuleEvent;
public function chargerModule(module:String):void
{
chargeurModule.url = module;
chargeurModule.loadModule();
}
public function finChargementModule(e:ModuleEvent):void
{
var chargeur:ModuleLoader = e.target as ModuleLoader;
var connexionInterface:* = chargeur.child as InterfaceModule;
if( connexionInterface != null ) {
=Flex3 FM.book Page 295 Mardi, 2. décembre 2008 3:32 15
Créer des applications modulaires
CHAPITRE 15
295
connexionInterface.chaine = "Message à afficher";
}
}
]]>
</mx:Script>
<mx:ModuleLoader id="chargeurModule" ready="finChargementModule(event)">
➥</mx:ModuleLoader>
<mx:Button id="btn_charger" x="468" y="10" label="Charger"
➥click="chargerModule('modLettre.swf')"/>
</mx:Application>
La procédure chargerModule est appelée lorsque l’utilisateur clique sur le bouton Charger.
Elle a pour fonction de charger le module modLettre.swf dans le composant ModuleLoader.
Une fois celui-ci chargé, la procédure finChargementModule est exécutée, laquelle établit
une connexion avec l’interface et fait appel à la procédure chaine() du module en passant
en paramètre la chaîne « Message à afficher ». Le résultat obtenu est illustré par la
figure 15-7.
Figure 15-7
Résultat concluant de la communication avec le module depuis l’application
Interagir avec l’application
Nous allons à présent voir qu’il est également possible de communiquer avec l’application
à partir du module. Pour cela, nous allons quelque peu modifier le code de notre module :
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="400"
➥height="300" implements="InterfaceModule">
<mx:Script>
<![CDATA[
[Bindable]
public var texte:String
public function set chaine(param:String):void
=Flex3 FM.book Page 296 Mardi, 2. décembre 2008 3:32 15
296
Comprendre Flex 3
PARTIE I
{
texte = param;
}
public function envoyerResultat():void
{
parentApplication.resultatCalcul(texte.length);
}
]]>
</mx:Script>
<mx:Panel x="10" y="11" width="380" height="141" layout="absolute" title="Nombre de
➥lettres">
<mx:TextInput x="10" y="10" width="340" id="chaine_txt" text="{texte}"/>
<mx:TextInput x="190" y="40" id="resultat_txt"/>
<mx:Button x="10" y="40" label="Calculer" click="envoyerResultat()"
➥id="btn_calculer"/>
</mx:Panel>
</mx:Module>
Grâce à la propriété parentApplication, il nous est possible de faire appel à une procédure
déclarée dans l’application contenant le module. C’est ainsi que nous appellerons la
procédure resultatCalcul() de l’application que nous allons à présent implémenter :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.events.ModuleEvent;
public function chargerModule(module:String):void
{
chargeurModule.url = module;
chargeurModule.loadModule();
}
public function finChargementModule(e:ModuleEvent):void
{
var chargeur:ModuleLoader = e.target as ModuleLoader;
var connexionInterface:* = chargeur.child as InterfaceModule;
if( connexionInterface != null ) {
connexionInterface.chaine = "Message a afficher";
}
}
[Bindable]
=Flex3 FM.book Page 297 Mardi, 2. décembre 2008 3:32 15
Créer des applications modulaires
CHAPITRE 15
297
private var resultat:String
public function resultatCalcul(param:int):void{
resultat = String(param);
}
]]>
</mx:Script>
<mx:ModuleLoader id="chargeurModule" ready="finChargementModule(event)">
➥</mx:ModuleLoader>
<mx:Button id="btn_charger" x="468" y="10" label="Charger"
➥click="chargerModule('modLettre.swf')"/>
<mx:TextInput x="468" y="40" id="resultatCalcul_txt" text="{resultat}"/>
</mx:Application>
Après avoir recréé une version de déploiement du module et copié les fichiers modLettre
.swf et modLettre.mxml dans l’application, nous pouvons la tester afin de vérifier que la
communication entre le module et l’application s’effectue correctement (figure 15-8).
Figure 15-8
Résultat de la communication entre le module et l’application
En résumé
La création et l’implémentation d’un module s’effectuent très facilement grâce à l’emploi
du composant ModuleLoader. Nous avons également vu qu’il est possible d’interagir avec
le module depuis l’application et inversement. En organisant l’architecture de vos applications sous forme de modules, vous allez pouvoir en améliorer la qualité en réduisant
leur délai de chargement et en optimisant leur exécution.
=Flex3 FM.book Page 298 Mardi, 2. décembre 2008 3:32 15
=Flex3 FM.book Page 299 Mardi, 2. décembre 2008 3:32 15
16
Interagir
avec le conteneur web
Jusqu’à présent, nous avons réduit l’espace de communication d’une application Flex à
elle-même. Cependant, il n’est pas inconcevable d’imaginer une application Flex intégrée
au sein d’une application web statique afin d’offrir des fonctionnalités plus évoluées et de
communiquer avec celle-ci.
C’est pourquoi, nous avons décidé de consacrer un chapitre à l’étude de cette communication. Nous aborderons tout d’abord la notion de deep linking qui va nous permettre de
naviguer au sein de notre application à l’aide des boutons Précédent et Suivant du navigateur, comme nous pourrions le faire avec une application web standard. Nous étudierons
ensuite la classe ExternalInterface et la bibliothèque Flex-Ajax Bridge, qui nous permettront
de réaliser un canal de communication entre une application Flex et son conteneur web.
La notion de deep linking
Les applications Flash n’offrent pas la possibilité de se déplacer dans l’application à
l’aide du navigateur. En effet, les boutons Précédent et Suivant sont dans ce cas inactifs,
ce qui peut dérouter certains utilisateurs habitués à utiliser ce moyen de navigation au
sein des applications web classiques. Grâce au deep linking, ce problème est désormais
résolu et l’utilisateur peut naviguer au sein de l’application Flex à l’aide de ces boutons.
Principe de fonctionnement
Le principe de base est assez simple, car il consiste à enregistrer toute action réalisée
dans l’application dans l’URL de la page qui la contient. Étant donné que le navigateur
=Flex3 FM.book Page 300 Mardi, 2. décembre 2008 3:32 15
300
Comprendre Flex 3
PARTIE I
enregistre l’historique des URL utilisées, lorsque l’utilisateur cliquera sur les boutons
Précédent ou Suivant, l’URL archivée sera affichée. En analysant cette URL, nous pourrons
alors déterminer l’action correspondante et la partie de l’application associée. Voyons
ceci à travers un exemple.
Imaginons une application composée d’un état principal et d’un état secondaire héritant
de l’état principal. Un bouton situé sur l’état de base permet d’accéder à l’état suivant,
soit l’état sécondaire. La figure 16-1 illustre le fonctionnement de cette application, que
nous pouvons détailler comme suit :
Étape ➊ : à l’initialisation de l’application, son URL se termine par le caractère dièse (#),
ce qui indique qu’il s’agit de la racine du site.
Étape ➋ : lorsque l’utilisateur clique sur le bouton Passer à la vue 2, l’état secondaire
s’affiche à l’écran.
Étape ➌ : nous ajoutons alors une information dans l’URL de l’application qui nous
servira de clé de navigation, à savoir vue2 (le nom attribué à cette clé est à la libre appréciation du développeur).
Étape ➍ : si l’utilisateur clique à présent sur le bouton Précédent, l’URL affichée correspond
à celle de la racine du site.
Figure 16-1
Principe du deep linking
=Flex3 FM.book Page 301 Mardi, 2. décembre 2008 3:32 15
Interagir avec le conteneur web
CHAPITRE 16
301
Étape ➎ : dans notre application Flex, nous allons extraire cette information et l’analyser :
• si la clé est vide, nous afficherons l’état de base de l’application ;
• si la clé est égale à la valeur vue2, nous afficherons l’état secondaire.
Comme la clé est vide (DeepLinking.html#), nous affichons l’état de base de l’application.
Étape ➏ : si l’utilisateur clique à présent sur le bouton Suivant de son navigateur, l’URL
affichée comporte la clé vue2 (DeepLinking.html#vue2). L’analyse de cette clé par l’application Flex aura pour résultat l’affichage de l’état secondaire.
Passons à présent à la mise en pratique de ce concept.
Navigateurs compatibles
Les navigateurs permettant d’utiliser la notion de deep linking sont :
• Internet Explorer 6 ;
• Internet Explorer 7 ;
• Firefox ;
• Safari ;
• Google Chrome.
Mise en pratique du deep linking
Nous allons à présent nous pencher sur le concept de deep linking en développant l’application dont nous venons de décrire le fonctionnement, afin de concrétiser cette nouvelle
notion.
Configuration du projet
Pour commencer, il convient de créer un nouveau projet Flex et de vérifier que la navigation
à l’aide des boutons Précédent et Suivant du navigateur est activée pour le projet. Pour
cela, rendez-vous dans les propriétés de votre projet en réalisant un clic droit sur celui-ci,
et dans la rubrique Flex Compiler, activez l’option Enable integration with browser navigation (figure 16-2).
En activant cette option, vous indiquez que les fichiers history.css et history.js devront
être utilisés lors de la création du conteneur web, dont la fonction principale est de
permettre l’exécution du deep linking.
// Extrait du fichier HTML généré chargé de contenir l’application
<!-- BEGIN Browser History required section -->
<link rel="stylesheet" type="text/css" href="history/history.css" />
<!-- END Browser History required section -->
<!-- BEGIN Browser History required section -->
<script src="history/history.js" language="javascript"></script>
<!-- END Browser History required section -->
=Flex3 FM.book Page 302 Mardi, 2. décembre 2008 3:32 15
302
Comprendre Flex 3
PARTIE I
Figure 16-2
Configuration du projet
Création de l’interface graphique
Notre projet étant à présent créé et correctement configuré, nous allons créer l’état principal et l’état secondaire de l’application comme suit :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
< !-- Bouton permettant de passer à l’état suivant -->
<mx:Button label="Passer à la vue 2" id="button1" click="currentState='vue2'"
➥x="46" y="21"/>
<mx:states>
< !—- État secondaire -->
<mx:State name="vue2">
<mx:RemoveChild target="{button1}"/>
<mx:AddChild position="lastChild">
<mx:Label text="vue 2" x="32" y="10" width="81" fontWeight="bold"
➥fontSize="15"/>
</mx:AddChild>
</mx:State>
</mx:states>
</mx:Application>
=Flex3 FM.book Page 303 Mardi, 2. décembre 2008 3:32 15
Interagir avec le conteneur web
CHAPITRE 16
303
À l’écoute du navigateur
Comme nous l’avons vu, la notion de deep linking est essentiellement basée sur
l’échange d’informations entre le navigateur et l’application. Pour réaliser cet échange,
nous allons utiliser les éléments suivants :
• La classe BrowserManager du package mx.manager permettant d’établir la communication
avec le navigateur.
• L’interface IBrowserManager du package mx.manager, qui va utiliser l’instance de la
classe BrowserManager, et permettre de réaliser l’ensemble des opérations sur l’URL de
la page affichée dans le navigateur.
• La classe BrowserChangeEvent du package mx.events permettant d’intercepter tout
événement réalisé à l’aide des méthodes de l’interface IBrowserManager sur l’URL de la
page affichée dans le navigateur.
Le code suivant illustre l’implémentation de ces éléments :
<mx:Script>
<![CDATA[
import mx.events.BrowserChangeEvent;
import mx.managers.IBrowserManager;
import mx.managers.BrowserManager;
]]>
</mx:Script>
Nous pouvons à présent saisir le code permettant de gérer le deep linking :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
➥creationComplete="initialiserUrl()" layout="absolute">
<mx:Button label="Passer à la vue 2" id="button1" click="currentState='vue2';
➥modifierURL('vue2')" x="46" y="21"/>
<mx:states>
<mx:State name="vue2">
<mx:RemoveChild target="{button1}"/>
<mx:AddChild position="lastChild">
<mx:Label text="vue 2" x="32" y="10" width="81" fontWeight="bold"
➥fontSize="15"/>
</mx:AddChild>
</mx:State>
</mx:states>
<mx:Script>
<![CDATA[
import mx.events.BrowserChangeEvent;
import mx.managers.IBrowserManager;
import mx.managers.BrowserManager;
// Déclaration d’une variable permettant de stocker l’instance
// de la classe BrowserManager
public var navigateur:IBrowserManager;
=Flex3 FM.book Page 304 Mardi, 2. décembre 2008 3:32 15
304
Comprendre Flex 3
PARTIE I
// A -- Procédure exécutée à l’initialisation de l’application
private function initialiserUrl():void
{
// Récupération de l’instance du navigateur
navigateur = BrowserManager.getInstance();
// Initialisation de l’URL du navigateur
navigateur.init(""); // Vide = #
// Déclenchement d’un événement à chaque changement de la valeur de l’URL
// du navigateur
navigateur.addEventListener(BrowserChangeEvent.BROWSER_URL_CHANGE,
➥actionSurUrl);
}
// B -- Procédure permettant d’ajouter des clés de navigation
private function modifierURL(parametre:String):void
{
navigateur.setFragment(parametre);
}
// C -- Procédure d’analyse de l’URL du navigateur
// déclenchée à chaque modification de l’URL du navigateur
private function actionSurUrl(event:Event):void{
// Récupération de la clé de navigation
var parametre:String = navigateur.fragment;
// En fonction de la clé, on affiche l’état correspondant
if (parametre=="")
{
currentState="";
}
else
{
currentState='vue2';
}
}
]]>
</mx:Script>
</mx:Application>
Exécutons à présent notre application et étudions son fonctionnement. La première
action réalisée est l’initialisation de l’application par la procédure initialiserUrl(), qui
va récupérer l’instance de la classe BrowserManager et l’affecter à la variable navigateur.
Cette instance correspond au navigateur utilisé par l’application en cours d’exécution.
Nous profitons également de cette initialisation pour placer un écouteur d’événement qui
=Flex3 FM.book Page 305 Mardi, 2. décembre 2008 3:32 15
Interagir avec le conteneur web
CHAPITRE 16
305
déclenchera l’action actionSurUrl à chaque changement de la valeur de l’URL du navigateur.
Cet écouteur a un rôle primordial dans la notion de deep linking car c’est grâce à lui qu’il
nous sera possible d’intercepter les changements d’URL déclenchés par l’utilisation des
boutons Précédent et Suivant du navigateur et d’en afficher la vue associée. Enfin,
l’initialisation se termine par l’utilisation de la méthode init("")qui va ajouter le caractère
dièse (#) à la fin de l’URL de l’application, signifiant que nous sommes à la racine du site.
Si nous cliquons sur le bouton Passer à la vue 2, la procédure modifierUrl est exécutée.
Cette procédure permet d’ajouter une clé de navigation à l’URL du navigateur (#vue2).
Cet ajout est réalisé à l’aide de la procédure setFragment de l’interface IBrowserManager,
qui est chargée d’ajouter la valeur qui lui est passée en paramètre à la suite du dièse de
l’URL : #cléDeNavigation.
Si nous cliquons à présent sur le bouton Précédent de notre navigateur, cela déclenche
une modification de l’URL qui est interceptée par l’écouteur que nous avons mis en
place. Cet écouteur déclenche alors l’exécution de la procédure actionSurUrl, qui analyse
la clé de navigation (via la méthode getFragment() de l’interface IBrowserManager) et affiche
l’état correspondant à cette clé.
Modifier le titre du navigateur
Pour modifier le titre du navigateur, il est possible d’utiliser la méthode setTitle("titreAAfficher")
de l’interface IbrowserManager.
Déploiement du projet
Comme nous l’avons vu lors de la phase de configuration du projet, le deep linking n’est
possible que si les fichiers permettant cette fonctionnalité sont présents dans le répertoire
de l’application. Par conséquent, lors de la phase de déploiement, il convient de ne pas
omettre ces fichiers et de les placer dans le répertoire history (situé par défaut dans le
répertoire bin-debug de l’application) à l’endroit où se trouve le conteneur web de l’application Flex.
Communiquer avec le conteneur web
Jusqu’à présent, nous avons réalisé des applications autonomes, mais il peut arriver
qu’une application soit développée à l’aide du framework Flex dans le but de dynamiser
l’aspect graphique d’une page statique.
Nous vous proposons ici d’étudier une telle application à travers un exemple. L’application
Flex sera chargée de lister les produits d’un site marchand dans un composant DataGrid ou
autre. Lorsque l’utilisateur sélectionnera l’un des produits, ses caractéristiques devront
être communiquées et affichées dans la page contenant l’application. Cet exemple vous
permettra de voir comment il est possible d’interagir avec le conteneur de l’application
mais aussi comment communiquer avec l’application à partir de ce conteneur.
=Flex3 FM.book Page 306 Mardi, 2. décembre 2008 3:32 15
306
Comprendre Flex 3
PARTIE I
Ainsi, l’exemple que nous allons mettre en place va consister dans un premier temps à
saisir deux nombres dans une application Flex. Ces deux nombres seront ensuite envoyés
à une fonction présente dans la page HTML chargée d’en effectuer la somme. Dans un
second temps, ce travail sera délégué à l’application Flex qui recevra en paramètres les
données saisies dans la page HTML.
De l’application Flex vers le conteneur web
Comme nous venons de le préciser, l’addition des deux nombres sera effectuée par une
fonction JavaScript de la page contenant notre application Flex. La première chose à faire
est donc de créer l’application et d’étudier comment il est possible d’appeler cette fonction.
Création du projet Flex
Pour commencer, créez un nouveau projet Flex que vous nommerez JsFlex. Ajoutez
ensuite les lignes de code suivantes à ce projet :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥height="374" width="328">
<mx:Script>
<![CDATA[
// Importation de la classe ExternalInterface
import flash.external.ExternalInterface;
// Procédure d’appel de la fonction JavaScript
// Passage en paramètres des nombres A et B
public function calculJavascript():void{
if (ExternalInterface.available) {
var procedureJavascript:String = "calculerSomme"
var s:String = ExternalInterface.call(procedureJavascript,
➥Number(txt_a.text), Number(txt_b.text));
}
}
]]>
</mx:Script>
<mx:Panel width="313" height="177" layout="absolute" x="10" y="10" title="Flex -&gt;
➥Conteneur Web" id="pAddition">
<mx:Form x="10" y="10" width="273" height="82" verticalScrollPolicy="off"
➥horizontalScrollPolicy="off">
<mx:FormItem label="Nombre A :">
<mx:TextInput id="txt_a"/>
</mx:FormItem>
=Flex3 FM.book Page 307 Mardi, 2. décembre 2008 3:32 15
Interagir avec le conteneur web
CHAPITRE 16
307
<mx:FormItem label="Nombre B :">
<mx:TextInput id="txt_b"/>
</mx:FormItem>
</mx:Form>
<mx:Button id="btnCalculer" x="10" y="100" label="Calculer" width="273"
➥click="calculJavascript()"/>
</mx:Panel>
</mx:Application>
La première étape consiste à importer la classe ExternalInterface du package flash.external
qui va nous permettre de communiquer avec la page HTML. Nous déclarons ensuite la
procédure calculJavascript dont le principe est le suivant : si une communication peut
être établie avec la page HTML, nous faisons alors appel à la procédure JavaScript
nommée calculerSomme() en prenant soin de lui passer en paramètres les deux nombres A
et B nécessaires à sa bonne exécution.
Vient ensuite l’écriture de la description de l’interface graphique qui se résume à l’implémentation d’un composant Panel contenant deux zones de saisie ainsi que les libellés de
ces dernières au sein d’un formulaire. Enfin, le bouton btnCalculer est inséré afin de
permettre l’appel de la procédure calculerSomme lorsque l’utilisateur clique dessus.
Pour tester le projet, il convient tout d’abord d’exporter l’application Flex vers une
version de déploiement située dans le répertoire bin-release du projet :
1. Effectuez un clic droit sur le nom du projet et sélectionnez Export dans le menu
contextuel qui s’affiche alors.
2. Choisissez ensuite Release Build et poursuivez en acceptant les options par défaut.
Nous ne nous étendrons pas d’avantage sur la création de la version de déploiement du
projet à l’aide de Flex Builder. Pour plus de renseignements à ce sujet, reportez-vous au
chapitre 18 de cet ouvrage.
Si tout s’est déroulé correctement, vous devriez être en possession d’un fichier SWF
nommé JsFlex.swf et situé dans le répertoire bin-release de votre projet. Nous pouvons à
présent nous consacrer à la réalisation du fichier HTML qui servira de conteneur à notre
application et hébergera la fonction JavaScript qu’il nous faudra également développer.
Création de la page HTML
Nous allons à présent créer un nouveau fichier HTML dans le répertoire bin-release de
notre projet que nous nommerons index.html. Pour ce faire, il suffit d’effectuer un clic
droit sur le répertoire bin-release, de sélectionner New>File et de spécifier le nom du
fichier HTML à créer, soit index.html. Une fois cela fait, passons à l’écriture du conteneur :
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/1998/REC➥html40-19980424/strict.dtd">
<html>
=Flex3 FM.book Page 308 Mardi, 2. décembre 2008 3:32 15
308
Comprendre Flex 3
PARTIE I
<head>
<title>Calcul de sommes </title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
function calculerSomme(a,b) {
var nombreA = new Number(a);
var nombreB = new Number(b);
var total = a+b;
document.getElementById("id_total").setAttribute("value",total);
}
</script>
</head>
<body>
<p>
<object id="fichierSWF" type="application/x-shockwave-flash" data="JsFlex.swf"
➥width="328" height="374">
<param name="src" value="JsFlex.swf">
<param name='flashVars' value=''/>
</object>
</p>
<h1>Application Flex -> Conteneur web</h1>
<label>Somme des deux nombres : </label>
<input type="text" id="id_total" name="id_total" value=""/>
</body>
</html>
Notre fichier est constitué de la procédure JavaScript calculerSomme, dont le rôle est de
récupérer les deux nombres passés en paramètres, d’en effectuer la somme et d’afficher
le résultat dans la zone de texte id_total. Soulignons également la présence de la balise
<object>, qui contient notre application.
Tout semble à présent fonctionnel. Pour nous en assurer, il suffit d’appeler la page du
conteneur HTML via son URL, par exemple http://localhost/FLEX_3/JsFlex/bin-release/.
La figure 16-3 illustre le résultat obtenu.
Conseil
Notez que cette URL doit être adaptée à votre configuration. Pour cet exemple, FLEX_3 correspond à
notre espace de travail Flex Builder et JsFlex représente le nom du projet.
Nous allons à présent voir comment réaliser l’opération inverse, c’est-à-dire appeler une
fonction ActionScript à partir du conteneur web.
=Flex3 FM.book Page 309 Mardi, 2. décembre 2008 3:32 15
Interagir avec le conteneur web
CHAPITRE 16
309
Figure 16-3
Interaction entre l’application Flex et le conteneur web
Du conteneur web vers l’application Flex
Nous allons quelque peu modifier notre fichier HTML en lui ajoutant un formulaire, deux
zones de saisie, une procédure JavaScript faisant appel à une procédure ActionScript de
notre application Flex, et un bouton permettant de déclencher l’appel à cette procédure.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/1998/REC➥html40-19980424/strict.dtd">
<html>
<head>
<title>Calcul de somme !</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
function calculerSomme(a,b) {
var nombreA = new Number(a);
var nombreB = new Number(b);
var total = a+b;
‰document.getElementById("id_total").setAttribute("value",total);
}
=Flex3 FM.book Page 310 Mardi, 2. décembre 2008 3:32 15
310
Comprendre Flex 3
PARTIE I
function appelProcedureFlex() {
var nombreA = parseInt(document.getElementById("nb_a")
➥.getAttribute("value"));
var nombreB = parseInt(document.getElementById("nb_b")
➥.getAttribute("value"));
document.getElementById("fichierSWF").calculerSomme(nombreA,nombreB);
}
</script>
</head>
<body>
<p>
<object id="fichierSWF" type="application/x-shockwave-flash" data="JsFlex.swf"
➥width="328" height="374">
<param name="src" value="JsFlex.swf">
<param name='flashVars' value=''/>
</object>
</p>
<h1>Application Flex -> Conteneur web</h1>
<label>Somme des deux nombres : </label>
<input type="text" id="id_total" name="id_total" value=""/>
<hr/>
<form onSubmit="return false;">
<div>
<label>Nombre A :</label>
<input type="text" id="nb_a">
</div>
<div>
<label>Nombre B :</label>
<input type="text" id="nb_b" />
</div>
<input type="button" onClick="appelProcedureFlex()" value="Calculer">
</form>
</body>
</html>
En observant la procédure appelProcedureFlex, nous remarquons que la procédure
ActionScript permettant de réaliser la somme des deux nombres est appelée via le nom
du conteneur SWF qui la contient, soit fichierSWF.calculerSomme(nombreA,nombreB);.
Formatage
Les paramètres envoyés à la procédure ActionScript doivent être formatés, afin que celle-ci puisse les
considérer comme des entiers et en réaliser la somme.
Nous pouvons à présent passer à l’écriture de la procédure ActionScript contenue dans
notre application Flex :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
=Flex3 FM.book Page 311 Mardi, 2. décembre 2008 3:32 15
Interagir avec le conteneur web
CHAPITRE 16
➥height="374" width="328" creationComplete="aliasProcedure()">
<mx:Script>
<![CDATA[
// ---- FLEX -> CONTENEUR WEB --import flash.external.ExternalInterface;
public function calculJavascript():void{
if (ExternalInterface.available) {
var fonctionJavascript:String = "calculerSomme"
var s:String = ExternalInterface.call(fonctionJavascript,
➥Number(txt_a.text), Number(txt_b.text));
}
}
// Création d’un alias pour la procédure de calcul
public function aliasProcedure():void {
ExternalInterface.addCallback("calculerSomme",calculActionScript);
}
// Procédure de calcul
public function calculActionScript(a:Number, b:Number):void{
var somme:Number = a + b
txt_somme.text = String(somme);
}
]]>
</mx:Script>‰
<mx:Panel width="313" height="177" layout="absolute" x="10" y="10" title="Flex -&gt;
➥Conteneur Web" id="pAddition">
<mx:Form x="10" y="10" width="273" height="82" verticalScrollPolicy="off"
➥horizontalScrollPolicy="off">
<mx:FormItem label="Nombre A :">
<mx:TextInput id="txt_a"/>
</mx:FormItem>
<mx:FormItem label="Nombre B :">
<mx:TextInput id="txt_b"/>
</mx:FormItem>
</mx:Form>
<mx:Button id="btnCalculer" x="10" y="100" label="Calculer" width="273"
➥click="calculJavascript()"/>
</mx:Panel>
<mx:Panel x="10" y="208" width="308" height="156" layout="absolute" title="Conteneur
➥web -&gt; Flex" id="pAdditionConteneur">
<mx:TextInput x="25" y="44" width="235" id="txt_somme"/>
</mx:Panel>
</mx:Application>
311
=Flex3 FM.book Page 312 Mardi, 2. décembre 2008 3:32 15
312
Comprendre Flex 3
PARTIE I
L’appel à la procédure de calcul est réalisé à partir d’un alias qui lui est attribué. Ainsi,
lorsque nous faisons appel à la procédure caculerSomme dans notre fichier HTML, nous
appelons en réalité la procédure ActionScript calculActionScript. Pour créer un alias,
nous utilisons la méthode addCallBack de la classe ExternalInterface, soit ExternalInterface
.addCallback("calculerSomme",calculActionScript);. Pour que cet alias soit reconnu et
utilisable, il ne faut pas oublier de l’initialiser lors de la création de l’application. Cette
initialisation est réalisée par un appel à la procédure aliasProcedure dès la fin de la création
de l’application : creationComplete="aliasProcedure()".
Vient ensuite la création de la procédure de calcul et la mise en place d’une zone de texte
chargée de contenir le résultat obtenu. Pour cela, nous vous laissons le soin d’analyser la
procédure calculActionScript et le code MXML ajouté en fin de fichier, dont le contenu
vous est maintenant familier.
Figure 16-4
Interaction entre le conteneur web et l’application Flex
=Flex3 FM.book Page 313 Mardi, 2. décembre 2008 3:32 15
Interagir avec le conteneur web
CHAPITRE 16
313
La dernière étape va consister à créer une nouvelle version de déploiement comme nous
l’avons fait pour la première version de ce projet. Une fois cette étape terminée, ouvrez
une nouvelle fenêtre dans votre navigateur (afin d’éviter tout problème de cache) et
saisissez l’URL de la page HTML du projet dans la barre d’adresse (figure 16-4).
Nous venons de voir comment il est possible d’interagir avec une application Flex via
l’utilisation de la classe ExternalInterface. Nous allons à présent étudier une autre
méthode consistant à utiliser la bibliothèque Flex-Ajax Bridge.
La bibliothèque Flex-Ajax Bridge
Flex-Ajax Bridge est une bibliothèque qui permet de se passer de la classe External
Interface pour communiquer depuis le conteneur HTML vers l’application Flex. Nous
allons voir que son implémentation est assez simple et offre de nombreuses possibilités :
accès aux composants pour en modifier les propriétés, accès à l’ensemble des procédures…
Ajout de la bibliothèque à un projet
Pour ajouter la bibliothèque Flex-Ajax Bridge à notre projet, il suffit d’effectuer un clic
droit sur le nom de ce dernier et de sélectionner Create Ajax Bridge. Une fenêtre apparaît
alors, dans laquelle il suffit d’accepter les options par défaut implémentant les fonctionnalités Flex-Ajax Bridge dans le répertoire src du projet. Si nous nous plaçons ensuite
dans le répertoire src du projet, nous notons la présence d’un nouveau répertoire nommé
bridge et contenant un fichier ActionScript (FABridge.as) dont le rôle est délivrer les
procédures et les fonctions nécessaires à l’implémentation de la bibliothèque Flex-Ajax
Bridge. Analysons à présent le fichier MXML de notre application :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥height="374" width="328" xmlns:ns1="bridge.*">
<ns1:FABridge/>
Comme nous l’avons vu au chapitre 10 consacré à la création de composants personnalisés,
l’importation d’un composant est réalisée à l’aide de la spécification d’un nouvel espace
de noms XML. Cet espace de noms est chargé de pointer vers les classes nécessaires à
l’utilisation du composant. Pour utiliser les fonctionnalités de Flex-Ajax Bridge au sein
d’une application, il convient de procéder de la même manière en définissant un nouvel
espace de noms XML (ns1) faisant appel aux classes contenues dans le fichier FABridge.as.
Utilisation de la bibliothèque
Reprenons l’exemple de la procédure de calcul consistant à saisir les valeurs dans le
conteneur et à déléguer le calcul à l’application Flex. Le fichier MXML correspondant
est le suivant :
=Flex3 FM.book Page 314 Mardi, 2. décembre 2008 3:32 15
314
Comprendre Flex 3
PARTIE I
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" height="374" width="328"
➥layout="absolute" xmlns:ns1="bridge.*">
<ns1:FABridge/>
<mx:Script>
<![CDATA[
// Procédure de calcul
public function calculActionScript(a:Number, b:Number):void {
var somme:Number = a + b;
txt_somme.text = String(somme);
}
]]>
</mx:Script>
<mx:Panel x="10" y="10" width="308" height="156" layout="absolute" title="Conteneur
➥web -&gt; Flex" id="pAdditionConteneur">
<mx:TextInput x="25" y="44" width="235" id="txt_somme"/>
</mx:Panel>
</mx:Application>
Jusque là, rien de bien nouveau si ce n’est la disparition de la classe ExternalInterface et
de la procédure de création d’alias. La plupart des changements ont été effectués dans le
fichier index.html :
<html>
<head>
<title>Calcul de sommes</title>
</head>
<script src="bridge/FABridge.js" ></script>
<SCRIPT LANGUAGE="JavaScript">
function calculerActionscript(){
var nombreA = parseInt(document.getElementById("nb_a").value);
var nombreB = parseInt(document.getElementById("nb_b").value);
var instanceFlex = FABridge.pontAjax.root();
instanceFlex.calculActionScript(nombreA,nombreB);
}
</SCRIPT>
<object id='fichierSWF' classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'
➥codebase='http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab'
➥height='400' width='400'>
<param name='src' value='JsFlex.swf'/>
<param name='flashVars' value='bridgeName=pontAjax'/>
<embed name='fichierSWF' src='JsFlex.swf' pluginspage='http://www.adobe.com/go/
➥getflashplayer' height='100%' width='100%' flashvars="bridgeName=pontAjax"/>
</object>
=Flex3 FM.book Page 315 Mardi, 2. décembre 2008 3:32 15
Interagir avec le conteneur web
CHAPITRE 16
315
<br/> <br/>
<h1>Flex-Ajax Bridge</h1>
<form>
<label>Nombre A : </label>
<input id="nb_a" />
<br/>
<label>Nombre B : </label>
<input id="nb_b" />
<br/>
<button onClick="calculerActionscript()">Calculer</button>
</form>
<br/>
</body>
</html>
Pour que Flex-Ajax Bridge fonctionne correctement, nous devons faire appel au fichier
FABridge.js contenant l’ensemble des procédures capables de communiquer avec l’application Flex. Ce fichier se trouve dans le répertoire frameworks\javascript\fabridge\src\
bridge du SDK de Flex 3 et doit être copié à l’endroit où se trouve la page index.html.
Nous reviendrons plus tard sur la phase de déploiement du projet.
Observons à présent la balise <object> permettant d’inclure notre application dans le
conteneur HTML. Elle contient le paramètre FlashVars qui va nous permettre de faire le
lien avec l’application Flex et les procédures s’y trouvant :
bridgeName=pontAjax
Par cette instruction, nous définissons un nom pour notre connexion afin que celle-ci puisse
être identifiée. Vient ensuite l’appel de la procédure en elle-même à l’aide de l’instruction
suivante :
var instanceFlex = FABridge.pontAjax.root();
instanceFlex.calculActionScript(nombreA,nombreB);
Grâce à ce code, nous créons une variable instanceFlex chargée de stocker l’instance de
notre application que nous pouvons récupérer grâce à la connexion que nous avons définie
précédemment. À partir de cette instance, il nous est alors possible d’invoquer une fonction,
une procédure ou encore un composant de notre application Flex.
Déploiement et test
Comme nous en avons maintenant l’habitude, il convient tout d’abord de réaliser une
version de déploiement du projet Flex.
La deuxième étape va ensuite consister à copier le répertoire bridge du kit Flex SDK et
son fichier FABridge.js dans le répertoire bin-release de notre projet. Pour ce faire, rendezvous dans le répertoire d’installation de Flex Builder 3 et parcourez l’arborescence pour
=Flex3 FM.book Page 316 Mardi, 2. décembre 2008 3:32 15
316
Comprendre Flex 3
PARTIE I
retrouver le répertoire devant être copié. Si cette arborescence ne correspond pas à votre
installation, n’hésitez pas à utiliser les outils de recherche de votre système d’exploitation
à partir du répertoire d’installation de Flex Builder.
{répertoire d’installation de Flex Builder 3}\sdks\3.0.0\frameworks\javascript\
➥fabridge\src\bridge
La dernière étape va tout simplement consister à ouvrir la page index.html dans une
nouvelle fenêtre de votre navigateur à l’aide de son URL afin de s’assurer de la bonne
exécution de la procédure calculActionScript (figure 16-5).
Figure 16-5
Utilisation de Flex-Ajax Bridge
Il est donc plus simple d’utiliser la bibliothèque Flex-Ajax Bridge que la classe External
Interface. En effet, là où nous devions créer des alias de procédures, il nous suffit
d’importer la bibliothèque qui se charge de réaliser ce travail pour nous, ce qui représente
un gain de temps non négligeable. Notez également que la bibliothèque Flex-Ajax
Bridge permet de manipuler l’ensemble des propriétés des composants de l’application
Flex ce qui peut s’avérer fort utile dans certaines situations (par exemple, le changement
de couleur des zones de texte…).
=Flex3 FM.book Page 317 Mardi, 2. décembre 2008 3:32 15
Interagir avec le conteneur web
CHAPITRE 16
317
//*
//* Modification du texte du champ txt_somme à partir de Javascript
/*
with(FABridge.pontAjax.root()){
// Récupération du composant getNomDuComposant()
var txt = getTxt_somme();
// Affectation de la nouvelle valeur setText()
txt.setText("Bonjour!");
}
En résumé
Au cours de ce chapitre, nous avons qu’une application Flex peut être totalement intégrée
à une application web statique et communiquer avec elle. Nous vous avons également
présenté les différentes méthodes permettant de réaliser cette communication non seulement
de l’application Flex vers le conteneur web mais également du conteneur vers l’application
Flex. Nous avons aussi étudié la notion de deep linking qui apporte une fonctionnalité
non négligeable aux applications, lesquelles sont désormais comparables aux applications
web classiques en termes de navigation.
Vous êtes désormais capable d’implémenter des fonctionnalités riches au sein d’applications web statiques existantes, ce qui vous permet d’étendre leurs aspects graphiques et
fonctionnels. Dans le chapitre suivant, nous allons aborder un tout autre domaine : le
débogage d’une application Flex.
=Flex3 FM.book Page 318 Mardi, 2. décembre 2008 3:32 15
=Flex3 FM.book Page 319 Mardi, 2. décembre 2008 3:32 15
17
Déboguer une application
Dans ce chapitre nous allons voir comment déboguer des applications à l’aide du débogueur de Flex Builder. Pour plus de clarté, nous aborderons ce point à travers un exemple
comportant volontairement un certain nombre d’erreurs que nous corrigerons au fur et à
mesure afin de découvrir les subtilités du débogueur.
Création de l’application d’étude
Nous allons développer une application simple consistant à calculer l’indice de masse
corporelle (IMC) d’un patient. L’IMC est obtenu en effectuant le rapport du poids du
patient en kilogrammes par sa taille en mètres élevée au carré, soit : IMC = masse/taille2.
Pour cela, nous allons tout d’abord créer l’interface graphique (figure 17-1) :
<mx:Panel x="10" y="10" width="330" height="195" layout="absolute" title="IMC">
<mx:Form x="10" y="10" width="281" height="83" horizontalScrollPolicy="off"
➥verticalScrollPolicy="off">
<mx:FormItem label="Taille (m) :">
<mx:TextInput id="taille_txt"/>
</mx:FormItem>
<mx:FormItem label="Poids (kg) :">
<mx:TextInput id="poids_txt"/>
</mx:FormItem>
</mx:Form>
<mx:Button x="10" y="101" label="Calculer" width="103" id="btn_calculer"/>
<mx:TextInput x="121" y="101" width="152" id="imc_txt"/>
</mx:Panel>
=Flex3 FM.book Page 320 Mardi, 2. décembre 2008 3:32 15
320
Comprendre Flex 3
PARTIE I
Figure 17-1
Interface graphique de l’application
L’interface créée, nous allons implémenter la procédure de calcul. Pour ce faire, nous
avons choisi de la créer dans un fichier ActionScript, dont l’appel s’effectuera dans le
fichier MXML de l’application. Ce fichier ActionScript s’intitulera IMC.as et sera situé
dans le répertoire src de l’application. Pour le créer, il suffit d’effectuer un clic droit sur
le répertoire src et de sélectionner New>ActionScript File dans le menu contextuel qui
apparaît alors. Lorsque l’assistant vous demande le nom du fichier à créer, indiquez
IMC.as. Une fois le fichier créé, saisissez les lignes de code suivantes :
public function calculerIMC()
{
var taille:Number = Number(taille_txt.text);
var poids:Number = Number(poids_txt.text);
var imc:Number = (poids)/(taille * taille)
imc_txt.text = String(imc);
}
Calculer la valeur d’un nombre à la puissance n
Dans notre exemple, pour élever la taille au carré, nous l’avons multipliée par elle-même. Il est également
possible d’utiliser la méthode pow(nombre,puissance) de la classe Math comme suit :
var imc:Number = (poids)/ (Math.pow(taille,2))
Nous devons ensuite lier ce fichier ActionScript à notre application et définir l’appel de la
procédure calculerIMC() qui sera exécutée lors du clic sur le bouton btn_calculer :
<mx:Script source="IMC.as"> </mx:Script>
<mx:Button x="10" y="101" label="Calculer" width="103" id="btn_calculer"
➥click="calculerIMC()"/>
Notre application est à présent terminée, concentrons-nous sur son exécution et son
débogage.
=Flex3 FM.book Page 321 Mardi, 2. décembre 2008 3:32 15
Déboguer une application
CHAPITRE 17
321
Identifier et corriger les erreurs grâce à la vue Problems
Avant d’exécuter l’application, nous vous invitons à consulter les informations présentes
dans la vue Problems située en bas de votre écran.
Cette vue regroupe les différents avertissements et erreurs produits par la compilation de
notre code. Il est important de souligner qu’à la différence d’une erreur (error), un avertissement (warning) ne bloque pas l’exécution de l’application, mais il est tout de même
souhaitable de le corriger. Nous constatons donc dans la figure 17-2 la présence de
l’avertissement suivant :
Figure 17-2
Affichage des avertissements
qui nous indique que Flex est incapable de déterminer si calculerIMC() est une procédure
ou une fonction. Il convient donc de corriger cet avertissement en ajoutant la mention :void :
public function calculerIMC():void
Procédure et fonction
Une procédure permet d’effectuer un traitement mais ne retourne pas de valeur. Nous spécifions qu’il
s’agit d’une procédure via la mention :void.
Public function maProcedure():void{
}
Dans le cas d’une fonction, nous devons préciser le type de la valeur renvoyée par celle-ci :
Public function maFonction():int{
var entier:int = 1;
return entier
}
La vue Problems est l’outil principal permettant de déboguer une application. En effet,
grâce à celle-ci, la majeure partie des erreurs peuvent être résolues sans qu’il soit nécessaire de réaliser un débogage avancé.
Le débogage avancé
Pour illustrer ce point, nous allons mettre en défaut notre application en provoquant une
erreur d’exécution. Pour ce faire, exécutons l’application et saisissons les valeurs 0 pour
=Flex3 FM.book Page 322 Mardi, 2. décembre 2008 3:32 15
322
Comprendre Flex 3
PARTIE I
Taille et 69 pour Poids. Cliquons ensuite sur le bouton Calculer afin d’observer le résultat
obtenu dans la zone de texte prévue à cet effet. Nous constatons alors qu’au lieu de nous
présenter l’indice de masse corporel attendu, la zone de réponse indique infinity. Que
s’est-il passé ? Il n’est pas évident de déterminer avec précision le moment où l’erreur
s’est produite. Nous allons donc stopper l’exécution de l’application lors de la phase de
calcul afin d’y voir plus clair.
Utilisation des points d’arrêt
Pour stopper l’exécution d’une application, il suffit de placer un point d’arrêt dans son
code. Vous pourrez ainsi exécuter l’application pas à pas et afin de détecter les éventuelles
erreurs présentes.
Dans notre exemple, nous savons que le problème vient de la procédure calculerIMC(). Il
serait donc judicieux de stopper l’application à cet endroit afin d’analyser le fonctionnement de cette procédure. Pour ce faire, il convient de se placer dans le fichier MXML
et, au regard de la ligne décrivant le bouton, d’effectuer un clic droit dans la marge et de
sélectionner Toogle breakpoint (figure 17-3).
Figure 17-3
Positionnement d’un point d’arrêt
Notre point d’arrêt est maintenant correctement positionné. Pour l’exploiter, nous devons
exécuter l’application en mode Debug en sélectionnant le menu Run>Debug (vous pouvez
également appuyer sur la touche F11).
À présent, ressaisissons les mêmes valeurs que précédemment (0 pour la taille et 69 pour
le poids) et cliquons sur le bouton Valider. Une fenêtre s’ouvre alors dans Flex Builder
nous demandant de confirmer l’ouverture de la perspective de débogage.
Exécution pas à pas
La meilleure façon de déboguer l’application consiste à vérifier le bon déroulement de
chaque procédure et fonction. Pour cela, la perspective de débogage met à notre disposition
deux icônes :
• L’icône Step into
permet d’entrer dans la procédure afin d’observer le déroulement
de chaque traitement.
=Flex3 FM.book Page 323 Mardi, 2. décembre 2008 3:32 15
Déboguer une application
CHAPITRE 17
• L’icône Step over
323
permet de poursuivre le traitement sans entrer dans la procédure.
Pour illustrer les actions provoquées par l’utilisation de ces icônes, nous vous invitons à
exécuter les opérations suivantes :
1. Vérifiez que vous avez bien exécuté l’application en mode Debug et accepté l’ouverture
de la perspective de débogage. Appuyez ensuite sur touche F5 (raccourci clavier de
Step into) pour entrer dans la procédure. La procédure calculerIMC() s’affiche alors
au milieu de l’écran (figure 17-4).
Figure 17-4
Entrée dans la procédure calculerIMC()
2. Réitérez cette opération. Le curseur de débogage pointe à présent sur la variable taille.
3. Si vous appuyez à nouveau sur la touche F5, vous entrez cette fois dans le détail de la
classe TextInput et pouvez visualiser le code de la méthode get Text() du composant
taille_txt.
4. Appuyez ensuite trois fois sur la touche F5 afin de placer le curseur de débogage sur
la variable poids.
5. À présent, appuyez sur la touche F6 (raccourci clavier de Step over). Vous constatez
alors que vous n’êtes pas entré dans le détail de la méthode Text() du composant
poids_txt et que vous êtes directement passé à la variable imc.
6. Pour stopper le débogage, cliquez sur l’icône représentant un petit carré rouge à côté
des icônes Step into et Step over.
7. Enfin, pour revenir à la perspective de développement, sélectionnez le menu
Windows>Perspective de Flex Builder et choisissez Flex Developpement.
Au fur et à mesure que vous naviguez dans le code, observez la vue Variables de la perspective de débogage (figure 17-5). Grâce à cette vue, nous pouvons visualiser les valeurs
prises par l’ensemble de nos variables. Après avoir calculé l’indice de masse corporelle,
la valeur de la variable imc est Infinity.
=Flex3 FM.book Page 324 Mardi, 2. décembre 2008 3:32 15
324
Comprendre Flex 3
PARTIE I
Figure 17-5
La vue Variables
Étant donné que les variables taille et poids possèdent toutes deux une valeur, le problème
ne peut donc provenir que de l’affectation de la variable imc. D’après les valeurs saisies pour
la taille (0) et le poids (69), le calcul de l’IMC équivaut à : IMC = 69 / 0 × 0. La division
par zéro étant impossible, la valeur Infinity est renvoyée. Le problème est donc identifié.
Pour le résoudre, il convient d’ajouter un test de vérification de la saisie utilisateur comme
suit :
var taille:int = int(taille_txt.text);
var poids:Number = Number(poids_txt.text);
if (taille != 0)
{
var imc:Number = (poids)/(taille * taille)
imc_txt.text = String(imc);
}
else
{
var msg_erreur:String = "Ne peut être calculé";
imc_txt.text = msg_erreur;
}
Gérer les points d’arrêt
La gestion des points d’arrêt s’effectue dans la vue Breakpoints, située à droite de la vue
Variables. En effectuant un clic droit sur un ou plusieurs points d’arrêt affichés dans cette
vue, il est possible :
• d’activer/de désactiver les points d’arrêt (Enable/Disable) ;
• de supprimer les points d’arrêt (Remove/Remove All) ;
• de se positionner dans le fichier où se trouve les points d’arrêt (Go to file) ;
• de passer outre les points d’arrêt (Skip All Breakpoints).
Notre application est à présent déboguée et fonctionnelle. Néanmoins, nous sommes loin
d’avoir exploité toutes les fonctionnalités du débogueur de Flex Builder.
=Flex3 FM.book Page 325 Mardi, 2. décembre 2008 3:32 15
Déboguer une application
CHAPITRE 17
325
Modifier la valeur des variables
En phase de test, il peut s’avérer intéressant de modifier la valeur des variables afin de
vérifier le comportement de la procédure en fonction de ces valeurs. Pour cela, il convient
de se placer dans la vue Variables et de double-cliquer sur la valeur de la variable à modifier.
Il suffit alors de saisir la valeur souhaitée, à condition que celle-ci soit initialisée.
Tracer un parcours
Placer un point d’arrêt n’est réellement nécessaire que si un problème survient dans un
traitement et qu’une analyse détaillée de ce traitement s’impose. Pour les cas plus
simples (vérification de passage dans un test ou une boucle, etc.), la solution consistant à
tracer le parcours du traitement peut être envisagée par l’emploi de la méthode trace() :
public function calculerIMC():void
{
var taille:int = int(taille_txt.text);
trace ('Taille : ' + taille);
var poids:Number = Number(poids_txt.text);
trace ('Poids : '+poids);
trace ('Debut de test');
if (taille != 0)
{
trace ('Cas : Taille !=0');
var imc:Number = (poids)/(taille * taille)
imc_txt.text = String(imc);
}
else
{
trace ('Cas : Taille =0 ->> ERREUR');
var msg_erreur:String = "Ne peut être calculé";
imc_txt.text = msg_erreur;
}
}
Pour bien comprendre l’utilité de cette méthode, nous allons exécuter l’application en
mode Debug et visualiser le résultat obtenu dans la vue Console. Nous y trouvons les
lignes suivantes :
Taille : 0
Poids : 69
Debut de test
Cas : Taille =0 ->> ERREUR
Nous pouvons alors en déduire que le traitement s’est déroulé correctement, car l’ensemble
des traces correspondantes découlent des valeurs saisies. En effet, comme nous avons
=Flex3 FM.book Page 326 Mardi, 2. décembre 2008 3:32 15
326
Comprendre Flex 3
PARTIE I
saisi la valeur 0 pour la taille, le test if (taille != 0) est faux. Ceci entraîne alors l’affichage de la trace ‘Cas : Taille = 0 ->>Erreur’. Avec cette manipulation, nous vérifions
donc que, lorsque la taille est égale à zéro, le traitement de gestion d’erreur s’exécute
convenablement.
Sélectionner les variables à surveiller
Pour sélectionner certaines variables, il suffit de cliquer dessus avec le bouton droit et de
choisir Watch nom de la variable. La variable sélectionnée s’affiche alors dans la vue
Expressions (figure 17-6) de la perspective de débogage, nous permettant ainsi d’étudier
son comportement, tout comme nous pourrions le faire dans la vue Variables. Mais nous
allons voir que cette vue offre une fonctionnalité supplémentaire permettant de manipuler
les données en modifiant leur expression.
Figure 17-6
Sélection de la variable taille dans la vue Expressions
La vue Expressions permet de manipuler la valeur des variables en modifiant leur opération.
Prenons un exemple : nous souhaitons modifier la valeur de la variable taille afin qu’elle
soit égale à deux fois sa valeur (taille = taille ¥ 2). Pour arriver à ce résultat, il suffit de
cliquer avec le bouton droit sur la variable taille affichée dans la vue Expressions et de
sélectionner Edit Watch Expression. Une nouvelle fenêtre s’ouvre alors, dans laquelle
nous pouvons saisir le traitement souhaité (figure 17-7).
Figure 17-7
Définition d’une expression
pour une variable donnée
=Flex3 FM.book Page 327 Mardi, 2. décembre 2008 3:32 15
Déboguer une application
CHAPITRE 17
327
À présent, si nous exécutons l’application en mode Debug et que nous observons la
variable taille dans la vue Expressions, nous remarquons que sa valeur a été révaluée en
fonction de l’opération précédemment saisie (figure 17-8).
Figure 17-8
Révaluation de la valeur saisie en fonction de l’expression
En résumé
Dans ce chapitre, nous avons présenté le fonctionnement du débogueur de Flex Builder,
application permettant d’analyser votre code de plusieurs façons différentes. Vous pourrez
ainsi observer le comportement de vos fonctions et de vos procédures tout en ayant la
possibilité d’interagir avec les données stockées dans les variables. Le débogueur de Flex
constitue un outil très performant qui vous sera certainement d’une aide non négligeable
si vous rencontrez des difficultés ou si votre code présente des erreurs.
Dans le chapitre suivant, nous allons nous pencher sur une autre nouveauté de Flex Builder 3 :
le profiling d’application. Ceci consiste à analyser l’ensemble de ses processus afin de
détecter les procédures gourmandes en mémoire ou en temps d’exécution. Nous verrons
également les bonnes pratiques permettant d’optimiser l’exécution d’une application Flex.
=Flex3 FM.book Page 328 Mardi, 2. décembre 2008 3:32 15
=Flex3 FM.book Page 329 Mardi, 2. décembre 2008 3:32 15
18
Analyser les performances
et optimiser l’application
Autre grande nouveauté de Flex Builder 3, la fonction d’analyse des performances était
attendue avec impatience par les développeurs. Réservé aux utilisateurs de la version
professionnelle de Flex Builder 3, cet outil permet d’analyser les moindres détails de
vos applications afin d’en améliorer les performances lors de l’exécution. Nous verrons
également quelques bonnes pratiques à observer afin d’optimiser l’exécution de vos
applications Flex avant de les déployer.
Présentation de l’analyseur
La version professionnelle de Flex Builder 3 met à notre disposition un outil d’analyse
avancé concernant l’exécution des applications, le Profiler. Il nous permettra en effet
d’analyser les performances applicatives (taux de mémoire occupée, temps processeur…)
et de contrôler les ressources mémoire utilisées en spécifiant le nombre et la taille des
objets instanciés, le nombre de procédures exécutées ainsi que leur temps d’exécution.
Procéder à l’analyse d’une application permet d’identifier et de comprendre les éléments
suivants :
• La redondance d’appel des procédures – L’analyseur permet de déterminer combien de
fois la procédure est appelée, information qui vous permettra d’optimiser les traitements.
• Le temps d’exécution d’une procédure – Si le temps d’exécution d’une procédure
est important, nous pourrons nous en rendre compte et procéder à son optimisation.
=Flex3 FM.book Page 330 Mardi, 2. décembre 2008 3:32 15
330
Comprendre Flex 3
PARTIE I
• Le nombre d’objets instanciés – Grâce à cette fonctionnalité, vous découvrirez qu’un
objet est parfois instancié plusieurs fois alors que cela n’est pas nécessaire. Vous
pourrez ainsi modifier le code afin de corriger cela.
• La taille des objets – En complément de la fonctionnalité précédente, vous pourrez
également identifier la taille des objets instanciés afin de visualiser leur occupation
mémoire.
• Le ramasse-miettes (garbage collector) – Il peut arriver que certains objets devenus
obsolètes, ou qui ne sont plus utilisés, soient toujours présents en mémoire. Grâce au
Profiler, vous pourrez les identifier et ainsi implémenter les méthodes de destruction
d’objet adéquates.
Le fonctionnement du Profiler repose sur l’utilisation d’un port de communication
permettant d’établir une connexion avec le Flash Player et l’application en cours d’exécution. Une fois la connexion établie, son travail consiste à réaliser à intervalles réguliers
des captures des actions réalisées par l’application.
L’analyseur en action
Étudions à présent son utilisation à travers un exemple concret. Pour cela, nous vous invitons
à créer un nouveau projet Flex que vous nommerez Profiler et à y insérer les lignes de
code suivantes :
<?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 afficherMessage():void
{
Alert.show("Message d’information");
}
]]>
</mx:Script>
<mx:Button x="10" y="10" label="Afficher" id="btn_afficherMessage"
➥click="afficherMessage()"/>
</mx:Application>
Comme vous pouvez le constater, il s’agit d’une petite application, contenant un bouton
qui déclenche l’exécution de la procédure afficherMessage(), affichant un message d’alerte,
lorsqu’on clique dessus.
=Flex3 FM.book Page 331 Mardi, 2. décembre 2008 3:32 15
Analyser les performances et optimiser l’application
CHAPITRE 18
331
Pare-feu
Dans la mesure où la communication s’effectue via un port spécifique du Flash Player, il se peut qu’elle
soit bloquée par votre pare-feu. Nous vous conseillons donc de le désactiver temporairement ou d’autoriser
l’accès au port 9999.
Pour lancer l’analyse de notre application, sélectionnez le menu Run>Profile. Une
nouvelle fenêtre apparaît alors, nous demandant l’autorisation d’ouvrir la perspective
d’analyse. Vous n’avez alors qu’à confirmer, ce qui déclenche l’exécution de l’application
et l’ouverture de la perspective d’analyse.
Avant de pouvoir utiliser cette perspective, vous devez indiquer quel type d’analyse vous
souhaitez effectuer. Pour une analyse complète, conservez les options cochées par défaut :
• analyse de la mémoire (Enable memory profiling) ;
• analyse du temps d’exécution des processus (Enable performance profiling).
Analyse des performances
Nous allons à présent analyser la performance de la procédure afficherMessage(). Pour
cela, placez-vous sur l’interface de l’application et cliquez sur le bouton qu’elle contient.
Le message d’alerte s’affiche correctement à l’écran. Ne le fermez pas encore et ouvrez
la perspective d’analyse de Flex Builder 3.
Nous allons procéder à une capture des événements. Pour cela, placez-vous dans la vue
Profile située en haut à gauche de l’écran et positionnez-vous sur la ligne commençant
par la mention [Running]. Dans la barre d’outils, cliquez ensuite sur l’icône Capture
Performance Profile représentée par une paire de lunettes et une horloge
. La vue
Performance Profile s’ouvre alors, affichant un tableau de données concernant l’ensemble
des méthodes et des procédures exécutées (figure 18-1).
Nous remarquons que l’une des lignes du tableau concerne l’appel à la procédure profiler
.afficherMessage. Le tableau 18-1 présente les informations obtenues en analysant l’exécution de cette procédure, celles-ci pouvant être différentes en fonction des performances
de votre ordinateur.
Pour entrer dans le détail de son exécution, il suffit de double-cliquer sur la ligne du tableau
affichée dans la vue Method Statistic (figure 18-2), afin de voir les statistiques complètes
concernant cette procédure.
La vue Performance Profile vous permettra donc d’identifier les méthodes pouvant éventuellement poser problème lors de l’exécution de l’application grâce à une analyse attentive
de leur temps d’exécution.
=Flex3 FM.book Page 332 Mardi, 2. décembre 2008 3:32 15
332
Comprendre Flex 3
PARTIE I
Figure 18-1
La vue Performance Profile
Tableau 18-1
Tableau d’analyse d’exécution de la procédure profiler.afficherMessage
Information
Valeur
Analyse
Method
Profiler.afficherMessage
--
--
Notre procédure n’appartient
à aucun package.
1
La procédure n’a été exécutée
qu’une seule fois.
12 (0.78%)
Temps d’exécution total :
12 millisecondes.
0
La procédure avait déjà été
exécutée lors de la capture.
12
--
0
--
Nom des méthodes et des procédures
Package
Nom du package d’appartenance
Calls
Nombre d’appels d’exécution de la procédure
Cumulative time
Somme des temps d’exécution de la procédure
et des sous-procédures associées
Self time
Temps d’exécution de la procédure au moment
de la capture
Avg. Cumulative time
Moyenne des temps d’exécution
Avg Self Time
Moyenne des temps d’exécution au moment de la capture
=Flex3 FM.book Page 333 Mardi, 2. décembre 2008 3:32 15
Analyser les performances et optimiser l’application
CHAPITRE 18
333
Figure 18-2
Analyse des statistiques
Analyse de l’occupation mémoire
Attardons nous à présent sur l’analyse de l’occupation de la mémoire de notre application.
Pour cela, comme précédemment, nous devons procéder à une capture d’événement en
cliquant cette fois-ci sur l’icône Take Memory Snapshot après nous être positionnés sur
la ligne commençant par la mention [Running].
La vue Memory Snapshot s’ouvre alors, nous permettant d’analyser la part d’occupation
de la mémoire de chaque processus. Pour ce faire, retournons dans notre application, en
cours d’exécution dans le navigateur, et appelons la procédure afficherMessage() en
cliquant sur le bouton Afficher, puis retournons dans la perspective d’analyse.
Figure 18-3
Analyse de la mémoire
Si nous analysons les résultats obtenus (figure 18-3), nous remarquons que l’élément le
plus gourmand en ressources mémoire est l’application elle-même (1 572 octets). En
double-cliquant sur la ligne profiler, nous visualisons le rapport détaillé le concernant.
Nous pouvons alors voir l’ensemble des objets instanciés et leur taux d’occupation de la
mémoire, qui expliquent la part importante d’occupation de la mémoire par l’application :
nous avons 32 objets instanciés (figure 18-4).
=Flex3 FM.book Page 334 Mardi, 2. décembre 2008 3:32 15
334
Comprendre Flex 3
PARTIE I
Figure 18-4
Analyse des objets instanciés
Méthodes d’analyse
Dans cette section, nous allons voir les méthodes d’analyse les plus fréquemment utilisées. Chacune est détaillée en un certain nombre d’étapes que nous vous invitons à
suivre.
Détecter les allocations mémoire inutiles
Pour commencer, nous allons vous présenter la méthode permettant de détecter les allocations de mémoire inutiles. Cela est souvent dû à la présence d’objets toujours instanciés
malgré le travail réalisé par le ramasse-miette :
1. Démarrez une session d’analyse en sélectionnant l’option Memory Profiling (voir la
section « L’analyseur en action »).
2. Créez deux captures de mémoire à deux moments différents. En cliquant une première
fois sur l’icône
et en réitérant cette action quelques secondes à quelques minutes
plus tard, selon l’analyse souhaitée.
=Flex3 FM.book Page 335 Mardi, 2. décembre 2008 3:32 15
Analyser les performances et optimiser l’application
CHAPITRE 18
335
3. Sélectionnez les deux captures effectuées et cliquez sur l’icône d’analyse permettant
de détecter les objets chargés en mémoire
.
4. Une nouvelle fenêtre s’ouvre alors dans laquelle vous pouvez visualiser l’ensemble
des méthodes et des objets toujours instanciés malgré la présence du ramasse-miettes.
La solution consistera donc à implémenter les méthodes de destruction d’objet pour
les objets concernés via la méthode delete :
package com.composants
{
public class ClMaClasse
{
public function ClMaClasse()
{
}
//Méthode de destruction
public function detruitre():void{
delete this;
}
}
}
//Exemple d'utilisation dans un fichier ActionScript :
import com.composants.ClMaClasse
//Intanciation de la classe
public var monObjet:ClMaClasse = new ClMaClasse();
//Destruction de l'objet
monObjet.detruitre();
Analyser le temps d’exécution des méthodes
« Pourquoi le temps d’exécution de mon application est-il si important ? » Cette question,
nous nous la sommes tous posée un jour. Bien souvent, il s’agit d’une procédure demandant
un temps de traitement important, mais il nous est parfois difficile de savoir de laquelle il
s’agit. Nous allons voir comment, à l’aide d’une méthode simple, il nous est possible de
la repérer.
1. Démarrez une session d’analyse en sélectionnant l’option Performance Profiling (voir
la section « L’analyseur en action »).
2. Réalisez une capture de performance comme expliqué à la section « Analyse des
performances ».
=Flex3 FM.book Page 336 Mardi, 2. décembre 2008 3:32 15
336
Comprendre Flex 3
PARTIE I
3. Dans la vue Performance Profile, vous pouvez organiser les résultats par ordre croissant/
décroissant en cliquant sur les titres des colonnes du tableau de résultat. Ainsi, il sera
possible de visualiser rapidement (notamment via la colonne Safe time indiquant le
temps d’exécution de la procédure) la méthode ayant un temps d’exécution important
pouvant cacher un problème (attente de réponse d’un service web, par exemple).
Déterminer le nombre d’instances d’une classe
Cette méthode va permettre de connaître le nombre d’objets instanciés pour une classe
donnée. Chaque instanciation de classe donnant naissance à un objet occupant de la
mémoire, il convient de détecter le nombre d’instanciations de classes afin de vérifier qu’il
correspond à la quantité d’objets utiles à l’application.
1. Démarrez une session d’analyse en sélectionnant l’option Memory Profiling.
2. Réalisez une capture de mémoire comme expliqué à la section « Analyse de l’occupation mémoire ».
3. Dans la vue Memory Snapshot, classez les noms des classes par ordre alphabétique
(en cliquant sur le titre de la colonne Class) afin de repérer facilement la classe
souhaitée.
4. Le nombre d’instances de la classe recherchée est indiqué par la valeur de la colonne
Instances. Si vous remarquez que ce nombre est supérieur à la quantité d’instanciations réalisées par le code de l’application, il se peut qu’il y reste des instanciations
inutiles (parfois réalisées lors de phases de test).
Visualiser les allocations d’objets
La méthode précédente nous permet de compter le nombre d’objets instanciés. Voyons à
présent comment connaître l’occupation mémoire de ceux-ci.
1. Démarrez une session d’analyse en sélectionnant l’option Memory Profiling et en
cochant cette fois l’option de visualisation d’allocations d’objets (Generate object
allocation stack trace).
2. Réalisez deux captures de mémoire à intervalles séparés, comme nous avons procédé
pour la détection d’allocation mémoire.
3. Sélectionnez-les et cliquez sur l’icône View Allocation Trace
.
4. La vue Allocation Trace qui s’ouvre alors présente l’ensemble des allocations. (Vous
pouvez les classer par ordre croissant/décroissant en cliquant sur les en-têtes des
colonnes).
Il existe bien entendu beaucoup d’autres méthodes que vous découvrirez à mesure que
vous vous familiariserez avec l’outil d’analyse. À vous ensuite de créer vos propres
procédures d’analyse en fonction de vos besoins.
=Flex3 FM.book Page 337 Mardi, 2. décembre 2008 3:32 15
Analyser les performances et optimiser l’application
CHAPITRE 18
337
Bonnes pratiques d’optimisation
L’optimisation d’une application Flex consiste essentiellement à améliorer son exécution
et à réduire son temps d’initialisation sur le poste client. Nous allons voir comment, à
partir de quelques bonnes pratiques, il est possible d’optimiser nos applications.
Calculer les performances applicatives
Comme nous l’avons vu, le Profiler de la version professionnelle Flex Builder 3 permet
de vérifier les performances d’une application. Cependant, ce dernier n’est présent que
dans la version professionnelle ; si vous utilisez Flex SDK pour développer vos application
ou Flex Builder dans sa version standard, vous ne pourrez donc pas vous en servir. Nous
allons toutefois présenter quelques petites astuces qui vous permettront toutefois d’apprécier
les performances de vos applications.
Calculer le temps d’initialisation
Grâce à la combinaison des méthodes getTimer() et callLater() du package flash.utils,
il est possible de calculer le temps d’initialisation d’une application :
• getTimer() permet de calculer le temps écoulé en millisecondes depuis l’exécution du
Flash Player.
• callLater() permet de reporter l’exécution d’une procédure au prochain rafraîchissement
de l’écran.
Ainsi, en calculant le temps écoulé entre l’exécution de l’application et l’affichage de
l’écran principal, nous pouvons déterminer le temps nécessaire à l’initialisation de
l’application :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="callLater(afficherTempsInitialisation)">
<mx:Script>
<![CDATA[
import flash.utils.Timer;
[Bindable]
public var tempsInitialisation:String;
private function afficherTempsInitialisation():void {
tempsInitialisation = "Temps d'initialisation: " + getTimer() + " ms";
}
]]>
</mx:Script>
<!-- Affichage du temps d’initialisation -->
<mx:Label id="l1" text="{tempsInitialisation}"/>
</mx:Application>
=Flex3 FM.book Page 338 Mardi, 2. décembre 2008 3:32 15
338
Comprendre Flex 3
PARTIE I
L’analyse du résultat de cette méthode peut être riche d’enseignements. Si le temps
d’initialisation est trop élevé, cela peut être dû à un chargement trop important d’images
ou à une procédure lourde en traitement.
Calculer l’occupation de la mémoire
Pour déterminer la taille de la mémoire occupée par le Flash Player, nous disposons de la
propriété totalMemory de la classe System.
La portion de code suivante permet de déterminer l’occupation de la mémoire après
l’initialisation de l’application :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
➥initialize="afficherMemoire()">
<mx:Script>
<![CDATA[
[Bindable]
public var memoireOccupee:String;
private function afficherMemoire():void {
memoireOccupee= "Mémoire occupée : " + flash.system.System.totalMemory
➥+ " octets";
}
]]>
</mx:Script>
<!-- Affichage de la taille mémoire occupée -->
<mx:Label id="l1" text="{memoireOccupee}"/>
</mx:Application>
Là encore, l’analyse du résultat permet de tirer une conclusion importante : si le taux
d’occupation mémoire est élevé, cela peut allonger le temps d’exécution sur le poste
client car la limite mémoire de son environnement peut facilement être atteinte. C’est
donc à vous de fixer un taux d’occupation mémoire que l’application ne doit pas dépasser.
Pour réussir cela, il convient de respecter quelques règles d’optimisation que nous allons
aborder dans la section suivante.
Améliorer l’exécution sur les postes clients
Comme nous le savons, une application Flex est exécutée sur le poste client. Pour une
meilleure performance d’exécution, il faut que notre application soit correctement configurée et respecte quelques règles de base.
Prévenir le dépassement du temps d’initialisation (time out)
Si l’application est téléchargée sur un poste client à faible capacité de traitement, il se
peut qu’un message d’erreur apparaisse, avertissant l’utilisateur que le temps d’initialisation
=Flex3 FM.book Page 339 Mardi, 2. décembre 2008 3:32 15
Analyser les performances et optimiser l’application
CHAPITRE 18
339
de l’application a été dépassé (60 secondes par défaut). Pour pallier ce problème, il suffit
d’augmenter la valeur de la propriété scriptTimeLimit de l’application comme suit :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" scriptTimeLimit="120">
</mx:Application>
À cause de la performance croissante des ordinateurs, le temps d’initialisation est rarement
dépassé et cette fonction peut ne pas être employée. Cependant, vous pouvez tout de
même en faire usage si votre application est susceptible d’être utilisée sur des machines
intégrées au sein d’un parc informatique ayant déjà quelques années (nous pensons, par
exemple, au parc informatique de certains hôpitaux).
Attention au cache du navigateur
Toute application Flex est téléchargée dans le répertoire des fichiers temporaires d’Internet
du poste client. Ce répertoire représente le cache du navigateur permettant de diminuer le
nombre de requêtes web effectuées.
Ainsi, si vous venez de mettre en ligne une nouvelle version de votre application Flex, il
est fort probable que les utilisateurs ne puissent en bénéficier et voir les modifications
effectuées. En effet, le cache de leur navigateur va détecter que la page contenant l’application a déjà été visitée et va donc afficher celle enregistrée dans le répertoire de stockage
au lieu de la recharger.
Pour résoudre ce problème, deux solutions s’offrent à nous. La première consiste à vider le
cache de chaque poste client (uniquement pour un déploiement sur site local), la seconde
à paramétrer la page web contenant l’application Flex. Attention, cette modification est à
apporter après compilation.
<!-<meta
<!-<meta
Ne pas utiliser le cache -->
http-equiv=”pragma” content=”no-cache”>
Forcer la date d’expiration pour recharger la page -->
http-equiv=”EXPIRES” content=” Mon, 22 Jul 2000 11:12:01 GMT”>
Dans cet exemple de code, nous avons spécifié une date antérieure à la date du jour. Le
navigateur web va donc en déduire que le fichier présent dans le cache est obsolète et va
par conséquent procéder au téléchargement de la dernière version de l’application.
Réduire la taille des fichiers SWF
Un fichier SWF de petite taille permet de réduire le temps de téléchargement et d’initialisation de l’application. Cette réduction de taille peut être effectuée en ne prenant que les
éléments vitaux à l’exécution de l’application.
Désactiver l’option de débogage
Lorsque l’option de débogage est sélectionnée lors de la compilation du projet, les numéros
de lignes et les fonctionnalités de débogage sont inclus dans le fichier SWF, ce qui
=Flex3 FM.book Page 340 Mardi, 2. décembre 2008 3:32 15
340
Comprendre Flex 3
PARTIE I
augmente sa taille. Cette option étant sélectionnée par défaut, il nous est possible de la
désactiver en modifiant les paramètres de compilation comme suit :
mxmlc -debug=false Application.mxml
Soulignons qu’il est impossible de paramétrer cette option dans Flex Builder 3, dans la
mesure où l’application contenant toutes les options de débogage est compilée dans le
répertoire bin-debug. La version de déploiement destinée aux clients, située quant à elle
dans le répertoire bin-release, est ainsi épurée de cette fonctionnalité
Compiler en mode Strict
Le fait d’utiliser le mode Strict de compilation implique la vérification de l’utilisation
effective de tous les packages et classes importés, ainsi que la vérification de la qualité de
votre code. Si vous utilisez Flex Builder 3 pour créer et compiler vos applications, ce
mode est automatiquement activé. Pour les autres versions de Flex, voici le code permettant
d’activer cette option lors de la compilation :
mxmlc -strict=true Application.mxml
Multiplier les fichiers SWF
Une dernière méthode pour réduire la taille d’une application consiste à la décomposer en
plusieurs petites applications pouvant alors être chargées à l’aide du composant SWFLoader.
Cette méthode présente l’avantage de ne charger que la partie applicative nécessaire, ce
qui réduit ainsi la taille du fichier applicatif principal. Nous aborderons cette notion plus
en détail dans la seconde partie de cet ouvrage consacrée à la mise en pratique.
Améliorer les méthodes de codage
Nous allons ici nous pencher sur les éléments auxquels il faudra faire attention lors de la
phase de développement de vos applications pour optimiser leur exécution.
Instancier les objets
ActionScript est un langage orienté objet. Néanmoins, chaque création d’objet entraîne le
stockage de données, ce qui provoque une diminution des performances de l’application.
Comme en Java, nous disposons cependant dans Flex d’un ramasse-miettes dont le rôle
est de supprimer les objets instanciés non utilisés. Par ailleurs, nous vous invitons à suivre
la règle de base suivante : instanciez un objet uniquement si vous en avez besoin. Vous
augmenterez ainsi les performances applicatives, car un objet instancié non employé occupe
inutilement de la mémoire.
« Tracer » avec parcimonie
Comme nous l’avons vu au chapitre 17 consacré au débogage, « tracer » le parcours d’une
application à l’aide de la méthode trace() permet de vérifier le bon fonctionnement d’un
=Flex3 FM.book Page 341 Mardi, 2. décembre 2008 3:32 15
Analyser les performances et optimiser l’application
CHAPITRE 18
341
processus. Cependant, chaque trace sera écrite sur le disque dur de l’utilisateur, provoquant
alors un ralentissement de l’application et une diminution de l’espace disque du client.
Pour pallier ce problème, il convient de désactiver les options de débogage lors de la
compilation (voir section précédente « Désactiver l’option de débogage ») ou d’intervenir
sur chaque poste client lorsque cela est possible (application intranet) et d’ajouter la ligne
de code suivante dans le fichier mm.cfg, situé dans le répertoire Documents and Settings/
nom_utilisateur :
TraceOutputFileEnable = 0
Vous désactiverez ainsi l’écriture des traces sur le poste de l’utilisateur et augmenterez la
performance de votre application.
Concevoir des interfaces graphiques
Nous vous conseillons de ne pas abuser des conteneurs (HBox, Panel…) sous peine de
réduire considérablement le temps d’initialisation de l’application. En effet, chaque
conteneur doit être positionné en fonction de son conteneur parent, ce qui demande des
ressources pour le calcul des positions de chacun. En ce qui concerne le positionnement
et le dimensionnement des composants, préférez la spécification dans le code des
propriétés adéquates (x, y, height et width) à l’utilisation des positionnements et dimensionnements relatifs.
De même, utilisez les effets avec parcimonie, car ils nécessitent également un certain
nombre de ressources de la part de la machine cliente, ce qui provoque un ralentissement
de l’exécution de l’application.
Déployer une application Flex
Déployer une application peut se résumer à copier les sources situées sur l’environnement
de développement vers l’environnement de déploiement accessible aux utilisateurs.
Certaines phases sont cependant indispensables et ne peuvent être omises.
L’incontournable liste de contrôle
Un peu à la manière d’un commandant de bord, nous devons vérifier certains prérequis
nécessaires au bon déploiement applicatif (tableau 18-1).
Tableau 18-1
Prérequis pour déployer une application
Élément à vérifier
Description
Compilation
Assurez-vous d’avoir bien compilé l’ensemble des éléments de votre
application à l’aide des compilateurs adéquats : mxmlc et compc.
Conteneur applicatif
Assurez-vous que vous disposer bien d’une page web contenant le
fichier SWF de votre application.
=Flex3 FM.book Page 342 Mardi, 2. décembre 2008 3:32 15
342
Comprendre Flex 3
PARTIE I
Tableau 18-1
Prérequis pour déployer une application (suite)
Élément à vérifier
Description
Détecteur de la version de Flash Player
Pour que la détection du Flash Player soit effective, vous devez disposer
du fichier AC_OETags.js.
Installation du Flash Player s’il n’est pas
détecté sur le poste client
Si vous souhaitez que le Flash Player soit installé automatiquement s’il
n’est pas présent sur le poste client, assurez-vous que vous disposez
bien des fichiers AC_OETags.js et playerProductInstall.swf.
Visualisation des sources
Déterminez s’il sera possible ou non de consulter les sources de
l’application.
Images/fichiers externes
Assurez-vous de bien déployer les images et fichiers externes nécessaires
au bon fonctionnement de votre application
Réseau
Vérifiez que l’ensemble des serveurs sont accessibles par votre application
(couche métier) et que celle-ci est accessible depuis l’extérieur (paramétrage des firewalls)
Services web
Vérifiez la disponibilité des services web que vous utilisez dans votre
application.
Tests applicatifs
Assurez-vous d’avoir effectué tous les tests applicatifs nécessaires.
Si tous les éléments du tableau 18-1 sont vérifiés et fonctionnels, vous pouvez procéder
au déploiement de votre application.
Mise en ligne de l’application
La mise en ligne (ou déploiement) d’une application Flex se réalise tout simplement en
copiant les fichiers issus de la compilation sur le serveur que vous avez dédié à l’hébergement de l’application.
Si vous décidez de déployer votre application à l’aide de Flex Builder 3, vous devrez
néanmoins procéder à une opération supplémentaire consistant à créer une version de
déploiement. Voici la marche à suivre pour cela :
1. Effectuez un clic droit sur le nom du projet et choisissez Export.
2. Une nouvelle fenêtre s’ouvre alors, vous demandant de préciser le type d’exportation
souhaité, sélectionnez Release Build et cliquez sur le bouton Next.
3. Dans l’interface qui s’affiche, indiquez si vous souhaitez ou non permettre la visualisation des sources de l’application en sélectionnant ou désélectionnant l’option Enable
source file.
4. Cliquez sur le bouton Finish pour terminer.
Si vous observez à présent l’arborescence de votre projet, vous constatez la présence
d’un répertoire nommé bin-release contenant les fichiers prêts à être copiés sur l’environnement de déploiement.
=Flex3 FM.book Page 343 Mardi, 2. décembre 2008 3:32 15
Analyser les performances et optimiser l’application
CHAPITRE 18
343
Page d’accueil
La page HTML contenant le fichier SWF porte le nom du projet. Il est tout à fait possible de la renommer
en index.html afin qu’elle soit considérée comme page d’accueil par le serveur web.
La figure 18-5 illustre le déploiement et l’utilisation d’une application Flex nous permettant
de mesurer l’importance de la phase de validation de chaque élément majeur de l’environnement applicatif.
Figure 18-5
Schéma de déploiement et d’utilisation d’une application
=Flex3 FM.book Page 344 Mardi, 2. décembre 2008 3:32 15
344
Comprendre Flex 3
PARTIE I
Étape 1 : le contenu du répertoire bin-release est copié dans le répertoire racine www du
serveur web.
Étapes 2 et 3 : l’utilisateur se connecte au serveur web qui lui délivre l’application Flex.
À ce stade, le travail du serveur web est terminé (si l’application ne comporte pas de
modules devant être téléchargés ultérieurement).
Étape 4 : l’application étant entièrement copiée sur le poste client, c’est à partir de celuici qu’elle va pouvoir se connecter au serveur de la couche métier, d’où l’importance du
paramétrage des adresses IP dans l’application et la configuration des firewalls permettant
l’accès à ces services.
Étape 5 : phase de communication entre le serveur contenant les services applicatifs et
celui contenant la base de données. Là encore, il convient de vérifier que tous les services
sont fonctionnels et que la communication n’est pas entravée.
En résumé
Au cours de ce chapitre, nous avons présenté les bases de l’utilisation de l’outil d’analyse
de Flex Builder Professionnel. Elles vous permettront de détecter les éventuelles erreurs
d’exécution ou d’allocation de mémoire de vos applications. Nous vous recommandons
d’utiliser le Profiler avant toute phase de déploiement afin d’obtenir une application de
qualité, car, ne l’oublions pas, celle-ci sera exécutée sur le poste client qui n’est peut-être
pas de la dernière génération. Une saturation de la mémoire peut, en effet, parfois avoir
des conséquences désastreuses sur l’utilisation de vos applications.
Pour compléter cette notion de qualité applicative, nous avons également consacré une
partie de ce chapitre à l’étude de l’optimisation et du processus de déploiement d’une
application. Les informations données dans ce chapitre ne sont pas exhaustives, il existe
de nombreux points d’optimisation et schémas de déploiement possibles en fonction de
l’architecture choisie. Cependant, vous disposez désormais des éléments indispensables
au bon déploiement de vos applications, que vous enrichirez par votre expérience.
Nous allons à présent sortir du cadre des applications exécutables à l’aide du navigateur
pour aborder le développement d’applications s’exécutant sur le poste client à l’aide du
runtime Adobe AIR.
=Flex3 FM.book Page 345 Mardi, 2. décembre 2008 3:32 15
19
Adobe AIR
Pour terminer la première partie de cet ouvrage, penchons-nous sur la machine virtuelle
Adobe AIR (Adobe Integrated Runtime). Grâce à elle, vous pourrez utiliser les méthodes
de développement d’applications web s’exécutant sans navigateur web, comme le ferait
une application développée en Java, Delphi ou C++. Adobe AIR étant basé sur la technologie Flash, il est donc naturel que le framework Flex donne la possibilité de développer
ce nouveau type d’applications portant le nom de RDA (Rich Desktop Application).
Le projet Adobe AIR
Adobe AIR (anciennement appelé Apollo) est une machine virtuelle, un peu à la manière
de la machine virtuelle de Java, permettant l’exécution d’applications web écrites en
Flash, HTML, JavaScript ou tout autre langage web. Il convient de souligner qu’une
application AIR s’exécutera de la même façon sur l’ensemble des systèmes d’exploitation
supportés par la machine virtuelle (Windows, Mac, Linux…), ce qui n’est pas le cas pour
d’autres langages.
Fonctionnement d’une application AIR
Le développement d’une application web AIR s’effectue à l’aide des outils proposés par
Adobe (Flash, Flex…) ou ses partenaires. Une fois le développement terminé, l’application
est exportée au format AIR puis proposée en téléchargement aux utilisateurs. Une fois
téléchargée, il suffit de l’installer. Cependant, la machine virtuelle d’Adobe doit être
présente sur le poste de l’utilisateur. Après l’installation, une icône apparaîtra sur le Bureau
du poste de l’utilisateur, lui permettant d’exécuter l’application téléchargée. Ceci témoigne
de la volonté des développeurs d’Abode AIR d’accorder autant d’importance à une
=Flex3 FM.book Page 346 Mardi, 2. décembre 2008 3:32 15
346
Comprendre Flex 3
PARTIE I
application web qu’à une application standard en ne la cantonnant plus à son exécution
dans un navigateur web.
Pour vous convaincre de la puissance de ces applications « nouvelle génération », nous
vous invitons à visiter le site d’Adobe à l’adresse suivante : http://www.adobe.com/
products/air/showcase/. Vous y trouverez de nombreux exemples d’applications web
AIR. Cette technologie est aujourd’hui utilisée par de grandes entreprises telles que
eBay, Yahoo! ou encore AOL, ce qui atteste de sa fiabilité et de son intérêt commercial
non négligeable.
Nouveaux composants
Comme nous venons de le voir, Adobe AIR exporte le monde des RIA (Rich Internet
Application) directement sur le poste de l’utilisateur (RDA – Rich Desktop Application).
Cette innovation va également donner naissance à une nouvelle fonctionnalité fort intéressante : l’accès aux données du disque dur de l’utilisateur à l’aide de composants spécifiques. Le tableau 19-1 présente l’ensemble des composants Adobe AIR et leur implémentation, illustrés page 348 (figures 19-1-a à 19-1-e).
Tableau 19-1
Les composants spécifique à Adobe AIR
Composant
Implémentation
FileSystemComboBox
<mx:Script>
<![CDATA[
Permet d’afficher les répertoires
et leur contenu dans une liste
déroulante.
// Importation de la classe de gestion des fichiers
import flash.filesystem.File;
]]>
</mx:Script>
<!-- Le répertoire parcouru est le Bureau de l’utilisateur:
➥File.desktopDirectory -->
<mx:FileSystemComboBox id="listeFichiersListeDeroulante" x="10"
➥y="59" directory="{File.desktopDirectory}" />
FileSystemDataGrid
Permet d’afficher les répertoires
et leur contenu dans un tableau.
FileSystemList
Permet d’afficher les répertoires
et leur contenu dans une liste.
<mx:Script>
<![CDATA[
import flash.filesystem.File;
]]>
</mx:Script>
<mx:FileSystemDataGrid id="listeFichiersTableau" x="10" y="133"
➥directory="{File.desktopDirectory}" />
<mx:Script>
<![CDATA[
import flash.filesystem.File;
]]>
</mx:Script>
<mx:FileSystemList id="listeFichiersListe" x="10" y="328"
➥width="502" height="104" directory="{File.desktopDirectory}" />
=Flex3 FM.book Page 347 Mardi, 2. décembre 2008 3:32 15
Adobe AIR
CHAPITRE 19
Tableau 19-1
Les composants spécifique à Adobe AIR (suite)
Composant
Implémentation
FileSystemTree
<mx:Script>
<![CDATA[
import flash.filesystem.File;
]]>
</mx:Script>
<mx:FileSystemTree id="listeFichiersArbre" x="10" y="466"
➥width="502" height="102" directory="{File.desktopDirectory}" />
Permet d’afficher les répertoires
et leur contenu sous forme
d’arborescence.
FileSystemHistoryButton
Permet de conserver un historique des répertoires visités.
Cet exemple met en relation le composant FileSystemList et deux composants FileSystemHistoryButton chargés d’enregistrer la navigation effectuée
dans le premier composant. Cet enregistrement permet à l’utilisateur de revenir
rapidement à un répertoire déjà visité.
Les commentaires ne sont insérés qu’a titre indicatif. Il convient de ne pas les
mentionner dans votre code à l’intérieur du composant FileSystemHistoryButon
comme nous l’avons fait, sous peine d’être confronté à un problème d’exécution
de votre projet.
<mx:Script>
<![CDATA[
import flash.filesystem.File;
]]>
</mx:Script>
<mx:HBox x="10" y="576">
<mx:FileSystemHistoryButton label="Precedent"
<!-- Stockage des répertoires parcourus -->
dataProvider="{listeFichiers.backHistory}"
<!-- Activation de la navigation antérieure sur le
➥composant listeFichiers -->
enabled="{listeFichiers.canNavigateBack}"
<!-- Action de retour en arrière déclenchée lors du
➥clic par l'utilisation -->
click="listeFichiers.navigateBack();"
<!-- Récupération de l'item sélectionné -->
itemClick="listeFichiers.navigateBack(event.index)"/>
<mx:FileSystemHistoryButton label="Suivant"
dataProvider="{listeFichiers.forwardHistory}"
enabled="{listeFichiers.canNavigateForward}"
click="listeFichiers.navigateForward();"
itemClick="listeFichiers.navigateForward(event.index)"/>
</mx:HBox>
<mx:FileSystemList id="listeFichiers" x="10" y="606"
➥height="102" width="503"/>
347
=Flex3 FM.book Page 348 Mardi, 2. décembre 2008 3:32 15
348
Comprendre Flex 3
PARTIE I
Figure 19-1-a
Le nouveau composant
FileSystemComboBox
Figure 19-1-b
Le nouveau composant
FileSystemDataGrid
Figure 19-1-c
Le nouveau composant
FileSystemList
Figure 19-1-d
Le nouveau composant
FileSystemTree
Figure 19-1-e
Le nouveau composant
FileSystemHistoryButton
=Flex3 FM.book Page 349 Mardi, 2. décembre 2008 3:32 15
Adobe AIR
CHAPITRE 19
349
Soulignons également la présence du composant HTML qui permet d’implémenter la visualisation de pages HTML. La portion de code suivante illustre cette fonctionnalité en
offrant la possibilité à l’utilisateur d’effectuer des recherches à l’aide de Google :
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥height="782">
<mx:HTML id="composantHTML” x="10" y="40" width="608" height="502"
location="http://www.google.fr" />
</mx:WindowedApplication>
Cet exemple peut également servir de base à la réalisation de votre propre navigateur
web, mais pour cela, il convient auparavant de voir comment créer des applications
Adobe AIR à l’aide de Flex Builder 3.
Première application AIR
Grâce à Flex Builder 3, il nous est possible de créer nos propres applications AIR. En
guise d’exemple, nous vous proposons de créer une application mettant en œuvre un
service web capable de récupérer l’évolution du CAC 40. Vous trouverez ce service web
à l’adresse suivante : http://www.webservicex.net/.
Création du projet
La première étape consiste à créer un nouveau projet Adobe AIR que nous nommerons
CAC40. Pour cela, cochez l’option Desktop application (runs in Adobe AIR) située sur la
fenêtre de création d’un nouveau projet Flex (figure 19-2).
Figure 19-2
Création d’une
application Adobe AIR
=Flex3 FM.book Page 350 Mardi, 2. décembre 2008 3:32 15
350
Comprendre Flex 3
PARTIE I
Procédez ensuite comme vous le feriez pour créer un nouveau projet Flex standard. Une
fois la création de l’application terminée, nous pouvons constater que l’arborescence du
projet Adobe AIR est identique à celle d’un projet Flex. Nous remarquons également la
disparition, dans le répertoire bin-debug, des fichiers permettant la gestion du navigateur
web et du Flash Player (AC_OETags.js, History.htm…). En effet, ceux-ci ne sont plus
nécessaires étant donné que l’application s’exécute sous la forme d’une application
locale.
Il est également intéressant de souligner que le fichier principal de l’application est un
fichier MXML. Nous emploierons donc les mêmes méthodes de développement
qu’auparavant. Si nous nous rendons dans le répertoire contenant les sources de ce
fichier, nous constatons la présence d’un élément qui distingue une application Adobe
AIR d’une application Flex : le remplacement de la balise <mx:Application> par la balise
<mx:WindowedApplication>. Il s’agit là de la seule différence entre un projet Flex standard
et un projet Flex Adobe AIR, le terme Windowed (fenêtré) évoquant bien la notion
d’application bureautique.
Pour preuve, voici le code que nous allons implémenter pour faire appel à notre service :
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥width="368" height="310" horizontalScrollPolicy="off" verticalScrollPolicy="off"
➥usePreloader="true">
<mx:WebService
id = "serviceCAC40"
wsdl="http://www.webservicex.net/stockquote.asmx?WSDL"
showBusyCursor="true">
<mx:operation name="GetQuote" resultFormat="object" fault="resultatKO(event)"
➥result="resultatOK(event)">
</mx:operation>
</mx:WebService>
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
public function resultatKO(e:FaultEvent):void
{
Alert.show("Erreur "+e.fault.faultString)
}
=Flex3 FM.book Page 351 Mardi, 2. décembre 2008 3:32 15
Adobe AIR
CHAPITRE 19
351
public function resultatOK(e:ResultEvent):void
{
var resultat:XML = new XML(e.result)
txt_entreprise.text = resultat.Stock[0].Name;
txt_date.text = resultat.Stock[0].Date;
txt_heure.text = resultat.Stock[0].Time;
txt_quotation.text = resultat.Stock[0].Last;
txt_evolution.text = resultat.Stock[0].Earns;
txt_variation.text = resultat.Stock[0].AnnRange;
}
public function invoquerService():void
{
serviceCAC40.GetQuote("CAC 40");
}
]]>
</mx:Script>
<mx:Button x="10" y="10" label="Invoquer le service" width="347"
➥click="invoquerService()"/>
<mx:Panel x="10" y="40" width="347" height="254" layout="absolute"
➥title="Quotation">
<mx:Form x="10" y="10" width="307" height="199" horizontalScrollPolicy="off"
➥verticalScrollPolicy="off">
<mx:FormItem label="Entreprise :">
<mx:TextInput width="150" id="txt_entreprise" editable="false"/>
</mx:FormItem>
<mx:FormItem label="Date :">
<mx:TextInput width="150" id="txt_date" editable="false"/>
</mx:FormItem>
<mx:FormItem label="Heure :">
<mx:TextInput width="150" id="txt_heure" editable="false"/>
</mx:FormItem>
<mx:FormItem label="Quotation :">
<mx:TextInput width="150" id="txt_quotation" editable="false"/>
</mx:FormItem>
<mx:FormItem label="Gain/Perte :">
<mx:TextInput width="150" id="txt_evolution" editable="false"/>
</mx:FormItem>
<mx:FormItem label="Variation annuelle :">
<mx:TextInput width="150" id="txt_variation" editable="false"/>
</mx:FormItem>
</mx:Form>
</mx:Panel>
</mx:WindowedApplication>
Le code utilisé ici est identique à celui que nous aurions implémenté pour une application
exécutée dans un navigateur.
=Flex3 FM.book Page 352 Mardi, 2. décembre 2008 3:32 15
352
Comprendre Flex 3
PARTIE I
Exécutons à présent l’application (figure 19-3). Elle semble fonctionner correctement,
néanmoins, au lieu de s’exécuter dans le navigateur web, elle se présente sous la forme
d’une application standard.
Figure 19-3
Exécution de l’application
Nous vous laissons donc imaginer les innombrables perspectives qu’offrent ces applications : dynamisme d’une application Flash exécutable sur tout environnement supportant
la machine virtuelle d’Adobe AIR, codée comme une application web, mais utilisable
comme un logiciel standard. La barrière entre les logiciels et les applications web vient
d’être franchie.
Déploiement de l’application
Le déploiement d’une application AIR à l’aide de Flex Builder 3 s’effectue de la même
manière que pour une application Flex standard, c’est-à-dire en exportant le projet vers
une version de déploiement (Release Build).
Afin de sécuriser vos applications et assurer un gage d’authenticité aux utilisateurs, il est
conseillé lors de la phase de déploiement de leur affecter un certificat. Si vous n’en
possédez pas encore, il vous est possible d’en créer un en cliquant sur le l’icône Create de
la fenêtre de déploiement. Si nous revenons à notre exemple, le fichier issu du déploiement n’est plus un fichier SWF comme nous en avons maintenant l’habitude, mais un
fichier AIR : CAC40.air.
Format de fichier AIR sans certificat
Si vous ne spécifiez aucun certificat pour votre application, le fichier issu de la compilation sera de type
AIRI (pour AIR Intermediate).
=Flex3 FM.book Page 353 Mardi, 2. décembre 2008 3:32 15
Adobe AIR
CHAPITRE 19
353
Pour déployer notre application, il suffit de copier ce fichier sur un serveur web à partir
duquel les utilisateurs pourront le télécharger et l’installer sur leur poste. Ils devront
cependant installer au préalable la machine virtuelle AIR, disponible à l’adresse
suivante : http://get.adobe.com/air/ (figure 19-4).
Figure 19-4
Installation de
la machine virtuelle
Adobe AIR
Sur le poste client
Le processus d’installation de l’application sur le poste client comprend les trois étapes suivantes (figure 19-5) :
Figure 19-5
Processus d’installation de l’application sur le poste client
1. Demande de confirmation et spécification du répertoire d’installation.
=Flex3 FM.book Page 354 Mardi, 2. décembre 2008 3:32 15
354
Comprendre Flex 3
PARTIE I
2. Création du raccourci sur le Bureau.
3. Exécution de l’application.
Une fois la machine virtuelle Adobe AIR installée, l’utilisateur possède une application web qu’il exécutera sur son
poste de la même façon que l’ensemble des applications qu’il utilise quotidiennement.
Gestion des données avec la bibliothèque SQLite
L’application que nous venons de développer fait appel à un service web, qui nous
retourne des informations stockées sur un serveur distant. Comme nous l’avons vu, une
application AIR peut être dotée de composants capables d’interagir avec l’ordinateur sur
lequel elle est installée (par exemple en accédant aux fichiers stockés sur le disque dur).
De la même manière, la bibliothèque SQLite nous permet de stocker des données sur le
poste de l’utilisateur, les rendant ainsi exploitables par toute application AIR.
La bibliothèque SQLite est un ensemble de fichiers écrits en langage C, permettant
d’implémenter un moteur SQL au sein d’une application. Contrairement à une base de
données classique (la communication avec l’application est basée sur le schéma client/
serveur), la base de donnée est alors « embarquée » dans l’application elle-même : les
données ne sont plus stockées dans des tables mais dans des fichiers textes.
Malgré cela, SQLite est basé sur la norme SQL92. Ceci nous permet donc d’utiliser les
instructions du langage SQL telles que CREATE TABLE pour la création de table, UPDATE
TABLE pour la modification de données, etc. Cependant, il est impossible de gérer les clés
étrangères (FOREIGN KEY), de créer des jointures externes (RIGHT/LEFT OUTER
JOIN), de gérer les droits des utilisateurs (GRANT/REVOKE) ou encore de supprimer
ou de modifier des colonnes d’une table.
Cependant, nous disposons tout de même des instructions principales du langage SQL
permettant de gérer les données comme nous le ferions dans une base de données classique.
Utiliser la bibliothèque SQLite dans une application AIR
Il est facile de faire intervenir la bibliothèque SQLite dans une application AIR car elle
est déjà intégrée au framework. Pour l’utiliser, il suffit donc de faire appel aux classes
détaillées dans le tableau 19-2.
Tableau 19-2
Classe
Classes nécessaires à l’utilisation de SQLite
Description
flash.filesystem.File
Permet de manipuler des fichiers sur le poste de l’utilisateur de l’application.
flash.data.SQLConnection
Gère les connexions au moteur de la base de données.
flash.data.SQLStatement
Permet d’exécuter des requêtes.
flash.data.SQLResult
Chargé d’accéder aux résultats des requêtes.
=Flex3 FM.book Page 355 Mardi, 2. décembre 2008 3:32 15
Adobe AIR
CHAPITRE 19
355
Le code ci-dessous, démontre l’usage de ces classes en réalisant la création d’une base de
données et d’une table test :
import
import
import
import
flash.data.SQLResult;
flash.filesystem.File;
flash.data.SQLStatement;
flash.data.SQLConnection;
public function utilisationSQLite():void{
//Création du fichier de bases de données sur le disque dur C
var fichier:File = new File("C:/baseDeDonnees.db");
//Création d’une nouvelle connexion au moteur de base de données
var sqlConnection:SQLConnection= new SQLConnection();
//Ouverture du fichier de la base de données
sqlConnection.open(fichier);
//Création d’une nouvelle requête
var requete:SQLStatement = new SQLStatement();
//Précision sur la connexion devant être utilisée pour l’exécution de la
➥requête
requete.sqlConnection = sqlConnection;
//Création de la requête à l’aide du langage SQL
requete.text = "CREATE TABLE tb_test (id INTEGER PRIMARY KEY AUTOINCREMENT )";
//Exécution de la requête
requete.execute();
}
SQLite par l’exemple
Pour illustrer la mise en place de la librairie SQLite au sein d’une application AIR, développons un carnet d’adresses. Ce projet, somme toute assez simple dans sa composition,
stockera les données nominatives des personnes répertoriées dans le carnet d’adresses.
L’interface graphique sera composée :
• d’un tableau contenant l’ensemble des contacts ;
• d’un formulaire permettant de manipuler les données d’un contact ;
• d’un bouton d’ajout ;
• d’un bouton de modification ;
• d’un bouton de suppression ;
• d’un bouton d’annulation.
=Flex3 FM.book Page 356 Mardi, 2. décembre 2008 3:32 15
356
Comprendre Flex 3
PARTIE I
Commençons donc par implémenter cette interface après avoir bien entendu créé un
nouveau projet Adode Air que nous nommerons airContact :
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" >
<mx:Panel x="10" y="10" width="430" height="375" layout="absolute"
➥title="Carnet d'adresses" id="pan_carnet">
<!-- TABLEAU -->
<mx:DataGrid id="dgContacts" x="10" y="10" width="390">
<mx:columns>
<mx:DataGridColumn headerText="Id" dataField="col0"
➥width="30"/>
<mx:DataGridColumn headerText="Prénom" dataField=
➥"col1"/>
<mx:DataGridColumn headerText="Nom" dataField=
➥"col2"/>
</mx:columns>
</mx:DataGrid>
<!-- FORMULAIRE -->
<mx:Form x="10" y="177" width="390" height="107"
➥verticalScrollPolicy="off" horizontalScrollPolicy="off">
<mx:FormItem label="Id">
<mx:TextInput id="txt_id" width="52" editable="false"
➥enabled="false"/>
</mx:FormItem>
<mx:FormItem label="Prénom : ">
<mx:TextInput id="txt_prenom"/>
</mx:FormItem>
<mx:FormItem label="Nom :">
<mx:TextInput id="txt_nom"/>
</mx:FormItem>
</mx:Form>
<!-- BOUTONS -->
<mx:Button id="btn_ajouter" x="330" y="297" label="Ajouter" />
<mx:Button id="btn_modifier" x="169" y="297" label="Modifier" />
<mx:Button id="btn_supprimer" x="73.5" y="297" label="Supprimer" />
<mx:Button x="251" y="297" label="Annuler" id="btn_annuler" />
</mx:Panel>
</mx:WindowedApplication>
=Flex3 FM.book Page 357 Mardi, 2. décembre 2008 3:32 15
Adobe AIR
CHAPITRE 19
357
Vient ensuite la mise en place de la logique d’interface qui, dans notre cas, peut se définir
par les règles suivantes :
• À l’initialisation de l’interface, seul le bouton Ajouter est actif.
• Si l’utilisateur sélectionne un contact dans le datagrid, seuls les boutons Supprimer,
Modifier et Annuler seront actifs.
Pour traduire ces règles, nous mettons en place les procédures ActionScript suivantes (le
résultat obtenu est illustré par la figure 19-06) :
Figure 19-06
Création de l’interface
graphique
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥creationComplete="initialisationIHM()" >
<mx:Script>
<![CDATA[
public function initialisationIHM():void
{
txt_id.text = "";
txt_nom.text="";
txt_prenom.text="";
btn_ajouter.enabled = true;
btn_modifier.enabled = false;
=Flex3 FM.book Page 358 Mardi, 2. décembre 2008 3:32 15
358
Comprendre Flex 3
PARTIE I
btn_supprimer.enabled = false;
btn_annuler.enabled = false;
}
public function modifiationSuppressionIHM():void{
btn_ajouter.enabled = false;
btn_modifier.enabled = true;
btn_supprimer.enabled = true;
btn_annuler.enabled = true;
}
]]>
</mx :Script>
[…]
</mx:WindowedApplication>
La dernière étape consiste à implémenter les procédures d’affichage, d’ajout, de modification et de suppression des données qui seront déclenchées par l’action de l’utilisateur
sur les différents éléments de l’interface :
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥creationComplete="initialisationIHM();SqliteConnection()">
<mx:Script>
<![CDATA[
import mx.events.ListEvent;
//Importation des classes nécessaires à SQLite
import flash.data.SQLResult;
import flash.filesystem.File;
import flash.data.SQLStatement;
import flash.data.SQLConnection;
public function initialisationIHM():void
{
txt_id.text = "";
txt_nom.text="";
txt_prenom.text="";
btn_ajouter.enabled = true;
btn_modifier.enabled = false;
btn_supprimer.enabled = false;
btn_annuler.enabled = false;
}
public function modifiationSuppressionIHM():void{
btn_ajouter.enabled = false;
btn_modifier.enabled = true;
=Flex3 FM.book Page 359 Mardi, 2. décembre 2008 3:32 15
Adobe AIR
CHAPITRE 19
btn_supprimer.enabled = true;
btn_annuler.enabled = true;
}
//Création d'une variable de connexion qui sera utilisée dans
//l'ensemble des procédures
public var sqlConnection:SQLConnection;
//Connexion au moteur de base de données
public function SqliteConnection():void
{
//Création du fichier de données nommé "base_Contacts.db"
var fichier:File = new File("C:/base_contacts.db");;
var fichierExiste:Boolean = fichier.exists;
sqlConnection = new SQLConnection();
sqlConnection.open(fichier);
//Si le fichier n’existe pas, on crée la table chargée de contenir les
➥enregistrements
if (!fichierExiste)
{
creationTable();
}
else
{
//Sinon on liste des contacts
listerContacts();
}
}
//Script de création de la table tb_contact chargée de contenir les contacts
➥du carnet d’adresses
private function creationTable():void
{
var stmt:SQLStatement = new SQLStatement();
stmt.sqlConnection = sqlConnection;
stmt.text = "CREATE TABLE tb_contact (id INTEGER PRIMARY KEY
➥AUTOINCREMENT , prenom longvarchar, nom longvarchar)";
stmt.execute();
}
//Listing des contacts
[Bindable]
public var tableauContacts:Array = new Array();
359
=Flex3 FM.book Page 360 Mardi, 2. décembre 2008 3:32 15
360
Comprendre Flex 3
PARTIE I
public function listerContacts():void
{
var stmt:SQLStatement = new SQLStatement();
stmt.sqlConnection = sqlConnection;
stmt.text = "SELECT * FROM tb_contact ORDER BY prenom ASC";
stmt.execute();
tableauContacts = stmt.getResult().data;
}
//Ajout d’un contact
public function ajouterContact():void
{
var prenom:String = txt_prenom.text;
var nom:String = txt_nom.text;
var stmt:SQLStatement = new SQLStatement();
stmt.sqlConnection = sqlConnection;
stmt.text = "INSERT INTO tb_contact (prenom,nom) VALUES
➥('"+prenom+"','"+nom+"')";
stmt.execute();
listerContacts();
initialisationIHM();
}
//Mise à jour d’un contact
private function miseAJourContact():void
{
var id:String = txt_id.text;
var prenom:String = txt_prenom.text;
var nom:String = txt_nom.text;
var stmt:SQLStatement = new SQLStatement();
stmt.sqlConnection = sqlConnection;
stmt.text = "UPDATE tb_contact SET prenom ='"+prenom+"', nom = '"+nom+"'
➥WHERE id ='"+id+"'" ;
stmt.execute();
//Mise à jour du tableau de données
listerContacts();
//Initialisation de l’interface graphique
initialisationIHM();
}
//Suppression d’un contact
public function supprimerContact():void
{
var id:String = txt_id.text;
var stmt:SQLStatement = new SQLStatement();
stmt.sqlConnection = sqlConnection;
=Flex3 FM.book Page 361 Mardi, 2. décembre 2008 3:32 15
Adobe AIR
CHAPITRE 19
361
stmt.text = "delete from tb_contact WHERE id ='"+id+"'";
stmt.execute();
listerContacts();
initialisationIHM();
}
//Affichage des données d’un contact après l’avoir sélectionné dans le tableau
public function afficherDonneesContact():void
{
txt_id.text = dgContacts.selectedItem.id;
txt_prenom.text = dgContacts.selectedItem.prenom;
txt_nom.text = dgContacts.selectedItem.nom;
modifiationSuppressionIHM();
}
]]>
</mx:Script>
<mx:Panel x="10" y="10" width="430" height="375" layout="absolute" title="Carnet
➥d'adresses" id="pan_carnet">
<!-- TABLEAU -->
<mx:DataGrid id="dgContacts" x="10" y="10" width="390" dataProvider
➥="{tableauContacts}" itemClick="afficherDonneesContact()">
<mx:columns>
<mx:DataGridColumn headerText="Id" dataField="id"
➥width="30"/>
<mx:DataGridColumn headerText="Prénom"
➥dataField="prenom"/>
<mx:DataGridColumn headerText="Nom" dataField="nom"/>
</mx:columns>
</mx:DataGrid>
<!-- FORMULAIRE -->
<mx:Form x="10" y="177" width="390" height="107"
➥verticalScrollPolicy="off" horizontalScrollPolicy="off">
<mx:FormItem label="Id">
<mx:TextInput id="txt_id" width="52" editable="false"
➥enabled="false"/>
</mx:FormItem>
<mx:FormItem label="Prénom : ">
<mx:TextInput id="txt_prenom"/>
</mx:FormItem>
<mx:FormItem label="Nom :">
<mx:TextInput id="txt_nom"/>
</mx:FormItem>
=Flex3 FM.book Page 362 Mardi, 2. décembre 2008 3:32 15
362
Comprendre Flex 3
PARTIE I
</mx:Form>
<!-- BOUTONS -->
<mx:Button id="btn_ajouter" x="330" y="297" label="Ajouter"
➥click="ajouterContact()" />
<mx:Button id="btn_modifier" x="169" y="297" label="Modifier"
➥click="miseAJourContact()" />
<mx:Button id="btn_supprimer" x="73.5" y="297" label="Supprimer"
➥click="supprimerContact()" />
<mx:Button x="251" y="297" label="Annuler" id="btn_annuler"
➥click="initialisationIHM()" />
</mx:Panel>
</mx:WindowedApplication>
En exécutant l’application, vous notez la création du fichier base_contacts.db à la racine
de votre disque dur C. Les instructions SQL sont bien réalisées lorsque vous cliquez sur
les différents éléments de l’interface.
Ce petit exemple nous a permis de voir qu’une application AIR peut facilement rendre les
mêmes services qu’une application bureautique classique (les données ne sont certes plus
distantes du poste utilisateur comme elles le seraient pour une application web). Adobe
AIR constitue donc une solution de développement bureautique intéressante et à
surveiller.
En résumé
Au cours de ce chapitre, nous avons vu les bases du développement d’applications AIR.
Désormais, vous êtes en mesure de créer, à partir d’un langage dédié au Web, des applications pouvant être installées et exécutées sur des postes clients, comme c’est le cas les
langages Java et C++, pour n’en citer que deux.
Ceci sonne-t-il le glas des applications dites standard ? Il serait prématuré d’avancer cela
car certaines applications sont optimisées en fonction de l’environnement sur lequel elles
sont exécutées, ce qui est actuellement impossible à réaliser pour une application AIR.
Toutefois, nous pouvons déjà affirmer que ce type d’application a un avenir prometteur et
que cette technologie mérite d’être suivie de très près.
=Flex3 FM.book Page 363 Mardi, 2. décembre 2008 3:32 15
Partie II
Cas pratiques
=Flex3 FM.book Page 364 Mardi, 2. décembre 2008 3:32 15
=Flex3 FM.book Page 365 Mardi, 2. décembre 2008 3:32 15
20
Création d’un projet
de site e-commerce
Nous voici à présent dans le premier chapitre consacré à la mise en pratique des connaissances acquises dans la première partie de cet ouvrage. Pour essayer d’être le plus proche
des besoins des entreprises en termes de réalisation d’application Internet, nous avons
choisi de développer une application de type e-commerce.
Pour mener à bien ce projet, nous commencerons par définir les besoins et les concevoir,
pour ensuite déterminer l’architecture applicative que nous allons adopter. Viendront
enfin la création du projet proprement dite et la configuration du serveur chargé de contenir
la couche métier et la couche de persistance des données.
Définition des besoins
E-Reflex est une société spécialisée dans la vente en ligne d’appareils photo numériques.
Pour dynamiser ses ventes et être en adéquation avec son produit de haute technologie, la
société souhaite effectuer la refonte de son site actuel avec le framework Flex.
Le dirigeant de la société E-Reflex souhaite que le projet puisse conserver son rôle de site
vitrine mais désire également dédier une partie du site aux commerciaux et gestionnaires
de stocks de l’entreprise. Ils pourront saisir les caractéristiques des produits en ligne mais
également avoir une vue d’ensemble sur les stocks de chacun d’eux. Bien sûr, il est
important que seuls les commerciaux et les membres de la société aient accès à cette
partie du site.
Pour la partie « vente en ligne », nous avons interrogé le dirigeant de la société afin qu’il
nous en décrive le processus :
=Flex3 FM.book Page 366 Mardi, 2. décembre 2008 3:32 15
366
Cas pratiques
PARTIE II
« Après avoir effectué une recherche sur la page d’accueil du site, l’utilisateur peut visualiser le détail du produit. Si ce produit l’intéresse et convient à ses attentes, il peut alors
l’ajouter à son panier d’achat.
La règle de gestion de base stipule qu’une commande donne naissance à une et une seule
facture. Néanmoins, si l’utilisateur souhaite payer en plusieurs fois, il devra contacter
notre service commercial qui pourra échelonner le paiement de sa commande éditant
ainsi plusieurs factures. Une autre chose très importante à signaler est que l’échéance de
paiement d’une facture est prévue à 30 jours après sa date de création. »
Il nous faut maintenant réaliser la conception de toutes ces informations.
Conception UML
Grâce aux explications du dirigeant, nous savons que l’entreprise propose à la vente des
produits achetés chez des fournisseurs. Nous allons donc représenter cette relation via un
diagramme de classes UML :
Figure 20-1
Diagramme de classe « Fournisseur – Appareil photo »
Après nous être renseignés auprès des commerciaux de l’entreprise, nous avons réalisé le
diagramme de classes illustré par la figure 20-1. La règle de gestion qui en découle est
qu’un appareil n’est disponible que chez un seul fournisseur. Nous avons également
décrit les attributs nécessaires à la gestion de stock :
• L’attribut stock détermine le nombre d’appareils actuellement en stock pour un appareil
donné.
• L’attribut stock_minimal fixe le seuil minimal qui, une fois dépassé, informe les commerciaux qu’une commande du produit devra être effectuée chez le fournisseur.
• L’attribut stock_maximal sert à déterminer le nombre de produits qui doivent être en
stock une fois la commande réalisée.
=Flex3 FM.book Page 367 Mardi, 2. décembre 2008 3:32 15
Création d’un projet de site e-commerce
CHAPITRE 20
367
Attardons-nous à présent sur le processus de commande et de facturation.
Figure 20-2
Diagramme de classes complet
D’après le diagramme de classes de la figure 20-2, nous pouvons déterminer qu’un utilisateur peut effectuer plusieurs commandes pouvant comporter chacune plusieurs appareils
photo. Comme nous l’a indiqué le dirigeant de l’entreprise E-Reflex, cette commande peut
donner lieu à plusieurs factures. Si nous observons attentivement la classe utilisateur,
nous apercevons l’ensemble des attributs nécessaires à son identification (login, motDePasse)
ainsi que l’attribut administrateur_site lui donnant accès ou non à la partie administration
du site.
Enfin n’oublions pas que toute commande effectuée influe sur la gestion du stock de chaque
appareil photo : les informations de stock devront être mises à jour à chaque nouvelle
commande d’un produit. Maintenant que nous avons les idées claires sur les souhaits des
=Flex3 FM.book Page 368 Mardi, 2. décembre 2008 3:32 15
368
Cas pratiques
PARTIE II
utilisateurs et que nous en avons réalisé la conception, il est temps de passer à l’étude de
l’architecture de notre projet.
Architecture du projet
Étant donné que le site doit être doté de deux parties distinctes (gestion des produits et
vente en ligne), nous devons optimiser l’architecture du projet de telle sorte que le visiteur
ne télécharge que la partie du site qui le concerne en fonction de son accréditation. C’est
pour cela que le projet sera basé sur une architecture modulaire. En procédant de cette
façon, nous découpons le projet en sous-applications, optimisant ainsi son exécution et le
temps de chargement.
Le site comportera donc deux modules, à savoir le module de gestion de produit et le
module de vente en ligne. L’ensemble sera contenu dans une application principale, qui
constituera le squelette du site E-Reflex.
Le module de gestion des produits permettra aux administrateurs du site de gérer les
fournisseurs et les produits associés (ajout, suppression, modification, gestion de stock…).
Quant au module de vente en ligne, il permettra aux utilisateurs :
• de créer un compte client ;
• d’effectuer des recherches sur l’ensemble des produits proposés par la société E-Reflex ;
• d’ajouter des articles à leur panier d’achat ;
• de réaliser une commande ;
• de payer en ligne.
Création du projet
Voilà, nous y sommes, nous avons identifié les besoins, réalisé la conception et déterminé
l’architecture globale de notre projet. Il est temps à présent de passer à sa réalisation.
Alors, allons-y !
Qu’allons nous réaliser ?
Nous avons souhaité que la partie « Étude de cas » soit à la fois pratique et source d’enseignements.
Notre objectif est de vous fournir une méthodologie de travail à adopter pour la réalisation d’applications
avec le framework Flex. Nous n’allons donc pas décrire l’ensemble des lignes de code permettant d’obtenir
un projet complet et fonctionnel, mais plutôt vous donner les éléments pour le réaliser vous-même, en vous
indiquant ce qu’il faut et ne faut pas faire. C’est en prenant conscience de nos erreurs que nous avançons.
Il serait donc inutile de décrire par la suite la réalisation complète du projet : beaucoup d’étapes seraient
redondantes et n’apporteraient rien. Nous allons donc nous consacrer à certaines parties du projet qui
nous paraissent importantes et vous permettront d’appliquer vos connaissances et d’en acquérir de
nouvelles. Néanmoins, vous pouvez télécharger une version complète et finalisée de ce projet sur la fiche
ouvrage sur le site des éditions Eyrolles : http://www.editions-eyrolles.com.
=Flex3 FM.book Page 369 Mardi, 2. décembre 2008 3:32 15
Création d’un projet de site e-commerce
CHAPITRE 20
369
Le squelette
Nous allons commencer par créer le squelette du site. Sa fonction principale sera de
contenir les deux modules applicatifs et de servir de point d’entrée des utilisateurs dans
l’application. Pour cela, ouvrons Flex Builder et créons un nouveau projet de type web
portant le nom eReflex. Ceci fait, nous allons pouvoir réaliser l’interface graphique du
site qui sera constituée :
• du logo de la société ;
• du composant viewStack chargé de contenir les modules ;
• d’une barre de navigation comportant une zone d’identification et deux boutons
permettant d’accéder à la partie vitrine ou administration du site.
Conseil
Pour stocker les images du site (logo et autres éléments d’identité graphiques), nous vous conseillons de
créer un sous-répertoire images dans le répertoire src du projet.
Logo de l’application
Le logo de l’application doit avoir les dimensions suivantes :
Largeur : 900 pixels
Hauteur : 94 pixels
Il vous est donc possible d’en créer un à votre convenance ou d’utiliser celui présent dans les sources de
l’application.
La figure 20-3 illustre le résultat obtenu après avoir saisi (dans le fichier ereflex.mxml du
projet) et exécuté le code ci-dessous :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Canvas width="900" height="730" horizontalCenter="0" verticalCenter="0">
<!-- LOGO -->
<mx:Image x="0" y="0" height="95" width="900" source="images/logo.jpg"/>
<!-- BARRE DE MENUS -->
<mx:ApplicationControlBar x="0" y="97" height="30" width="900">
<mx:Button label="Accueil" id="btn_accueil" click="conteneurVues
➥.selectedIndex = 0"/>
<mx:Button label="Administration" id="btn_administration"
➥click="conteneurVues.selectedIndex = 1"/>
=Flex3 FM.book Page 370 Mardi, 2. décembre 2008 3:32 15
370
Cas pratiques
PARTIE II
Figure 20-3
Interface graphique du projet
<mx:Canvas width="686" height="22">
<mx:Label x="144" y="2" text="Identifiant :" fontWeight="bold"
➥id="lab_identifiant"/>
<mx:Label x="365" y="2" text="Mot de passe :" fontWeight="bold"
➥id="lab_motDePasse"/>
<mx:TextInput x="226" y="0" width="118" id="txt_identifiant"/>
<mx:TextInput x="459" y="0" width="119" displayAsPassword="true"
➥id="txt_motDePasse"/>
<mx:Button x="586" y="1" label="Connecter" id="btn_action" />
</mx:Canvas>
</mx:ApplicationControlBar>
<!-- CONTENEUR DE VUES -->
<mx:ViewStack id="conteneurVues" x="0" y="132" width="900" height="590">
<mx:Canvas id="vueAccueil" label="Accueil" width="100%" height="100%">
<mx:Label x="10" y="10" text="ACCUEIL"/>
</mx:Canvas>
=Flex3 FM.book Page 371 Mardi, 2. décembre 2008 3:32 15
Création d’un projet de site e-commerce
CHAPITRE 20
371
<mx:Canvas id="vueAdministration" label="Administration" width="100%"
➥height="100%">
<mx:Label x="10" y="10" text="GESTION DES PRODUITS"/>
</mx:Canvas>
</mx:ViewStack>
</mx:Canvas>
</mx:Application>
La barre de navigation contient les boutons Accueil et Administration, faisant chacun
appel à une vue du composant ViewStack. Ainsi le bouton Accueil, affiche la vue portant
l’index 0 (correspondant au module de vente en ligne) et le bouton Administration affiche
la vue de gestion des produits.
Vous pouvez également constater la présence de zones de saisie servant à l’identification
de l’utilisateur pour lui permettre d’accéder à la partie administration du site.
L’étape suivante va consister à créer nos premières procédures ActionScript permettant
de sécuriser l’accès à l’espace d’administration du site.
Accès à l’espace d’administration
L’idée est de définir un identifiant et un mot de passe qui seront codés dans l’application.
Si l’utilisateur saisit correctement ces informations, il aura alors accès à la partie administration du site, sinon un message d’erreur s’affichera à l’écran.
Pour réaliser cela, nous devons définir la logique de fonctionnement de l’interface graphique, c’est-à-dire l’état des composants avant et après la connexion. Réalisons le tableau
suivant :
Tableau 20-1
Logique de fonctionnement de l’interface graphique
Action/
composants
Bouton
Administration
Libellés identifiant
et mot de passe
Zones
de texte
Bouton
de connexion
État initial
Invisible
Visibles
Visibles
et vides
Visible, porte le libellé
Connecter
Connexion
reussie
Visible
Invisibles
Invisibles
Visible, porte le libellé
Déconnecter
À partir de ce tableau, nous pouvons facilement déduire le principe de connexion suivant :
lorsque l’utilisateur se connecte, les zones d’identification disparaissent et le bouton
Administation devient accessible. Néanmoins, une subtilité réside dans le libellé du
bouton de connexion : à l’état initial, il porte le libellé Connecter ; une fois la connexion
réalisée, son libellé devient Déconnecter. Cela permettra de réaliser les actions de
connexion et de déconnexion avec un seul et même bouton.
=Flex3 FM.book Page 372 Mardi, 2. décembre 2008 3:32 15
372
Cas pratiques
PARTIE II
Voyons comment implémenter ceci :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥creationComplete="initialisationIHM()">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
//Procédure de connexion
private function connexion():void
{
if (btn_action.label == "Connecter")
{
if (txt_identifiant.text == 'abc' && txt_motDePasse.text=='1234')
{
connexionIHM();
}
else
{
Alert.show("Accès refusé")
}
}
else
{
initialisationIHM()
}
}
//Initialisation de l’interface graphique
private function initialisationIHM():void
{
btn_administration.visible = false;
lab_identifiant.visible = true;
lab_motDePasse.visible = true;
txt_identifiant.visible = true;
txt_motDePasse.visible=true;
btn_action.label= "Connecter"
}
//Une fois que l’on est connecté, certains éléments de l’interface sont visibles
➥d’autres sont cachés
private function connexionIHM():void
{
btn_administration.visible = true;
lab_identifiant.visible = false;
lab_motDePasse.visible = false;
txt_identifiant.visible = false;
txt_motDePasse.visible=false;
txt_identifiant.text = "";
txt_motDePasse.text = "";
=Flex3 FM.book Page 373 Mardi, 2. décembre 2008 3:32 15
Création d’un projet de site e-commerce
CHAPITRE 20
373
btn_action.label= "Déconnecter"
}
]]>
</mx:Script>
<mx:Canvas width="900" height="730" horizontalCenter="0" verticalCenter="0">
[…]
<!-- BARRE DE MENUS -->
<mx:ApplicationControlBar x="0" y="97" height="30" width="900">
<mx:Button label="Accueil" id="btn_accueil" click="conteneurVues
➥.selectedIndex = 0"/>
<mx:Button label="Administration" id="btn_administration"
➥click="conteneurVues.selectedIndex = 1"/>
<mx:Canvas width="686" height="22">
<mx:Label x="144" y="2" text="Identifiant :" fontWeight="bold"
➥id="lab_identifiant"/>
<mx:Label x="365" y="2" text="Mot de passe :" fontWeight="bold"
➥id="lab_motDePasse"/>
<mx:TextInput x="226" y="0" width="118" id="txt_identifiant"/>
<mx:TextInput x="459" y="0" width="119" displayAsPassword="true"
➥id="txt_motDePasse"/>
<mx:Button x="586" y="1" label="Connecter" id="btn_action"
➥click="connexion()"/>
</mx:Canvas>
</mx:ApplicationControlBar>
[…]
</mx:Canvas>
</mx:Application>
Voici l’explication fonctionnelle de ce code : lorsque l’utilisateur clique sur le bouton de
connexion, le système vérifie le libellé du bouton. Si ce dernier porte le libellé Connecter, le
système procède à la vérification de la concordance de l’identifiant et du mot de passe
sinon il réinitialise l’interface de connexion (figures 20-4 et 20-5).
Figure 20-4
Interface à l’état initial
=Flex3 FM.book Page 374 Mardi, 2. décembre 2008 3:32 15
374
Cas pratiques
PARTIE II
Figure 20-5
Connexion de l’utilisateur réussie
Le squelette est à présent terminé. Il ne reste plus qu’à y greffer les modules. Mais avant
de procéder à leur développement, il convient de préparer le serveur applicatif.
Préparation du serveur
Pour la couche métier et la couche de persistance des données, nous allons utiliser le trio
PHP/MySQL et AMFPHP.
Prérequis : PHP et AMFPHP
Nous vous invitons à vérifier que l’environnement PHP est correctement installé et configuré sur votre ordinateur.
Si cet environnement n’est pas présent, nous vous conseillons d’utiliser l’application
easyPHP pour la partie PHP/MySQL, disponible à l’adresse suivante : http://www.easyphp
.org/, où vous pourrez également obtenir de l’aide concernant son installation.
AMFPHP
L’installation d’AMFPHP est décrite au chapitre 13 de cet ouvrage.
La base de données MySQL
Voici le script de création de la base de données de notre projet, découlant du diagramme
de classes créé lors de la phase de conception.
Afin de minimiser le temps de création de la base de données, vous pouvez télécharger ce script sur la
fiche du livre, à l’adresse http://www.editions-eyrolles.com. Vous n’aurez plus qu’à l’exécuter sur
votre serveur MySQL.
--- CREATION DE LA BASE DE DONNEES REFLEX
-CREATE DATABASE IF NOT EXISTS reflex;
USE reflex;
=Flex3 FM.book Page 375 Mardi, 2. décembre 2008 3:32 15
Création d’un projet de site e-commerce
CHAPITRE 20
--- TABLE `tb_fournisseur`
-DROP TABLE IF EXISTS `tb_fournisseur`;
CREATE TABLE `tb_fournisseur` (
`id` int(10) unsigned NOT NULL auto_increment,
`nom` varchar(45) NOT NULL,
`adresse` text NOT NULL,
`cp` varchar(6) NOT NULL,
`ville` varchar(45) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
--- DONNEES TABLE `tb_fournisseur`
--
INSERT INTO `tb_fournisseur` (`id`,`nom`,`adresse`,`cp`,`ville`) VALUES
(1,'Fournisseur_1','25, rue basse','59000','Lille'),
(2,'Fournisseur_2','24, avenue de la photo','59100','Roubaix'),
(3,'Fournisseur_3','58 Av. jean Jaures\rAppt 44','59100','Roubaix');
--- TABLE `tb_appareilphoto`
-DROP TABLE IF EXISTS `tb_appareilphoto`;
CREATE TABLE `tb_appareilphoto` (
`id` int(10) unsigned NOT NULL auto_increment,
`description` text NOT NULL,
`prix` double NOT NULL,
`stock` int(10) unsigned NOT NULL,
`stockmin` int(10) unsigned NOT NULL,
`stockmax` int(10) unsigned NOT NULL,
`prixha` double NOT NULL,
`fournisseur` int(10) unsigned NOT NULL,
`nom` varchar(45) NOT NULL,
PRIMARY KEY USING BTREE (`id`),
KEY `FK_tb_appareilphoto_1` (`fournisseur`),
CONSTRAINT `FK_tb_appareilphoto_1` FOREIGN KEY (`fournisseur`) REFERENCES
➥`tb_fournisseur` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
--- DONNEES TABLE `tb_appareilphoto`
375
=Flex3 FM.book Page 376 Mardi, 2. décembre 2008 3:32 15
376
Cas pratiques
PARTIE II
--
INSERT INTO `tb_appareilphoto` (`id`,`description`,`prix`,`stock`,`stockmin`,
➥`stockmax`,`prixha`,`fournisseur`,`nom`) VALUES
(1,'Description',200,10,5,20,150,1,'Appareil_1'),
(2,'Description',50,5,2,20,30,1,'Appareil_2'),
(3,'Description',90,50,10,100,40,2,'Appareil_3'),
(4,'Description',180,4,1,84,100,2,'Appareil_4'),
(5,'description',500,2,0,3,400,2,'Appareil_5');
--- TABLE `tb_utilisateur`
-DROP TABLE IF EXISTS `tb_utilisateur`;
CREATE TABLE `tb_utilisateur` (
`id` int(10) unsigned NOT NULL auto_increment,
`prenom` varchar(20) NOT NULL,
`nom` varchar(20) NOT NULL,
`login` varchar(10) NOT NULL,
`motpasse` varchar(45) NOT NULL,
`email` varchar(45) NOT NULL,
`adresse` text NOT NULL,
`cp` varchar(5) NOT NULL,
`ville` varchar(30) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--- TABLE `tb_commande`
-DROP TABLE IF EXISTS `tb_commande`;
CREATE TABLE `tb_commande` (
`id` int(10) unsigned NOT NULL auto_increment,
`date` datetime NOT NULL,
`adresse` text NOT NULL,
`cp` varchar(5) NOT NULL,
`ville` varchar(45) NOT NULL,
`traitee` tinyint(1) NOT NULL,
`datetraitement` datetime NOT NULL,
`utilisateur` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `FK_tb_commande_1` (`utilisateur`),
CONSTRAINT `FK_tb_commande_1` FOREIGN KEY (`utilisateur`) REFERENCES
=Flex3 FM.book Page 377 Mardi, 2. décembre 2008 3:32 15
Création d’un projet de site e-commerce
CHAPITRE 20
377
➥`tb_utilisateur` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--- TABLE `tb_facture`
-DROP TABLE IF EXISTS `tb_facture`;
CREATE TABLE `tb_facture` (
`id` int(10) unsigned NOT NULL auto_increment,
`commande` int(10) unsigned NOT NULL,
`montant` double NOT NULL,
PRIMARY KEY (`id`),
KEY `FK_tb_facture_1` (`commande`),
CONSTRAINT `FK_tb_facture_1` FOREIGN KEY (`commande`) REFERENCES `tb_commande`
➥(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--- TABLE `tb_lignecommande`
-DROP TABLE IF EXISTS `tb_lignecommande`;
CREATE TABLE `tb_lignecommande` (
`appareilphoto` int(10) unsigned NOT NULL auto_increment,
`commande` varchar(45) NOT NULL,
PRIMARY KEY (`appareilphoto`,`commande`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Faisons le point
Ainsi s’achève la première partie de notre projet. Nous possédons à présent un squelette
applicatif qui va contenir les deux modules de notre site. L’accès sécurisé à la partie
d’administration du site a été implémenté de façon basique, certes, mais fonctionnelle.
Néanmoins, cette verification d’accès n’est pas réalisée à partir de la base de données,
comme cela était prévu dans la phase de conception. Cette fonctionnalité ne sera pas
décrite dans le projet, la laissant ainsi à votre charge. Nous allons néanmoins, dans le
chapitre suivant, aborder l’ensemble des notions qui vous permettront de la réaliser seul.
=Flex3 FM.book Page 378 Mardi, 2. décembre 2008 3:32 15
=Flex3 FM.book Page 379 Mardi, 2. décembre 2008 3:32 15
21
Module d’administration
du site e-commerce
Nous allons créer le premier module de notre site E-Reflex, permettant la gestion des
fournisseurs et des produits associés, ce qui nous permettra d’aborder les notions suivantes :
• l’utilisation du composant RemoteObject (chapitre 12) ;
• la notion de modèle (chapitre 2) ;
• le databinding (chapitre 11) ;
• l’utilisation de la bibliothèque AMFPHP (chapitre 13) ;
• la gestion des données (chapitre 11) ;
• la création de modules (chapitre 15) ;
• la demande de confirmation d’exécution de procédure (nouvelle notion) ;
• la lecture d’un fichier XML externe (nouvelle notion) ;
• l’alimentation du composant comboBox (chapitre 5) ;
• le déploiement et l’intégration d’un module (chapitre 15).
Important
Avant de poursuivre la lecture de ce chapitre, assurez-vous d’avoir terminé la réalisation du squelette
applicatif du chapitre 20, ainsi que la configuration de votre environnement de développement contenant
PHP/MySQL et AMFPHP.
=Flex3 FM.book Page 380 Mardi, 2. décembre 2008 3:32 15
380
Cas pratiques
PARTIE II
Création du module
Phase préparatoire
Nous allons commencer par créer un nouveau projet Flex que nous nommerons module
Administration, puis lui ajouterons un module en créant un fichier MXML Module au sein de
notre projet avec les caractéristiques suivantes (figure 21-1) :
• nom : modAdministration ;
• Width (largeur) = 900 pixels (largeur du canevas du composant viewStack chargé de
contenir le module) ;
• Heigth (hauteur) = 590 pixels ;
• non optimisé (utilisable dans toute application Flex).
Figure 21-1
Création du module
=Flex3 FM.book Page 381 Mardi, 2. décembre 2008 3:32 15
Module d’administration du site e-commerce
CHAPITRE 21
381
Pour pouvoir tester le module tout au long de sa phase de développement, nous allons
ajouter un composant ModuleLoader dans le fichier MXML du projet faisant appel au
module que nous somme en train de créer :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:ModuleLoader id="module" url="modAdministration.swf"> </mx:ModuleLoader>
</mx:Application>
Design de l’interface
Ce module va permettre la gestion des fournisseurs et des produits mis en vente. Nous
avons donc choisi de distinguer les deux gestions en implémentant un composant tab
Navigator comme suit :
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="900"
➥height="590">
<mx:TabNavigator x="0" y="0" width="900" height="590">
<!-- FOURNISSEURS -->
<mx:Canvas label="Fournisseurs" width="100%" height="100%">
</mx:Canvas>
<!-- PRODUITS -->
<mx:Canvas label="Produits" width="100%" height="100%">
</mx:Canvas>
</mx:TabNavigator>
</mx:Module>
Nous allons, dans un premier temps, nous consacrer à la mise en place de la gestion des
fournisseurs.
Gestion des fournisseurs
Créons tout d’abord l’interface graphique. Le code ci-dessous permet de réaliser l’interface graphique illustrée à la figure 21-2 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="900"
➥height="590">
<mx:TabNavigator x="0" y="0" width="900" height="590">
=Flex3 FM.book Page 382 Mardi, 2. décembre 2008 3:32 15
382
Cas pratiques
PARTIE II
<!-- FOURNISSEURS -->
<mx:Canvas label="Fournisseur" width="100%" height="100%" >
<mx:DataGrid id="dg_fournisseur" x="10" y="10" height="510">
<mx:columns>
<mx:DataGridColumn headerText="REF" dataField="id" width="70"/>
<mx:DataGridColumn headerText="NOM" dataField="nom"
➥width="250"/>
<mx:DataGridColumn headerText="--" dataField="adresse"
➥width="-1" visible="false"/>
<mx:DataGridColumn headerText="--" dataField="cp" width="-1"
➥visible="false"/>
<mx:DataGridColumn headerText="NOM" dataField="ville" width="-1"
➥visible="false"/>
</mx:columns>
</mx:DataGrid>
<mx:Panel id="pn_fournisseur" x="340" y="10" width="548" height="537"
➥layout="absolute" title="Informations fournisseur">
<mx:Form x="10" y="10" height="217" width="508"
➥horizontalScrollPolicy="off" verticalScrollPolicy="off">
<mx:FormHeading id="hf_entete"/>
<mx:FormItem label="REF :">
<mx:TextInput id="txt_ref" enabled="false" editable="false"
➥text=""/>
</mx:FormItem>
<mx:FormItem label="Nom :" required="true">
<mx:TextInput width="370" id="txt_nom"/>
</mx:FormItem>
<mx:FormItem label="Adresse :" required="true">
<mx:TextArea width="370" id="txt_adresse"/>
</mx:FormItem>
<mx:FormItem label="Code Postal" required="true">
<mx:TextInput width="113" id="txt_codePostal" maxChars="6"/>
</mx:FormItem>
<mx:FormItem label="Ville :" required="true">
<mx:TextInput width="370" id="txt_ville"/>
</mx:FormItem>
</mx:Form>
<mx:HBox x="10" y="235" width="100%" horizontalAlign="right">
<mx:Button id = "btn_supprimer" label="Supprimer" enabled=
➥"false"/>
<mx:Button id = "btn_modifier" label="Modifier" enabled="false"/>
<mx:Button id = "btn_ajouter" label="Ajouter" enabled=
➥"false" />
<mx:Button id = "btn_annuler" label="Annuler" enabled="false"/>
</mx:HBox>
=Flex3 FM.book Page 383 Mardi, 2. décembre 2008 3:32 15
Module d’administration du site e-commerce
CHAPITRE 21
383
</mx:Panel>
<mx:Button x="10" y="525" label="Nouveau" width="322" id="btn_nouveau" />
</mx:Canvas>
<!-- PRODUITS -->
<mx:Canvas label="Produits" width="100%" height="100%">
</mx:Canvas>
</mx:TabNavigator>
</mx:Module>
Les fournisseurs seront listés dans le datagrid de gauche tandis que la logique applicative
(ajout/suppression/modification) sera assurée par la partie de droite.
Figure 21-2
Interface graphique de gestion des fournisseurs
Gestion des produits
Réalisons à présent l’interface de gestion des produits (figure 21-3) :
=Flex3 FM.book Page 384 Mardi, 2. décembre 2008 3:32 15
384
Cas pratiques
PARTIE II
Figure 21-3
Interface de gestion des produits
<!-- PRODUITS -->
<mx:Canvas label="Produits" width="100%" height="100%" >
<mx:Form x="23" y="5" width="358" height="45" horizontalScrollPolicy
➥="off" verticalScrollPolicy="off">
<mx:FormItem label="Fournisseur :">
<mx:ComboBox width="230" id="cmb_fournisseurs" ></mx:ComboBox>
</mx:FormItem>
</mx:Form>
<mx:AdvancedDataGrid x="23" y="63" id="advdg_produit"
➥designViewDataType="flat" height="168" width="852" >
<mx:columns>
<mx:AdvancedDataGridColumn headerText="REF" dataField="id"
➥width="50"/>
<mx:AdvancedDataGridColumn headerText="NOM" dataField="nom"
➥width="150"/>
<mx:AdvancedDataGridColumn headerText="STOCK" dataField="stock"
➥width="50"/>
<mx:AdvancedDataGridColumn headerText="--" dataField=
=Flex3 FM.book Page 385 Mardi, 2. décembre 2008 3:32 15
Module d’administration du site e-commerce
CHAPITRE 21
➥"description" width="-1" visible="false"/>
<mx:AdvancedDataGridColumn headerText="--" dataField="stockmin"
➥width="-1" visible="false"/>
<mx:AdvancedDataGridColumn headerText="--" dataField="stockmax"
➥width="-1" visible="false"/>
<mx:AdvancedDataGridColumn headerText="--" dataField="prixha"
➥width="-1" visible="false"/>
<mx:AdvancedDataGridColumn headerText="--" dataField=
➥"fournisseur" width="-1" visible="false"/>
</mx:columns>
</mx:AdvancedDataGrid>
<mx:Button x="755" y="239" label="Nouveau produit"
➥id="btn_nouveauproduit"/>
<mx:Panel x="24" y="269" width="852" height="278" layout="absolute"
➥id="panel_produit">
<mx:Form x="10" y="10" height="181" width="526"
➥horizontalScrollPolicy="off" verticalScrollPolicy="off">
<mx:FormItem label="REF :">
<mx:TextInput id="txt_refproduit" width="80" enabled="false"
➥editable="true"/>
</mx:FormItem>
<mx:FormItem label="Nom :" required="true">
<mx:TextInput width="400" id="txt_nomproduit"/>
</mx:FormItem>
<mx:FormItem label="Description :" required="true">
<mx:TextArea height="63" width="400" id="txt_description"/>
</mx:FormItem>
<mx:FormItem label="Prix vente :" required="true">
<mx:TextInput width="80" id="txt_prixvente"/>
</mx:FormItem>
</mx:Form>
<mx:VRule x="567" y="10" width="1" height="181"/>
<mx:Form x="592" y="10" height="181" width="230"
➥horizontalScrollPolicy="off" verticalScrollPolicy="off">
<mx:FormItem label="Prix d'achat :" required="true">
<mx:TextInput width="80" id="txt_prixha"/>
</mx:FormItem>
<mx:FormItem label="Stock min :" required="true">
<mx:TextInput width="80" id="txt_stockmin"/>
</mx:FormItem>
<mx:FormItem label="Stock max :" required="true">
<mx:TextInput width="80" id="txt_stockmax"/>
</mx:FormItem>
<mx:FormItem label="Stock :" required="true">
<mx:TextInput width="80" id="txt_stock" editable="false"
➥enabled="false"/>
</mx:FormItem>
385
=Flex3 FM.book Page 386 Mardi, 2. décembre 2008 3:32 15
386
Cas pratiques
PARTIE II
<mx:FormItem label="Ref. fournisseur :">
<mx:TextInput width="80" id="txt_reffournisseur" enabled=
➥"false" editable="false"/>
</mx:FormItem>
</mx:Form>
<mx:HBox x="10" y="208" width="814" height="29"
➥horizontalAlign="right">
<mx:Button label="Supprimer" enabled="false"
➥id="btn_supprimerpt"/>
<mx:Button label="Modifier" enabled="false" id="btn_modifierpt"/>
<mx:Button label="Ajouter" enabled="false" id="btn_ajouterpt"/>
<mx:Button label="Annuler" enabled="false" id="btn_annulerpt"/>
</mx:HBox>
</mx:Panel>
</mx:Canvas>
Les fournisseurs sont listés dans une comboBox. Lorsque l’utilisateur en sélectionne un
dans la liste déroulante, cela met à jour le tableau contenant la liste des produits liés à ce
fournisseur. Nous avons choisi d’implémenter un tableau de type « Avancé » (advancedDatagrid) offrant à l’utilisateur des possibilités de tri avancées.
Le panel permet de gérer les données du produit sélectionné dans le tableau : suppression
et modification. Il autorise également l’ajout d’un nouveau produit.
Gestion des fournisseurs
Les différentes étapes du processus d’implémentation de la gestion des fournisseurs sont
les suivantes :
1. création des services PHP ;
2. création du modèle (classes ActionScript) ;
3. mise en place de la logique IHM (activation/désactivation des boutons) ;
4. mise en place de la logique applicative ;
5. mise en place de la validation du format et des champs à renseigner impérativement.
Création des services PHP
La phase initiale va consister à développer les services de la couche métier : le listing et
l’ajout/suppression/modification d’un fournisseur.
=Flex3 FM.book Page 387 Mardi, 2. décembre 2008 3:32 15
Module d’administration du site e-commerce
CHAPITRE 21
387
Création du fichier
Nous allons nous positionner dans le répertoire services d’AMFPHP et y créer le fichier
servModAdministration.php contenant le code suivant :
<?php
class ServModAdministration {
protected $serveur = 'localhost';
protected $mdp = 'mysql';
protected $utilisateur = 'root';
protected $baseDeDonnees = 'reflex';
protected $connexion = null;
protected $methodTable = null;
public function construct() {
/******************************************
/*
LISTE DES SERVICES
*
/******************************************/
$this->methodTable = array(
'serviceListerFournisseurs'=>array(
'description'=>'Listelesfournisseurs',
'access'=>'remote'
),
'serviceASMFournisseurs' => array(
'description'=>'Ajout Suppression Modification d\'un fournisseur',
'access'=>'remote'
)
);
}
}
?>
Les paramètres de connexion à la base de données sont contenus dans des attributs, suivis
de la déclaration des différents services. Il convient donc de les adapter en fonctions de
ce que vous avez paramétré lors de l’installation du serveur MySQL.
Lister les fournisseurs
Le premier service que nous allons implémenter est celui permettant de lister les fournisseurs contenus dans la base de données. Pour cela, après avoir effectué une connexion,
nous réaliserons une requête dont le résultat sera contenu dans un tableau et envoyé à
notre module :
function serviceListerFournisseurs ()
{
//connexion à la base de données MySQL avec nom d'hôte, login et password
$db = mysql_connect($this->serveur,$this->utilisateur,$this->mdp);
=Flex3 FM.book Page 388 Mardi, 2. décembre 2008 3:32 15
388
Cas pratiques
PARTIE II
//Sélection de la base de données
mysql_select_db($this->baseDeDonnees, $db);
//Requête
$Requete = "select * from tb_fournisseur";
//Stockage du résultat
$Resultat = mysql_query( $Requete );
//Alimentation d'un tableau avec la liste des fournisseurs
while ($Fournisseur = mysql_fetch_object ($Resultat))
{
$tableauFournisseurs[] = $Fournisseur;
}
//Envoi du tableau
return( $tableauFournisseurs);
}
Ajouter/supprimer/modifier un fournisseur
Ce service va nous permettre d’ajouter, modifier ou supprimer un fournisseur :
function serviceASMFournisseurs ($type,$id,$nom,$adresse,$cp,$ville)
{
//connexion à la base de données MySQL avec nom d'hôte, login et password
$db = mysql_connect($this->serveur,$this->utilisateur,$this->mdp);
//Sélection de la base de données
mysql_select_db($this->baseDeDonnees, $db);
//Requête SQL établie en fonction du cas d’ajout, de modification, de
➥suppression
switch ($type) {
case 'A' : $Requete = "insert into tb_fournisseur (nom,adresse,cp,ville)
➥values ('$nom','$adresse','$cp','$ville') ";
break;
case 'M' :
$Requete = "update tb_fournisseur set nom = '$nom',
➥adresse='$adresse', cp='$cp', ville='$ville' where id = $id ";
break;
case 'S' : $Requete = "delete from tb_fournisseur where id = $id ";
break;
}
$Resultat = mysql_query( $Requete );
return( "OK");
}
=Flex3 FM.book Page 389 Mardi, 2. décembre 2008 3:32 15
Module d’administration du site e-commerce
CHAPITRE 21
389
Le service reçoit, en complément, des informations sur le fournisseur et le type d’opération
à effectuer :
• A = ajout ;
• M = modification ;
• S = suppression.
Une requête est alors créée puis exécutée en fonction de ce paramètre. Grâce à cette
méthode, il est inutile de créer trois services différents pour l’ajout, la suppression et la
modification de fournisseur !
Test des services PHP
Avant de procéder à la programmation de notre module, nous devons nous assurer que les
services créés sont fonctionnels. Pour cela, nous vous invitons à vous rendre sur la page
du browser d’AMFPHP (http://localhost/amfphp/brower) et de réaliser l’ensemble des
tests nécessaires :
• exécution du service serviceListerFournisseurs ;
• ajout, suppression et modification d’un fournisseur.
Création des classes
Il est temps à présent d’implémenter le modèle de notre module qui va se charger de stocker
temporairement les informations et d’interagir avec les services que nous venons de créer.
Commençons par l’arborescence de répertoires nécessaire au stockage de nos classes afin
de créer le package. Rendez-vous dans le répertoire src, créez-y un répertoire com. Ajoutez
au répertoire nouvellement créé le répertoire ereflex et son sous-répertoire administration.
L’arborescence obtenue doit être semblable à celle-ci :
+ src
|------+ com
|---------+ereflex
|------------- administration
La première classe dont nous allons nous occuper est la classe fournisseur. Plaçons-nous
dans le répertoire administration et créons un nouveau fichier ActionScript Class nommé
Fournisseur et contenant le code suivant :
package com.ereflex.administration
{
import mx.rpc.remoting.mxml.RemoteObject;
public class Fournisseur
{
//Attributs
private var _id:int;
=Flex3 FM.book Page 390 Mardi, 2. décembre 2008 3:32 15
390
Cas pratiques
PARTIE II
private
private
private
private
var
var
var
var
_nom:String;
_adresse:String;
_cp:String;
_ville:String;
//Constructeur
public function Fournisseur(p_id:int,p_nom:String, p_adresse:String,
➥p_cp:String, p_ville:String )
{
_id = p_id;
_nom = p_nom;
_adresse = p_adresse;
_cp=p_cp;
_ville = p_ville;
}
//Getters
public function get id():int{
return _id;
}
public function get nom():String{
return _nom
}
public function get adresse():String{
return _adresse;
}
public function get cp():String{
return _cp;
}
public function get ville():String{
return _ville;
}
//Setters
public function set id(param:int):void{
_id = param;
}
public function set nom(param:String):void{
_nom = param;
=Flex3 FM.book Page 391 Mardi, 2. décembre 2008 3:32 15
Module d’administration du site e-commerce
CHAPITRE 21
}
public function set adresse(param:String):void{
_adresse = param;
}
public function set cp(param:String):void{
_cp = param;
}
public function set ville(param:String):void{
_ville = param;
}
//METHODES
public function ajouter(param:String):void
{
var service:RemoteObject = new RemoteObject();
service.endpoint = param;
service.showBusyCursor = true;
service.destination="amfphp";
service.source="ServModAdministration";
service.serviceASMFournisseurs('A',_id,_nom,_adresse,_cp,_ville);
}
public function modifier(param:String):void
{
var service:RemoteObject = new RemoteObject();
service.endpoint = param;
service.showBusyCursor = true;
service.destination="amfphp";
service.source="ServModAdministration";
service.serviceASMFournisseurs('M',_id,_nom,_adresse,_cp,_ville);
}
public function supprimer(param:String):void
{
var service:RemoteObject = new RemoteObject();
service.endpoint = param;
service.showBusyCursor = true;
service.destination="amfphp";
service.source="ServModAdministration";
service.serviceASMFournisseurs('S',_id,_nom,_adresse,_cp,_ville);
}
}
}
391
=Flex3 FM.book Page 392 Mardi, 2. décembre 2008 3:32 15
392
Cas pratiques
PARTIE II
L’ajout, la suppression et la modification font appel à un objet service issu de l’instanciation
de la classe RemoteObject. Le paramètre utilisé par ces méthodes sert à définir l’URL du
fichier gateway.php d’AMFPHP, permettant ainsi de réutiliser plus facilement cette classe
(nul besoin de la modifier en cas de changement d’URL).
Logique IHM
Mettre en place la logique IHM consiste à définir l’état des composants en fonction de
l’action de l’utilisateur. Par exemple, si l’utilisateur clique sur le bouton Nouveau, il est
évident que le bouton Supprimer ne doit pas être actif. Pour réaliser l’exhaustivité des
cas, nous allons établir le tableau suivant :
Tableau 21-1
État des composants en fonction des actions de l’utilisateur
Action\Bouton
Nouveau
Ajouter
Supprimer
Modifier
Annuler
Zones de texte
État initial
de l’IHM
Actif
Inactif
Inactif
Inactif
Inactif
Vides
Action
sur le bouton
Nouveau
–
Actif
Inactif
Inactif
Actif
Vides
En-tête du formulaire :
Nouveau Fournisseur
Sélection
d’une ligne
dans le tableau
Actif
Inactif
Actif
Actif
Inactif
Contiennent les informations
du fournisseur
En-tête du formulaire :
Fournisseur :
nom_du_fournisseur
Il ne nous reste plus qu’à coder tout ceci !
Créons un fichier ActionScript que nous nommerons FournisseurAS3.as, contenant le
code suivant :
/******************************************************************
*
IHM
* ****************************************************************/
//Mise à vide des zones de texte
public function RAZZonesTextes():void
{
txt_ref.text = "";
txt_nom.text = "";
txt_adresse.text = "";
txt_codePostal.text = "";
txt_ville.text = "";
hf_entete.label = "";
}
//État initial de l'IHM
public function initIHM():void
=Flex3 FM.book Page 393 Mardi, 2. décembre 2008 3:32 15
Module d’administration du site e-commerce
CHAPITRE 21
393
{
RAZZonesTextes()
btn_modifier.enabled = false;
btn_supprimer.enabled = false;
btn_ajouter.enabled = false;
btn_nouveau.enabled = true;
btn_annuler.enabled = false;
}
//Action sur le bouton Nouveau
public function clickBoutonNouveau():void
{
hf_entete.label = "Nouveau Fournisseur";
RAZZonesTextes();
btn_modifier.enabled = false;
btn_supprimer.enabled = false;
btn_ajouter.enabled = true;
btn_nouveau.enabled = false;
btn_annuler.enabled = true;
}
//Sélection d'une ligne dans le tableau
public function selectionLigneTableauIHM():void
{
btn_modifier.enabled = true;
btn_supprimer.enabled = true;
btn_ajouter.enabled = false;
btn_nouveau.enabled = true;
btn_annuler.enabled = false;
}
Modifions à présent le fichier MXML du module afin de prendre en compte la logique
précédemment codée :
<!-- Import du script -->
<mx:Script source="FournisseurAS3.As"></mx:Script>
[…]
<!-- Initialisation de l’interface -->
<mx:Canvas label="Fournisseurs" width="100%" height="100%" creationComplete="
➥initIHM()">
[…]
<!-- Action sur le bouton annuler -->
<mx:Button id = "btn_annuler" label="Annuler" click="initIHM()" enabled="false"/>
[…]
<!-- Action sur le bouton Nouveau -->
<mx:Button x="10" y="525" label="Nouveau" width="322" id="btn_nouveau"
➥click="clickBoutonNouveau()"/>
=Flex3 FM.book Page 394 Mardi, 2. décembre 2008 3:32 15
394
Cas pratiques
PARTIE II
Logique applicative
La logique applicative va consister à développer les procédures capables d’interagir avec
le modèle afin de satisfaire les règles de gestion.
Paramétrage d’AMFPHP
Dans l’optique du déploiement, nous allons créer un fichier XML contenant les informations nécessaires pour communiquer avec AMFPHP. Nous devrons en effet certainement
modifier l’adresse du serveur AMFPHP, ce qui devient très ardu lorsque celle-ci est
spécifiée dans le code de l’application.
Créons donc le fichier parametrage_amfphp.xml dans le répertoire src du projet, contenant
le code suivant :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<parametre>
<amfphp>
<serveur>http://localhost/amfphp/gateway.php</serveur>
</amfphp>
</parametre>
Pour lire ce fichier, nous devons créer une procédure ActionScript capable d’effectuer
cela, exécutée après la création du module :
Import mx.controls.Alert;
/****************************************************
*
CHARGEMENT DES PARAMETRES AMFPHP
* **************************************************/
public var URL:String;
public function chargerParametrageAmfPhp():void
{
var chargeur:URLLoader = new URLLoader ();
var adresse:URLRequest = new URLRequest ("parametrage_amfphp.xml");
chargeur.load(adresse);
chargeur.addEventListener(Event.COMPLETE, finDuChargement);
chargeur.addEventListener(IOErrorEvent.IO_ERROR, indiquerErreur);
}
public function finDuChargement ( event:Event ):void
{
var contenu:XML = new XML(event.target.data);
URL = contenu.amfphp.serveur;
}
public function indiquerErreur( event:Event ):void
{
Alert.show("Erreur lors du chargement des paramètres amfphp");
}
=Flex3 FM.book Page 395 Mardi, 2. décembre 2008 3:32 15
Module d’administration du site e-commerce
CHAPITRE 21
395
Le chargement du fichier XML consiste à instancier la classe URLLoader et lui affecter des
événements déclenchés selon le résultat du chargement du fichier.
Si le chargement s’est correctement déroulé, nous extrayons du fichier XML la valeur de
la balise serveur afin d’en affecter la variable publique URL. Cette procédure devant être
exécutée au chargement du module, nous allons affecter à sa méthode creationComplete la
procédure chargerParametrageAmfPhp() :
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="900"
➥height="590" creationComplete="chargerParametrageAmfPhp()">
Afficher la liste des fournisseurs
Pour afficher la liste des fournisseurs, nous allons utiliser la notion de DataBinding. En
effet, nous allons créer une variable tableauFournisseur comme source de liaison avec le
dataprovider du datagrid. Ainsi, lorsque tableauFournisseur sera mis à jour, datagrid le
sera aussi :
/****************************************************
*
APPEL DU SERVICE DE LISTING DES FOURNISSEURS
* **************************************************/
[Bindable]
public var tableauFournisseurs:Array;
public function listerFournisseurs():void
{
var service:RemoteObject = new RemoteObject();
service.endpoint = URL;
service.showBusyCursor = true;
service.destination="amfphp";
service.source="ServModAdministration";
service.serviceListerFournisseurs.addEventListener("result",
➥resultatOKListerFournisseurs);
service.serviceListerFournisseurs.addEventListener("fault", resultatKO)
service.serviceListerFournisseurs();
}
public function resultatOKListerFournisseurs(e:ResultEvent):void
{
tableauFournisseurs = e.result as Array;
}
public function resultatKO(e:FaultEvent):void
{
Alert.show(e.fault.faultString, 'Error');
}
Il convient à présent de modifier le fichier MXML du module afin de faire appel à la
procédure listerFournisseurs() lorsque le canvas contenant l’interface graphique est affiché
=Flex3 FM.book Page 396 Mardi, 2. décembre 2008 3:32 15
396
Cas pratiques
PARTIE II
à l’écran (événement show), sans oublier de créer la liaison entre le dataprovider du datagrid
et la variable tableauFournisseurs :
<mx:Canvas label="Fournisseurs" width="100%" height="100%"
➥show="listerFournisseurs();initIHM()">
<mx:DataGrid id="dg_fournisseur" x="10" y="10" height="510"
➥dataProvider="{tableauFournisseurs}">
Afficher les données d’un fournisseur sélectionné
Pour afficher les données d’un fournisseur sélectionné dans le datagrid, nous allons faire
appel à son événement itemClick() :
<mx:DataGrid id="dg_fournisseur" x="10" y="10" height="510"
➥dataProvider="{tableauFournisseurs}" itemClick="selectionnerFournisseur(event)">
Lorsque l’utilisateur sélectionne une ligne du datagrid, la procédure selectionner
Fournisseur() est alors exécutée, mettant à jour les zones de texte et exécutant la logique
IHM définie pour cette action :
/****************************************************
*
SELECTION D'UN FOURNISSEUR
* **************************************************/
public function selectionnerFournisseur(e:ListEvent):void
{
txt_ref.text = e.currentTarget.selectedItem.id;
txt_nom.text = e.currentTarget.selectedItem.nom;
txt_adresse.text = e.currentTarget.selectedItem.adresse;
txt_codePostal.text = e.currentTarget.selectedItem.cp;
txt_ville.text = e.currentTarget.selectedItem.ville;
hf_entete.label = "Fournisseur :"+e.currentTarget.selectedItem.nom;
selectionLigneTableauIHM();
}
Ajouter, supprimer, modifier un fournisseur
Le code ci-dessous décrit les trois procédures faisant appel aux méthodes ajouter, supprimer
et modifier de la classe Fournisseur :
/******************************************************************
*
AJOUT/MODIFICATION/SUPPRESSSION D'UN FOURNISSEUR
* ****************************************************************/
public function ajouterFournisseur():void
{
var identifiant:int = 0;
var nom:String = txt_nom.text;
var adresse:String = txt_adresse.text;
=Flex3 FM.book Page 397 Mardi, 2. décembre 2008 3:32 15
Module d’administration du site e-commerce
CHAPITRE 21
var cp:String = txt_codePostal.text;
var ville:String = txt_ville.text;
//Instanciation de la classe fournisseur
var obj_Fournisseur:Fournisseur = new
➥Fournisseur(identifiant,nom,adresse,cp,ville);
//Appel de la méthode d'ajout
obj_Fournisseur.ajouter(URL);
//Mise à jour du tableau des fournisseurs
listerFournisseurs();
initIHM()
}
public function modifierFournisseur():void
{
var identifiant:int = int(txt_ref.text);
var nom:String = txt_nom.text;
var adresse:String = txt_adresse.text;
var cp:String = txt_codePostal.text;
var ville:String = txt_ville.text;
//Instanciation de la classe fournisseur
var obj_Fournisseur_modif:Fournisseur = new
➥Fournisseur(identifiant,nom,adresse,cp,ville);
//Appel de la méthode de modification
obj_Fournisseur_modif.modifier(URL);
//Mise à jour du tableau des fournisseurs
listerFournisseurs();
initIHM()
}
public function supprimerFournisseur():void
{
Alert.show("Voulez vous supprimer ce fournisseur ?", "Suppression
➥fournisseur", Alert.OK | Alert.CANCEL, this,confirmerSuppression, null,
➥Alert.OK);
}
private function confirmerSuppression(eventObj:CloseEvent):void {
if (eventObj.detail==Alert.OK) {
397
=Flex3 FM.book Page 398 Mardi, 2. décembre 2008 3:32 15
398
Cas pratiques
PARTIE II
var
var
var
var
var
identifiant:int = int(txt_ref.text);
nom:String = txt_nom.text;
adresse:String = txt_adresse.text;
cp:String = txt_codePostal.text;
ville:String = txt_ville.text;
//Instanciation de la classe fournisseur
var obj_Fournisseur_suppr:Fournisseur = new
➥Fournisseur(identifiant,nom,adresse,cp,ville);
//Appel de la méthode de suppression
obj_Fournisseur_suppr.supprimer(URL);
//Mise à jour du tableau des fournisseurs
listerFournisseurs();
initIHM();
}
}
Si nous observons avec attention ces quelques lignes, nous remarquons que la suppression
d’un fournisseur n’est exécutée qu’après validation de la part de l’utilisateur. Cette
confirmation de suppression est réalisée à l’aide de la classe Alert, en créant une fenêtre
de confirmation comme suit :
Alert.show("Voulez vous supprimer ce fournisseur ?", "Suppression fournisseur",
➥Alert.OK | Alert.CANCEL, this, confirmerSuppression, null, Alert.OK);
Les paramètres utilisés sont les suivants :
1. texte de la demande ;
2. titre de la fenêtre ;
3. boutons présents sur la fenêtre (Ok et Annuler) ;
4. fenêtre parente ;
5. action à réaliser lors du clic sur l’un des boutons de la fenêtre ;
6. bouton cliqué par défaut lorsque l’utilisateur appuie sur la touche Entrée de son
clavier.
Il nous est alors possible d’intercepter le choix de l’utilisateur et de réaliser une action en
fonction de celui-ci:
if (eventObj.detail==Alert.OK) {
}
Vérification des données transmises
La dernière étape du processus va être la vérification des données saisies afin de répondre
aux attentes du système d’information.
=Flex3 FM.book Page 399 Mardi, 2. décembre 2008 3:32 15
Module d’administration du site e-commerce
CHAPITRE 21
399
Saisie obligatoire
Dans notre formulaire, les champs txt_nom, txt_adresse, txt_codePostal et txt_ville
doivent obligatoirement être saisis lors des phases d’ajout et de modification. Nous allons
donc commencer par mettre en place le validateur pour chacun de ces champs :
<mx:Script source="FournisseurAS3.As"></mx:Script>
<!-- VALIDATION DONNÉES -->
<mx:StringValidator id="v_nom" required="true" property="text" source="{txt_nom}"
➥requiredFieldError="Ce champ est obligatoire"></mx:StringValidator>
<mx:StringValidator id="v_adresse" required="true" property="text"
➥source="{txt_adresse}" requiredFieldError="Ce champ est obligatoire">
➥</mx:StringValidator>
<mx:StringValidator id="v_ville" required="true" property="text" source="{txt_ville}"
➥requiredFieldError="Ce champ est obligatoire"></mx:StringValidator>
Nous allons ensuite créer une fonction capable de valider notre formulaire, cette dernière
renvoyant la valeur 1 s’il est validé, 0 sinon :
/******************************************************************
*
VALIDATION DES DONNÉES
* ****************************************************************/
import mx.validators.Validator;
public function validationFormulaire():int{
var valide:int = 1;
//Stockage des erreurs de validation dans un tableau
var tableau_validation:Array = Validator.validateAll([v_nom,v_adresse,v_ville]);
// Si le tableau ne contient aucun élément, le traitement peut être effectué
if(tableau_validation.length != 0) {
valide = 0;
}
return valide;
}
Il ne nous reste plus qu’à modifier les procédures d’ajout et de modification d’un fournisseur
en n’exécutant ces actions que si le formulaire a été validé auparavant :
public function ajouterFournisseur():void
{
if(validationFormulaire() == 1)
{
var identifiant:int = 0;
var nom:String = txt_nom.text;
var adresse:String = txt_adresse.text;
var cp:String = txt_codePostal.text;
=Flex3 FM.book Page 400 Mardi, 2. décembre 2008 3:32 15
400
Cas pratiques
PARTIE II
var ville:String = txt_ville.text;
//Instanciation de la classe fournisseur
var obj_Fournisseur:Fournisseur = new
➥Fournisseur(identifiant,nom,adresse,cp,ville);
//Appel de la méthode d'ajout
obj_Fournisseur.ajouter(URL);
//Mise à jour du tableau des fournisseurs
listerFournisseurs();
//Réinitialisation des zones de texte
initIHM()
}
}
public function modifierFournisseur():void
{
if(validationFormulaire() == 1)
{
var identifiant:int = int(txt_ref.text);
var nom:String = txt_nom.text;
var adresse:String = txt_adresse.text;
var cp:String = txt_codePostal.text;
var ville:String = txt_ville.text;
//Instanciation de la classe fournisseur
var obj_Fournisseur_modif:Fournisseur = new
➥Fournisseur(identifiant,nom,adresse,cp,ville);
//Appel de la méthode d'ajout
obj_Fournisseur_modif.modifier(URL);
//Mise à jour du tableau des fournisseurs
listerFournisseurs();
//Réinitialisation des zones de texte
initIHM()
}
}
Vérifier le format du code postal
De la même façon que nous avons vérifié la bonne saisie des champs obligatoires, nous
allons employer un validateur (zipCodeValidator) pour vérifier le bon format et la présence
de données dans le champ txt_codePostal :
<!-- CODE POSTAL -->
<mx:ZipCodeValidator property="text" id="v_cp" source="{txt_codePostal}"
➥requiredFieldError="Ce champ est obligatoire" wrongLengthError="Format erroné">
➥</mx:ZipCodeValidator>
=Flex3 FM.book Page 401 Mardi, 2. décembre 2008 3:32 15
Module d’administration du site e-commerce
CHAPITRE 21
401
Enfin, modifions la procédure de validation du formulaire afin que ce nouvel élément soit
pris en compte :
/******************************************************************
*
VALIDATION DES DONNÉES
****************************************************************/
import mx.validators.Validator;
public function validationFormulaire():int{
var valide:int = 1;
//Stockage des erreurs de validation dans un tableau
var tableau_validation:Array = Validator.validateAll
➥([v_nom,v_adresse,v_cp,v_ville]);
// Si le tableau ne contient aucun élément, le traitement peut être effectué
if(tableau_validation.length != 0) {
valide = 0;
}
return valide;
}
Aspect graphique de la validation
Après avoir modifié ou ajouté un fournisseur, les zones de texte se réinitialisent, déclenchant la vérification de la saisie (à cause du DataBinding réalisé sur les validateurs). Elles
sont donc entourées de rouge, car leur propriété text contient une chaîne vide. Pour pallier
cela, nous allons créer deux procédures permettant d’activer et de désactiver les composants de validation. Ainsi, lorsque nous réinitialiserons le contenu des zones de saisie,
nous désactiverons auparavant la validation des champs pour les réactiver une fois la
réinitialisation terminée :
public function desactiverValidateurs():void
{
v_nom.enabled = false;
v_adresse.enabled = false;
v_cp.enabled = false;
v_ville.enabled = false;
}
public function activerValidateurs():void
{
v_nom.enabled = true;
v_adresse.enabled = true;
v_cp.enabled = true;
v_ville.enabled = true;
}
=Flex3 FM.book Page 402 Mardi, 2. décembre 2008 3:32 15
402
Cas pratiques
PARTIE II
//Modification de la procédure initIHM
public function initIHM():void
{
desactiverValidateurs();
RAZZonesTextes();
activerValidateurs();
btn_modifier.enabled = false;
btn_supprimer.enabled = false;
btn_ajouter.enabled = false;
btn_nouveau.enabled = true;
btn_annuler.enabled = false;
}
La première partie du module est à présent terminée. Nous pouvons vérifier son bon
fonctionnement en exécutant le projet moduleAdministration (figure 21-4).
Figure 21-4
Première partie du module fonctionnel
=Flex3 FM.book Page 403 Mardi, 2. décembre 2008 3:32 15
Module d’administration du site e-commerce
CHAPITRE 21
403
À vos claviers : la gestion des produits
Nous venons de terminer la première partie de notre module consistant à gérer les fournisseurs. Néanmoins, il reste à développer la partie concernant la gestion des produits.
Pour y parvenir il est nécessaire de valider les étapes suivantes :
• alimenter la liste déroulante contenant les fournisseurs ;
• lister les produits correspondants au fournisseur sélectionné dans la liste déroulante ;
• afficher les données du produit sélectionné dans les zones de texte correspondantes ;
• ajouter, supprimer, modifier un produit pour un fournisseur donné ;
• vérifier la qualité des données saisies avant modification et ajout.
À vous de jouer !
Quelques pistes de travail
Nous vous conseillons d’adopter la même démarche que celle que nous avons suivie pour
la partie précédente (création des services PHP, définition de la logique IHM…). De plus,
n’oubliez pas que l’alimentation du composant comboBox s’effectue selon un format bien
particulier (voir le chapitre 5).
Nous vous recommandons de créer un fichier ProduitAS3.as chargé de contenir la logique
applicative. Enfin, pour vous aider, nous vous dévoilons le code de base de la classe Appareil
Photo :
package com.ereflex.administration
{
public class AppareilPhoto
{
//Attributs
private var _id:int;
private var _nom:String;
private var _description:String;
private var _prix:Number;
private
private
private
private
private
var
var
var
var
var
_stock:int;
_stockMin:int;
_stockMax:int;
_prixHa:Number;
_fournisseur:int;
//Constructeur
public function AppareilPhoto(p_id:int, p_nom:String, p_description:String,
➥p_prixvente:Number, p_prixha:Number, p_stockmin:int, p_stockmax:int,
➥p_stock:int, p_fournisseur:int)
{
_id = p_id;
_nom = p_nom;
=Flex3 FM.book Page 404 Mardi, 2. décembre 2008 3:32 15
404
Cas pratiques
PARTIE II
_description = p_description;
_prix = p_prixvente;
_stock = p_stock;
_stockMin = p_stockmin;
_stockMax = p_stockmax;
_prixHa = p_prixha;
_fournisseur = p_fournisseur;
}
//Getters
public function get id():int{
return _id;
}
public function get nom():String{
return _nom;
}
public function get description():String{
return _description;
}
public function get prix():Number{
return _prix;
}
public function get stock():int{
return _stock;
}
public function get stockMin():int{
return _stockMin;
}
public function get stockMax():int{
return _stockMax;
}
public function get prixHa():Number{
return _prixHa;
}
public function get fournisseur():int{
return _fournisseur;
}
//Setters
public function set id(param:int):void{
_id = param;
}
public function set nom(param:String):void{
=Flex3 FM.book Page 405 Mardi, 2. décembre 2008 3:32 15
Module d’administration du site e-commerce
CHAPITRE 21
405
_nom = param;
}
public function set description(param:String):void{
_description = param;
}
public function set prix(param:Number):void{
_prix = param;
}
public function set stock(param:int):void{
_stockMin = param;
}
public function set stockMin(param:int):void{
_stockMin = param;
}
public function set stockMax(param:int):void{
_stockMax = param;
}
public function set prixHa(param:Number):void{
_prixHa = param;
}
public function set fournisseur(param:int):void{
_fournisseur = param;
}
}
}
Solution
Vous avez réussi ? Félicitations ! Dans le cas contraire voici une solution possible, afin
que vous puissiez comprendre vos erreurs.
Services PHP
Il convient tout d’abord d’ajouter les services dans le tableau contenant la liste de ceux-ci
dans le fichier servModAdministration.php :
function ServModAdministration ()
{
/******************************************
/*
LISTE DES SERVICES
*
/******************************************/
$this->methodTable = array(
"serviceListerFournisseurs" => array(
=Flex3 FM.book Page 406 Mardi, 2. décembre 2008 3:32 15
406
Cas pratiques
PARTIE II
"description" => "Liste les fournisseurs",
"access" => "remote"
),
"serviceASMFournisseurs" => array(
"description" => "Ajout Suppression Modification d'un fournisseur",
"access" => "remote"
),
"serviceComboFournisseurs" => array(
"description" => "Liste les fournisseurs dans la combo",
"access" => "remote"
),
"serviceListerProduitsFournisseurs" => array(
"description" => "Liste les produits d'un fournisseur",
"access" => "remote"
),
"serviceASMProduit" => array(
"description" => "Ajout Suppression Modification d'un produit",
"access" => "remote"
)
);
}
Alimentation de la liste déroulante
Rappelez-vous, nous avons vu dans le chapitre 5 que le composant comboBox avait besoin
de deux arguments lors de son alimentation :
• un label servant à afficher la donnée dans la liste ;
• un data permettant de stocker l’identifiant de la donnée affichée.
La requête permettant l’affichage des fournisseurs dans la liste déroulante devra donc
retourner ces deux arguments :
function serviceComboFournisseurs (){
//connexion à la base de données MySQL avec nom d'hôte, login et password
$db = mysql_connect($this->serveur,$this->utilisateur,$this->mdp);
//Sélection de la base de donnée
mysql_select_db($this->baseDeDonnees, $db);
//Requête
$Requete = "select nom as label, id as data from tb_fournisseur order by
➥nom asc";
$Resultat = mysql_query( $Requete );
//Alimentation d'un tableau avec la liste des fournisseurs
while ($Fournisseur = mysql_fetch_object ($Resultat))
{
$tableauFournisseurs[] = $Fournisseur;
}
=Flex3 FM.book Page 407 Mardi, 2. décembre 2008 3:32 15
Module d’administration du site e-commerce
CHAPITRE 21
407
//Envoi du tableau
return( $tableauFournisseurs);
}
Lister les produits du fournisseur sélectionné
Afin de lister les produits du fournisseur sélectionné, créez une méthode ayant pour paramètre l’identifiant du fournisseur sélectionné :
function serviceListerProduitsFournisseurs ($idFournisseur){
//connexion à la base de données MySQL avec nom d'hôte, login et password
$db = mysql_connect($this->serveur,$this->utilisateur,$this->mdp);
//Sélection de la base de donnée
mysql_select_db($this->baseDeDonnees, $db);
//Requête
$Requete = "select * from tb_appareilphoto where fournisseur =
➥$idFournisseur";
$Resultat = mysql_query( $Requete );
//Alimentation d'un tableau avec la liste des appareils photo
while ($Appareil = mysql_fetch_object ($Resultat))
{
$tableauAppareilsPhoto[] = $Appareil;
}
//Envoi du tableau
return( $tableauAppareilsPhoto);
}
Ajouter/supprimer/modifier un produit
Il suffit d’adapter la méthode utilisée pour l’ajout, la modification et la suppression d’un
fournisseur que nous avons développée auparavant :
function serviceASMProduit($type,$id,$nom,$description,$prix,$stock,$stockmin,
➥$stockmax,$prixha,$fournisseur){
//connexion à la base de données MySQL avec nom d'hôte, login et password
$db = mysql_connect($this->serveur,$this->utilisateur,$this->mdp);
//Sélection de la base de données
mysql_select_db($this->baseDeDonnees, $db);
=Flex3 FM.book Page 408 Mardi, 2. décembre 2008 3:32 15
408
Cas pratiques
PARTIE II
//Requête SQL établie en fonction du cas d’ajout, de modification, de
➥suppression
switch ($type) {
case 'A' : $Requete = "insert into tb_appareilphoto
➥(nom,description,prix,stock,stockmin,stockmax,prixha,fournisseur)
➥values ('$nom','$description','$prix','$stock','$stockmin',
➥'$stockmax','$prixha','$fournisseur') ";
break;
case 'M' : $Requete = "update tb_appareilphoto set nom='$nom',
➥description = '$description', prix='$prix', stock='$stock',
➥stockmin='$stockmin', stockmax='$stockmax', prixha = '$prixha'
➥where id = $id ";
break;
case 'S' : $Requete = "delete from tb_appareilphoto where id = $id ";
break;
}
$Resultat = mysql_query( $Requete );
//Envoi du résultat
return( "OK");
}
Classe AppareilPhoto
Les modifications que nous devons apporter à la classe AppareilPhoto concernent l’ajout
des méthodes ajouter, modifier et supprimer :
package com.ereflex.administration
{
import mx.rpc.remoting.mxml.RemoteObject;
public class AppareilPhoto
{
[…]
//MÉTHODES
public function ajouter(param:String):void
{
var service:RemoteObject = new RemoteObject();
service.endpoint = param;
service.showBusyCursor = true;
service.destination="amfphp";
service.source="ServModAdministration";
service.serviceASMProduit('A',_id,_nom,_description,_prix,_stock,
➥_stockMin,_stockMax,_prixHa,_fournisseur);
}
=Flex3 FM.book Page 409 Mardi, 2. décembre 2008 3:32 15
Module d’administration du site e-commerce
CHAPITRE 21
409
public function modifier(param:String):void
{
var service:RemoteObject = new RemoteObject();
service.endpoint = param;
service.showBusyCursor = true;
service.destination="amfphp";
service.source="ServModAdministration";
service.serviceASMProduit('M',_id,_nom,_description,_prix,
➥_stock,_stockMin,_stockMax,_prixHa,_fournisseur);
}
public function supprimer(param:String):void
{
var service:RemoteObject = new RemoteObject();
service.endpoint = param;
service.showBusyCursor = true;
service.destination="amfphp";
service.source="ServModAdministration";
service.serviceASMProduit('S',_id,_nom,_description,_prix,
➥_stock,_stockMin,_stockMax,_prixHa,_fournisseur);
}
}
Logique IHM
Nous allons, comme pour la partie permettant la gestion des fournisseurs, dresser un
tableau des actions de l’utilisateur possibles et indiquer le comportement correspondant
des composants de l’interface graphique :
Tableau 21-2
État des composants en fonction des actions de l’utilisateur
Action/bouton
Modifier
Nouveau
Supprimer
Ajouter
Annuler
Zone de texte
stock
Zones de texte
État initial
Inactif
Actif
Inactif
Inactif
Inactif
Non éditable
et non active
Vides
Action
sur le bouton
nouveau
Inactif
Inactif
Inactif
Actif
Actif
Éditable
et active
Vides sauf la zone de
texte contenant la référence du fournisseur qui
doit contenir la valeur de
l’identifiant du fournisseur
sélectionné
Sélection
d’une ligne
dans le tableau
Actif
Actif
Actif
Inactif
Inactif
Non éditable
et non active
Contient les données du
produit sélectionné
=Flex3 FM.book Page 410 Mardi, 2. décembre 2008 3:32 15
410
Cas pratiques
PARTIE II
Il convient ensuite d’éditer le fichier ProduitAS3.as en ajoutant ces procédures :
/****************************************************
*
IHM
* **************************************************/
//Mise à vide des zones de texte
public function RAZZonesTexteProduit():void
{
txt_refproduit.text = "";
txt_nomproduit.text = "";
txt_description.text = "";
txt_prixvente.text = "";
txt_prixha.text = "";
txt_stockmin.text = "";
txt_stockmax.text = "";
txt_stock.text = "";
txt_reffournisseur.text = "";
panel_produit.title = "";
}
//État initial de l'IHM
public function initIHMProduit():void
{
RAZZonesTexteProduit();
btn_nouveauproduit.enabled = true;
btn_supprimerpt.enabled = false;
btn_modifierpt.enabled = false;
btn_ajouterpt.enabled = false;
btn_annulerpt.enabled = false;
txt_stock.enabled = false;
txt_stock.editable = false;
}
//Action sur le bouton Nouveau
public function clickBoutonNouveauProduit():void
{
RAZZonesTexteProduit();
panel_produit.title = "Nouveau produit";
btn_nouveauproduit.enabled = false;
btn_supprimerpt.enabled = false;
btn_modifierpt.enabled = false;
btn_ajouterpt.enabled = true;
btn_annulerpt.enabled = true;
txt_stock.enabled = true;
txt_stock.editable = true;
//Récupération de l'identifiant du fournisseur
txt_reffournisseur.text = cmb_fournisseurs.selectedItem.data;
}
=Flex3 FM.book Page 411 Mardi, 2. décembre 2008 3:32 15
Module d’administration du site e-commerce
CHAPITRE 21
411
//Sélection d'une ligne dans le tableau
public function selectionLigneTableauProduitIHM():void
{
btn_nouveauproduit.enabled = true;
btn_supprimerpt.enabled = true;
btn_modifierpt.enabled = true;
btn_ajouterpt.enabled = false;
btn_annulerpt.enabled = false;
}
Validation des données
Il faut, tout d’abord, mettre en place les validateurs adéquats dans le fichier MXML, puis
créer la procédure de validation du formulaire dans le fichier ProduitAS3.as :
<!-- VALIDATION DES DONNÉES TEXTE -->
<mx:StringValidator id="v_description" required="true" property="text"
➥source="{txt_description}" requiredFieldError="Ce champ est obligatoire">
➥</mx:StringValidator>
<mx:StringValidator id="v_nomproduit" required="true" property="text"
➥source="{txt_nomproduit}" requiredFieldError="Ce champ est obligatoire">
➥</mx:StringValidator>
<!-- FORMAT DES DONNÉES NUMÉRIQUES -->
<mx:NumberValidator id="v_prixvente" required="true" property="text"
➥source="{txt_prixvente}" requiredFieldError="Ce champ est obligatoire"
➥invalidCharError="Format erroné !" ></mx:NumberValidator>
<mx:NumberValidator id="v_prixha" required="true" property="text"
➥source="{txt_prixha}" requiredFieldError="Ce champ est obligatoire"
➥invalidCharError="Format erroné !"></mx:NumberValidator>
<mx:NumberValidator id="v_stockmin" required="true" property="text"
➥source="{txt_stockmin}" requiredFieldError="Ce champ est obligatoire"
➥invalidCharError="Format erroné !"></mx:NumberValidator>
<mx:NumberValidator id="v_stockmax" required="true" property="text"
➥source="{txt_stockmax}" requiredFieldError="Ce champ est obligatoire"
➥invalidCharError="Format erroné !"></mx:NumberValidator>
<mx:NumberValidator id="v_stock" required="true" property="text" source="{txt_stock}"
➥requiredFieldError="Ce champ est obligatoire" invalidCharError="Format erroné !">
➥</mx:NumberValidator>
/******************************************************************
*
VALIDATION DES DONNÉES
* ****************************************************************/
import mx.validators.Validator;
public function validationFormulaireProduit():int{
=Flex3 FM.book Page 412 Mardi, 2. décembre 2008 3:32 15
412
Cas pratiques
PARTIE II
var valide:int = 1;
//Stockage des erreurs de validation dans un tableau
var tableau_validation:Array = Validator.validateAll([v_nomproduit,
➥v_description,v_prixvente,v_prixha,v_stockmin,v_stockmax,v_stock]);
// Si le tableau ne contient aucun élément, le traitement peut être effectué
if(tableau_validation.length != 0) {
valide = 0;
}
return valide;
}
public function desactiverValidateursProduit():void
{
v_nomproduit.enabled = false;
v_description.enabled = false;
v_prixvente.enabled = false;
v_prixha.enabled = false;
v_stockmin.enabled = false;
v_stockmax.enabled = false;
v_stock.enabled = false;
}
public function activerValidateursProduit():void
{
v_nomproduit.enabled = true;
v_description.enabled = true;
v_prixvente.enabled = true;
v_prixha.enabled = true;
v_stockmin.enabled = true;
v_stockmax.enabled = true;
v_stock.enabled = true;
}
Nous en profitons également pour modifier la procédure initIHMProduit(), afin de désactiver
la vérification des données avant chaque réinitialisation du formulaire :
//État initial de l'IHM
public function initIHMProduit():void
{
desactiverValidateursProduit();
RAZZonesTexteProduit();
activerValidateursProduit();
btn_nouveauproduit.enabled = true;
btn_supprimerpt.enabled = false;
=Flex3 FM.book Page 413 Mardi, 2. décembre 2008 3:32 15
Module d’administration du site e-commerce
CHAPITRE 21
btn_modifierpt.enabled = false;
btn_ajouterpt.enabled = false;
btn_annulerpt.enabled = false;
txt_stock.enabled = false;
txt_stock.editable = false;
}
Logique applicative
Voici le code des procédures permettant :
• d’alimenter la liste déroulante ;
• de lister les produits d’un fournisseur sélectionné ;
• de visualiser les données d’un produit sélectionné dans le tableau ;
• d’ajouter, supprimer et modifier un produit.
/****************************************************
*
ALIMENTATION DE LA COMBOBOX
* **************************************************/
public function alimenterComboFournisseurs():void
{
var service:RemoteObject = new RemoteObject();
service.endpoint = URL;
service.showBusyCursor = true;
service.destination="amfphp";
service.source="ServModAdministration";
service.serviceComboFournisseurs.addEventListener("result",
➥resultatOKComboFournisseurs);
service.serviceComboFournisseurs.addEventListener("fault", resultatKO)
service.serviceComboFournisseurs();
}
public function resultatOKComboFournisseurs(e:ResultEvent):void
{
cmb_fournisseurs.dataProvider = e.result as Array;
//>> ON SÉLECTIONNE LE PREMIER ENREGISTREMENT DE LA LISTE DÉROULANTE
cmb_fournisseurs.selectedIndex = 0;
//>> ON AFFICHE LES DONNÉES DU FOURNISSEUR SÉLECTIONNÉ
listerAppareils();
}
/*********************************************************
* LISTING DES PRODUITS POUR LE FOURNISSEUR SÉLECTIONNÉ
* *******************************************************/
[Bindable]
public var tableauProduits:Array;
413
=Flex3 FM.book Page 414 Mardi, 2. décembre 2008 3:32 15
414
Cas pratiques
PARTIE II
public function listerAppareils():void
{
var service:RemoteObject = new RemoteObject();
service.endpoint = URL;
service.showBusyCursor = true;
service.destination="amfphp";
service.source="ServModAdministration";
service.serviceListerProduitsFournisseurs.addEventListener("result",
➥resultatOKListerAppareils );
service.serviceListerProduitsFournisseurs.addEventListener("fault", resultatKO)
//Récupération de la valeur sélectionnée dans la comboBox
service.serviceListerProduitsFournisseurs(cmb_fournisseurs.selectedItem.data);
}
public function resultatOKListerAppareils (e:ResultEvent):void
{
tableauProduits = e.result as Array
}
public function resultatOKListerAppareils (e:ResultEvent):void
{
advdg_produit.dataProvider = e.result as Array
}
/****************************************************
*
SÉLECTION D'UN PRODUIT
* **************************************************/
Import mx.events.ListEvent;
public function selectionnerProduit(e:ListEvent):void
{
txt_refproduit.text = e.currentTarget.selectedItem.id;
txt_nomproduit.text = e.currentTarget.selectedItem.nom;
txt_description.text = e.currentTarget.selectedItem.description;
txt_prixvente.text = e.currentTarget.selectedItem.prix;
txt_prixha.text = e.currentTarget.selectedItem.prixha;
txt_stockmin.text = e.currentTarget.selectedItem.stockmin;
txt_stockmax.text = e.currentTarget.selectedItem.stockmax;
txt_stock.text = e.currentTarget.selectedItem.stock;
txt_reffournisseur.text = e.currentTarget.selectedItem.fournisseur;
panel_produit.title = e.currentTarget.selectedItem.nom;
selectionLigneTableauProduitIHM()
}
/******************************************************************
*
AJOUT/MODIFICATION/SUPPRESSION D'UN PRODUIT
*****************************************************************/
public function ajouterProduit():void
=Flex3 FM.book Page 415 Mardi, 2. décembre 2008 3:32 15
Module d’administration du site e-commerce
CHAPITRE 21
{
if(validationFormulaireProduit() == 1) {
var identifiant:int = 0;
var nom:String = txt_nomproduit.text;
var description:String = txt_description.text;
var prix:Number = Number(txt_prixvente.text);
var stock:int = int(txt_stock.text);
var stockMin:int = int(txt_stockmin.text);
var stockMax:int = int(txt_stockmax.text);
var prixHa:Number = Number(txt_prixha.text);
var fournisseur:int = int(txt_reffournisseur.text);
//Instanciation de la classe AppareilPhoto
var obj_Produit:AppareilPhoto = new AppareilPhoto(identifiant,nom,
➥description,prix,prixHa,stockMin,stockMax,stock,fournisseur);
//Appel de la méthode d'ajout
obj_Produit.ajouter(URL);
//Mise à jour du tableau des produits
listerAppareils();
//Réinitialisation des zones de texte
initIHMProduit()
}
}
public function modifierProduit():void
{
if(validationFormulaireProduit() == 1) {
var identifiant:int = int(txt_refproduit.text);
var nom:String = txt_nomproduit.text;
var description:String = txt_description.text;
var prix:Number = Number(txt_prixvente.text);
var stock:int = int(txt_stock.text);
var stockMin:int = int(txt_stockmin.text);
var stockMax:int = int(txt_stockmax.text);
var prixHa:Number = Number(txt_prixha.text);
var fournisseur:int = int(txt_reffournisseur.text);
//Instanciation de la classe AppareilPhoto
var obj_Produit_modifier:AppareilPhoto = new AppareilPhoto(identifiant,nom,
➥description,prix,prixHa,stockMin,stockMax,stock,fournisseur);
//Appel de la méthode de modification
obj_Produit_modifier.modifier(URL);
//Mise à jour du tableau des produits
listerAppareils();
//Réinitialisation des zones de texte
initIHMProduit()
}
}
415
=Flex3 FM.book Page 416 Mardi, 2. décembre 2008 3:32 15
416
Cas pratiques
PARTIE II
public function supprimerProduit():void
{
Alert.show("Voulez vous supprimer ce produit ?", "Suppression produit",
➥Alert.OK | Alert.CANCEL, this,confirmerSuppressionproduit, null, Alert.OK);
}
private function confirmerSuppressionproduit(eventObj:CloseEvent):void {
if (eventObj.detail==Alert.OK) {
var identifiant:int = int(txt_refproduit.text);
var nom:String = txt_nomproduit.text;
var description:String = txt_description.text;
var prix:Number = Number(txt_prixvente.text);
var stock:int = int(txt_stock.text);
var stockMin:int = int(txt_stockmin.text);
var stockMax:int = int(txt_stockmax.text);
var prixHa:Number = Number(txt_prixha.text);
var fournisseur:int = int(txt_reffournisseur.text);
//Instanciation de la classe AppareilPhoto
var obj_Produit_supprimer:AppareilPhoto = new AppareilPhoto(identifiant,
➥nom,description,prix,prixHa,stockMin,stockMax,stock,fournisseur);
//Appel de la méthode de suppression
obj_Produit_supprimer.supprimer(URL);
//Mise à jour du tableau des produits
listerAppareils();
//Réinitialisation des zones de texte
initIHMProduit()
}
}
Fichier MXML
La dernière étape consiste à implémenter les logiques IHM et applicative dans le fichier
MXML :
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="900"
➥height="590" creationComplete="chargerParametrageAmfPhp()">
<mx:Script source="FournisseurAS3.As"></mx:Script>
<mx:Script source="ProduitAS3.as"> </mx:Script>
[…]
<mx:TabNavigator>
[…]
<!-- PRODUITS -->
<mx:Canvas label="Produits" width="100%" height="100%"
➥show="alimenterComboFournisseurs();initIHMProduit()">
=Flex3 FM.book Page 417 Mardi, 2. décembre 2008 3:32 15
Module d’administration du site e-commerce
CHAPITRE 21
<mx:Form x="23" y="5" width="358" height="45" horizontalScrollPolicy=
➥"off"verticalScrollPolicy="off">
<mx:FormItem label="Fournisseur :">
<mx:ComboBox width="230" id="cmb_fournisseurs"
➥change="listerAppareils()"></mx:ComboBox>
</mx:FormItem>
</mx:Form>
<mx:AdvancedDataGrid x="23" y="63" id="advdg_produit"
➥dataProvider="{tableauProduits}" designViewDataType="flat"
➥height="168" width="852" itemClick="selectionnerProduit(event)">
<mx:columns>
<mx:AdvancedDataGridColumn headerText="REF" dataField="id"
➥width="50"/>
<mx:AdvancedDataGridColumn headerText="NOM" dataField="nom"
➥width="150"/>
<mx:AdvancedDataGridColumn headerText="STOCK" dataField="stock"
➥width="50"/>
<mx:AdvancedDataGridColumn headerText="--" dataField=
➥"description" width="-1" visible="false"/>
<mx:AdvancedDataGridColumn headerText="--" dataField="stockmin"
➥width="-1" visible="false"/>
<mx:AdvancedDataGridColumn headerText="--" dataField="stockmax"
➥width="-1" visible="false"/>
<mx:AdvancedDataGridColumn headerText="--" dataField="prixha"
➥width="-1" visible="false"/>
<mx:AdvancedDataGridColumn headerText="--" dataField=
➥"fournisseur" width="-1" visible="false"/>
</mx:columns>
</mx:AdvancedDataGrid>
<mx:Button x="755" y="239" label="Nouveau produit"
➥id="btn_nouveauproduit" click="clickBoutonNouveauProduit()"/>
<mx:Panel x="24" y="269" width="852" height="278" layout="absolute"
➥id="panel_produit">
<mx:Form x="10" y="10" height="181" width="526"
➥horizontalScrollPolicy="off" verticalScrollPolicy="off">
<mx:FormItem label="REF :">
<mx:TextInput id="txt_refproduit" width="80" enabled="false"
➥editable="true"/>
</mx:FormItem>
<mx:FormItem label="Nom :" required="true">
<mx:TextInput width="400" id="txt_nomproduit"/>
</mx:FormItem>
<mx:FormItem label="Description :" required="true">
<mx:TextArea height="63" width="400" id="txt_description"/>
</mx:FormItem>
<mx:FormItem label="Prix vente :" required="true">
<mx:TextInput width="80" id="txt_prixvente"/>
417
=Flex3 FM.book Page 418 Mardi, 2. décembre 2008 3:32 15
418
Cas pratiques
PARTIE II
</mx:FormItem>
</mx:Form>
<mx:VRule x="567" y="10" width="1" height="181"/>
<mx:Form x="592" y="10" height="181" width="230"
➥horizontalScrollPolicy="off" verticalScrollPolicy="off">
<mx:FormItem label="Prix d'achat :" required="true">
<mx:TextInput width="80" id="txt_prixha"/>
</mx:FormItem>
<mx:FormItem label="Stock min :" required="true">
<mx:TextInput width="80" id="txt_stockmin"/>
</mx:FormItem>
<mx:FormItem label="Stock max :" required="true">
<mx:TextInput width="80" id="txt_stockmax"/>
</mx:FormItem>
<mx:FormItem label="Stock :" required="true">
<mx:TextInput width="80" id="txt_stock" editable="false"
➥enabled="false"/>
</mx:FormItem>
<mx:FormItem label="Ref. fournisseur :">
<mx:TextInput width="80" id="txt_reffournisseur" enabled
➥="false" editable="false"/>
</mx:FormItem>
</mx:Form>
<mx:HBox x="10" y="208" width="814" height="29"
➥horizontalAlign="right">
<mx:Button label="Supprimer" enabled="false"
➥id="btn_supprimerpt" click="supprimerProduit()"/>
<mx:Button label="Modifier" enabled="false"
➥id="btn_modifierpt" click="modifierProduit()"/>
<mx:Button label="Ajouter" enabled="false"
➥id="btn_ajouterpt" click="ajouterProduit()"/>
<mx:Button label="Annuler" enabled="false"
➥id="btn_annulerpt" click="initIHMProduit()"/>
</mx:HBox>
</mx:Panel>
</mx:Canvas>
</mx:TabNavigator>
</mx:Module>
Voilà, c’est terminé ! Nous disposons à présent d’un module fonctionnel prêt à être
déployé et intégré dans notre application finale (figure 21-5).
=Flex3 FM.book Page 419 Mardi, 2. décembre 2008 3:32 15
Module d’administration du site e-commerce
CHAPITRE 21
419
Figure 21-5
Seconde partie du module fonctionnel
Version de déploiement du module
Pour déployer un module, il est nécessaire d’en créer une version de déploiement. Pour
cela, placez-vous sur le nom du projet (moduleAdministration), cliquez droit puis choisissez
l’option export dans le menu contextuel.
Dans la fenêtre qui s’ouvre, sélectionnez l’option Release-build puis cliquez sur Next et
terminez en cliquant sur le bouton Finish.
Si tout s’est déroulé correctement, un nouveau répertoire bin-release contenant l’ensemble
des fichiers issus de la compilation a été ajouté à la racine du projet.
Intégration du module dans l’application principale
Le module étant indépendant, nous n’avons nul besoin de créer une interface pour interagir
avec l’application. Par conséquent, l’intégration du module dans l’application eReflex se
résume à copier les fichiers modAdministration.swf et parametrage-amfphp.xml, présents
dans répertoire bin-release de l’application moduleAdministration, vers le répertoire src
de l’application eReflex (figure 21-6).
=Flex3 FM.book Page 420 Mardi, 2. décembre 2008 3:32 15
420
Cas pratiques
PARTIE II
Figure 21-6
Intégration du module dans l’application principale
Nous n’avons plus maintenant qu’à appeler le module dans le Canvas de la vue administration en implémentant un composant ModuleLoader :
<mx:Canvas id="vueAdministration" label="Administration" width="100%" height="100%">
<mx:ModuleLoader id="moduleAdministration" url="modAdministration.swf">
➥</mx:ModuleLoader>
</mx:Canvas>
Nous pouvons à présent visualiser notre travail en exécutant le projet E-Reflex et en nous
connectant au module d’administration.
Figure 21-7
Chargement du module d’administration dans l’application principale
=Flex3 FM.book Page 421 Mardi, 2. décembre 2008 3:32 15
Module d’administration du site e-commerce
CHAPITRE 21
421
En résumé
Grâce à ce premier module, nous avons pu mettre en pratique les connaissances de base
utliles pour tout développement de projet Flex. Nous vous invitons à recréer ce module
sans l’aide de l’ouvrage afin de vérifier vos connaissances et vos aptitudes à créer des
services PHP, établir la connexion de ces services avec l’application Flex, mettre en place
un modèle et vérifier la saisie de l’utilisateur.
Dans le chapitre suivant, nous allons nous consacrer au module « Site » du projet, où nous
mettrons en pratique nos connaissances sur les composants et aborderons une nouvelle
notion : les ItemRenderer.
=Flex3 FM.book Page 422 Mardi, 2. décembre 2008 3:32 15
=Flex3 FM.book Page 423 Mardi, 2. décembre 2008 3:32 15
22
Module de vente en ligne :
le panier d’achat
Nous allons à présent nous consacrer au développement de la première partie du module
constituant le cœur du site E-Reflex, dans laquelle nous implémenterons le composant de
filtrage de données développé dans le chapitre 10, pour ensuite se consacrer à la gestion
du panier d’achat.
À travers ce module, nous aborderons les notions suivantes :
• état et transition (chapitre 9) ;
• utilisation d’un composant (chapitre 10) ;
• ItemRenderer (nouvelle notion) ;
• formater des données (chapitre 11) ;
• lier des données (chapitre 11).
Important
Dans ce chapitre, nous allons utiliser le composant développé dans le chapitre 10 de cet ouvrage. Pour
profiter pleinement de ce cas pratique nous vous conseillons donc d’avoir lu ce chapitre et réalisé le
composant qui y est décrit.
Création du module
Nous allons, comme pour le module précédent, créer un nouveau projet que nous nommerons
cette fois-ci moduleSite, dans lequel nous créerons un nouveau module avec les paramètres
suivants :
=Flex3 FM.book Page 424 Mardi, 2. décembre 2008 3:32 15
424
Cas pratiques
PARTIE II
• nom : modSite ;
• width (largeur) = 900 pixels ;
• heigth (hauteur) = 590 pixels ;
• non optimisé (utilisable dans toute application Flex).
Là encore, pour pouvoir tester le module tout au long de sa phase de développement,
nous allons ajouter, dans le fichier MXML du projet, un composant ModuleLoader faisant
appel au module que nous sommes en train de créer :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:ModuleLoader id="module" url="modSite.swf"> </mx:ModuleLoader>
</mx:Application>
Design de l’interface
L’interface va être notre page d’accueil du site E-Reflex, elle permettra à l’utilisateur de
rechercher un appareil photo et en visualiser le détail. Si l’appareil lui convient, il pourra
alors l’ajouter à son panier et passer commande.
Les états
Nous allons créer deux états. Le premier, l’état de base, comportera trois panneaux
(figure 22-1) :
• un panneau de recherche ;
• un panneau représentant le panier du client ;
• un panneau inactif contenant le détail de l’appareil photo choisi.
Le second état, que nous nommerons etat_visualisationarticle, héritant de l’état de
base, il comportera les mêmes panneaux mais, cette fois-ci, le panneau de recherche sera
désactivé (figure 22-2).
Voici le code de ces états :
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="900"
➥height="590" >
<mx:Script source="SiteAS3.as"> </mx:Script>
=Flex3 FM.book Page 425 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : le panier d’achat
CHAPITRE 22
Figure 22-1
État de base
<!-- ***************** ÉTAT PRINCIPAL ******************** -->
<!-- PANNEAU DE RECHERCHE -->
<mx:Panel x="10" y="10" width="618" height="560" layout="absolute" title="Recherche"
➥id="panel_recherche" horizontalScrollPolicy="off" verticalScrollPolicy="off">
</mx:Panel>
<!-- PANIER D’ACHAT -->
<mx:Panel x="636" y="10" width="250" height="452" layout="absolute" title="Mon
➥panier" id="panel_panier">
<mx:DataGrid x="10" y="10" height="367" id="dg_panier" width="210">
<mx:columns>
<mx:DataGridColumn headerText="Appareils" dataField="col1"/>
</mx:columns>
</mx:DataGrid>
<mx:Button x="10" y="380" label="Vider" width="107" id="btn_viderpanier"/>
<mx:Button x="125" y="380" label="Commander" id="btn_commander"/>
</mx:Panel>
425
=Flex3 FM.book Page 426 Mardi, 2. décembre 2008 3:32 15
426
Cas pratiques
PARTIE II
Figure 22-2
État de visualisation du détail d’un appareil photo
<!-- PANNEAU DE DÉTAIL D’ARTICLE -->
<mx:Panel x="636" y="470" width="250" height="100" layout="absolute"
➥title="Détail Article" id="panel_detail" verticalScrollPolicy="off"
➥horizontalScrollPolicy="off">
<mx:Form x="10" y="10" width="13" height="40" horizontalScrollPolicy="off"
➥verticalScrollPolicy="off" id="form_detail">
<mx:FormItem label="Référence :" id="lab_reference">
<mx:TextInput width="70" id="txt_ref" editable="false"/>
</mx:FormItem>
<mx:FormItem label="Nom :">
<mx:TextInput width="402" id="txt_nom" editable="false"/>
</mx:FormItem>
<mx:FormItem label="Description :">
<mx:TextArea width="402" height="84" id="txt_description"
➥editable="false"/>
</mx:FormItem>
<mx:FormItem label="Prix TTC :">
<mx:TextInput width="76" id="txt_prix" editable="false"/>
</mx:FormItem>
<mx:FormItem label="Qté en stock :">
=Flex3 FM.book Page 427 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : le panier d’achat
CHAPITRE 22
427
<mx:TextInput width="76" id="txt_qte" editable="false"/>
</mx:FormItem>
</mx:Form>
</mx:Panel>
<!-- ***************** ÉTAT SECONDAIRE******************** -->
<mx:states>
<mx:State name="etat_visualisationarticle">
<mx:SetProperty target="{panel_recherche}" name="height" value="107"/>
<mx:SetProperty target="{panel_detail}" name="x" value="10"/>
<mx:SetProperty target="{panel_detail}" name="y" value="10"/>
<mx:SetProperty target="{panel_recherche}" name="y" value="470"/>
<mx:SetProperty target="{panel_recherche}" name="width" value="250"/>
<mx:SetProperty target="{panel_recherche}" name="x" value="636"/>
<mx:SetProperty target="{panel_detail}" name="height" value="570"/>
<mx:SetProperty target="{panel_detail}" name="width" value="618"/>
<mx:SetProperty target="{form_detail}" name="width" value="578"/>
<mx:SetProperty target="{form_detail}" name="height" value="510"/>
<mx:AddChild relativeTo="{form_detail}" position="lastChild">
<mx:FormItem>
<mx:HBox width="444" horizontalAlign="right">
<mx:Button label="Ajouter au panier" id="button1"/>
<mx:Button label="Fermer" width="125"/>
</mx:HBox>
</mx:FormItem>
</mx:AddChild>
</mx:State>
</mx:states>
</mx:Module>
Comme nous vous l’avons indiqué en introduction de ce chapitre nous allons employer le
composant développé dans le chapitre 10 qui va offrir à l’utilisateur un outil de recherche.
C’est par son implémentation que nous allons commencer le développement de ce
module.
Voyons comment implémenter le composant de recherche. La première chose à faire est
de récupérer le fichier swc issu de la compilation du composant et de l’insérer dans notre
module. Si vous l’avez supprimé de votre disque, référez-vous au chapitre 10 afin de le
recompiler.
Pour insérer un composant dans la bibliothèque de notre module Flex, il convient de
procéder comme suit :
1. positionnez-vous dans les propriétés du projet ;
=Flex3 FM.book Page 428 Mardi, 2. décembre 2008 3:32 15
428
Cas pratiques
PARTIE II
2. dans le menu de gauche de la fenêtre, choisissez l’option Flex Build Path puis sélectionnez l’onglet library path ;
3. sur la partie droite de l’écran, cliquez sur le bouton add swc, ce qui nous permet
d’importer le fichier swc de notre composant.
Maintenant que le composant est ajouté à la bibliothèque, nous pouvons l’implémenter
dans notre état principal, et plus particulièrement dans le panneau de recherche :
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="900"
➥height="590" xmlns:composant="com.composants.*">
Implémentation du composant
Voici le code réalisant l’insertion du composant dans l’interface graphique du module :
<!-- Création des colonnes du tableau de notre composant -->
<mx:ArrayCollection id="colonnes">
<mx:Object entete="FOURNISSEUR" champ="nomF" visible="true" longueur="150"/>
<mx:Object entete="NOM" champ="champFiltre" visible="true" longueur="300"/>
<mx:Object entete="PRIX (¤)" champ="prixA" visible="true" longueur="60"/>
<mx:Object entete="STOCK" champ="stockA" visible="true" longueur="50"/>
<mx:Object entete="--" champ="idt" visible="false" longueur="-1"/>
<mx:Object entete="--" champ="descriptionA" visible="false" longueur="-1"/>
<mx:Object entete="--" champ="prixA" visible="false" longueur="-1"/>
</mx:ArrayCollection>
<mx:Panel x="10" y="10" width="618" height="560" layout="absolute"
➥title="Recherche" id="panel_recherche" horizontalScrollPolicy="off"
➥verticalScrollPolicy="off">
<composant:FiltreTableau id="listeAppareilsPhotos"
height="500"
width="578"
libelle="Nom :"
tableauDonnees="{sourceDonnees}"
colonnes="{colonnes}" x="10" y="10" horizontalScrollPolicy="off"
➥verticalScrollPolicy="off">
</composant:FiltreTableau>
</mx:Panel>
Comme vous pouvez le constater, notre composant comportera quatre colonnes visibles
et le filtrage sera effectuée sur le nom de l’appareil photo.
L’étape suivante va consister à alimenter le composant avec la liste des appareils photo.
Pour cela, nous allons créer un service PHP que nous exécuterons, comme nous l’avons
fait dans le module précédent, à l’aide du composant RemoteObject.
Pour le détail de la création du service et de son exécution, reportez-vous au chapitre
précédent. Voici la liste des fichiers à créer et le code qui les compose.
=Flex3 FM.book Page 429 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : le panier d’achat
CHAPITRE 22
Fichier de service PHP servModSite.php :
<?php
class ServModSite {
protected $_serveur = 'localhost';
protected $_methodTable = array();
protected $_mdp = '';
protected $_utilisateur = 'root';
protected $_baseDeDonnees = 'reflex';
protected $_connexion = null;
public function __construct() {
/******************************************
/*
LISTE DES SERVICES
*
/******************************************/
$this->_methodTable = array(
'serviceListerAppareils' => array(
'description' => 'Liste les appareils photo',
'access' => 'remote',
)
);
}
/* Permet la connexion au serveur de base de données */
protected function _connect() {
$this->_connexion = mysql_connect($this->_serveur,$this->_utilisateur,
➥$this->_mdp);
$selectDb = mysql_select_db($this->_baseDeDonnees,$this->_connexion);
}
/* Permet la fermeture de la connexion au serveur de base de données */
protected function _disconnect() {
if(null !== $this->_connexion) mysql_close();
}
public function serviceListerAppareils () {
$this->_connect();
$requete = "select f.id as idF,
f.nom as nomF,
a.id as idt,
a.nom as champFiltre,
a.description as descriptionA,
a.prix as prixA,
a.stock as stockA,
a.stockmin as stockminA,
a.stockmax as stockmaxA,
a.prixha as prixhaA
from tb_fournisseur f,
429
=Flex3 FM.book Page 430 Mardi, 2. décembre 2008 3:32 15
430
Cas pratiques
PARTIE II
tb_appareilphoto a
where a.fournisseur = f.id
order by f.nom asc";
$resultat = mysql_query($requete);
//Alimentation d'un tableau avec la liste des appareils
$tableauAppareils = array();
while ($appareil = mysql_fetch_object($resultat)) {
$tableauAppareils[] = $appareil;
}
$this->_disconnect();
return $tableauAppareils;
}
?>
Fichier parametrage-amfphp.xml :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<parametre>
<amfphp>
<serveur>http://localhost/amfphp/gateway.php</serveur>
</amfphp>
</parametre>
Fichier ActionScript SiteAS3.as :
import
import
import
import
mx.controls.Alert;
mx.rpc.events.FaultEvent;
mx.rpc.events.ResultEvent;
mx.rpc.remoting.mxml.RemoteObject;
/****************************************************
*
CHARGEMENT DES PARAMÈTRES AMFPHP
* **************************************************/
public var URL:String
public function chargerParametrageAmfPhp():void
{
var chargeur:URLLoader = new URLLoader ();
var adresse:URLRequest = new URLRequest ("parametrage_amfphp.xml");
chargeur.load(adresse);
chargeur.addEventListener(Event.COMPLETE, finDuChargement);
chargeur.addEventListener(IOErrorEvent.IO_ERROR, indiquerErreur);
}
public function finDuChargement ( event:Event ):void
{
var contenu:XML = new XML(event.target.data);
URL = contenu.amfphp.serveur;
listerAppareils();
}
=Flex3 FM.book Page 431 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : le panier d’achat
CHAPITRE 22
431
public function indiquerErreur( event:Event ):void
{
Alert.show("Erreur lors du chargement des paramètres amfphp");
}
Modification du fichier modSite.mxml (ajout de l’attribut creationComplete() qui appellera
la procédure chargerParametrageAmfPhp()) :
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="900"
➥height="590" xmlns:composant="com.composants.*" creationComplete=
➥"chargerParametrageAmfPhp()">
<mx:Script source="SiteAS3.as"> </mx:Script>
Procédure d’alimentation du composant :
/****************************************************
*
ALIMENTATION DU COMPOSANT
* **************************************************/
[Bindable]
public var sourceDonnees:ArrayCollection;
public function listerAppareils():void
{
var service:RemoteObject = new RemoteObject();
service.endpoint = URL;
service.showBusyCursor = true;
service.destination="amfphp";
service.source="ServModSite";
service.serviceListerAppareils.addEventListener("result",
➥resultatOKListerAppareils);
service.serviceListerAppareils.addEventListener("fault", resultatKO)
service.serviceListerAppareils();
}
public function resultatOKListerAppareils(e:ResultEvent):void
{
var resultat:Array = e.result as Array;
//Transformation du Array en ArrayCollection nécessaire à l'alimentation du
➥tableau
sourceDonnees = new ArrayCollection(resultat)
}
public function resultatKO(e:FaultEvent):void
{
Alert.show(e.fault.faultString, 'Error');
}
=Flex3 FM.book Page 432 Mardi, 2. décembre 2008 3:32 15
432
Cas pratiques
PARTIE II
Voilà, c’est terminé ! Si nous exécutons l’application, nous constatons que le tableau est
correctement alimenté et que la fonction de filtrage du tableau est fonctionnelle (figure 22-3).
Cela prouve, une fois de plus, que le composant que nous avons créé est digne de ce nom
car il peut s’adapter à l’application dans laquelle il est implémenté !
Figure 22-3
Composant fonctionnel
Lorsque l’utilisateur va sélectionner un produit dans le tableau, nous allons afficher l’état
etat_visualisationarticle qui va offrir à l’utilisateur une vision du détail du produit
sélectionné.
Avant de mettre en place la cinématique de ce changement d’état, il convient auparavant
de vous fournir le code complet de l’IHM à des fins de vérifications.
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="900"
➥height="590" xmlns:composant="com.composants.*" creationComplete
➥="chargerParametrageAmfPhp()">
<mx:Script source="SiteAS3.as"> </mx:Script>
<!-- Création des colonnes du tableau de notre composant -->
<mx:ArrayCollection id="colonnes">
<mx:Object entete="FOURNISSEUR" champ="nomF" visible="true" longueur="150"/>
<mx:Object entete="NOM" champ="champFiltre" visible="true" longueur="300"/>
<mx:Object entete="PRIX (¤)" champ="prixA" visible="true" longueur="60"/>
<mx:Object entete="STOCK" champ="stockA" visible="true" longueur="50"/>
<mx:Object entete="--" champ="idt" visible="false" longueur="-1"/>
<mx:Object entete="--" champ="descriptionA" visible="false" longueur="-1"/>
<mx:Object entete="--" champ="prixA" visible="false" longueur="-1"/>
</mx:ArrayCollection>
=Flex3 FM.book Page 433 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : le panier d’achat
CHAPITRE 22
<!-- ***************** ÉTAT PRINCIPAL ******************** -->
<mx:Panel x="10" y="10" width="618" height="560" layout="absolute"
➥title="Recherche" id="panel_recherche" horizontalScrollPolicy="off"
➥verticalScrollPolicy="off">
<composant:FiltreTableau id="listeAppareilsPhotos"
height="500"
width="578"
libelle="Nom :"
tableauDonnees="{sourceDonnees}"
colonnes="{colonnes}" x="10" y="10" horizontalScrollPolicy="off"
➥verticalScrollPolicy="off">
</composant:FiltreTableau >
</mx:Panel>
<mx:Panel x="636" y="10" width="250" height="452" layout="absolute"
➥title="Mon panier" id="panel_panier">
<mx:DataGrid x="10" y="10" height="367" id="dg_panier" width="210">
<mx:columns>
<mx:DataGridColumn headerText="Appareils" dataField="col1"/>
</mx:columns>
</mx:DataGrid>
<mx:Button x="10" y="380" label="Vider" width="107" id="btn_viderpanier"/>
<mx:Button x="125" y="380" label="Commander" id="btn_commander"/>
</mx:Panel>
<mx:Panel x="636" y="470" width="250" height="100" layout="absolute"
➥title="Détail Article" id="panel_detail" verticalScrollPolicy="off"
➥horizontalScrollPolicy="off">
<mx:Form x="10" y="10" width="13" height="40" horizontalScrollPolicy="off"
➥verticalScrollPolicy="off" id="form_detail">
<mx:FormItem label="Référence :" id="lab_reference">
<mx:TextInput width="70" id="txt_ref" editable="false"/>
</mx:FormItem>
<mx:FormItem label="Nom :">
<mx:TextInput width="402" id="txt_nom" editable="false"/>
</mx:FormItem>
<mx:FormItem label="Description :">
<mx:TextArea width="402" height="84" id="txt_description"
➥editable="false"/>
</mx:FormItem>
<mx:FormItem label="Prix TTC :">
<mx:TextInput width="76" id="txt_prix" editable="false"/>
</mx:FormItem>
<mx:FormItem label="Qté en stock :">
<mx:TextInput width="76" id="txt_qte" editable="false"/>
</mx:FormItem>
</mx:Form>
</mx:Panel>
433
=Flex3 FM.book Page 434 Mardi, 2. décembre 2008 3:32 15
434
Cas pratiques
PARTIE II
<!-- ***************** ÉTAT SECONDAIRE******************** -->
<mx:states>
<mx:State name="etat_visualisationarticle">
<mx:SetProperty target="{panel_recherche}" name="height" value="107"/>
<mx:SetProperty target="{panel_detail}" name="x" value="10"/>
<mx:SetProperty target="{panel_detail}" name="y" value="10"/>
<mx:SetProperty target="{panel_recherche}" name="y" value="470"/>
<mx:SetProperty target="{panel_recherche}" name="width" value="250"/>
<mx:SetProperty target="{panel_recherche}" name="x" value="636"/>
<mx:SetProperty target="{panel_detail}" name="height" value="570"/>
<mx:SetProperty target="{panel_detail}" name="width" value="618"/>
<mx:SetProperty target="{form_detail}" name="width" value="578"/>
<mx:SetProperty target="{form_detail}" name="height" value="510"/>
<mx:AddChild relativeTo="{form_detail}" position="lastChild">
<mx:FormItem>
<mx:HBox width="444" horizontalAlign="right">
<mx:Button label="Ajouter au panier" id="button1"/>
< !-- Fermeture de l’état et ouverture de l’état de base -->
<mx:Button label="Fermer" click="currentState=''"
➥width="125"/>
</mx:HBox>
</mx:FormItem>
</mx:AddChild>
</mx:State>
</mx:states>
</mx:Module>
Nous pouvons à présent coder les changements d’état lorsque l’utilisateur effectue sa
sélection de produit dans le tableau du composant.
Rappelez-vous, lors du développement du composant nous avons prévu une procédure
permettant de récupérer la valeur de la variable valeurRenvoyee correspondant à la valeur
du champ idt (identifiant) de la ligne sélectionnée par l’utilisateur. Nous allons donc
insérer un champ de type textinput dans notre interface, dont la propriété text sera liée à
la valeur de la variable valeurRenvoyee. Ce champ ne servant pas aux utilisateurs de notre
site, nous le rendrons invisible.
Lorsque la valeur du champ invisible sera modifiée (à chaque sélection d’une ligne dans le
tableau du composant), cela déclenchera une procédure qui exécutera un service capable
de récupérer les informations du produit sélectionné (grâce à l’identifiant transmis) et
d’ouvrir l’état de visualisation du détail.
=Flex3 FM.book Page 435 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : le panier d’achat
CHAPITRE 22
435
Modifions donc notre fichier modSite.mxml afin d’y insérer la zone de texte invisible :
<composant:FiltreTableau id="listeAppareilsPhotos"
height="500"
width="578"
libelle="Nom :"
tableauDonnees="{sourceDonnees}"
colonnes="{colonnes}" x="10" y="10" horizontalScrollPolicy="off"
➥verticalScrollPolicy="off">
</composant:FiltreTableau>
<mx:TextInput x="10" y="408" text="{listeAppareilsPhotos.valeurRenvoyee}"
➥updateComplete="selectionAppareil()" visible="false"/>
et créons la procédure selectionAppareil() permettant l’ouverture de l’état etat
_visualisationarticle :
/****************************************************
*
SÉLECTION D'UN APPAREIL DANS LA LISTE
* **************************************************/
public function selectionAppareil():void{
if (listeAppareilsPhotos.valeurRenvoyee != null)
{
//Ouverture de l'état permettant la visualisation du détail de l'appareil
➥sélectionné
currentState = 'etat_visualisationarticle'
//Envoi de l'identifiant au champ txt_ref dans l'état
➥etat_visualisationproduit
txt_ref.text = listeAppareilsPhotos.valeurRenvoyee
}
}
Les transitions
Afin de mettre un peu de mouvement dans cette interface, nous allons utiliser des transitions
pour passer d’un état à un autre.
Cette partie n’étant pas des plus aisées à décrire dans un livre, nous vous conseillons de
lire ce qui suit et de mettre en place les transitions afin de vous rendre compte de leur
fonctionnement.
Voici la transition que nous allons employer lorsque nous passerons de l’état de base vers
l’état de visualisation du détail de l’appareil photo sélectionné :
1. le composant situé dans le panneau de recherche est réduit ;
2. le panneau recherche est réduit à son tour pour prendre la taille du panneau affichant
le détail ;
=Flex3 FM.book Page 436 Mardi, 2. décembre 2008 3:32 15
436
Cas pratiques
PARTIE II
3. le panneau de détail est déplacé vers la gauche pour laisser la place au panneau de
recherche ;
4. le panneau de recherche est déplacé et prend la place du panneau de détail ;
5. le panneau de détail est positionné aux anciennes coordonnées du panneau de recherche ;
6. le panneau de détail est agrandi pour prendre la taille qu’occupait le panneau de
recherche ;
7. le formulaire que contient le panneau de détail est agrandi, permettant d’afficher
l’ensemble des informations sur l’appareil photo sélectionné.
Ajoutons donc cette transition à notre fichier modSite.mxml :
<!-- ***************** TRANSITIONS ******************** -->
<mx:transitions>
<mx:Transition id="ouvertureDetail" fromState=""
➥toState="etat_visualisationarticle">
<mx:Sequence>
<mx:Resize target="{listeAppareilsPhotos}" heightTo="0" widthTo="0"
➥duration="1000"></mx:Resize>
<mx:Resize target="{panel_recherche}" heightTo="100" widthTo="250"
➥duration="1000"> </mx:Resize>
<mx:Move target="{panel_detail}" xTo="378" yTo="470" duration="1000">
➥</mx:Move>
<mx:Move target="{panel_recherche}" xTo="636" yTo="470"
➥duration="1000"></mx:Move>
<mx:Move target="{panel_detail}" xTo="10" yTo="10" duration="1000">
➥</mx:Move>
<mx:Resize target="{panel_detail}" heightTo="560" widthTo="618"
➥duration="1000" > </mx:Resize>
<mx:Resize target="{form_detail}" heightTo="510" widthTo="578"
➥duration="1000" > </mx:Resize>
</mx:Sequence>
</mx:Transition>
</mx:transitions>
La transition vers l’état de base sera, quant à elle, la suivante :
1. le formulaire situé dans le panneau de détail est réduit ;
2. le panneau de détail est réduit à son tour pour prendre la taille du panneau de recherche ;
3. le panneau de recherche est déplacé vers la gauche pour laisser la place au panneau
de détail ;
4. le panneau de détail est déplacé et prend la place du panneau de recherche ;
5. le panneau de recherche est positionné aux anciennes coordonnées du panneau de
détail ;
6. le panneau de recherche est agrandi pour prendre la taille qu’occupait le panneau de
détail ;
=Flex3 FM.book Page 437 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : le panier d’achat
CHAPITRE 22
437
7. le composant que contient le panneau de recherche est agrandi afin d’afficher la liste
des appareils que nous proposons à la vente.
<!-- ***************** TRANSITIONS ******************** -->
<mx:transitions>
[…]
<mx:Transition id="ouvertureRecherche" fromState="etat_visualisationarticle"
➥toState="">
<mx:Sequence>
<mx:Resize target="{form_detail}" heightTo="40" widthTo="10"
➥duration="1000"> </mx:Resize>
<mx:Resize target="{panel_detail}" heightTo="100" widthTo="250"
➥duration="1000"> </mx:Resize>
<mx:Move target="{panel_recherche}" xTo="378" yTo="470"
➥duration="1000"></mx:Move>
<mx:Move target="{panel_detail}" xTo="636" yTo="470" duration="1000">
➥</mx:Move>
<mx:Move target="{panel_recherche}" xTo="10" yTo="10"
➥duration="1000"></mx:Move>
<mx:Resize target="{panel_recherche}" heightTo="560" widthTo="618"
➥duration="1000" > </mx:Resize>
<mx:Resize target="{listeAppareilsPhotos}" heightTo="500"
➥widthTo="578" duration="1000"></mx:Resize>
</mx:Sequence>
</mx:Transition>
</mx:transitions>
Voyons à présent comment alimenter les zones de texte de l’état présentant le détail de
l’appareil photo sélectionné.
Affichage du détail d’un produit
Comme vous devez vous en douter, il s’agit là de créer un nouveau service dont voici le
code :
public function servideDetailAppareil($idAppareil){
$this->_connect();
$requete = 'SELECT * FROM tb_appareilphoto WHERE id='.(int)$idAppareil.
➥' LIMIT 1';
$resultat = mysql_query($requete);
$tableauAppareil = array();
while ($appareil = mysql_fetch_object($resultat)) {
$tableauAppareil[] = $appareil;
}
$this->_disconnect();
return $tableauAppareil;
}
=Flex3 FM.book Page 438 Mardi, 2. décembre 2008 3:32 15
438
Cas pratiques
PARTIE II
Modifions à présent la procédure selectionAppareil() afin d’exécuter ce service :
/****************************************************
*
SÉLECTION D'UN APPAREIL DANS LA LISTE
* **************************************************/
public function selectionAppareil():void{
if (listeAppareilsPhotos.valeurRenvoyee != null)
{
var service:RemoteObject = new RemoteObject();
service.endpoint = URL;
service.showBusyCursor = true;
service.destination="amfphp";
service.source="ServModSite";
service.servideDetailAppareil.addEventListener("result",
➥resultatOKDetailAppareil);
service.servideDetailAppareil.addEventListener("fault", resultatKO)
//Appel du service et passage de l’identifiant de l’appareil en paramètre
service.servideDetailAppareil(listeAppareilsPhotos.valeurRenvoyee);
}
}
public function resultatOKDetailAppareil(e:ResultEvent):void
{
var resultat:Array = e.result as Array;
//Transformation du résultat en ArrayCollection
var tableau:ArrayCollection = new ArrayCollection(resultat)
//Analyse du tableau reçu en paramètre et récupération des données du premier
➥enregistrement
if (tableau.length != 0)
{
txt_ref.text = tableau[0].id;
txt_description.text = tableau[0].description;
txt_nom.text = tableau[0].nom;
txt_prix.text = tableau[0].prix;
txt_qte.text = tableau[0].stock;
//On a déplacé l'ouverture de l'état dans cette procédure
currentState = 'etat_visualisationarticle'
}
}
=Flex3 FM.book Page 439 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : le panier d’achat
CHAPITRE 22
439
La première partie du module est à présent terminée. Nous allons maintenant nous atteler
au développement du panier d’achat.
Gestion du panier d’achat
Dans cette partie, nous allons aborder le design du panier pour ensuite nous concentrer
sur son alimentation.
Design du panier avec ItemRenderer
L’objectif est de présenter, pour chaque ligne de produit présent dans le panier, sa référence,
son nom et son prix.
Nous avons utilisé le composant Datagrid pour afficher l’ensemble des produits ajoutés
au panier. Cependant, il ne permet pas la présentation multi-ligne des données, c’est
pourquoi nous allons devoir utiliser un composant de type conteneur, qui servira à mettre
en forme chaque ligne du Datagrid.
Le principe réside en la création d’un composant MXML où il nous sera possible de
réaliser la mise en forme souhaitée. Ce composant sera ensuite utilisé dans la propriété
itemRenderer de la ligne du datagrid (figure 22-4), ce qui créera un masque de mise en
forme pour chaque ligne du datagrid.
Figure 22-4
Principe de mise en forme avec la propriété ItemRenderer
=Flex3 FM.book Page 440 Mardi, 2. décembre 2008 3:32 15
440
Cas pratiques
PARTIE II
Créons le composant de mise en forme. La première étape consiste à ajouter un nouveau
fichier MXML Component à notre projet ayant les caractéristiques suivantes :
• nom : ItemRenderer_Panier ;
• type : Canvas ;
• hauteur (height) : 70 px ;
• largeur (width) : 210 px (correspond à la largeur d’une ligne du DataGrid).
Les données affichées dans le datagrid seront issue de son dataprovider, qui sera alimenté
par un tableau d’objets contenant les attributs suivants :
• refProduit, stockant la référence du produit ;
• nomProduit, stockant le nom du produit ;
• prixProduit, stockant le prix du produit.
Néanmoins, le dataprovider ne sert qu’à alimenter les lignes du datagrid et non notre
composant de mise en forme. Pour cela nous ferons appel, dans notre composant de mise
en forme, à la propriété data qui effectuera une connexion avec la ligne du datagrid
concernée par la mise en forme et permettra d’en extraire les données.
Voici le code de notre composant :
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="210" height="70"
➥horizontalScrollPolicy="off" verticalScrollPolicy="off">
<mx:CurrencyFormatter id="formatEuros" currencySymbol="¤" alignSymbol="right" />
<mx:Label x="13" y="10" text="Réf :" id="lab_referenceProduit"/>
<mx:Text x="46" y="10" text="{data.refProduit}" width="78" id="txt_refpanier"
➥fontStyle="italic" height="18"/>
<mx:Text x="10" y="36" text="{data.nomProduit}" width="117" id="txt_nompanier"
➥fontWeight="bold"/>
<!-- Ajout d’une ligne verticale de séparation -->
<mx:VRule x="132" y="0" width="11" height="70" strokeWidth="1"/>
<mx:Text x="139" y="25" id="txt_prixpanier"
text="{formatEuros.format(data.prixProduit)}"
width="66" height="29" fontWeight="bold"
textAlign="center" fontSize="14"
/>
</mx:Canvas>
Nous avons désactivé l’affichage des barres de défilement horizontal et vertical du
Canvas, évitant ainsi tout défaut d’affichage. Nous avons ensuite implémenté le composant currencyFormater qui nous permettra d’afficher le prix du produit ajouté au panier
=Flex3 FM.book Page 441 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : le panier d’achat
CHAPITRE 22
441
sous le format Euros. On observe enfin que chaque zone de texte récupère la valeur qui
lui est propre grâce à la propriété data et que la valeur contenue dans la zone de texte
txt_prixpanier fait appel au composant currencyFormater afin de mettre en forme la
donnée qu’il contient.
Nous terminons en appelant le masque de mise en forme dans le tableau représentant le
panier d’achat situé dans le fichier modSite.mxml, sans oublier d’ajuster la hauteur des
lignes du datagrid à 70 pixels afin d’afficher notre composant dans son intégralité :
<mx:DataGrid x="10" y="10" height="367" id="dg_panier" width="210" rowHeight="70"/>
<mx:columns>
<mx:DataGridColumn headerText="Appareils"
➥itemRenderer="ItemRenderer_Panier"/>
</mx:columns>
</mx:DataGrid>
Ajouter un produit au panier
L’ajout d’un produit au panier s’effectue à l’aide d’une procédure mettant à jour une
collection d’objets. Notez que le dataProvider du datagrid représentant le panier d’achat
est lié par la notion de databinding à la collection d’objets. De ce fait, lorsque la collection
d’objets est mise à jour, les données affichées dans le panier le sont aussi. Il convient
donc d’ajouter cette procédure au fichier SiteAS3.as :
[Bindable]
public var panierAchat:ArrayCollection = new ArrayCollection();
public function ajouterPanier():void
{
var reference:String = txt_ref.text
var prix:Number = Number(txt_prix.text)
var nom:String = txt_nom.text
panierAchat.addItem({refProduit:reference, nomProduit:nom, prixProduit:prix})
}
puis de créer la liaison entre la variable panierAchat et le dataProvider du panier d’achat :
<mx:DataGrid x="10" y="10" height="367" id="dg_panier" width="210" rowHeight="70"
dataProvider="{panierAchat}"
/>
L’appel de la procédure ajouterPanier() sera effectué lorsque l’utilisateur cliquera sur le
bouton Ajouter situé dans l’état etat_visualisationarticle. Il faut donc spécifier cet
appel comme suit :
<!-- ***************** ÉTAT SECONDAIRE ******************** -->
<mx:states>
<mx:State name="etat_visualisationarticle">
<mx:SetProperty target="{panel_recherche}" name="height" value="107"/>
=Flex3 FM.book Page 442 Mardi, 2. décembre 2008 3:32 15
442
Cas pratiques
PARTIE II
<mx:SetProperty target="{panel_detail}" name="x" value="10"/>
<mx:SetProperty target="{panel_detail}" name="y" value="10"/>
<mx:SetProperty target="{panel_recherche}" name="y" value="470"/>
<mx:SetProperty target="{panel_recherche}" name="width" value="250"/>
<mx:SetProperty target="{panel_recherche}" name="x" value="636"/>
<mx:SetProperty target="{panel_detail}" name="height" value="570"/>
<mx:SetProperty target="{panel_detail}" name="width" value="618"/>
<mx:SetProperty target="{form_detail}" name="width" value="578"/>
<mx:SetProperty target="{form_detail}" name="height" value="510"/>
<mx:AddChild relativeTo="{form_detail}" position="lastChild">
<mx:FormItem>
<mx:HBox width="444" horizontalAlign="right">
<mx:Button label="Ajouter au panier" id="button1"
➥click="ajouterPanier()"/>
<mx:Button label="Fermer" click="currentState=''"
➥width="125"/>
</mx:HBox>
</mx:FormItem>
</mx:AddChild>
</mx:State>
</mx:states>
Vider le panier
Pour vider le panier, nous allons employer la méthode removeAll() de la classe Array
Collection. Pour cela, créons une procédure viderPanier() contenant le code suivant :
public function viderPanier():void
{
panierAchat.removeAll();
}
Comme une liaison entre le dataProvider du panier et la variable panierAchat a été effectuée,
l’utilisateur verra disparaître l’ensemble des éléments de son panier. Mais cela n’est possible que si nous appelons notre nouvelle procédure lors du clic sur le bouton Vider situé
dans le Panel contenant notre panier. Placez-vous bien sur l’état de base lors de l’implémentation de cet appel, sous peine de ne voir s’exécuter la procédure de suppression
d’éléments que lorsque l’utilisateur se situera sur l’état etat_visualisatioarticle !
<mx:Button x="10" y="380" label="Vider" width="107" id="btn_viderpanier"
➥click="viderPanier()"/>
Nous pouvons à présent tester le bon fonctionnement de notre panier en y ajoutant des
produits et en vidant son contenu.
=Flex3 FM.book Page 443 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : le panier d’achat
CHAPITRE 22
443
À vos claviers : création de l’interface graphique
Votre travail va consister à préparer l’interface graphique qui nous servira de base de
travail pour le chapitre suivant. L’objectif est de créer l’interface graphique de passage
d’une commande présenté à la figure 22-5.
Figure 22-5
État « etat_commande »
Ce qu’il faut réaliser
Il faut créer un nouvel état que nous nommerons etat_commande, héritant de l’état de base,
dont l’appel sera effectué en cliquant sur le bouton Commander situé dans le Panel du
panier.
Dans cet état, nous vous demanderons d’y placer les éléments suivants :
• Un formulaire de saisie d’informations sur le client (figure 22-6).
=Flex3 FM.book Page 444 Mardi, 2. décembre 2008 3:32 15
444
Cas pratiques
PARTIE II
Figure 22-6
Informations sur le client
• Un composant TileList, contenant l’ensemble des produits présents dans le panier.
Vous devez y ajouter une fonctionnalité permettant de choisir la quantité voulue et
recalculant le total à payer par produit (figure 22-7).
Figure 22-7
Mise en place du composant TileList
• Un tableau nommé dg_commande contenant les colonnes Ref, Produit, Prix, Quantité, Total.
L’alimentation de ce tableau ne nous intéresse pas pour le moment. Ajoutez-y également un label contenant le texte « Total à payer » et une zone de texte (figure 22-8).
Figure 22-8
Tableau de commande
=Flex3 FM.book Page 445 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : le panier d’achat
CHAPITRE 22
445
• Un bouton portant le libellé « Valider Commande » dont l’action sur celui-ci déclenchera
la validation du formulaire de saisie d’information et, selon le résultat de la validation,
affichera le texte « Commande Validée ».
• Un bouton Retour permettant à l’utilisateur d’annuler sa commande et de revenir au
détail de l’article.
Avant de vous laisser réaliser cette interface, nous allons modifier le code d’ajout d’un
produit dans le panier en ajoutant les champs quantiteProduit, servant à stocker la quantité commandée, et totalProduit, servant à stocker le montant total à payer pour chaque
produit.
public function ajouterPanier():void
{
var reference:String = txt_ref.text
var prix:Number = Number(txt_prix.text)
var nom:String = txt_nom.text
panierAchat.addItem({refProduit:reference, nomProduit:nom, prixProduit:prix,
➥quantiteProduit:1, totalProduit:prix})
}
La partie la plus complexe de l’exercice réside dans la mise en place du composant TileList.
La solution, comme vous devez vous en douter, consiste à créer un ItemRenderer permettant
la mise en forme de chaque cellule du composant TileList. N’oubliez pas de modifier les
valeurs des champs totalPrix et quantitePrix du dataProvider du composant TileList (la
propriété data.nomduchamp sert à récupérer la valeur de la ligne en cours de lecture mais
permet aussi de modifier la valeur du dataProvider de la ligne lue).
Solution
Création de l’interface
La difficulté résidait essentiellement dans l’alimentation du composant TileList :
<!-- ***************** ÉTAT COMMANDE ******************** -->
<mx:State name="etat_commande">
<mx:RemoveChild target="{panel_recherche}"/>
<mx:RemoveChild target="{panel_panier}"/>
<mx:RemoveChild target="{panel_detail}"/>
<mx:AddChild position="lastChild">
<mx:Panel x="10" y="10" width="880" height="570" layout="absolute"
➥title="Passer votre commande" id="panel_commande">
<!-- FORMULAIRE DE SAISIE -->
<mx:Label x="10" y="12" text="Adresse de livraison :"
➥fontWeight="bold" id="lab_adresseLivraison"/>
<mx:Form x="10" y="38" width="288" height="186"
➥horizontalScrollPolicy="off" verticalScrollPolicy="off">
<mx:FormItem label="Prénom :" required="true">
<mx:TextInput id="txt_prenomCommande"/>
=Flex3 FM.book Page 446 Mardi, 2. décembre 2008 3:32 15
446
Cas pratiques
PARTIE II
</mx:FormItem>
<mx:FormItem label="Nom :" required="true">
<mx:TextInput id="txt_nomCommande"/>
</mx:FormItem>
<mx:FormItem label="Adresse :" required="true">
<mx:TextArea id="txt_adresseCommande"/>
</mx:FormItem>
<mx:FormItem label="Code Postal :" required="true">
<mx:TextInput id="txt_cpCommande"/>
</mx:FormItem>
<mx:FormItem label="Ville :" required="true">
<mx:TextInput id="txt_villeCommande"/>
</mx:FormItem>
</mx:Form>
<!-- MISE EN PLACE DU COMPOSANT TITLELIST -->
<mx:Label x="366" y="12" text="Votre panier :" fontWeight="bold"
➥id="lab_VotrePanier"/>
<mx:TileList itemRenderer="ItemRenderer_PreCommande" x="366" y="38" height="228"
➥dataProvider="{panierAchat}" rowHeight="98" columnWidth="400" width="400"
➥id="tl_Panier"></mx:TileList>
<mx:HRule x="10" y="274" width="840" height="14" strokeWidth="1"/>
<!-- LE TABLEAU -->
<mx:Label x="10" y="308" text="Votre commande :"
➥fontWeight="bold" id="lab_VotreCommande"/>
<mx:DataGrid x="10" y="334" width="840" height="84"
➥id="dg_commande">
<mx:columns>
<mx:DataGridColumn headerText="Ref" dataField=" "/>
<mx:DataGridColumn headerText="Produit" dataField=" "/>
<mx:DataGridColumn headerText="Prix (¤)" dataField=" "/>
<mx:DataGridColumn headerText="Quantité" dataField=" "/>
<mx:DataGridColumn headerText="Total (¤)" dataField=" "/>
</mx:columns>
</mx:DataGrid>
<mx:Label x="602" y="431" text="Total à payer :"
➥id="lab_TotalAPayer"/>
<mx:Text x="681" y="426" text="Text" width="169" height="27"
➥fontWeight="bold" fontSize="16" textAlign="center"
➥id="txt_totalCommande"/>
<mx:HRule x="10" y="457" width="840" height="14" strokeWidth="1"/>
<!-- LE BOUTON DE VALIDATION -->
=Flex3 FM.book Page 447 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : le panier d’achat
CHAPITRE 22
447
<mx:Button x="705" y="483" label="Valider la commande"
➥id="btn_validerCommande" click="validerCommande()"/>
<!-- LE BOUTON DE RETOUR -->
<mx:Button x="10" y="483" label="Retour" click=
➥"currentState='etat_visualisationarticle'" id="btn_retour"/>
</mx:Panel>
</mx:AddChild>
</mx:State>
N’oublions pas de faire appel à cet état lorsque l’utilisateur cliquera sur le bouton
Commander présent sur l’interface du panier :
<mx:Panel x="636" y="10" width="250" height="452" layout="absolute" title="Mon
➥panier" id="panel_panier">
<mx:DataGrid x="10" y="10" height="367" id="dg_panier" width="210"
➥rowHeight="70"
dataProvider="{panierAchat}"
>
<mx:columns>
<mx:DataGridColumn headerText="Appareils"
➥itemRenderer="ItemRenderer_Panier"/>
</mx:columns>
</mx:DataGrid>
<mx:Button x="10" y="380" label="Vider" width="107" id="btn_viderpanier"
➥click="viderPanier()"/>
<mx:Button x="125" y="380" label="Commander" id="btn_commander"
➥click="currentState='etat_commande'"/>
</mx:Panel>
Création de l’ItemRenderer
Nous avons choisi de nommer notre ItemRenderer ItemRenderer_PreCommande.mxml. Nous
l’avons créé à partir du composant HBox qui permet d’aligner automatiquement sur le plan
horizontal les composants qui y sont insérés.
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="98"
➥horizontalScrollPolicy="off" verticalScrollPolicy="off">
<mx:Script>
<![CDATA[
//Calcul du prix total
public function calculerPrix():void
{
//Mise à jour du DataProvider
data.quantiteProduit = num_quantite.value;
data.totalProduit = num_quantite.value * (Number(data.prixProduit));
//Mise à jour de la zone de texte txt_prixTotal
txt_prixTotal.text = formatEuros.format(data.totalProduit)
}
=Flex3 FM.book Page 448 Mardi, 2. décembre 2008 3:32 15
448
Cas pratiques
PARTIE II
]]>
</mx:Script>
<!-- FORMAT EUROS -->
<mx:CurrencyFormatter id="formatEuros" alignSymbol="right" currencySymbol="¤" />
<!-- DÉTAIL DU PRODUIT -->
<mx:Canvas width="227" height="97" horizontalScrollPolicy="off"
➥verticalScrollPolicy="off">
<mx:Text x="0" y="5" text="PRODUIT" width="227" fontWeight="bold"
➥textAlign="center"/>
<mx:HRule x="0" y="26" strokeWidth="1" width="227"/>
<mx:Label x="10" y="31" text="Ref :" id="lab_ref"/>
<mx:Text x="61" y="31" text="{data.refProduit}" width="156" id="txt_ref"
➥textAlign="left" fontWeight="bold"/>
<mx:Label x="10" y="51" text="Nom :" id="lab_nom"/>
<mx:Text x="61" y="52" text="{data.nomProduit}" width="156" id="txt_nom"
➥textAlign="left" fontWeight="bold"/>
<mx:Label x="10" y="71" text="Prix :" id="lab_prix"/>
<mx:Text x="61" y="71" text="{formatEuros.format(data.prixProduit)}"
➥width="156" id="txt_prix" textAlign="left" fontWeight="bold"/>
</mx:Canvas>
<!-- SAISIE DE LA QUANTITÉ -->
<mx:Canvas width="58" height="97" verticalScrollPolicy="off"
➥horizontalScrollPolicy="off">
<mx:Text x="0" y="5" text="QTE" fontWeight="bold" textAlign="center"
➥width="58"/>
<mx:NumericStepper x="12" y="46" height="23" width="38" id="num_quantite"
➥minimum="1" stepSize="1" value="{data.quantiteProduit}"
➥change="calculerPrix()"/>
<mx:HRule x="0" y="26" strokeWidth="1" width="58" height="1"/>
</mx:Canvas>
<!-- AFFICHAGE DU PRIX TOTAL -->
<mx:Canvas width="98" height="99" horizontalScrollPolicy="off"
➥verticalScrollPolicy="off">
<mx:Text x="0" y="5" text="PRIX TOTAL" width="98" textAlign="center"
➥fontWeight="bold"/>
<mx:HRule x="-1" y="26" strokeWidth="1"/>
<mx:Text x="10" y="47" text="{formatEuros.format(data.totalProduit)}"
➥fontSize="14" fontWeight="bold" width="78" textAlign="center"
➥id="txt_prixTotal"/>
</mx:Canvas>
</mx:HBox>
=Flex3 FM.book Page 449 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : le panier d’achat
CHAPITRE 22
449
Mise en place de la validation du formulaire
La première étape consiste à créer les éléments de validation dans le fichier modSite.mxml
(placez-les en dessous des transitions déjà présentes) :
<!-- ***************** VALIDATEURS COMMANDES ******************** -->
<mx:StringValidator id="val_prenom" property="text" source="{txt_prenomCommande}"
➥required="true" requiredFieldError="Ce champ est obligatoire" />
<mx:StringValidator id="val_nom" property="text" source="{txt_nomCommande}"
➥required="true" requiredFieldError="Ce champ est obligatoire" />
<mx:StringValidator id="val_adresse" property="text" source="
➥{txt_adresseCommande}" required="true" requiredFieldError="Ce champ est
➥obligatoire" />
<mx:StringValidator id="val_ville" property="text" source="{txt_villeCommande}"
➥required="true" requiredFieldError="Ce champ est obligatoire" />
<mx:ZipCodeValidator id="val_codePostal" property="text"
➥source="{txt_cpCommande}" required="true" requiredFieldError="Ce champ est
➥obligatoire" wrongLengthError="Format erroné !!" />
Terminez par la création des procédures de validation du formulaire dans le fichier
SiteAS3.as :
/****************************************************
*
CRÉATION COMMANDE
* **************************************************/
import mx.validators.Validator;
//Procédure de validation des champs
public function validerSaisie():int
{
var valide:int = 1;
var tableau_validation:Array = Validator.validateAll
➥([val_prenom,val_nom,val_adresse,val_ville,val_codePostal]);
if (tableau_validation.length != 0) {
valide = 0;
}
return valide;
}
//Procédure de validation de la commande
public function validerCommande():void
{
if (validerSaisie()==1)
{
Alert.show("La commande est validée")
}
}
=Flex3 FM.book Page 450 Mardi, 2. décembre 2008 3:32 15
450
Cas pratiques
PARTIE II
Cela ne présente pas de grandes difficultés, étant donné que nous avions abordé la validation
de formulaire dans le chapitre précédent.
En résumé
Dans ce chapitre, traitant de la première partie de la vente en ligne, nous avons pu mettre
en pratique nos connaissances sur la création d’états et de transitions et l’utilisation de
composants personnalisés. Nous avons également abordé la notion d’ItemRenderer, outil
permettant de réaliser des masques de mise en forme applicables à tout composant, et
pratiqué la création de services PHP, la validation de données et le databinding.
Dans le chapitre suivant, nous allons terminer le module concernant le cœur du site E-Reflex
en étudiant la notion de glisser-déposer et en appliquant nos connaissances sur la gestion
des pop-ups, acquises dans le chapitre 6.
=Flex3 FM.book Page 451 Mardi, 2. décembre 2008 3:32 15
23
Module de vente en ligne :
commande et facturation
Dans cette deuxième partie du module de vente en ligne, nous allons nous concentrer sur
la création de la commande et de sa facturation (édition et impression). Enfin, nous
terminerons par la création d’une interface qui rendra possible la réalisation du paiement
en ligne.
Dans cette partie, nous allons travailler sur les nouvelles notions suivantes :
• le glisser-déposer (drag and drop) ;
• l’impression ;
• la manipulation de dates ;
• l’utilisation du composant <mx:repeater>.
Important
Avant de poursuivre la lecture de ce chapitre, il convient d’avoir réalisé l’ensemble des tâches demandées
dans le chapitre précédent. Si vous n’avez pas réalisé ce travail, vous pouvez télécharger les sources sur
la fiche de l’ouvrage : www.editions-eyrolles.com
Création de la commande
Nous allons dans un premier temps nous consacrer à la mise en place du processus de
commande. Pour passer sa commande, l’utilisateur prendra les éléments de son panier
qu’il souhaite commander et viendra les déposer dans le tableau de commande que vous
avez créé dans le chapitre précédent.
=Flex3 FM.book Page 452 Mardi, 2. décembre 2008 3:32 15
452
Cas pratiques
PARTIE II
Implémenter le glisser-déposer dans le tableau de commander
Pour implémenter l’opération de glisser-déposer (drag and drop), nous devons définir
l’objet source et l’objet de destination. Notre objet source est le panier à partir duquel nous
allons effectuer le glissé (drag). Notre objet de destination est le tableau de commande
dans lequel nous allons déposer (drop) les produits.
La première étape va donc consister à mettre définir les actions sur chaque objet :
Le panier :
<mx:TileList
dragEnabled="true"
itemRenderer="ItemRenderer_PreCommande"
x="366"
y="38"
height="228"
dataProvider="{panierAchat}"
rowHeight="98"
columnWidth="400"
width="400"
id="tl_Panier">
</mx:TileList>
Le tableau de commande :
<mx:DataGrid
dropEnabled="true"
x="10" y="334" width="840" height="84" id="dg_commande">
<mx:columns>
<mx:DataGridColumn headerText="Ref"
➥dataField="refProduit"/>
<mx:DataGridColumn headerText="Produit"
➥dataField="nomProduit"/>
<mx:DataGridColumn headerText="Prix"
➥dataField="prixProduit"/>
<mx:DataGridColumn headerText="Quantité"
➥dataField="quantiteProduit"/>
<mx:DataGridColumn headerText="Total"
➥dataField="totalProduit"/>
</mx:columns>
</mx:DataGrid>
Lorsque l’utilisateur déposera le produit dans le tableau de commandes, les données
contenues dans ce tableau seront une copie des données présentes dans le panier. Par
conséquent, les champs alimentant le tableau de commande doivent être identiques à
ceux contenus dans le dataProvider du panier.
Nous pouvons à présent tester notre application et vérifier le bon fonctionnement du
glisser-déposer mis en place.
=Flex3 FM.book Page 453 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : commande et facturation
CHAPITRE 23
453
Supprimer l’article du panier
Lorsque l’utilisateur a sélectionné son article et l’a déposé dans le tableau de commande,
celui-ci ne doit plus être présent dans son panier. Pour réaliser cette suppression, nous
devons activer la propriété dragMoveEnabled du composant source :
<mx:TileList
dragEnabled="true"
dragMoveEnabled="true"
itemRenderer="ItemRenderer_PreCommande"
x="366"
y="38"
height="228"
dataProvider="{panierAchat}"
rowHeight="98"
columnWidth="400"
width="400"
id="tl_Panier">
</mx:TileList>
Si nous exécutons notre module, nous voyons qu’il est possible de sélectionner un
produit, de le placer dans le tableau de commande et de le voir disparaître de notre panier.
L’objectif est donc atteint (figure 23-1).
Figure 23-1
Ajout d’un produit dans le tableau de commande
=Flex3 FM.book Page 454 Mardi, 2. décembre 2008 3:32 15
454
Cas pratiques
PARTIE II
Implémenter l’inverse
Nous sommes en mesure de déplacer un produit du panier vers le tableau de commande. Néanmoins, il
se peut que l’utilisateur se trompe et souhaite remettre le produit dans son panier.
Les objets source et destination étant inversés, il suffit d’activer les propriétés dragEnabled et dragMove
Enabled du tableau de commande, et permettre la possibilité de redéposer un produit dans le panier en
activant la propriété dropEnabled.
Le tableau de commande :
<mx:DataGrid
dropEnabled="true"
dragEnabled="true"
dragMoveEnabled="true"
x="10" y="334" width="840" height="84" id="dg_commande">
<mx:columns>
<mx:DataGridColumn headerText="Ref"
➥dataField="refProduit"/>
<mx:DataGridColumn headerText="Produit"
➥dataField="nomProduit"/>
<mx:DataGridColumn headerText="Prix"
➥dataField="prixProduit"/>
<mx:DataGridColumn headerText="Quantité"
➥dataField="quantiteProduit"/>
<mx:DataGridColumn headerText="Total"
➥dataField="totalProduit"/>
</mx:columns>
</mx:DataGrid>
Le panier :
<mx:TileList
dragEnabled="true"
dragMoveEnabled="true"
dropEnabled="true"
itemRenderer="ItemRenderer_PreCommande"
x="366"
y="38"
height="228"
dataProvider="{panierAchat}"
rowHeight="98"
columnWidth="400"
width="400"
id="tl_Panier">
</mx:TileList>
Il est à présent possible de remettre un produit dans le panier, annulant ainsi la commande de ce dernier
(figure 23-2).
=Flex3 FM.book Page 455 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : commande et facturation
CHAPITRE 23
455
Figure 23-2
Remise du produit dans le panier d’achat
Calcul du prix total de la commande
Le prix total de la commande est calculé en réalisant la somme des prix de chaque
produit situé dans le tableau de commande. Ce calcul est effectué à chaque mise à jour du
contenu de ce tableau, c’est-à-dire à chaque fois que l’utilisateur dépose ou retire un
élément dans le tableau. On peut traduire ce processus comme suit :
• Lorsque l’utilisateur déplace un produit du panier vers le tableau, le prix de ce produit
est ajouté au total de la commande.
• Lorsque l’utilisateur déplace un produit de tableau de commande vers le panier
d’achat, le prix de ce produit est déduit du total de la commande.
Si nous analysons bien ces deux phrases, nous souhaitons que le calcul soit effectué après
déplacement complet du produit. Pour réaliser cela, nous allons utiliser le déclencheur
d’événement dragComplete() des deux composants :
<mx:TileList
dragEnabled="true"
dragMoveEnabled="true"
dropEnabled="true"
=Flex3 FM.book Page 456 Mardi, 2. décembre 2008 3:32 15
456
Cas pratiques
PARTIE II
dragComplete="calculerTotalCommande(event)"
name="listePanier">
</mx:TileList>
<mx:DataGrid
dropEnabled="true"
dragMoveEnabled="true"
dragEnabled="true"
dragComplete="calculerTotalCommande(event)"
➥name="tableauCommande"
Ainsi, lorsque le produit est déplacé, la procédure calculerTotalCommande() est exécutée.
La propriété name a également été ajoutée, permettant de déterminer le composant étant à
l’origine du déplacement (dragInitiator) et de déterminer ainsi, l’ajout ou la diminution
du prix total du produit sélectionné au total de la commande. Voyons à présent le code de
la procédure calculerTotalCommande() :
/****************************************************
* CALCUL DU TOTAL DE LA COMMANDE
* **************************************************/
[Bindable]
public var totalCommande:int = 0
public function calculerTotalCommande(e:DragEvent):void
{
if (e.dragInitiator.name == "listePanier")
{
totalCommande += e.currentTarget.selectedItem.totalProduit
}
else
{
totalCommande -= e.currentTarget.selectedItem.totalProduit
}
}
Comme nous venons de l’indiquer, en fonction du nom de composant étant à l’origine du
déplacement du produit, la valeur du champ totalProduit est ajoutée ou soustraite à la
variable totalCommande.
Enfin, pour que cela soit entièrement fonctionnel, il convient de lier la propriété text du
composant txt_totalCommande chargé d’afficher le total de la commande en prenant soin
de formater le résultat, via le composant CurrencyFormatter, afin que celui-ci soit présenté
sous forme monétaire (figure 23-3) :
=Flex3 FM.book Page 457 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : commande et facturation
CHAPITRE 23
457
<!-- FORMAT EURO (A PLACER AU DESSUS DE L'ETAT PRINCIPAL) -->
<mx:CurrencyFormatter id="formatEuros" alignSymbol="right" currencySymbol="€" />
<!-- composant txt_totalCommande de l’état etat_commande -->
<mx:Text x="681" y="426" text="{formatEuros.format(totalCommande)}" width="169"
➥height="27" fontWeight="bold" fontSize="16" textAlign="center"
➥id="txt_totalCommande"/>
Figure 23-3
Calcul du total de la commande
Création de la facture
Nous souhaitons proposer la visualisation de la facture à l’aide d’un pop-up. Dans ce
pop-up, nous disposerons un bouton permettant d’imprimer la facture.
Implémentation du pop-up de facturation
Comme nous l’avons vu dans le chapitre 6, pour créer un pop-up, il faut créer un nouveau
fichier MXML Component basé sur le composant TitleWindow. Nous le nommerons pop
Facture.mxml et il accueillera le code permettant de réaliser la facture illustrée par la
figure 23-4 :
=Flex3 FM.book Page 458 Mardi, 2. décembre 2008 3:32 15
458
Cas pratiques
PARTIE II
Figure 23-4
Pop-up de facturation
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow close="fermerPopUp()" xmlns:mx="http://www.adobe.com/2006/mxml"
➥layout="absolute" width="544" height="570" title="Votre Facture"
➥showCloseButton="true">
<mx:Script>
<![CDATA[
//Procédure de fermeture
import mx.managers.PopUpManager;
public function fermerPopUp():void
{
PopUpManager.removePopUp(this)
}
=Flex3 FM.book Page 459 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : commande et facturation
CHAPITRE 23
459
//Impression de la Facture
import mx.printing.*
public function imprimerFacture():void
{
var impression:FlexPrintJob = new FlexPrintJob()
impression.start();
impression.addObject(this,FlexPrintJobScaleType.NONE)
impression.send();
}
]]>
</mx:Script>
<!-- TITRE -->
<mx:Label x="10" y="10" text="EReflex" width="165" fontWeight="bold"
➥fontSize="24"/>
<mx:HRule x="10" y="42" width="496" height="8" strokeWidth="1"/>
<!-- ADRESSE CLIENT -->
<mx:Canvas x="10" y="58" width="265" height="171" borderStyle="solid"
➥cornerRadius="20">
<mx:Label x="10" y="10" text="Adresse de livraison / Destinataire"
➥fontWeight="bold" id="lab_adresse" textDecoration="underline"/>
<mx:Text x="10" y="36" text="prenom" width="89" id="txt_prenomFacture"/>
<mx:Text x="107" y="36" text="nom" id="txt_nomFacture" width="146"/>
<mx:TextArea x="10" y="62" width="243" id="txt_adresseFacture"
➥text="adresse" height="67"/>
<mx:Text x="10" y="137" text="cp" id="txt_cpFacture" width="59"/>
<mx:Text x="69" y="137" text="ville" width="184" id="txt_villeFacture"/>
</mx:Canvas>
<!-- INFORMATIONS FACTURE -->
<mx:Canvas x="283" y="58" width="223" height="171" borderStyle="solid"
➥cornerRadius="20">
<mx:Label x="10" y="10" text="Facture" fontWeight="bold" id="lab_facture"
➥textDecoration="underline"/>
<mx:Label x="10" y="38" text="Numéro :" fontWeight="bold"/>
<mx:Text x="97" y="38" text="12345679" width="114" id="txt_numFacture"/>
<mx:Label x="10" y="64" text="Date : " id="lab_date" fontWeight="bold"/>
<mx:Text x="97" y="64" text="date" width="114" id="txt_dateFacture"/>
<mx:Label x="10" y="90" text="Echéance :" fontWeight="bold"
➥id="lab_echeance"/>
<mx:Text x="97" y="90" text="echeance" width="114" id="txt_echeanceFacture"/>
<mx:Label x="10" y="116" text="Montant (¤) :" fontWeight="bold"
➥id="lab_montant"/>
<mx:Text x="97" y="116" text="montant" width="114" id="txt_montantFacture"/>
</mx:Canvas>
=Flex3 FM.book Page 460 Mardi, 2. décembre 2008 3:32 15
460
Cas pratiques
PARTIE II
<!-- PRODUITS -->
<mx:Canvas x="10" y="237" width="496" height="207">
<mx:DataGrid x="10" y="10" width="476" height="174" editable="false"
➥id="dg_facture">
<mx:columns>
<mx:DataGridColumn headerText="Produit" dataField="nomProduit"/>
<mx:DataGridColumn headerText="Quantite" dataField="quantiteProduit"
➥width="100"/>
<mx:DataGridColumn headerText="Prix (¤)" dataField="totalProduit"
➥width="100"/>
</mx:columns>
</mx:DataGrid>
</mx:Canvas>
<mx:Label x="273" y="452" text="Nous vous remercions de votre confiance"/>
<mx:Button id="btn_imprimer" x="433" y="492" label="Imprimer" />
</mx:TitleWindow>x
Créons à présent la procédure qui ouvrira le pop-up tout en lui transmettant les données
de la facturation. Pour cela, éditons le fichier SiteAS3.as en lui ajoutant ces quelques
lignes :
/****************************************************
* FACTURE
* **************************************************/
import mx.managers.PopUpManager
public function ouvertureFacture():void
{
//Création d'un objet PopUp créé en instanciant la classe popFacture
//Cela permet de pouvoir accéder à l'ensemble de ses objets et de leurs
//transmettre des données
var objetPopUp:popFacture = popFacture
➥(PopUpManager.createPopUp(this,popFacture,true));
objetPopUp.txt_prenomFacture.text = txt_prenomCommande.text
objetPopUp.txt_nomFacture.text = txt_nomCommande.text
objetPopUp.txt_adresseFacture.text = txt_adresseCommande.text
objetPopUp.txt_cpFacture.text = txt_cpCommande.text
objetPopUp.txt_villeFacture.text = txt_villeCommande.text
objetPopUp.dg_facture.dataProvider = dg_commande.dataProvider;
objetPopUp.txt_montantFacture.text = txt_totalCommande.text;
//Calcul des dates
//Date du jour :
var dateDuJour:Date = new Date();
objetPopUp.txt_dateFacture.text = String(dateDuJour.getDate()+'/'
➥+(dateDuJour.getMonth()+1)+"/"+dateDuJour.getFullYear());
=Flex3 FM.book Page 461 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : commande et facturation
CHAPITRE 23
461
//Date d'échéance = 30 jours plus tard soit dans 30*24*60*60*1000 Millisecondes !
var dateEcheance:Date = new Date(dateDuJour.getTime()+(30*24*60*60*1000))
objetPopUp.txt_echeanceFacture.text = String(dateEcheance.getDate()+'/'
➥+(dateEcheance.getMonth()+1)+"/"+dateEcheance.getFullYear());
}
Regardons de plus près la méthode utilisée pour l’ajout ou la soustraction de temps à une
date. Pour ajouter ou soustraire du temps à une date, il convient de calculer le nombre de
millisecondes que ce temps représente. Les règles énoncées ci-dessous pourront vous
servir de bases de calcul :
• Une seconde représente 1 000 millisecondes.
• Une minute représente 60 ¥ 1 000 millisecondes = 60 000 ms.
• Une heure représente 60 ¥ 60 ¥ 1 000 = 3 600 000 ms.
• Une journée représente 24 ¥ 60 ¥ 60 ¥ 1 000 = 86 400 000 ms.
Une fois le nombre de millisecondes déterminé, il faut ensuite extraire le nombre de
millisecondes écoulées entre la date, faisant l’objet d’ajout ou de soustraction de temps,
et le 1er janvier 1970 (cette extraction est réalisée à l’aide de la méthode getTime()). Une
fois ce calcul réalisé, nous lui ajoutons ou soustrayons le nombre de millisecondes que
représente le temps à ajouter ou soustraire :
//Détermination de la date d’échéance fixée 30 jours plus tard de la date du jour:
var dateDuJour:Date = new Date();
var dateEcheance:Date = new Date(dateDuJour.getTime()+(30*24*60*60*1000))
Tout semblant en place, nous allons à présent faire appel à ce pop-up. Le pop-up de facturation ne peut s’ouvrir que si l’ensemble de la commande est validée, c’est-à-dire si la
procédure validerSaisie() retourne 1 et si le dataprovider mis en place précédemment
contient au moins un élément. Pour cela, modifions la procédure comme suit :
public function validerCommande():void
{
if (validerSaisie()==1 && dg_commande.dataProvider.length != 0)
{
ouvertureFacture();
}
}
Nous avons ajouté la vérification de la présence d’au moins un produit dans la commande,
car sans cela, il est bien inutile de créer une facture.
Si nous exécutons notre module, le pop-up s’ouvre bien lors de la validation de la
commande et que les données de la facture y sont reprises et affichées correctement. Il ne
nous reste plus qu’a imprimer la facture !
=Flex3 FM.book Page 462 Mardi, 2. décembre 2008 3:32 15
462
Cas pratiques
PARTIE II
Impression de la facture
Pour réaliser des impressions à l’aide du framework Flex, nous avons à notre disposition
la classe FlexPrintJob située dans le package mx.printing. Cette classe permet l’impression d’objets présents dans une interface graphique. Ainsi, nous avons la possibilité
d’imprimer un Panel et l’ensemble de champs qu’il contient, un datagrid, une zone de
texte, etc. La réalisation de la tâche d’impression se réalise en quatre temps :
1. Instanciation de la classe FlexPrintJob permettant de créer un travail d’impression.
2. Démarrage du travail d’impression.
3. Ajout de l’objet à imprimer dans le travail d’impression avec la spécification de l’échelle
à utiliser.
4. Exécution de l’impression.
La spécification de l’échelle s’effectue en utilisant la classe FlexPrintJobScale en choisissant
l’une de ces méthodes :
Méthode
Description
MATCH_WIDTH
Méthode utilisée par défaut. Elle adapte la longueur de l’objet à imprimer à celle de la page.
MATCH_HEIGHT
Adapte la hauteur de l’objet à imprimer à celle de la page. Dans certains cas, cela entraîne
l’impression de plusieurs pages si l’objet ne peut être adapté.
SHOW_ALL
Adapte les dimensions de l’objet afin qu’il soit imprimé sur une seule page.
FILL_PAGE
Adapte les dimensions de l’objet afin que sa hauteur soit égale à la hauteur de la page.
NONE
N’effectue aucune modification sur les dimensions de l’objet à imprimer. Il sera imprimé avec
les dimensions spécifiées dans l’application Flex.
Mettons ceci en pratique en ajoutant le code suivant à notre pop-up :
//Impression de la Facture
import mx.printing.*
public function imprimerFacture():void
{
//Création du travail d'impression :
var travailImpression:FlexPrintJob = new FlexPrintJob()
//Debut du travail d'impression
travailImpression.start();
//Ajout de l'ojet à imprimer (This = le pop-up entier)
travailImpression.addObject(this,FlexPrintJobScaleType.NONE)
//Execution de l'impression
travailImpression.send();
}
=Flex3 FM.book Page 463 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : commande et facturation
CHAPITRE 23
463
Ajoutons à présent l’appel de cette procédure au bouton btn_imprimer :
<mx:Button id="btn_imprimer" x="433" y="492" label="Imprimer"
➥click="imprimerFacture()"
Enfin, exécutons le module pour vérifier que l’impression se réalise correctement.
À vos claviers : création d’un pop-up de paiement
et de validation de la commande
Votre contribution, dans ce chapitre, va consister à créer un autre pop-up où l’utilisateur
pourra saisir le numéro de sa carte bancaire et valider sa commande. Ce pop-up (que
nous nommerons popPaiement.mxml) sera appelé à partir du pop-up de facturation à l’aide
d’un bouton portant le libellé Paiement en ligne.
L’interface graphique du pop-up sera constituée d’un clavier numérique ainsi que d’une
liste déroulante offrant à l’utilisateur la possibilité de choisir le type de carte de paiement
souhaité (figure 23-5), sans oublier un bouton permettant de valider le paiement. Bien
entendu, le format de validation de la donnée saisie diffère selon le type de carte sélectionnée ! Il convient donc de s’assurer que la donnée saisie par l’utilisateur (à l’aide
uniquement du clavier numérique) soit correctement formatée.
Figure 23-5
Pop-up de réalisation du paiement
=Flex3 FM.book Page 464 Mardi, 2. décembre 2008 3:32 15
464
Cas pratiques
PARTIE II
Les types de cartes disponibles sont :
• American Express
• MasterCard
• Visa
Nous allons concentrer nos explications sur l’utilisation du composant <mx:Repeater>
avec qui nous allons de suite faire connaissance.
Répétition de composants : <mx:Repeater>
Vous conviendrez certainement que la création du pavé numérique n’est pas des plus
sympathique : 10 chiffres, 10 boutons, 10 identifiants différents…. Mais grâce au composant
<mx:repeater>, ce travail est terminé ! Voyons ceci en détail :
<mx:Script>
<![CDATA[
[Bindable]
public var listeBoutons:Array=[1,2,3,4,5,6,7,8,9,0];
]]>
</mx:Script>
<mx:ArrayCollection id="boutons" source="{listeBoutons}"/>
<mx:Tile x="0" y="65" direction="horizontal" id="tl_boutons">
<mx:Repeater id="clavierSaisie" dataProvider="{boutons}">
<mx:Button id="btn_clavier" label="{clavierSaisie.currentItem}" width="60"
➥height="35"/>
</mx:Repeater>
</mx:Tile>
Nous avons d’abord créé un tableau contenant les 10 chiffres du clavier numérique.
Ensuite, nous avons transformé ce tableau en collection d’objet afin qu’il puisse être
exploité par le dataProvider du composant <mx:repeater>.
Figure 23-6
Utilisation du composant <mx :Repeater>
=Flex3 FM.book Page 465 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : commande et facturation
CHAPITRE 23
465
L’objectif de notre composant <mx :repeater> est de créer autant de bouton qu’il y a de
données dans son dataProvider. Couplé au composant <mx:Tile>, qui est capable d’agencer
automatiquement les composants dans une grille en fonction de leur nombre (10 composants = 2 lignes de 4 composants et 1 ligne de 2, comme vous pouvez le voir sur la figure
23-6), le clavier numérique se construit en quelques lignes de code seulement !
Pour connaître la valeur du bouton cliqué, il suffit de récupérer la valeur de l’item affecté
au bouton. Pour cela, nous utilisons la méthode getRepeaterItem() du bouton :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
[Bindable]
public var listeBoutons:Array=[1,2,3,4,5,6,7,8,9,0];
import mx.controls.Alert
public function valeurBouton(valeur:String):void
{
Alert.show(valeur);
}
]]>
</mx:Script>
<mx:ArrayCollection id="boutons" source="{listeBoutons}"/>
<mx:Tile x="0" y="65" direction="horizontal" id="tl_boutons">
<mx:Repeater id="clavierSaisie" dataProvider="{boutons}">
<mx:Button id="btn_clavier" label="{clavierSaisie.currentItem}" width="60"
➥height="35"
click="valeurBouton(String(event.currentTarget
➥.getRepeaterItem()))"/>
</mx:Repeater>
</mx:Tile>
</mx:Application>
À présent, à vous de travailler sur la mise en place du pop-up de paiement en ligne.
Solution
Vous avez peut-être consulté l’aide de Flex Builder et avez sans doute trouvé la solution.
Sinon, c’est dommage, car la solution y figurait : saisir credicardvalidator dans la zone
=Flex3 FM.book Page 466 Mardi, 2. décembre 2008 3:32 15
466
Cas pratiques
PARTIE II
de recherche de l’aide. Cet exemple, a en effet pour but de vous montrer que l’aide de
Flex Builder est extrêmement riche en contenu et au moindre souci ou doute, il ne faut
pas hésiter à la consulter. La solution au problème s’y trouve certainement !
Avez-vous pensé à implémenter un bouton pour effacer la zone de saisie en cas d’erreur ?
Car n’oublions pas que seul le clavier numérique devait être utilisé pour la saisie du
numéro de carte bancaire :
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow close="fermerPopUp()" xmlns:mx="http://www.adobe.com/2006/mxml"
➥layout="absolute" width="400" height="378" showCloseButton="true"
➥title="Réalisation du paiement">
<mx:Script>
<![CDATA[
[Bindable]
public var listeBoutons:Array=[1,2,3,4,5,6,7,8,9,0,'C'];
import mx.controls.Alert
public function valeurBouton(valeur:String):void
{
if (valeur != 'C')
{
txt_numeroCarte.text += valeur;
}
else
{
txt_numeroCarte.text = '';
}
}
import mx.managers.PopUpManager;
public function fermerPopUp():void
{
PopUpManager.removePopUp(this)
}
]]>
</mx:Script>
<mx:ArrayCollection id="boutons" source="{listeBoutons}"/>
<!-- MODELE STOCKANT LA LISTE DES CARTES DE PAIEMENT ET LEUR FORMAT -->
<mx:Model id="cartesPaiement">
<carte>
<type>{cmb_cartes.selectedItem.data}</type>
=Flex3 FM.book Page 467 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : commande et facturation
CHAPITRE 23
467
<format>{txt_numeroCarte.text}</format>
</carte>
</mx:Model>
<!--- VALIDATION DU FORMAT EN FONCTION DE LA CARTE PAIEMENT -->
<mx:CreditCardValidator id="val_cartePaiement"
cardTypeSource="{cartesPaiement}" cardTypeProperty="type"
cardNumberSource="{cartesPaiement}" cardNumberProperty="format"
trigger="{btn_valider}" triggerEvent="click"
cardTypeListener="{cmb_cartes}"
cardNumberListener="{txt_numeroCarte}"
wrongLengthError="Format erroné !"
wrongTypeError="Format erroné !"
valid="Alert.show('Paiement accepté');"/>
<mx:Panel title="Validez votre paiement" layout="absolute" height="299"
➥horizontalCenter="0" verticalCenter="0">
<!--- FORMULAIRE DE SAISIE -->
<mx:Form id="frm_saisie" x="0" y="0">
<mx:FormItem label="Choix de la carte :">
<mx:ComboBox id="cmb_cartes">
<mx:dataProvider>
<mx:Object label="American Express" data="American Express"/>
<mx:Object label="MasterCard" data="MasterCard"/>
<mx:Object label="Visa" data="Visa"/>
</mx:dataProvider>
</mx:ComboBox>
</mx:FormItem>
<mx:FormItem label="Numéro de la carte :">
<mx:TextInput id="txt_numeroCarte" editable="false"/>
</mx:FormItem>
</mx:Form>
<!--- CLAVIER NUMERIQUE -->
<mx:Tile x="10" y="90" direction="horizontal" id="tl_boutons" >
<mx:Repeater id="clavierSaisie" dataProvider="{boutons}">
<mx:Button id="btn_clavier" label="{clavierSaisie.currentItem}" width="60"
➥height="35"
click="valeurBouton(String(event.currentTarget
➥.getRepeaterItem()))"/>
</mx:Repeater>
</mx:Tile>
<!--- BOUTON DE VALIDATION -->
<mx:Button id="btn_valider" label="Effectuer le paiement" x="10" y="227"
➥width="306"/>
=Flex3 FM.book Page 468 Mardi, 2. décembre 2008 3:32 15
468
Cas pratiques
PARTIE II
</mx:Panel>
</mx:TitleWindow>
Nous pouvons à présent tester notre pop-up (figure 23-7), phase qui achève la réalisation
de notre module.
Figure 23-7
Pop-up de paiement en ligne
Déploiement du module
Notre module terminé, il est maintenant temps de passer à la phase de déploiement et
d’intégration au site E-Reflex. Pour cela, nous allons procéder de façon identique au
module d’administration en réalisant une exportation dite « Release Build » du projet :
1. Positionnez-vous sur le nom du projet (moduleSite).
2. Cliquez avec le bouton droit de la souris et choisissez l’option Export.
3. Choisissez l’option Release Build.
4. Cliquez sur Next et enfin sur Finish.
5. Placez-vous dans le répertoire bin-debug du projet et copiez les fichiers modSite.swf et
popFacture.swf dans le répertoire src du projet eReflex.
=Flex3 FM.book Page 469 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : commande et facturation
CHAPITRE 23
469
6. Éditons ensuite le fichier eReflex.mxml en important le module modSite dans le canvas
vueAccueil :
<!-- CONTENEUR DE VUES -->
<mx:ViewStack id="conteneurVues" x="0" y="132" width="900" height="590">
<mx:Canvas id="vueAccueil" label="Accueil" width="100%" height="100%">
<mx:ModuleLoader id="moduleSite" url="modSite.swf">
➥</mx:ModuleLoader>
</mx:Canvas>
<mx:Canvas id="vueAdministration" label="Administration" width="100%"
➥height="100%">
<mx:ModuleLoader id="moduleAdministration"
➥url="modAdministration.swf"></mx:ModuleLoader>
</mx:Canvas>
</mx:ViewStack>
Il ne nous reste plus qu’à tester l’ensemble de notre projet (figure 23-8).
Figure 23-8
Intégration du module de vente en ligne au site E-Reflex
=Flex3 FM.book Page 470 Mardi, 2. décembre 2008 3:32 15
470
Cas pratiques
PARTIE II
Optimisation et déploiement
Dans cette partie, qui clôt la réalisation de notre premier cas pratique, nous allons voir
comment optimiser notre application et comment la déployer.
Optimiser le temps de chargement
Comme il nous l’a été spécifié dans le cahier des charges du projet, seuls les administrateurs du site ont accès à la partie administration. Une fois connectés à cette partie de
l’application, ils ne peuvent visualiser la partie vitrine du site. Dans ce cas, il est inutile
de charger l’ensemble des modules de l’application lors de l’initialisation de l’application ! Ceci nous permettra de gagner du temps lors du chargement de l’application. Pour
ce faire, éditons le fichier MXML du projet eReflex en lui ajoutant ces quelques lignes :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥creationComplete="initialisationIHM()">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
private function connexion():void
{
if (btn_action.label == "Connecter")
{
if (txt_identifiant.text == 'abc' && txt_motDePasse.text=='1234')
{
connexionIHM();
}
else
{
Alert.show("Accès refusé")
}
}
else
{
initialisationIHM()
}
}
private function initialisationIHM():void
{
btn_administration.visible = false;
lab_identifiant.visible = true;
lab_motDePasse.visible = true;
txt_identifiant.visible = true;
txt_motDePasse.visible=true;
=Flex3 FM.book Page 471 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : commande et facturation
CHAPITRE 23
btn_action.label= "Connecter"
//Chargement du module Site
chargerModuleSite();
conteneurVues.selectedIndex = 0;
}
private function connexionIHM():void
{
btn_administration.visible = true;
lab_identifiant.visible = false;
lab_motDePasse.visible = false;
txt_identifiant.visible = false;
txt_motDePasse.visible=false;
txt_identifiant.text = "";
txt_motDePasse.text = "";
btn_action.label= "Déconnecter"
//Chargement du module d'administration
chargerModuleAdministration();
conteneurVues.selectedIndex = 1;
}
//Procédure de chargement/déchargement de modules
private function dechargerModuleAdministration():void
{
moduleAdministration.unloadModule();
}
private function dechargerModuleSite():void
{
moduleSite.unloadModule();
}
private function chargerModuleSite():void
{
dechargerModuleAdministration()
moduleSite.loadModule();
}
private function chargerModuleAdministration():void
{
dechargerModuleSite()
moduleAdministration.loadModule();
}
]]>
471
=Flex3 FM.book Page 472 Mardi, 2. décembre 2008 3:32 15
472
Cas pratiques
PARTIE II
</mx:Script>
<mx:Canvas width="900" height="730" horizontalCenter="0" verticalCenter="0">
<!-- LOGO -->
<mx:Image x="0" y="0" height="95" width="900" source="images/logo.jpg"/>
<!-- BARRE DE MENUS -->
<mx:ApplicationControlBar x="0" y="97" height="30" width="900">
<mx:Button label="Accueil" id="btn_accueil"
➥click="conteneurVues.selectedIndex = 0;chargerModuleSite()"/>
<mx:Button label="Administration" id="btn_administration"
➥click="conteneurVues.selectedIndex = 1;chargerModuleAdministration()"/>
<mx:Canvas width="686" height="22">
<mx:Label x="144" y="2" text="Identifiant :" fontWeight="bold"
➥id="lab_identifiant"/>
<mx:Label x="365" y="2" text="Mot de passe :" fontWeight="bold"
➥id="lab_motDePasse"/>
<mx:TextInput x="226" y="0" width="118" id="txt_identifiant"/>
<mx:TextInput x="459" y="0" width="119" displayAsPassword="true"
➥id="txt_motDePasse"/>
<mx:Button x="586" y="1" label="Connecter" id="btn_action"
➥click="connexion()"/>
</mx:Canvas>
</mx:ApplicationControlBar>
<!-- CONTENEUR DE VUES -->
<mx:ViewStack id="conteneurVues" x="0" y="132" width="900" height="590">
<mx:Canvas id="vueAccueil" label="Accueil" width="100%" height="100%">
<mx:ModuleLoader id="moduleSite" url="modSite.swf">
➥</mx:ModuleLoader>
</mx:Canvas>
<mx:Canvas id="vueAdministration" label="Administration" width="100%"
➥height="100%">
<mx:ModuleLoader id="moduleAdministration"
➥url="modAdministration.swf"></mx:ModuleLoader>
</mx:Canvas>
</mx:ViewStack>
</mx:Canvas>
</mx:Application>
=Flex3 FM.book Page 473 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : commande et facturation
CHAPITRE 23
473
Lors de l’initialisation de l’application, seul le module Site est chargé. À chaque fois que
l’utilisateur change de module, cela a pour conséquence de décharger le module affiché
pour charger le module souhaité. En faisant cela, nous avons réduit le temps de chargement
de notre application. Certes, sur un petit projet comme le nôtre, cela ne se ressent pas
forcément, mais sur un projet de grande envergure, cette méthode est payante.
Faire patienter l’utilisateur
Comme nous venons de l’évoquer, le chargement d’un module peut parfois prendre du
temps. Lors de cette phase, l’utilisateur a devant lui un écran vide, qu’il s’empresse de
fermer ou affirme que le projet n’est pas fonctionnel. Pour pallier ce problème, nous
allons informer l’utilisateur que le chargement de ces modules est en cours grâce à une
zone de texte, qui affichera le pourcentage de chargement effectué.
Pour commencer, nous allons agrandir de quelques pixels notre canvas applicatif afin d’y
insérer la zone de texte :
<mx:Canvas width="900" height="754" horizontalCenter="0" verticalCenter="0">
<!-- LOGO -->
<mx:Image x="0" y="0" height="95" width="900" source="images/logo.jpg"/>
Plaçons ensuite la zone de texte en bas à gauche de l’application :
<mx :ViewStack>
[…]
</mx:ViewStack>
<!—AFFICHAGE DE LA PROGRESSION DU CHARGEMENT -->
<mx:Label text="{texte}"
fontWeight="bold"
fontSize="14"
x="10"
y="727"
width="325" id="txt_progression"
visible="false">
</mx:Label>
Par défaut, la zone de texte est invisible. Elle sera affichée à chaque nouveau chargement
d’un module via la procédure afficherProgression que voici :
//Procédure d'affichage de progression de chargement
[Bindable]
public var texte:String
public function afficherProgression(e:ProgressEvent):void
{
//Affichage de la zone de progression
txt_progression.visible = true;
//Taille du module
var tailleModule:Number = e.bytesTotal;
=Flex3 FM.book Page 474 Mardi, 2. décembre 2008 3:32 15
474
Cas pratiques
PARTIE II
//Nombre d'octet chargés:
var nbOctets:Number = e.bytesLoaded;
//Calcul du pourcentage de chargement
var pourcentage:Number = Math.round((nbOctets/tailleModule)*100)
//Affichage du texte
texte = "Chargement du module : "+ String(pourcentage)+"%";
if (nbOctets == tailleModule)
{
txt_progression.visible = false;
}
}
Rappel
Si vous souhaitez revoir les détails de cette portion de code, reportez-vous au chapitre 15 traitant des
applications modulaires.
Dans cette procédure, nous attirons votre attention sur la présence de la variable texte.
Elle est chargée de contenir le résultat calculé et de transmettre ce résultat à la zone de
texte par le biais du DataBinding. Il ne nous reste plus qu’à faire appel à cette procédure
lors du chargement de chaque module comme suit :
<!-- CONTENEUR DE VUES -->
<mx:ViewStack id="conteneurVues" x="0" y="132" width="900" height="590">
<mx:Canvas id="vueAccueil" label="Accueil" width="100%" height="100%">
<mx:ModuleLoader id="moduleSite" url="modSite.swf"
progress="afficherProgression(event)"
></mx:ModuleLoader>
</mx:Canvas>
<mx:Canvas id="vueAdministration" label="Administration" width="100%"
➥height="100%">
<mx:ModuleLoader id="moduleAdministration" progress=
➥"afficherProgression(event)" url="modAdministration.swf">
➥</mx:ModuleLoader>
</mx:Canvas>
</mx:ViewStack>
Voilà, c’est à présent terminé. Le résultat obtenu n’est peut être pas visible si vous exécutez
l’application sur votre réseau local, car le chargement est quasi instantané. Néanmoins, la
figure 23-9 illustre ce résultat obtenu sur un serveur distant.
=Flex3 FM.book Page 475 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : commande et facturation
CHAPITRE 23
475
Figure 23-9
Indication du pourcentage de chargement du module
Déploiement de l’application
Maintenant que notre application est davantage optimisée, nous allons pouvoir la déployer.
Création de la version de déploiement
La première étape va consister à créer une version de déploiement du projet.
1. Cliquez avec le bouton droit sur le projet eReflex et sélectionnez le menu Export.
2. Dans la fenêtre qui se présente à l’écran, choisissez l’option release-build.
3. Terminons ce processus en cliquant respectivement sur les boutons Next puis Finish
de la fenêtre.
=Flex3 FM.book Page 476 Mardi, 2. décembre 2008 3:32 15
476
Cas pratiques
PARTIE II
Ceci a pour conséquence la création du répertoire bin-release dans l’arborescence du projet
contenant la version de déploiement de ce dernier. Dans ce répertoire, nous y trouvons les
fichiers et répertoires suivants (tableau 23-1) :
Tableau 23-1
Fichiers contenus dans le répertoire bin-release
Nom du répertoire
Rôle
History
Permet de gérer le deep linking.
Image
Contient l’ensemble des images du projet.
AC_OETags.js
Permet de détecter la présence du Flash Player et d’en proposer l’installation
le cas échéant.
eReflex.html
Chargé de contenir le fichier eReflex.swf.
eReflex.swf
Issu de la compilation du fichier MXML du projet.
modAdministration.swf
Module d’administration.
modSite.swf
Module du site vitrine.
parametrage_amfphp.xml
Contenant les paramètres de connexion à AMF php.
playerProducInstall.swf
Permet de télécharger et d’installer le Flash Player si ce dernier n’est pas
présent sur le poste de l’utilisateur.
popFacture.swf
Pop-up de facturation.
L’ensemble de ces fichiers doit ensuite être copié sur le serveur web chargé d’accueillir
l’application. À cet étape, libre à vous de copier le répertoire bin-release ou de créer un
répertoire sur le serveur web qui contiendra l’ensemble de ces fichiers.
Paramétrage de l’application
La dernière étape consiste à paramétrer l’application en fonction de son nouvel environnement. Il convient tout d’abord de procéder à l’édition du fichier parametrage_amfphp.xml.
Souvenez-vous, dans le chapitre 2, nous avions insisté sur le mécanisme client/serveur
d’une application Flex. En effet, l’application étant chargée sur le poste client, l’ensemble
des références vers les serveurs de base de données ou ceux de la couche métier doivent
être adaptés en conséquence.
Ainsi, si notre serveur contenant la couche métier de notre application a l’adresse 192.168.2.1
sur notre réseau local, celle-ci n’est nullement utilisable via l’Internet. Pour que les services
soient accessibles, il faut utiliser l’adresse web publique du serveur. Voici un exemple de
configuration pour le fichier de paramétrage d’amfphp :
PARAMETRAGE DU FICHIER SUR LE POSTE DE DEVELOPPEMENT
<?xml version="1.0" encoding="ISO-8859-1" ?>
<parametre>
<amfphp>
<serveur>http://localhost/amfphp/gateway.php</serveur>
</amfphp>
=Flex3 FM.book Page 477 Mardi, 2. décembre 2008 3:32 15
Module de vente en ligne : commande et facturation
CHAPITRE 23
477
</parametre>
PARAMETRAGE DU FICHIER SUR LE SERVEUR ACCESSIBLE VIA INTERNET
<parametre>
<amfphp>
<serveur>http://82.127.X.X/amfphpv19/gateway.php</serveur>
</amfphp>
</parametre>
Ainsi lorsque l’application sera chargée sur le poste de l’utilisateur, les requêtes d’exécution
de services seront redirigées vers le serveur 82.127.x.x qui contient la passerelle AMFPHP
et les services associés.
Enfin n’oublions pas un point de détail important : il faut installer la base de données
MySQL ainsi qu’AMFPHP et l’ensemble des services PHP associés sur le ou les serveurs
qui leur seront dédiés !
Conseil
Pour votre premier déploiement, nous vous conseillons de ne pas séparer les couches graphique, métier
et persistance de données sur deux voire trois serveurs différents. Il suffit donc d’installer tout ceci sur un
seul serveur ou mieux encore, de faire en sorte que votre poste de développement fasse office de serveur
accessible via l’Internet ! Ceci vous permettra de résoudre plus facilement les problèmes que vous seriez
susceptible de rencontrer. Le point crucial du déploiement et les problèmes les plus fréquemment rencontrés
sont issus du paramétrage du fichier parametrage_amfphp.xml.
Fin du site E-Reflex ?
Si nous faisons le point sur ce projet, voici ce que nous avons réalisé :
• la mise en place de la partie de gestion des produits ;
• l’implémentation de la partie vente en ligne.
À première vue tout semble terminé, mais détrompez vous ! Si nous savons créer une
commande, il nous est toujours impossible de la stocker dans notre base de données. Ceci
implique donc la création de services PHP, la mise en place d’un modèle au sein de notre
application Flex, sans oublier la gestion automatique des commandes de stocks, la création
d’une interface permettant la création d’un compte client, etc. De plus, que se passe-t-il
si l’un des modules fait défaut lors du chargement ? Actuellement… rien, car nous
n’avons pas implémenté cette fonctionnalité (mais nous l’avons détaillée au chapitre 15).
Donc, il reste encore beaucoup de choses à faire…
Si nous avons choisi de ne pas aborder ces notions, c’est que nous souhaitions nous
concentrer sur l’apport de nouvelles connaissances telles que l’implémentation du glisserdéposer, l’utilisation de pop-up, la manipulation de dates et l’utilisation du composant
<mx :Renderer> dont l’intérêt est sans doute plus grand que la description de longs services
PHP, de classes ActionScript ou d’interfaces graphiques.
=Flex3 FM.book Page 478 Mardi, 2. décembre 2008 3:32 15
=Flex3 FM.book Page 479 Mardi, 2. décembre 2008 3:32 15
24
Créer un lecteur MP3
avec Adobe AIR
Dans ce cas pratique, nous allons créer une application multimédia exécutable à l’aide de
la machine virtuelle d’Adobe AIR : un lecteur MP3. Cette application vous permettra de
concrétiser la notion d’application bureautique riche (RDA, Rich Desktop Application)
qui est une autre facette du framework Flex.
Après avoir abordé l’utilisation du composant FileSystemTree et la description des méthodes
de lecture d’un fichier audio, nous nous attarderons sur les fonctionnalités de notre application pour ensuite terminer par sa réalisation et son déploiement. Dans ce cas pratique
nous aborderons notamment les notions suivantes :
• l’utilisation du composant FileSystemTree ;
• l’étude des méthodes de lecture d’un fichier audio à l’aide d’ActionScript ;
• l’utilisation du composant PopMenuButton.
Rechercher des MP3 à l’aide de <mx :FileSystemTree>
L’avantage d’une application Adobe AIR est qu’elle s’exécute sur le poste de l’utilisateur
tout en étant réalisée à l’aide de langage web. Le principal privilège de ce type d’exécution
réside dans l’utilisation de composants spécifiques interagissant avec le poste de travail.
Le composant FileSystemTree fait partie de ceux-ci en permettant le parcours du disque
dur, ce qui va nous être très utile pour rechercher les MP3 situés sur le disque dur de
l’utilisateur.
=Flex3 FM.book Page 480 Mardi, 2. décembre 2008 3:32 15
480
Cas pratiques
PARTIE II
Comme nous l’avons fait dans le chapitre 5 pour les composants utilisés dans une application web, nous allons décrire l’usage du composant FileSystemTree du point de vue du
développeur, en étudiant son implémentation et son interaction avec l’utilisateur.
Implémentation
Pour commencer, nous allons créer un nouveau projet (File > new Flex projet>Desktop
application) que nous appellerons Lecteur_mp3.
Le composant FileSystemTree n’est disponible que pour les applications Adobe AIR. Son
rôle est de représenter l’ensemble des dossiers et fichiers du disque dur de l’utilisateur
sous forme d’arborescence. Son implémentation est semblable au composant Tree, à la
seule exception que l’alimentation en données s’effectue automatiquement à partir des
informations contenues sur le disque dur de l’utilisateur (figure 24-1).
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:FileSystemTree
x="10"
y="25"
width="300"
height="363"
id="fs_disqueDur"
showHidden="true"
showExtensions="true"
directory="{new File('h:\\Flex_3')}"/>
</mx:WindowedApplication>
Figure 24-1
Composant FileSystemTree
=Flex3 FM.book Page 481 Mardi, 2. décembre 2008 3:32 15
Créer un lecteur MP3 avec Adobe AIR
CHAPITRE 24
481
Par défaut, notre composant liste l’ensemble des lecteurs des partitions du disque ou des
lecteurs externes présents sur le poste de travail. Il nous est cependant possible de lui
spécifier un répertoire par défaut via sa propriété directory. Vous pouvez également activer
d’autres options comme la visualisation des fichiers cachés (showHidden) ou l’affichage
des extensions de chaque fichiers (showExtension).
Interaction avec l’utilisateur
Grâce à ce composant, l’utilisateur peut sélectionner des fichiers ou des dossiers de son
disque dur, afin de les utiliser dans diverses tâches comme l’envoi par e-mail, l’ouverture
du fichier à des fins d’édition, etc. Le code ci-dessous dévoile une petite partie du cas
pratique en décrivant la méthode utilisée pour détecter si le fichier sélectionné porte
l’extension mp3 ou non :
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.controls.Alert
public function typeFichier(e:Event):void
{
var fichier:File = e.currentTarget.selectedItem as File;
if(!fichier.isDirectory)
{
if (fichier.extension.toLowerCase()=="mp3")
{
Alert.show("C'est un mp3 !");
}
}
}
]]>
</mx:Script>
<mx:FileSystemTree
x="10"
y="25"
width="300"
height="363"
id="fs_disqueDur"
showHidden="true"
showExtensions="true"
itemClick="typeFichier(event)"
/>
</mx:WindowedApplication>
=Flex3 FM.book Page 482 Mardi, 2. décembre 2008 3:32 15
482
Cas pratiques
PARTIE II
Nous déclarons tout d’abord une variable de type fichier capable de stocker les informations
sur le fichier sélectionné. À partir de cet instant il nous est possible de déterminer s’il
s’agit d’un dossier (fichier.isDirectory) ou, dans le cas contraire, d’en extraire l’extension
(fichier.extension.toLowerCase), afin de déterminer s’il s’agit d’un fichier de type MP3
ou non.
Maintenant que nous savons rechercher les fichiers MP3 sur le disque dur de l’utilisateur,
nous allons découvrir comment les lire.
Lire un fichier MP3 avec ActionScript
Pour lire un fichier MP3 à l’aide d’ActionScript, nous devons faire appel aux classes
suivantes
• flash.media.Sound qui permet le chargement ; la lecture et l’obtention d’information
sur le fichier MP3 ;
• flash.media.SoundChannel qui offre la possibilité de connaître la progression de la
lecture, de stopper celle-ci, de connaître le volume des canaux droit et gauche de la
musique et de lui appliquer des transformations.
Voici comment les utiliser à travers les étapes du processus de lecture :
1. Instanciation de la classe flash.media.Sound pour la création d’un nouvel objet :
var mp3:Sound = new Sound();
2. Chargement du fichier MP3 et exécution d’un traitement lorsque celui-ci est terminé :
// Veiller à utiliser les \\ !!
var p_chemin:String = "c:\\fichier.mp3"
var requete:URLRequest = new URLRequest(p_chemin);
mp3.load(requete)
mp3.addEventListener( Event.COMPLETE, finChargement );
3. Extraction des informations et lecture du fichier :
public function finChargement(event:Event):void
{
//Création d’un objet Sound à partir du fichier chargé
var mp3:Sound = Sound(event.target);
//Extraction des Id3
var p_artiste:String
var p_album:String =
var p_annee:String =
var p_titre:String =
Tags
= mp3.id3.artist;
mp3.id3.album;
mp3.id3.year;
mp3.id3.songName;
//Extraction de la durée en millisecondes
var p_duree:Number = mp3.length;
//Création d’un nouvel objet SoundChannel
=Flex3 FM.book Page 483 Mardi, 2. décembre 2008 3:32 15
Créer un lecteur MP3 avec Adobe AIR
CHAPITRE 24
483
var chanson:SoundChannel = new SoundChannel();
//Lecture du fichier MP3 au début (position 0)
//en l'affectant à l'objet Chanson ce qui va nous
//permettre de déclencher un événement lors de la fin
//de la lecture, ou durant celle-ci
chanson = mp3.play(0)
4. Déclenchement d’événements lors de certaines étapes de la lecture (ici à la fin) :
//Déclenchement d'un événement lors de la fin de la lecture
chanson.addEventListener(Event.SOUND_COMPLETE, finChanson)
public function finChanson(e:Event):void
{
Alert.show("Fin de la lecture");
}
Voici le code complet vous permettant de lire un fichier MP3 situé sur votre disque dur et
affichant le message « Fin de lecture » lorsque la lecture de celui-ci est terminée :
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.controls.Alert
import flash.media.Sound;
import flash.media.SoundChannel;
public function lireMp3():void
{
var mp3:Sound = new Sound();
var p_chemin:String = "L:\\Fichier.mp3"
var requete:URLRequest = new URLRequest(p_chemin);
mp3.load(requete)
mp3.addEventListener( Event.COMPLETE, finChargement );
}
public function finChargement(e:Event):void
{
var
var
var
var
var
var
var
mp3:Sound = Sound(e.target)
p_artiste:String = mp3.id3.artist;
p_album:String = mp3.id3.album;
p_annee:String = mp3.id3.year;
p_titre:String = mp3.id3.songName;
p_duree:Number = mp3.length;
chanson:SoundChannel = new SoundChannel();
=Flex3 FM.book Page 484 Mardi, 2. décembre 2008 3:32 15
484
Cas pratiques
PARTIE II
chanson = mp3.play(0)
chanson.addEventListener(Event.SOUND_COMPLETE,
➥finChanson)
}
public function finChanson(e:Event):void
{
Alert.show("Fin de la lecture");
}
]]>
</mx:Script>
<mx:Button x="28" y="19" label="Button" id="btn_lire" click="lireMp3()"/>
</mx:WindowedApplication>
Nous avons extrait les données contenues dans les tags ID3 pouvant alors être exploitées
pour afficher, en cours de lecture, le titre du morceau, le nom de l’artiste, le numéro de
piste dans l’album, etc.
La durée est exprimée en millisecondes. Pour l’afficher au format standard (minutes:
secondes), il convient de créer une variable de type Date à partir de cette donnée et d’en
extraire les secondes et les minutes :
var p_duree:Number = mp3.length;
//Transformation de la durée
var minutes:String;
var secondes:String;
var temps:Date = new Date(0,0,0,0,0,0,p_duree);
minutes = String(temps.getMinutes());
//Si les secondes sont inférieures à 10 on ajoute un 0 avant la valeur, par
➥exemple : 6 = 06
if (temps.getSeconds() < 10 ){secondes = "0"+String
➥(temps.getSeconds())}else{secondes=String(temps.getSeconds())};
Alert.show (minutes+":"+secondes)
Nous allons à présent voir les différentes méthodes qui vont nous permettre de manipuler
la lecture du fichier MP3.
Les tags ID3
Les balises (tags) ID3 sont insérées dans le fichier MP3 et permettent de stocker des informations sur celuici (artiste, titre, album…). Attention cependant, ces informations ne sont pas systématiquement précisées.
=Flex3 FM.book Page 485 Mardi, 2. décembre 2008 3:32 15
Créer un lecteur MP3 avec Adobe AIR
CHAPITRE 24
485
Principales fonctions de lecture d’un fichier audio
Lorsque nous lisons un fichier MP3, il est parfois nécessaire de le mettre en pause pour
ensuite en reprendre la lecture ou de le stopper ou encore de connaître la progression de
la lecture. Ce sont ces actions que nous allons aborder dans cette partie.
Stopper et mettre en pause
Il n’existe pas de fonction pause à proprement parler, mais la classe SoundChannel dispose
d’une propriété forte intéressante : la propriété position.
Cette propriété indique la position du curseur de lecture, c’est-à-dire le temps écoulé
depuis le début de la lecture du MP3, exprimé en millisecondes. En stockant cette
propriété dans une variable, il nous est possible de stopper la lecture et de la reprendre à
la position préalablement stockée :
//Enregistrement de la position
var position:Number = chanson.position;
//Arrêt de la lecture
chanson.stop();
//Reprise de la lecture
chanson = mp3.play(position)
Connaître la progression de la lecture
Pour connaître la progression de la lecture d’un fichier MP3, nous allons utiliser la classe
flash.utils.timer qui permet de créer un minuteur déclenchant la répétition d’un événement suivant un certain délai exprimé en milliseconde.
Ainsi, pour récupérer le temps de lecture écoulé, il nous suffit de récupérer la position de
lecture toutes les x millisecondes et d’en afficher le résultat :
//Création du minuteur (Déclenchement de l’événement toutes les 50 millisecondes
var positionTimer:Timer = new Timer(50);
//Indication de l’événement à déclencher
positionTimer.addEventListener(TimerEvent.TIMER, progressionLecture);
//Démarrage du minuteur
positionTimer.start();
//PROGRESSION DE LA LECTURE
private function progressionLecture(e:Event):void{
var p_duree:Number = chanson.position;
var minutes:String;
var secondes:String;
var temps:Date = new Date(0,0,0,0,0,0,p_duree);
minutes = String(temps.getMinutes());
=Flex3 FM.book Page 486 Mardi, 2. décembre 2008 3:32 15
486
Cas pratiques
PARTIE II
if (temps.getSeconds() < 10 ){secondes = "0"+String
➥(temps.getSeconds())}else{secondes=String(temps.getSeconds())};
var progression :String = minutes+":"+secondes
}
Exemple complet
Voici à présent le code permettant de lire, d’afficher le temps de lecture, de mettre en
pause, de reprendre la lecture et de stopper un fichier MP3 (figure 24-2) :
Figure 24-2
Fonctions de bases
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥creationComplete="chargerMp3()">
<mx:Script>
<![CDATA[
import mx.controls.Alert
import flash.media.Sound;
import flash.media.SoundChannel;
public var
public var
public var
[Bindable]
public var
mp3:Sound = new Sound();
chanson:SoundChannel = new SoundChannel();
position:Number = 0;
progression:String;
public function chargerMp3():void
{
var p_chemin:String = "C:\\Fichier.mp3"
var requete:URLRequest = new URLRequest(p_chemin);
mp3.load(requete)
mp3.addEventListener( Event.COMPLETE, finChargement );
}
public function lire():void
{
chanson = mp3.play(position);
var positionTimer:Timer = new Timer(50);
positionTimer.addEventListener(TimerEvent.TIMER, progressionLecture);
positionTimer.start();
=Flex3 FM.book Page 487 Mardi, 2. décembre 2008 3:32 15
Créer un lecteur MP3 avec Adobe AIR
CHAPITRE 24
}
private function progressionLecture(e:Event):void{
var p_duree:Number = chanson.position;
var minutes:String;
var secondes:String;
var temps:Date = new Date(0,0,0,0,0,0,p_duree);
minutes = String(temps.getMinutes());
if (temps.getSeconds() < 10 ){secondes = "0"+String(temps
➥.getSeconds())}else{secondes=String(temps.getSeconds())};
progression = minutes+":"+secondes
}
public function stopper():void
{
chanson.stop();
position = 0;
}
public function mettreEnPause():void
{
position = chanson.position;
chanson.stop();
}
public function finChargement(e:Event):void
{
Alert.show ("Chargement MP3 Terminé")
}
]]>
</mx:Script>
<mx:Button x="10" y="19" label="Lire" id="btn_lire" click="lire()" width="65"/>
<mx:Button x="83" y="19" label="Pause" width="65" id="btn_pause"
➥click="mettreEnPause()"/>
<mx:Button x="156" y="19" label="Stop" width="65" id="btn_stop"
➥click="stopper()"/>
<mx:TextInput x="10" y="49" width="211" id="txt_progression"
➥text="{progression}"/>
</mx:WindowedApplication>
487
=Flex3 FM.book Page 488 Mardi, 2. décembre 2008 3:32 15
488
Cas pratiques
PARTIE II
Définition des fonctionnalités de notre application
Maintenant que nous connaissons les différentes méthodes qui interviennent dans la lecture
d’un fichier MP3, nous pouvons nous consacrer pleinement à notre étude de cas.
L’objectif du projet est de créer un lecteur MP3 sous forme d’une application Adobe AIR où
l’utilisateur aurait la possibilité de parcourir les dossiers de son disque dur et d’y sélectionner les fichiers MP3 qu’il souhaite écouter. La figure 24-3 illustre les différentes parties
de l’interface graphique de notre lecteur MP3 dont nous allons décrire les fonctionnalités.
Figure 24-3
Interface graphique du lecteur MP3
=Flex3 FM.book Page 489 Mardi, 2. décembre 2008 3:32 15
Créer un lecteur MP3 avec Adobe AIR
CHAPITRE 24
489
Gestion de la liste de lecture
La liste de lecture (playlist) affiche l’ensemble des fichiers MP3 que l’utilisateur a sélectionnés et qu’il souhaite lire (figure 24-4).
Figure 24-4
Liste de lecture
Son mode de fonctionnement est le suivant :
• l’utilisateur sélectionne un fichier MP3 dans le composant FileSystemTree ;
• ce fichier est analysé puis ajouté à la liste de lecture.
Les informations affichées dans la liste de lecture sont le titre du fichier MP3 (issu des
tags ID3) et sa durée.
Pour chaque ajout de fichier MP3, le temps total de lecture de la liste est calculé. Notons
également la présence des boutons Supprimer et Vider permettant de supprimer un fichier
de la liste de lecture ou de la vider intégralement.
Il est également intéressant d’offrir à l’utilisateur la possibilité d’écouter sa liste de
lecture en boucle. Pour assurer cette fonctionnalité, le composant PopUpMenuButton sera
utilisé en proposant les valeurs « En boucle » ou « Lecture simple ».
=Flex3 FM.book Page 490 Mardi, 2. décembre 2008 3:32 15
490
Cas pratiques
PARTIE II
Règles de gestion
Voici à présent les règles de gestion de la liste de lecture :
• pour chaque ajout ou suppression de fichier MP3, le temps de lecture total doit être
recalculé ;
• le mode de lecture proposé par défaut est « En boucle » ;
• lorsque la lecture d’un fichier MP3 est terminée, celle du morceau suivant démarre
automatiquement.
Le composant PopUpMenuButton
Ce composant permet de créer des menus dont le fonctionnement et la présentation sont
identiques au composant ComboBox (figure 24-5).
Figure 24-5
Composant PopUpMenuButton
Implémentation et alimentation en données
Son implémentation est assez simple et se résume à créer un tableau de libellés (Label)
venant alimenter le dataProvider du composant :
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
[Bindable]
public var menus:Array = [{label:"Menu_1"},{label:"Menu_2"}];
]]>
</mx:Script>
<mx:PopUpMenuButton x="32" y="44" id="popMenu" dataProvider="{menus}"/>
</mx:WindowedApplication>
Interaction avec l’utilisateur
Pour connaître, l’option de menu sélectionnée par l’utilisateur, nous devons déclencher
un événement lors de la sélection d’un item (itemClick) afin d’un récupérer le libellé :
=Flex3 FM.book Page 491 Mardi, 2. décembre 2008 3:32 15
Créer un lecteur MP3 avec Adobe AIR
CHAPITRE 24
491
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
[Bindable]
public var menus:Array = [{label:"Menu_1"},{label:"Menu_2"}];
//Import de la classe permettant de gérer les événements sur les menus
import mx.events.MenuEvent;
import mx.controls.Alert;
public function choixMenu(e:MenuEvent):void
{
Alert.show(e.currentTarget.label)
}
]]>
</mx:Script>
<mx:PopUpMenuButton x="32" y="44" id="popMenu" dataProvider="{menus}"
➥itemClick="choixMenu(event)"/>
</mx:WindowedApplication>
Comme vous pouvez le constater, ce composant est assez simple à implémenter et peut
également nous permettre de créer des menus avancés comme le démontre l’exemple cidessous (figure 24-6) :
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<!-- CRÉATION DE MENU AVEC SOUS MENUS -->
<mx:XMLList id="menuAvance">
<node label="Menu_1">
<node label="SousMenu_1">
<node label="SousMenu_2"/>
<node label="SousMenu_3"/>
</node>
</node>
</mx:XMLList>
<mx:PopUpMenuButton x="32" y="44" labelField="@label" id="popMenu"
➥dataProvider="{menuAvance}"/>
</mx:WindowedApplication>
=Flex3 FM.book Page 492 Mardi, 2. décembre 2008 3:32 15
492
Cas pratiques
PARTIE II
Figure 24-6
Menu avancé
Interface de lecture
Commune à tout lecteur MP3, cette interface permet de :
• lire un fichier MP3 ;
• mettre en pause et reprendre la lecture ;
• passer au fichier MP3 suivant ;
• revenir au début du fichier MP3 en cours de lecture ;
• revenir au fichier MP3 précédent.
Cette interface nous permet également d’obtenir des informations sur la progression de la
lecture et de connaître le titre du fichier MP3 accompagné de son temps total de lecture
(figure 24-7).
Figure 24-7
Interface de lecture
=Flex3 FM.book Page 493 Mardi, 2. décembre 2008 3:32 15
Créer un lecteur MP3 avec Adobe AIR
CHAPITRE 24
493
Il est temps à présent de passer au codage du projet.
À vos claviers : création d’un lecteur MP3
L’ensemble des fonctionnalités du projet étant à présent décrites, vous disposez des
éléments nécessaires à la création de l’application.
Ce cas pratique étant le dernier de l’ouvrage, il nous a semblé important de vous laisser
une autonomie complète dans sa réalisation en vous laissant maître de vos choix de
conception et de réalisation. En effet, cela vous permettra de vérifier l’acquisition des
connaissances présentées tout au long de cet ouvrage et de déterminer ainsi votre capacité
à développer des applications à l’aide du Framework Flex.
Nous ne doutons pas de votre succès dans la réalisation de ce cas pratique. Néanmoins,
nous vous proposons la solution suivante.
Nous avons organisé notre application en quatre fichiers distincts :
• ClassesLecteurMp3.as : la classe de notre lecteur MP3 et ses méthodes associées (lecture,
affichage de la progression de lecture…) ;
• LecteurMP3AS3.as : diverses procédures faisant appel aux méthodes de la classe Classes
LecteurMP3, mais aussi à la gestion des composants de l’IHM ;
• LecteurMP3.mxml : fichier principal de l’application ;
• Bleu_lagon.css : feuille de styles CSS donnant un aspect plus sympathique à notre
application. Ce fichier est optionnel.
Voici donc le code de chacun de ces fichiers.
Fichier de styles CSS
Nous avons choisi de créer un style de type « Bleu lagon », mais libre à vous de l’adapter
en fonction de vos envies :
/* CSS file */
Button {
cornerRadius: 11;
highlightAlphas: 0.22, 0.43;
fillAlphas: 0.27, 0.39, 0.27, 1;
color: #003366;
textSelectedColor: #0b333c;
borderColor: #000033;
themeColor: #000033;
fontFamily: Arial;
}
Application {
backgroundColor: #003366;
=Flex3 FM.book Page 494 Mardi, 2. décembre 2008 3:32 15
494
Cas pratiques
PARTIE II
backgroundGradientColors: #006699, #68808c;
themeColor: #006699;
color: #ffffff;
}
Tree {
backgroundAlpha: 0.41;
color: #000000;
openDuration: 551;
dropShadowEnabled: true;
shadowDistance: 4;
shadowDirection: right;
fontFamily: Arial;
cornerRadius: 9;
}
DataGrid {
backgroundColor: #006699;
alternatingItemColors: #006699, #006699;
headerColors: #006699, #e6eeee;
verticalGridLines: false;
useRollOver: true;
color: #ffffff;
headerStyleName: "mydataGridHeaderStyle";
}
.mydataGridHeaderStyle {
color: #000099;
}
Canvas{
borderStyle: solid;
borderThickness: 1;
cornerRadius: 9;
borderColor: #084570;
}
.tempsMP3{
fontFamily: Arial;
fontSize: 16;
color: #ffffcc;
textAlign: right;
}
.arrierePlanDeLecture{
backgroundAlpha: 0.92;
backgroundColor: #000000;
cornerRadius: 14;
=Flex3 FM.book Page 495 Mardi, 2. décembre 2008 3:32 15
Créer un lecteur MP3 avec Adobe AIR
CHAPITRE 24
495
dropShadowEnabled: true;
shadowDirection: right;
shadowDistance: 4;
}
.titre{
color: #0099cc;
fontSize: 16;
}
.tempsTotalPlayList{
fontSize: 12;
fontWeight:bold;
textAlign: right;
}
Code de la classe ClassesLecteurMp3
Remarquez l’usage du DataBinding pour certains attributs de la classe, permettant d’intercepter la modification de leur valeur et d’afficher celle-ci dans l’interface graphique (afin
d’obtenir la progression de lecture par exemple).
//Création préalable du package com.lecteurMP3
package com.lecteurMp3
{
import mx.collections.ArrayCollection;
public class ClasseLecteurMP3
{
import
import
import
import
import
import
flash.media.Sound;
flash.media.SoundChannel;
flash.net.URLRequest;
mx.controls.Alert;
flash.events.*
flash.utils.Timer;
/********************************
*
ATTRIBUTS PRIVÉS
*
********************************/
private var _listeFichiersMP3:ArrayCollection; //Liste des MP3 de la playlist
private var _mp3:Sound; //Fichier MP3
private var _chanson:SoundChannel; //Chanson en cours de lecture
private var _lectureEnBoucle:Boolean = true; // Lecture en boucle de la
➥playlist
private var _lectureEnCours:Boolean = false; //Indique si une lecture est en
➥cours ou non
=Flex3 FM.book Page 496 Mardi, 2. décembre 2008 3:32 15
496
Cas pratiques
PARTIE II
private var _positionDePause:int = 0; //Position de pause de la chanson
//Information ID3 Tag
private var _artiste:String;
private var _album:String;
private var _annee:String;
private var _duree:Number;
/*********************************************
*
ATTRIBUTS PUBLIC LIÉS A l'IHM
*
*********************************************/
[Bindable]
public var indexDeLecture:int = 0; //Index de selection du fichier Mp3 dans
➥la playlist
[Bindable]
public var titre:String; // Titre de la chanson
[Bindable]
public var progression:String //Progression de la lecture
/**************************
*
CONSTRUCTEUR
*
**************************/
public function ClasseLecteurMP3()
{
}
/*******************************
*
GETTERS / SETTERS
*
*******************************/
//---- CRÉATION DE LA LISTE DE MP3 --public function set listeFichiersMP3 (liste:ArrayCollection):void
{
_listeFichiersMP3 = liste
}
//--- INFORMATIONS ID3 TAGS --public function get artiste():String
{
return _artiste;
}
public function get album():String
=Flex3 FM.book Page 497 Mardi, 2. décembre 2008 3:32 15
Créer un lecteur MP3 avec Adobe AIR
CHAPITRE 24
{
return _album;
}
public function get annee():String
{
return _annee;
}
public function get duree():Number
{
return _duree;
}
//--- POSITION DE PAUSE
public function set positionDePause (index:int):void
{
_positionDePause = index;
}
/*******************************
*
MÉTHODES
*
*******************************/
public function modeLecture(mode:String):void
{
if (mode == "En boucle")
{
_lectureEnBoucle = true;
}
else
{
_lectureEnBoucle = false;
}
}
//---- DÉBUT LECTURE ---public function lire():void
{
if (_lectureEnCours == 1 && _positionDePause == 0)
{
_chanson.stop();
}
var request:URLRequest = new URLRequest
➥(_listeFichiersMP3[indexDeLecture].chemin);
_mp3 = new Sound();
497
=Flex3 FM.book Page 498 Mardi, 2. décembre 2008 3:32 15
498
Cas pratiques
PARTIE II
_mp3.load(request);
titre = _listeFichiersMP3[indexDeLecture].titre + "
➥["+_listeFichiersMP3[indexDeLecture].dureeAffichee+"]";
_artiste = _listeFichiersMP3[indexDeLecture].artiste;
_album = _listeFichiersMP3[indexDeLecture].album;
_annee = _listeFichiersMP3[indexDeLecture].annee;
_duree = _listeFichiersMP3[indexDeLecture].duree;
_chanson = _mp3.play(_positionDePause)
_chanson.addEventListener(Event.SOUND_COMPLETE,
➥passageAutomatiqueSuivant);
var positionTimer:Timer = new Timer(50);
positionTimer.addEventListener(TimerEvent.TIMER, progressionLecture);
positionTimer.start();
_lectureEnCours = true;
}
//--- AFFICHAGE DE LA PROGRESSION DE LA LECTURE --private function progressionLecture(e:Event):void{
var p_duree:Number = _chanson.position;
var minutes:String;
var secondes:String;
var temps:Date = new Date(0,0,0,0,0,0,p_duree);
minutes = String(temps.getMinutes());
if (temps.getSeconds() < 10 ){secondes = "0"+String
➥(temps.getSeconds())}else{secondes=String(temps.getSeconds())};
progression = minutes+":"+secondes
}
//---- PASSAGE AUTOMATIQUE AU SUIVANT ---public function passageAutomatiqueSuivant(e:Event):void
{
var indice:int = indexDeLecture;
indice++;
_positionDePause = 0
if (indice > (_listeFichiersMP3.length -1))
{
if (_lectureEnBoucle == true) {
indexDeLecture = 0;
lire();
}
=Flex3 FM.book Page 499 Mardi, 2. décembre 2008 3:32 15
Créer un lecteur MP3 avec Adobe AIR
CHAPITRE 24
else
{
stopper();
}
}
else
{
indexDeLecture++;
lire();
}
}
//---- PASSAGE MANUEL AU SUIVANT ---public function passageManuelSuivant():void
{
var indice:int = indexDeLecture;
indice++;
_positionDePause = 0
if (indice > (_listeFichiersMP3.length -1))
{
if (_lectureEnBoucle == true) {
indexDeLecture = 0;
lire();
}
}
else
{
indexDeLecture++;
lire();
}
}
//---- PASSAGE MANUEL AU PRÉCÉDENT ---public function passageManuelPrecedent():void
{
var indice:int = indexDeLecture;
indice--;
_positionDePause = 0
if (indice < 0)
499
=Flex3 FM.book Page 500 Mardi, 2. décembre 2008 3:32 15
500
Cas pratiques
PARTIE II
{
indexDeLecture = 0;
}
lire()
}
//---- STOPPER ---public function stopper():void
{
_chanson.stop();
_lectureEnCours = false;
progression = "00:00";
}
//---- METTRE EN PAUSE ---public function mettreEnPause():void
{
_positionDePause = _chanson.position;
stopper();
}
//---- REVENIR AU DÉBUT ---public function revenirDebut():void
{
stopper();
lire();
}
}
}
Fichier LecteurMP3AS3.as
Dans ce fichier, nous avons créé des procédures liées aux différents composants de
l’interface graphique : démarrage de la lecture, alimentation de la liste de lecture, etc.
/*****************************************
* INSTANCIATION DE LA CLASSE LECTEUR MP3
******************************************/
import com.lecteurMp3.ClasseLecteurMP3;
[Bindable]
=Flex3 FM.book Page 501 Mardi, 2. décembre 2008 3:32 15
Créer un lecteur MP3 avec Adobe AIR
CHAPITRE 24
public var lecteur:ClasseLecteurMP3 = new ClasseLecteurMP3;
/*****************************************
* SELECTION D'UN MP3
******************************************/
//SELECTION DES MP3
public function choixFichier(e:Event):void
{
var fichier:File = e.currentTarget.selectedItem as File;
if(!fichier.isDirectory)
{
if (fichier.extension.toLowerCase()=="mp3")
{
analyserFichierMP3(fichier)
}
}
}
/*****************************************
* ANALYSE DU FICHIER MP3
******************************************/
import com.lecteurMp3.ClasseLecteurMP3;
import flash.media.Sound;
import flash.net.URLRequest;
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.events.ListEvent;
import mx.events.MenuEvent;
[Bindable]
public var tableauFichiersMP3:ArrayCollection = new ArrayCollection();
public var p_nomFichier:String
public function analyserFichierMP3(fichierMP3:File):void
{
//Analyse du fichier
var p_chemin:String = fichierMP3.url;
501
=Flex3 FM.book Page 502 Mardi, 2. décembre 2008 3:32 15
502
Cas pratiques
PARTIE II
p_nomFichier = fichierMP3.name
//Chargement du MP3 et extraction des ID3 tags
var request:URLRequest = new URLRequest(p_chemin);
var mp3:Sound = new Sound();
mp3.load(request)
mp3.addEventListener( Event.COMPLETE, finChargement );
}
public function finChargement(event:Event):void
{
var
var
var
var
var
var
var
mp3:Sound = Sound(event.target);
p_chemin:String = String(event.target.url);
p_artiste:String = mp3.id3.artist;
p_album:String = mp3.id3.album;
p_annee:String = mp3.id3.year;
p_titre:String = mp3.id3.songName;
p_duree:Number = mp3.length;
//Transformation de la durée
var minutes:String;
var secondes:String;
var temps:Date = new Date(0,0,0,0,0,0,p_duree);
minutes = String(temps.getMinutes());
if (temps.getSeconds() < 10 ){secondes = "0"+String
➥(temps.getSeconds())}else{secondes=String(temps.getSeconds())};
var p_dureeAffichee:String = minutes+":"+secondes
//Vérification de la présence du titre du morceau
if (p_artiste == null) {p_artiste = p_nomFichier};
mp3.close();
//Stockage dans le tableau des MP3
tableauFichiersMP3.addItem({chemin:p_chemin,
nom:p_nomFichier,
artiste:p_artiste,
album:p_album,
annee:p_annee,
titre:p_titre,
duree:p_duree,
dureeAffichee:p_dureeAffichee})
//Mise à jour de l'attribut listeFichierMP3 de la classe ClasseLecteurMP3
lecteur.listeFichiersMP3 = tableauFichiersMP3;
//Calcul du temps total de lecture de la playlist
=Flex3 FM.book Page 503 Mardi, 2. décembre 2008 3:32 15
Créer un lecteur MP3 avec Adobe AIR
CHAPITRE 24
calculerTempsTotal();
}
/*****************************************
* LECTURE D'UN FICHIER
******************************************/
public function boutonPlay():void
{
var index:int = dg_titres.selectedIndex;
lecteur.indexDeLecture = index;
lecteur.lire();
txt_progression.visible = true;
}
public function doubleClickPlayList(e:ListEvent):void
{
var index:int = e.currentTarget.selectedIndex;
lecteur.indexDeLecture = index;
lecteur.lire()
txt_titreEcoute.text = lecteur.titre;
txt_progression.visible = true;
}
public function boutonStop():void
{
lecteur.stopper()
txt_progression.visible = false;
}
public function boutonPause():void
{
lecteur.mettreEnPause();
}
public function boutonSuivant():void
{
lecteur.passageManuelSuivant()
}
public function boutonPrecedent():void
{
lecteur.passageManuelPrecedent()
}
503
=Flex3 FM.book Page 504 Mardi, 2. décembre 2008 3:32 15
504
Cas pratiques
PARTIE II
public function boutonDebut():void
{
lecteur.revenirDebut();
}
/*****************************************
* GESTION DE LA PLAYLIST
******************************************/
public function supprimerMp3():void
{
var index:int = dg_titres.selectedIndex;
tableauFichiersMP3.removeItemAt(index);
lecteur.listeFichiersMP3 = tableauFichiersMP3;
calculerTempsTotal();
}
public function viderPlayList():void
{
lecteur.stopper();
tableauFichiersMP3.removeAll();
lecteur.listeFichiersMP3 = tableauFichiersMP3;
txt_titreEcoute.text = "";
txt_progression.visible = false;
tempsTotal = "Temps : 00:00";
}
[Bindable]
public var tempsTotal:String = "Temps : 00:00";
public function calculerTempsTotal():void{
var p_duree:Number =0;
for (var i:int=0; i<tableauFichiersMP3.length; i++)
{
p_duree += tableauFichiersMP3[i].duree;
}
var minutes:String;
var secondes:String;
var temps:Date = new Date(0,0,0,0,0,0,p_duree);
=Flex3 FM.book Page 505 Mardi, 2. décembre 2008 3:32 15
Créer un lecteur MP3 avec Adobe AIR
CHAPITRE 24
505
minutes = String(temps.getMinutes());
if (temps.getSeconds() < 10 ){secondes = "0"+String
➥(temps.getSeconds())}else{secondes=String(temps.getSeconds())};
tempsTotal= "Temps : "+minutes+":"+secondes
}
/*****************************************
* CHOIX DU MODE DE LECTURE
******************************************/
[Bindable]
public var modeLecture:Array = [{label:"En boucle"},{label:"Lecture simple"}];
public function choixModeLecture(e:MenuEvent):void
{
lecteur.modeLecture(e.currentTarget.label)
}
Fichier principal
Voici enfin, le code du fichier principal de l’application où nous avons utilisé les propriétés maxHeight, maxWidth, minHeight et maxHeight afin d’empêcher le redimensionnement de
la fenêtre par l’utilisateur.
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
➥height="544" width="799" horizontalScrollPolicy="off" verticalScrollPolicy="off"
➥maxHeight="544" maxWidth="799" minHeight="544" minWidth="799">
<mx:Style source="bleu_lagon.css"> </mx:Style>
<mx:Script source = "LecteurMP3AS3.as"> </mx:Script>
<!-- FILESYSTEMTREE -->
<mx:Canvas x="10" y="133" width="450" height="386" horizontalScrollPolicy="off"
➥verticalScrollPolicy="off">
<mx:Label x="10" y="10" text="Vos MP3 :" fontWeight="bold" width="218"
➥textAlign="left"/>
<mx:FileSystemTree x="10" y="36" height="326" width="430" id="arbre_mp3"
➥itemClick="choixFichier(event)"/>
</mx:Canvas>
<!-- INTERFACE DE LECTURE -->
<mx:Canvas x="10" y="10" width="450" height="115">
<mx:HBox x="6" y="71" width="100%">
=Flex3 FM.book Page 506 Mardi, 2. décembre 2008 3:32 15
506
Cas pratiques
PARTIE II
<mx:Button
<mx:Button
<mx:Button
<mx:Button
<mx:Button
<mx:Button
</mx:HBox>
label="&lt;&lt;" width="65" click="boutonPrecedent()"/>
label="&lt;" width="65" click="boutonDebut()"/>
label="&gt;" width="65" id="btn_lire" click="boutonPlay()"/>
label="&gt;&gt;" width="65" click="boutonSuivant()"/>
label="||" width="65" click="boutonPause()" id="btn_pause"/>
label="Stop" width="65" click="boutonStop()"/>
<mx:Canvas x="5" y="7" width="433" height="56"
➥styleName="arrierePlanDeLecture">
<mx:Label x="10" y="16" text="{lecteur.titre}" width="319" height="24"
➥fontWeight="bold" fontSize="12" id="txt_titreEcoute" styleName="titre"/>
<!-- Databinding avec l’attribut progression de la classe -->
<mx:Text x="348" y="14" text="{lecteur.progression}" width="72" height="27"
➥id="txt_progression" styleName="tempsMP3" visible="false"/>
</mx:Canvas>
</mx:Canvas>
<!-- LISTE DE LECTURE -->
<mx:DataGrid doubleClickEnabled="true" x="468" y="10" width="319" height="458"
➥id="dg_titres" dataProvider="{tableauFichiersMP3}" selectedIndex=
➥"{lecteur.indexDeLecture}" itemDoubleClick="doubleClickPlayList(event)">
<mx:columns>
<mx:DataGridColumn headerText="Play List" dataField="titre"/>
<mx:DataGridColumn headerText="Temps" dataField="dureeAffichee"
➥width="50"/>
</mx:columns>
</mx:DataGrid>
<mx:Button x="575" y="497" label="Supprimer" id="btn_supprimer"
➥click="supprimerMp3()" width="102"/>
<mx:Button x="685" y="497" label="Vider la playlist" click="viderPlayList()"
➥id="btn_viderplaylist"/>
<mx:PopUpMenuButton x="468" y="497" dataProvider="{modeLecture}"
➥selectedField="0" itemClick="choixModeLecture(event)" width="102"/>
<mx:Text x="632" y="471" text="{tempsTotal}" id="txt_tempTotal"
➥styleName="tempsTotalPlayList" width="155" height="18"/>
</mx:WindowedApplication>
Déploiement du projet
Comme nous en avons maintenant l’habitude, pour déployer le projet, il convient de
l’exporter vers une version de type Release-build. Néanmoins, pour que le déploiement
soit complet, il convient de créer un certificat de sécurité assurant l’authenticité de votre
application à ses utilisateurs. Sur ce point, nous vous renvoyons au chapitre 18 de cet
ouvrage.
=Flex3 FM.book Page 507 Mardi, 2. décembre 2008 3:32 15
Créer un lecteur MP3 avec Adobe AIR
CHAPITRE 24
507
En résumé
Ce chapitre clôt la partie purement pratique de cet ouvrage où nous avons souhaité vous
présenter des cas couvrant les fonctionnalités majeures du framework Flex. Néanmoins,
pour parfaire vos connaissances, la meilleur méthode consiste à créer vous-même des
applications diverses et variées.
Comme nous l’avons vu dans le chapitre 1, le framework Flex ne cesse de se perfectionner,
et de nouvelles versions sortent régulièrement. Durant l’écriture de cet ouvrage, nous
avons appris la sortie, courant 2009 (vraisemblablement dans la seconde moitié de
l’année) de Flex 4. C’est donc tout naturellement que nous allons terminer cet ouvrage
par les nouveautés proposées dans cette version.
=Flex3 FM.book Page 508 Mardi, 2. décembre 2008 3:32 15
=Flex3 FM.book Page 509 Mardi, 2. décembre 2008 3:32 15
25
Flex 4 Gumbo
Nous n’aurions pu terminer cet ouvrage sans y mentionner le successeur de Flex 3 : le
projet Gumbo (Flex 4). À l’heure où nous écrivons ces lignes, la version disponible en
téléchargement est la bêta 4.0.0.3957. Vous conviendrez donc que nous n’avons pas pu
étudier l’ensemble des détails de la future version du framework Flex, car celle-ci n’est
pas encore finalisée. Néanmoins nous pouvons d’ores et déjà dévoiler les nouveautés
majeures qu’elle apporte.
Les nouveautés de Flex 4
La nouvelle version du framework Flex s’oriente selon les trois axes suivants:
• améliorer la collaboration entre les développeurs et les designers ;
• améliorer les performances du compilateur ;
• exploiter au mieux les fonctionnalités du Flash Player 10 sur lequel les applications
Flex seront exclusivement exécutées.
Le premier axe est de loin le plus important, et se concrétise par l’apparition d’un
nouveau format graphique nommé FXG basé, une fois encore, sur la syntaxe XML. Ce
format va permettre au designer utilisant le produit Thermo d’Adobe d’exporter leurs
créations dans ce nouveau format.
=Flex3 FM.book Page 510 Mardi, 2. décembre 2008 3:32 15
510
Cas pratiques
PARTIE II
Projet Thermo
Ce projet a pour vocation de réaliser une scission entre le design et développement d’une application Flex.
En effet, le projet Thermo permettra aux designers de réaliser la partie graphique de l’application dont le
rendu sera ensuite transformé au format FXG, intégrable dans une application Flex. Pour plus d’informations sur ce projet, nous vous recommandons de consulter la page suivante : http://labs.adobe.com/
wiki/index.php/Thermo.
Dans cette nouvelle version, nous soulignons également la disparition de MXML 2006
au profit de MXML 2009. Ceci implique l’utilisation d’un nouvel espace de noms
(namespace), l’apparition de nouvelles balises et la redéfinition de certains composants
de Flex 3.
Bien entendu, nous aurons l’occasion dans ce chapitre de rentrer dans le détail de chacune
de ces modifications. Pour lors, nous vous proposons de découvrir l’outil permettant
d’exécuter nos futures applications : le Flash Player 10.
Installer le Flash Player 10
Comme nous l’avons évoqué en début de chapitre, les applications développées à l’aide
de la version 4 du framework ne seront exécutables qu’avec le Flash Player 10. En version
bêta (disponible depuis le 15 mai 2008), la nouvelle version du Flash Player (nommée
Astro) apporte également son lot de nouveautés :
• gestion native des effets 3D (zoom, rotation...) ;
• création d’effets personnalisés à l’aide du langage Adobe Pixel Blender (successeur du
langage Hydra) ;
• diminution de l’allocation mémoire et du temps processeur à son exécution.
Au vu de ces quelques lignes, nous pouvons d’ores et déjà imaginer l’impact sur nos
applications Flex. Pour nous donner un avant-goût de ces nouvelles possibilités, Adobe met
à notre disposition une application de démonstration. Avant cela, il convient de configurer
notre environnement de travail en installant la nouvelle version du Flash Player.
Avant d’installer la version bêta du Flash Player 10, il convient de désinstaller la version 9
de votre environnement. Pour cela, rendez-vous sur la page Labs du site d’Adobe http://
labs.adobe.com/technologies/flashplayer10/releasenotes.html#install et téléchargez-y le
logiciel de désinstallation correspondant à votre système d’exploitation. Exécutez-le.
Une fois cette étape terminée, il ne nous reste plus qu’à télécharger et installer la version
beta du plug-in Flash Player 10 librement téléchargeable à cette adresse : http://labs
.adobe.com/downloads/flashplayer10.html.
Afin de vérifier le bon déroulement de cette installation, exécutez l’application de démonstration disponible à cette adresse : http://labs.adobe.com/technologies/flashplayer10/
demos/ (figure 25-1), et observez au passage les nouvelles fonctionnalités du Flash Player.
=Flex3 FM.book Page 511 Mardi, 2. décembre 2008 3:32 15
Flex 4 Gumbo
CHAPITRE 25
511
Figure 25-1
Application de démonstration du Flash Player 10
FXG 1.0, nouveau format graphique
Comme nous l’avons vu, l’axe principal de la nouvelle version du framework est
d’améliorer la collaboration entre le développeur et le designer. Un développeur n’étant
pas forcément designer dans l’âme (et vise-versa), Flex 3 imposait aux développeurs de
mettre à disposition leur sources aux équipes graphiques, afin qu’elles réalisent les interfaces de l’application. Avec le framework Flex 4, ce temps est révolu !
En effet, grâce au nouveau format graphique FXG, interprétable par le nouveau framework,
et au projet Thermo, il est désormais possible pour les designers de créer l’interface
graphique de l’application, puis de l’intégrer au sein du framework.
Les spécifications techniques de ce nouveau format étant très nombreuses, nous ne le
décrirons pas en détail, les spécifications étant disponibles à l’adresse suivante : http://
opensource.adobe.com/wiki/display/flexsdk/FXG+1.0+Specification. Un exemple valant
mieux qu’un long discours, penchons-nous sur le code suivant, qui permet de dessiner un
petit personnage, certes basique (figure 25-2) :
<Group>
<!-- TETE -->
<Ellipse x="80" y="10" width="40" height="40" id="tete">
=Flex3 FM.book Page 512 Mardi, 2. décembre 2008 3:32 15
512
Cas pratiques
PARTIE II
<fill>
<SolidColor color="#000000"/>
</fill>
</Ellipse>
<!-- BRAS -->
<Rect width="100" height="30" x="50" y="50" id="bras">
<fill>
<SolidColor color="#000000"/>
</fill>
</Rect>
<!-- CORPS -->
<Rect width="30" height="45" x="85" y="70" id="corps">
<fill>
<SolidColor color="#000000"/>
</fill>
</Rect>
<!-- HANCHES -->
<Rect width="60" height="25" x="70" y="115" id="hanche">
<fill>
<SolidColor color="#000000"/>
</fill>
</Rect>
<!-- JAMBE DROITE -->
<Rect width="20" height="20" x="110" y="140" id="jambeDroite">
<fill>
<SolidColor color="#000000"/>
</fill>
</Rect>
<!-- JAMBE GAUCHE -->
<Rect width="20" height="20" x="70" y="140" id="jambeGauche">
<fill>
<SolidColor color="#000000">
</fill>
</Rect>
</Group>
=Flex3 FM.book Page 513 Mardi, 2. décembre 2008 3:32 15
Flex 4 Gumbo
CHAPITRE 25
513
Figure 25-2
Création d’un personnage à l’aide de FXG
La balise <Group> a pour fonction première de créer un groupement d’éléments qui sont
ici représentés par les rectangles (<rec>) et l’ellipse (<ellipse>). Grâce aux balises <fill>
et <solidColor>, nous colorons l’ensemble des éléments.
Comme FXG est intégré au framework Flex, nous pouvons utiliser ces mêmes balises au
sein d’un fichier MXML, c’est d’ailleurs ce que nous verrons un peu plus loin dans ce
chapitre.
MXML 2009
L’une des principales nouveautés apportées par la version 4 de Flex est la disparition du
langage MXML 2006 au profit MXML 2009. Dans sa version 2009, le langage MXML
nous apporte les nouveautés suivantes :
• l’utilisation d’un nouvel espace de noms ;
• l’apparition de nouvelles balises ;
• la notion de DataBinding bi-directionnel ;
• la modification de certains composants.
Voici tout ceci en détail.
Un nouvel espace de noms
La première question que l’on est en droit de poser est l’utilité d’utiliser un nouvel espace
de noms. Comme nous l’avons vu au début de cet ouvrage, un espace de noms permet de
définir les balises utilisées par le langage MXML. Étant donné que certains composants
ont de nouvelles propriétés, et que le langage MXML s’est enrichi, l’ancien espace de
noms n’est plus utilisable. C’est la raison pour laquelle nous devons en utiliser un nouveau.
Il se présente maintenant sous cette forme :
xmlns= « http://ns.adobe.com/mxml/2009 »
=Flex3 FM.book Page 514 Mardi, 2. décembre 2008 3:32 15
514
Cas pratiques
PARTIE II
Notons qu’aucun préfixe n’a été spécifié, contrairement à celui utilisé dans Flex 3
(xmlns :mx= http://www.adobe.com/2006/mxml). Ceci signifie que la méthode d’appel des
balises du langage MXML est également modifiée. Par exemple, si on écrivait dans
Flex 3 <mx :Model>, cela deviendra <Model> dans Flex 4.
Ce nouvel espace de noms ne sert que pour appeler les balises spécifiques du langage
MXML 2009. Il faut donc lui adjoindre un espace de noms utilisant les composants
graphiques de Flex 4, que l’on préfixera à notre convenance (ici cpflex4) :
xmlns:cpflex4="library:adobe/flex/gumbo"
Enfin, si nous souhaitons faire appel à l’espace de noms Halo de Flex 3 qui sert à réaliser
l’habillage de composants (cf. chapitre 8), il convient d’ajouter ceci :
xmlns:mx="library:adobe/flex/halo"
Pour résumer, la déclaration d’une application à l’aide de MXML 2009, se présente à
présent sous cette forme :
<Application
xmlns="http://ns.adobe.com/mxml/2009"
xmlns:mx="library:adobe/flex/halo"
xmlns:cpflex4="library:adobe/flex/gumbo"
>
</Application>
Voyons à présent quelques nouveautés présentes dans le langage MXML 2009.
La balise <private>
La première petite nouveauté de cette version 2009 de MXML est l’apparition de la
balise <private>. Avant toute chose, il est important de signaler que le contenu de cette balise
sera exclu lors de la compilation du projet. À quoi sert-elle ? Eh bien tout simplement à
insérer un commentaire sur le fichier :
<Private>
<Commentaire>Commentaire sur l'application</Commentaire>
</Private>
Attention à l’implémentation
La balise <private> ne peut être insérée qu’en fin de fichier MXML avant la fermeture de la balise
<application>.
Le couple de balises <library> et <description>
Issus du format FXG, le couple de balise <library> et <description> permet de créer des
bibliothèques graphiques réutilisables au sein de l’application, évitant ainsi la redondance
de code.
=Flex3 FM.book Page 515 Mardi, 2. décembre 2008 3:32 15
Flex 4 Gumbo
CHAPITRE 25
515
En guise d’exemple, reprenons notre dessin de personnage (figure 25-2). Si nous l’observons
à nouveau, nous voyons que nous avons dessiné cinq rectangles définis sous le même
format graphique et dont seuls le nom, la disposition et les dimensions diffèrent.
Tout ceci aurait pu être écrit bien plus simplement grâce aux balises <library> et
<definition> :
<?xml version="1.0" encoding="utf-8"?>
<Application
xmlns="http://ns.adobe.com/mxml/2009"
xmlns:cpflex4="library:adobe/flex/gumbo"
>
<!-- CREATION DE LA BIBLIOTHÈQUE GRAPHIQUE -->
<Library>
<Definition name="Tete" >
<Ellipse x="80" y="10" width="40" height="40">
<fill>
<SolidColor color="#000000"/>
</fill>
</Ellipse>
</Definition>
<Definition name="Membre" >
<Rect >
<fill>
<SolidColor color="#000000"/>
</fill>
</Rect>
</Definition>
</Library>
<!-- UTILISATION DE BIBLIOTHÈQUE GRAPHIQUE -->
<!-- Tete -->
<Tete> </Tete>
<!-- Bras -->
<Membre width="100" height="30" x="50" y="50"/>
<!-- Corps -->
<Membre width="30" height="45" x="85" y="70" ></Membre>
<!-- Hanches -->
<Membre width="60" height="25" x="70" y="115" ></Membre>
<!-- Jambe droite -->
=Flex3 FM.book Page 516 Mardi, 2. décembre 2008 3:32 15
516
Cas pratiques
PARTIE II
<Membre width="20" height="20" x="110" y="140" ></Membre>
<!-- Jambe Gauche -->
<Membre width="20" height="20" x="70" y="140" ></Membre>
</Application>
Dans cet exemple, nous avons créé une bibliothèque graphique contenant une ellipse et
un rectangle. Ces éléments graphiques sont décrits dans la balise <definition> qui sera
ensuite appelée dans le code de l’application affichant l’élément graphique correspondant. On constate donc que l’usage d’une bibliothèque graphique comporte l’avantage de
diminuer le nombre de lignes de code et permet de modifier facilement le design de
l’élément, qui, lui, est décrit en un seul et unique point de l’application.
Attention
La balise <library> doit obligatoirement être déclarée en début de document. Il ne peut donc y voir
d’autre déclaration avant celle-ci.
Le DataBinding bi-directionnel
Voici une nouveauté attendue, permettant de réaliser le DataBinding bi-directionnel.
Rappelez vous, dans Flex 3, le DataBinding consistait à mettre à jour une donnée A qui
répercutait cette mise à jour dans la donnée B. Avec Flex 4, la donnée B pourra, à son
tour, mettre à jour la donnée A. Voyons ceci en détail :
<cpflex4:TextInput
widthInChars="2"
x="10"
y="70"
id="txtValeur_1">
</cpflex4:TextInput>
<cpflex4:TextInput
widthInChars="2"
x="10"
y="100"
id="txtValeur_2"
text="@{txtValeur_1.text}">
</cpflex4:TextInput>
Analysons tout ceci. À première vue, de par la présence des accolades dans la propriété
text de la zone de texte txtValeur_2, celle-ci est liée à la propriété text de la zone de
saisie txtValeur_1. Ceci ne nous étonne que très peu car nous avons l’habitude de cette
notation fréquemment utilisée dans la version 3 du framework. Néanmoins, si nous
regardons de plus prêt, nous notons la présence d’une arobase. C’est elle qui va permettre
de définir la notion de DataBinding bi-directionnel. En voici le fonctionnement:
=Flex3 FM.book Page 517 Mardi, 2. décembre 2008 3:32 15
Flex 4 Gumbo
CHAPITRE 25
517
• Lorsque le contenu de la première zone de saisie est modifié, le contenu de la seconde
l’est également.
• Lorsque le contenu de la seconde zone de saisie est modifié, le contenu de la première
s’en trouve également modifié.
Amélioration de certains composants de Flex 3
Là encore, nous ne verrons pas les apports de cette nouvelle version du framework de
manière exhaustive, car la version que nous testons est loin d’être finalisée. Voici donc à
l’heure où nous écrivons ces lignes, les principales modifications.
Remplacement du composant <mx:Label>
Tout d’abord, le composant <mx:Label> est remplacé par le composant <TextBox> dont
voici la syntaxe :
<cpflex4:TextBox text="Composant TextBox " id="labelX" x="10" y="10" />
Le composant <TextInput>
Jusqu’à présent, il n’existait pas de propriété portant sur les zones de saisie permettant
d’en dimensionner automatiquement la longueur en fonction du nombre maximum de
caractères. C’est maintenant chose faite grâce à la propriété widthInChars applicable
notamment au composant <TextInput> :
<cpflex4:TextInput widthInChars="5" />
La figure 25-3, illustre cela : la longueur du composant s’est adaptée pour n’afficher que
cinq caractères.
Figure 25-3
Le composant TextInput
Le composant <TextArea>
Comme nous le savons, le composant <TextArea> permet de saisir plusieurs lignes de
texte. La nouveauté apportée à ce composant est la possibilité de limiter le nombre de
caractères affichés sur une ligne et le nombre de lignes visibles à l’écran.
Si nous souhaitons limiter à 20 le nombre de caractères par ligne, nous aurons recours à
la propriété widthInChars. Pour ne proposer que trois lignes à l’écran, nous emploierons la
propriété heightInLine. Ces deux propriétés permettent donc de dimensionner automatiquement le composant :
<cpflex4:TextArea widthInChars="20" heightInLines="3" />
=Flex3 FM.book Page 518 Mardi, 2. décembre 2008 3:32 15
518
Cas pratiques
PARTIE II
Figure 25-4
Le composant TextArea
D’autres composants apportent également leur lot de nouveautés. Citons par exemple
<HSlider> ou son homologue <VSlider>, ainsi que <NumericStepper>, mais la documentation
sur les nouveautés de Flex 4 n’est actuellement pas encore assez fournie pour pouvoir les
illustrer à l’aide d’exemple. Néanmoins, il vous est possible de consulter cette documentation en perpétuelle évolution sur le site de l’éditeur en vous rendant à cette adresse :
http://opensource.adobe.com/wiki/display/flexsdk/Gumbo ou bien en consultant la documentation du langage MXML consultable à partir de ce lien : http://livedocs.adobe.com/
flex/gumbo/langref/
Installation de l’environnement de développement
À présent, franchissons le pas et installons la nouvelle version du SDK de Flex 4. Pour
cela, nous allons tout d’abord le télécharger sur le site d’Adobe. Rendez-vous à l’adresse :
http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4 et téléchargez l’archive
de la dernière version bêta du SDK d’Adobe disponible. Décompressez cette archive
téléchargée sur votre environnement de travail. Passons ensuite à la configuration du Flex
Builder pour qu’il puisse utiliser cette nouvelle version et faire usage du Flash Player 10
(qui, rappelons-le, est indispensable à l’exécution des applications Flex 4).
Étant donné que nous allons créer un nouvel environnement de développement propre à
Flex 4, il faut éviter que les projets Flex 4 soient mélangés avec les projets Flex 3, développés jusqu’à présent. Pour cela, nous allons créer un nouvel espace de travail (workspace)
dans le Flex Builder qui sera dédié exclusivement aux applications Flex 4.
Espace de travail
Un espace de travail, ou workspace, est un répertoire contenant les sources de vos projets et l’ensemble
de leurs fichiers de configuration utilisés par Eclipse.
Pour créer ce nouvel espace de travail, il suffit de procéder comme suit :
1. Exécutez l’application Flex Builder.
2. Ouvrez le menu File.
3. Positionnez-vous sur le sous-menu Switch Workspace.
4. Cliquez sur le sous-menu Other.
=Flex3 FM.book Page 519 Mardi, 2. décembre 2008 3:32 15
Flex 4 Gumbo
CHAPITRE 25
519
5. Une fenêtre de configuration s’ouvre alors (figure 25-5), où nous devons spécifier le
répertoire de stockage des projets Flex 4, que vous aurez au préalable créé sur notre
disque dur.
6. Cliquez ensuite sur le bouton OK. Flex Builder redémarre pour prendre en compte ce
nouveau paramétrage.
Revenir à l’espace de travail de Flex 3
Pour réutiliser l’espace de travail précédent, il suffit d’ouvrir le menu File, de se positionner à nouveau sur
le sous-menu Switch Workspace et de sélectionner l’espace de travail correspondant aux projets Flex 3.
Figure 25-5
Création d’un nouvel espace de travail
L’étape suivante consiste à indiquer à Flex Builder l’endroit où se situe le nouveau SDK :
1. Ouvrez le menu Windows de Flex Builder.
2. Choisissez le sous-menu Preferences.
3. Dans la fenêtre qui s’ouvre, parcourez l’arborescence et sélectionnez sur le nœud
Flex.
4. Sélectionnez ensuite le nœud Installed SDK.
5. Dans la partie de droite de l’écran, nous avons l’ensemble des SDK installés. Pour
ajouter le SDK de Flex 4, il suffit de cliquer sur le bouton Add situé à droite de l’écran.
Ceci ouvre d’un pop-up, où nous cliquons sur le bouton Browse et choisissons le
répertoire de l’archive décompressée du SDK.
6. Nous terminons ensuite en cliquant sur le bouton OK et cochons ensuite Flex 4 afin
d’indiquer à Flex Builder son nouveau SDK de référence (figure 25-6).
=Flex3 FM.book Page 520 Mardi, 2. décembre 2008 3:32 15
520
Cas pratiques
PARTIE II
Figure 25-6
Installation du SDK 4
Le SDK de Flex 4 est à présent installé, mais vérifions son bon fonctionnement en créant
une première application Flex 4.
Première application 3D avec Flex 4
Création et configuration du projet
Avant toute chose, il convient de créer un nouveau projet que nous nommerons 3dFlex4.
Ensuite, indiquons au Flex Builder que notre projet doit s’exécuter à l’aide du Flash
Player 10. Pour cela, il suffit de suivre ce cheminement :
1. Cliquez-droit sur le projet et choisissez le sous-menu Properties.
2. Dans la partie gauche de la fenêtre qui se présente à l’écran, sélectionnez l’élément
Flex Compiler.
3. Dans la partie droite de la fenêtre, assurez-vous que le SDK utilisé est bien Flex 4.0.
4. Enfin, modifiez la version du Flash Player requis (10.0.0).
5. Terminez en cliquant sur le bouton OK (figure 25-7).
=Flex3 FM.book Page 521 Mardi, 2. décembre 2008 3:32 15
Flex 4 Gumbo
CHAPITRE 25
521
Figure 25-7
Configuration du projet
Mise à jour automatique du Flash Player et erreur de compilation
Il arrive que la mise à jour automatique du Flash Player entraîne une erreur de compilation de vos projets
Flex. Pour remédier à cela, il suffit de modifier la version du Flash Player comme nous venons de le faire.
Maintenant que notre projet est configuré, nous pouvons passer au codage.
Création de l’interface
Nous vous proposons de découvrir comment utiliser la fonctionnalité 3D en réalisant une
petite application permettant d’effectuer la rotation d’un rectangle autour de ses axes X,
Y et Z.
Commençons tout d’abord par utiliser les espaces de noms nécessaires, c’est-à-dire
l’espace de noms de MXML 2009 et celui des composants de Flex 4 : cpflex4 :
<Application
xmlns="http://ns.adobe.com/mxml/2009"
xmlns:cpflex4="library:adobe/flex/gumbo"
>
=Flex3 FM.book Page 522 Mardi, 2. décembre 2008 3:32 15
522
Cas pratiques
PARTIE II
Nous implémentons ensuite trois composants <HSLider> qui nous serviront à faire varier
l’angle de rotation de chacun de axes, ainsi que leur libellés associés :
<cpflex4:TextBox text="X : " id="labelX" x="10" y="10" />
<cpflex4:HSlider minimum="-360" maximum="360" value="0" id="sliderX" x="30" y="10">
➥</cpflex4:HSlider>
<cpflex4:TextBox text="Y : " id="labelY" x="10" y="40"/>
<cpflex4:HSlider minimum="-360" maximum="360" value="0" id="sliderY" x="30" y="40">
➥</cpflex4:HSlider>
<cpflex4:TextBox text="Z : " id="labelZ" x="10" y="70"/>
<cpflex4:HSlider minimum="-360" maximum="360" value="0" id="sliderZ" x="30" y="70" >
➥</cpflex4:HSlider>
Chaque composant <HSlider> est définit sur la plage [-360;360] correspondant à une rotation
complète sur chacun des axes.
Pour que notre interface soit complète, il nous manque l’élément essentiel : le rectangle
qui va faire l’objet des rotations. Pour le dessiner, nous allons utiliser le composant <Rect>
issu du format FXG vu précédemment :
<cpflex4:Rect width="200" height="100" x="100" y="200" id="rectangle" >
<cpflex4:fill>
<cpflex4:SolidColor color="#FF45EDF"/>
</cpflex4:fill>
</cpflex4:Rect>
Notre interface est à présent terminée. Si vous avez scrupuleusement suivi les étapes de
configuration du projet, vous devriez être en mesure de l’exécuter et de visualiser le
résultat qui doit être semblable à la figure 25-8.
Figure 25-8
Interface graphique du projet
=Flex3 FM.book Page 523 Mardi, 2. décembre 2008 3:32 15
Flex 4 Gumbo
CHAPITRE 25
523
Codage de l’application
Passons maintenant à l’implémentation des rotations. Si nous observons les propriétés du
composant <Rect>, nous remarquons la présence de trois nouvelles propriétés, jusque-là
inconnues dans le framework Flex 3 :
• rotationX : définissant l’angle de rotation par rapport à l’axe X ;
• rotationY : définissant l’angle de rotation par rapport à l’axe Y ;
• rotationZ : définissant l’angle de rotation par rapport à l’axe Z.
Comme vous l’avez sans doute deviné, nous allons exploiter ces nouvelles fonctionnalités
afin de réaliser les rotations souhaitées. Pour ce faire, ajoutons ces trois procédures :
<Script>
public function axeX():void{
rectangle.rotationX = sliderX.value;
}
public function axeY():void{
rectangle.rotationY = sliderY.value;
}
public function axeZ():void{
rectangle.rotationZ = sliderZ.value;
}
</Script>
La première chose que nous remarquons est que la balise <script> n’est pas précédée du
préfixe cpflex4. Cela est dû au fait que cette balise n’est pas un composant, mais fait partie
du langage MXML. Sa définition est donc située dans l’espace de noms xmlns=http://
ns.adobe.com/mxml/2009.
Analysons à présent la procédure axeX(). Elle récupère la valeur du composant <HSlider>
portant l’identifiant sliderX et l’affecte à la propriété rotationX du composant Rectangle.
Cette affectation a pour conséquence de modifier l’angle de rotation de l’axe X du rectangle
et de le faire tourner autour de cet axe. Les procédure axeY() et axeZ() ont le même fonctionnement mais modifient l’angle de rotation respectivement autour des axes Y et Z, en
fonction des valeur sélectionnées à l’aide des composants sliderY et sliderZ.
Pour que l’ensemble soit fonctionnel, il ne nous reste qu’à faire appel à ces procédures
lors du changement de valeur sur les composants <HSlider> :
<cpflex4:HSlider minimum="-360" maximum="360" value="0" id="sliderX" x="30" y="10"
➥change="axeX()"></cpflex4:HSlider>
=Flex3 FM.book Page 524 Mardi, 2. décembre 2008 3:32 15
524
Cas pratiques
PARTIE II
<cpflex4:HSlider minimum="-360" maximum="360" value="0" id="sliderY" x="30" y="40"
➥change="axeY()"></cpflex4:HSlider>
<cpflex4:HSlider minimum="-360" maximum="360" value="0" id="sliderZ" x="30" y="70"
➥change="axeZ()" ></cpflex4:HSlider>
Pour plus de clarté, voici le code complet de cet exemple dont le résultat est illustré par la
figure 25-9. Notez également la présence d’un commentaire spécifié à l’aide de la balise
<private> :
<?xml version="1.0" encoding="utf-8"?>
<Application
xmlns="http://ns.adobe.com/mxml/2009"
xmlns:cpflex4="library:adobe/flex/gumbo"
>
<Script>
public function axeX():void{
rectangle.rotationX = sliderX.value ;
}
public function axeY():void{
rectangle.rotationY = sliderY.value ;
}
public function axeZ():void{
rectangle.rotationZ = sliderZ.value ;
}
</Script>
<cpflex4:TextBox text="X : " id="labelX" x="10" y="10" />
<cpflex4:HSlider minimum="-360" maximum="360" value="0" id="sliderX" x="30" y="10"
➥change="axeX()"></cpflex4:HSlider>
<cpflex4:TextBox text="Y : " id="labelY" x="10" y="40"/>
<cpflex4:HSlider minimum="-360" maximum="360" value="0" id="sliderY" x="30" y="40"
➥change="axeY()"></cpflex4:HSlider>
=Flex3 FM.book Page 525 Mardi, 2. décembre 2008 3:32 15
Flex 4 Gumbo
CHAPITRE 25
<cpflex4:TextBox text="Z : " id="labelZ" x="10" y="70"/>
<cpflex4:HSlider minimum="-360" maximum="360" value="0" id="sliderZ" x="30" y="70"
➥change="axeZ()" ></cpflex4:HSlider>
<!-- Rectangle -->
<cpflex4:Rect width="200" height="100" x="100" y="200" id="rectangle"
<cpflex4:fill>
<cpflex4:SolidColor color="#FF45EDF"/>
</cpflex4:fill>
</cpflex4:Rect>
<Private>
<Commentaire>
Premiere application 3D avec Flex 4
</Commentaire>
</Private>
</Application>
Figure 25-9
Utilisation des propriétés de rotation 3D
>
525
=Flex3 FM.book Page 526 Mardi, 2. décembre 2008 3:32 15
526
Cas pratiques
PARTIE II
En conclusion
Ce dernier chapitre nous a permis de nous rendre compte que le projet Flex est en perpétuelle évolution, proposant à chaque version de nouvelles fonctionnalités plus étonnantes
les unes que les autres. Cette inventivité permet de contrecarrer la concurrence que représente notamment le projet Silverlight de Microsoft (qui a annoncé sa portabilité sur
Eclipse le 13 octobre 2008). L’aventure Flex est loin d’être terminée ! Nous espérons vous
avoir donné envie de la poursuivre…
=Flex3 FM.book Page 527 Mardi, 2. décembre 2008 3:32 15
Index
A
AC_OETags.js 342
accès aux données
HTTPService 223
RemoteObject 223
WebService 223
accordéon 126
ActionScript 16, 18, 174, 286,
310, 482
algorithme de boucle 19
boucle 19
condition 19, 20
fonction 21
implémenter HTTPService 247
MXML 171
opération booléenne 20
procédure 21
programmation objet 22
variable 18, 19
Adobe AIR 67, 345
composant 346
FileSystemComboBox 346
FileSystemDataGrid 346
FileSystemHistoryButton 347
FileSystemList 346
FileSystemTree 347
HTML 349
déploiement 352
Desktop Application 349
fonctionnement 345
mx:WindowedApplication 350
SQLite 354
AdvancedDataGrid, mode de tri
Expert 90
afficherLabel 110
agencement des composants 135
AIR 12
AIRI 352
Ajax 8
algorithme de boucle 19
alias 314
AMF (protocole) 242
AMFPHP (Action Message
Format PHP) 241, 374, 387, 389,
394
browser 252
test du service 252
analyse de performances 329
Ant 39, 40
antivirus et Flash Player 331
Apollo 345
application
déploiement 39
intégrer un module 288
modulaire 285
architecture
modulaire 368
n-tiers 13
Array 107
ArrayCollection 78, 85, 107
ascenseur 146
attribut
déclaration 23
icon 107
label 107
autoLoad 100
autonome (mode) 48
avertissement 321
Avg. Cumulative time 332
Avg. Self Time 332
B
balise
mx:Module 285
object 315
Style 148
SWF 152
base de données 13, 14, 374
Bindable 202
dispacthEvent 205
bin-debug 340
bin-release 342, 476
BlazeDS 263
data push 263
échange de données 276
J2EE 263
remote_config.xml 270
borderSkin 155
bottom 144
bouton 17
C
cache du navigateur (désactiver)
339
callLater 337
Calls 332
canal, my-polling-amf 278
Canvas 124, 125, 277
capture
d’événement 331, 333
des actions de l’application 330
certificat 352
AIRI 352
champFiltre 177
chargement, afficher la
progression 290
classe 15, 22
ActionScript 22
Alert 398
ArrayCollection 442
BrowserChangeEvent 303
Canvas 179
ExternalInterface 313, 314, 316
instancier 23
Math 320
=Flex3 FM.book Page 528 Mardi, 2. décembre 2008 3:32 15
528
Programmation Flex 3
classe (suite)
nombre d’instances 336
servComposants 252, 254
Validator 218
VideoDisplay 101
ColdFusion 52
colonne
regrouper 88, 90
trier 88
commentaire, private 514
communication entre application
et module 293
compc 174, 195
compilateur 30, 174
compc 31, 341
mxmlc 30, 341
compilation 36
automatisation 39
créer un script 40
html-wrapper 42
manuelle 39
mode Strict 340
Tomcat 273
composant 31, 173
Adobe AIR, FileSystemTree
479
ArrayCollection 175
Button 34
Canvas 176
comboBox 406
compc 175, 195
conteneur
ApplicationControlBar 111
Canvas 112
Form 115
FormHeading 115
FormItem 115
Grid 116
HBox 113
HDividedBox 113
Panel 117
TitleWindow 118
VBox 113
VDividedBox 113
contrôle
AdvancedDataGrid 88, 386
Button 76
CheckBox 76
ColorPicker 103
ComboBox 77
DataGrid 85
DateChooser 104
DateFiled 104
HorizontalList 106
HSlider 105, 132
Image 100
Label 82
LinkButton 107
List 77
ListBox 77
NumericStepper 106
OLAPDataGrid 92
radioButton 80
radioButtonGroup 80
RichTextEditor 83
SWFLoader 100
Text 82
TextArea 82
TextInput 82
TileList 106
ToogleButton 76
Tree 108
VideoDisplay 101
VSlider 105
créer 175
DataGrid 175, 176, 439
dimensionner 135
émetteur, mx:Producer 279
graphique
AreaChart 128
BarChart 128
BubbeChart 128
CandlestickChart 128
ColumnChart 128
HLOCChart 128
LineChart 128
PieChart 128
PlotChart 128
HBox 447
HTTPService 17, 225
Label 176
ModuleLoader 288, 290, 295,
424
mx:Label 517
navigation
Accordion 126
PopUpMenuButton 490
TabNavigator 123
tabNavigator 381
ViewStack 124
Panel 34
positionner 138, 143
récepteur, mx:Consumer 279
RemoteObject 238, 241, 274
spécification des dimensions
137
taille 136
TextArea 517
TextBox 517
TextInput 176, 517
ToggleButtonBar 125
WebService 17, 235
xmlns 180
conception UML 366
constructeur 23
conteneur 17
HTML 315
optimisation 341
web 305, 309
intégration 38
couche 13
métier 223
création de projet 365
creationComplete 84
CSS (Cascading Style Sheet) 147,
493
ActionScript 150
color 147
fontFamily 147
fontSize 147
fontStyle 147
fontWeight 147
paddingBottom 147
paddingLeft 147
paddingRight 148
paddingTop 148
textAlign 148
textDecoration 148
textIdent 148
CSSStyleDeclaration 151
Cumulative time 332
currencyFormater 440
curseur de lecture 485
curveTo 155
CVS (Concurrent Versions
System) 68
D
data push 263
DataBinding 16, 79, 190, 199,
200, 395, 495
ActionScript 201
bi-directionnel 205, 516
Bindable 202
BindingUtils 201
mx:Binding 201
=Flex3 FM.book Page 529 Mardi, 2. décembre 2008 3:32 15
Index
DataGrid 85, 175, 188, 190
alimenter 182
dataProvider 78, 90, 104, 107,
109, 125, 132, 190, 442
date
calcul 461
format 104
formatage, mx:DateFormatter
219
débogage 319
exécution pas à pas 322
mode avancé 321
modifier la valeur des variables
325
point d’arrêt 322
profiling 329
trace 325
deep linking 11, 299, 301, 476
BrowserChangeEvent (classe)
303
BrowserManager (classe) 303
history.css 301
history.js 301
déploiement 315, 341
Adobe AIR 352
bin-release 342
check list 341
Release Build 342
version 419
design pattern 16
designViewDataType 90
diagramme de classes UML 366
dimensionner
composant 135
par défaut 136
pourcentage 137
données
DataBinding 199
formatage 218
hiérarchie 108
mx:EmailValidator 215
présentation hiérarchique 88
saisie obligatoire 213
validation 212
vérification 215, 398
visualisation 90
drawCircle 155
drawRect 155
E
E4X (ECMAScript for XML) 226
easyPHP 374
échange de données
BlazeDS 276
mx:Consumer 279
mx:Producer 279
Eclipse 47, 48
espace de travail 518
IDE Open Source Eclipse 54
Linux 49
ECMAScript 18
effet
blur 163
combinaison 165
Dissolve 163
Fade 163
Glow 163
Iris 163
Move 163
Rezise 164
Rotate 164
sequence 165
target (cible) 165
transition 163, 166
WipeDown 164
WipeLeft 164
WipeRight 164
WipeUp 164
zoom 164
erreur
compilation
Flash Player 521
corriger avec la vue Problems
321
espace
de noms 17, 510
XML 313
de travail 519
état 157
currentState 162
de base 157
mx:AddChild 161
mx:SetProperty 160
mx:states 159
target 160
transition 163, 423
événement 188
executerService 256
extends 22
F
fenêtre, redimensionner 505
FileSystemTree 480, 489
filtre 188
Firefox 301
Flash 299
référencement 11
Flash Player 8, 10, 342
AC_OETags.js 342
antivirus 331
désinstaller la version 9 510
getTimer 337
installation automatique 342
mémoire occupée 338
mise à jour 29, 521
totalMemory 338
version 10 510
flash.media.Sound 482
flash.media.SoundChannel 482
flash.utils 337
flash.utils.timer 485
Flex Builder 47
installation 49
mode
Autonome 48
Plug-in 48
perspective 56
travail collaboratif 68
Flex SDK 27
Flex-Ajax Bridge 299, 313
flv 101
fonction, alimenterDatagrid 85
format
Date 484
de données, zipCodeValidator
400
FXG 510
format de données
credicardvalidator 465
currencyFormater 440
formatage 220
ActionScript 310
code postal
mx:ZipCodeFormatter 219
date mx:DateFormatter 219
monétaire 219
nombre mx:NumberFormatter
219
numéro de téléphone
mx:PhoneFormatter 219
formulaire (validation) 218, 449
front end 13
FXG 18, 509, 511
Rect 522
529
=Flex3 FM.book Page 530 Mardi, 2. décembre 2008 3:32 15
530
Programmation Flex 3
G
gateway.php 242, 392
getOperation 255
getTimer 337
glisser-déposer 451
dragComplete 455
dragEnabled 454
dragInitiator 456
dragMoveEnabled 453
Google
Chrome 301
Web Toolkit 4
H
habillage (skin) 153
Height 136
heightInLine 517
héritage 22
HierarchicalData 90
horizontalAlign 139
horizontalCenter 144
horizontalScrollPolicy 146
HSlider 518, 522, 523
HSQLDB 270
html-wrapper 42
HTTPService 14, 223, 261
implémentation ActionScript
247
mx:HTTPService 227
PHP 241
I
IDE 270
Eclipse 4, 7, 270
Flex Builder 8
NetBeans 270
identifiant, récupérer valeur 189
idt 177
IHM 15, 392
impression 451, 462
FlexPrintJobScale 462
initialisation, calculer le temps d’
337
installation, Flex Builder 49
instance d’une classe 336
interface graphique 135, 381
agencement des composants 135
Internet Explorer 301
item 81
itemClick 110, 396, 490
ItemClickEvent 81
ItemRenderer 423, 439, 447
J
J2EE 263
classe
création 270
déploiement 272
RemoteObject 274
Tomcat 264
Java
J2EE 268
SDK 264
JDK (Java Developpement Kit) 28
JRE (Java Runtime Environment)
28
JSEclipse 52
L
label 109
labelField 109
layout 139
left 144
liaison des données 199
librairie
ajouter à un projet 313
AMFPHP 242
Flex-Ajax Bridge 299, 313, 316
graphique
déclaration 516
description 514
library 514
licence 27
lineTo 155
Linux
plug-in Flex Builder 49
Silverlight 10
liste déroulante 190
ListeEvent 110
listerComposants 250
LiveCycle Data Services ES 64,
263
logique
applicative 394
IHM 392
M
machine virtuelle 345
maxHeight 136, 505
maxWidth 136, 505
mémoire
allocution inutile 334
occupation 333, 338
menu, accordéon 127
message d’erreur 215
Method 332
méthode
ActionScript 22
init 305
J2EE 268
exécution 274
pow 320
setTitle 305
temps d’exécution 335
trace 325
minHeight 136, 505
minWidth 136
mise en forme
ItemRenderer 423
mx:repeater 451
mm.cfg 341
mode Debug 322
MODEL 16
modèle, classe 389
module 285
ActionScript 288
charger 288
compiler 287
créer 286
implémenter un composant 287
intégrer dans une application 288
interaction 292
avec l’application 295
loadModule() 288
ModuleLoader 381
mx:ModuleLoader 288
parentApplication 296
progression du chargement
290, 473
version de déploiement 297
MP3 482
multithreading 62
MVC (modèle-vue-contrôleur) 15,
206
ActionScript 209
balise 209
gestion des données 201
mx:Model 206
mx:Application 17
=Flex3 FM.book Page 531 Mardi, 2. décembre 2008 3:32 15
Index
MXML (Macromedia fleX
Markup Language) 16, 17, 174,
313, 510, 513
2009 18
ActionScript 171
appel des balises 514
Component 177
espace de noms 513
mx:RemoteObject 238
RemoteObject 254
my-polling-amf 278
MySQL 374
N
navigateur 305
deep linking 299
ExternalInterface 307
Flex-Ajax Bridge 313
JavaScript 307
nœud, récupérer valeur 109
NumericStepper 518
O
object 107
objet
allocation 336
instancié 330
taille 330
OLAP (OnLine Analytical
Processing) 92
onglet 123, 124
opérateur
booléen 20
comparaison 20
optimisation 337
cache du navigateur 339
compilation mode Strict 340
occupation mémoire 338
temps d’initialisation 337, 338
P
package 22, 332
paddingBottom 139
paddingLeft 139
paddingRight 139
paddingTop 139
page d’accueil 343
panier 439
vider 442
paramètre, FlashVars 315
parentApplication, module 296
passerelle, remote-config.xml 271
percentHeigth 136
percentWidth 136
performances
analyse 331
applicatives 337
PHP (Hypertext Preprocessor) 241
environnement 224
générateur d’application 257
Pixel Blender 510
Play 101
plug-in 49
Eclipse 55
Linux 49
mode 48
point d’arrêt 62, 322, 324
pop-up 118, 457
createPopUp 119
parentApplication 122
PopUpManager 119
removePopUp 119
TitleWindow 457, 458, 460
PopUpMenuButton 489
positionnement
absolu 143
automatique 138
par contraintes 143
poste client 338
AIR 345, 353
cache du navigateur 339
mm.cfg 341
temps d’initialisation 338
private 514, 524
procédure 315
afficherProgression() 292
appelProcedureFlex 310
chargerModule 295
initialiserUrl() 304
interceptionErreur() 290
redondance d’appel 329
reporter l’exécution 337
temps d’exécution 329
Profiler 330
ligne 333
profiling 329
allocation d’objet 336
occupation de la mémoire 333
temps d’exécution 335
projet, création 365
propriété
autoPlay 101
implements 294
531
itemRenderer 439
position 485
selectedDate 105
source 101
url 288
protocole, AMF 242
proxy 226
R
ramasse-miettes 330, 340
RDA (Rich Desktop Application) 12
Release-build 506
RemoteObject 14, 223, 392
AMFPHP 250
implémentation ActionScript
256
MXML 254
PHP 250
send 255
removeAll() 442
répétition de mise en forme
mx:Repeater 464
RIA (Rich Internet Application)
14
right 144
RPC (Remote Procedure Call) 223
S
Safari 301
scaleContent 100
script 523
balise 35
compilation 40
scriptTimeLimit 339
selectedIndex 126
selectedItem 104
Self time 332
sérialisation des données 242
servComposants 252, 254
servComposants.php 250
serveur 270
BlazeDS, configuration 271
configuration 278
Tomcat 265
service
PHP 387
web
fonctionnement 236
mx:WebService 229
serviceListerComposants 254,
255, 256
=Flex3 FM.book Page 532 Mardi, 2. décembre 2008 3:32 15
532
Programmation Flex 3
services (répertoire) 242
servRO.serviceListerComposants
256
setStyleDeclaration 151
Silverlight 10
SimpleXML 229
skin 151
disabledSkin 151
downSkin 151
focusSkin 151
overSkin 151
programmation 153
selectedDownSkin 151
selectedOverSkin 151
selectedUpSkin 151
upSkin 151
snapInterval 106
SoundChannel 485
stepSize 106
style
ActionScript 150
CSS 147
CSS externe 149
image 152
visualiser les propriétés
d’un composant 148
Style (balise) 148
StyleManager 150
styleName 148
swc 174
SWC (Shockwave Component) 32
SWF (ShockWave Flash) 23, 30,
152, 341, 343
balise Style 152
exclure les lignes et
fonctionnalités de débogage
339
taille 339
SWFLoader 340
System 338
T
tableau, trier 90
TabNavigator 124
tb_composant 261
temps d’initialisation 338
text 83
Thermo 510, 511
tickInterval 106
TileList 444
time line 6
Tomcat 265, 270
répertoire de compilation 273
top 144
totalMemory 338
trace 62, 325, 326
optimiser 340
transition 163, 435
ActionScript 169
effet 163
fromState 168
mx.effects 163
mx:Parallel 166
mx:Sequence 165
mx:transitions 164
toState 168
verticalCenter 144
VerticalScrollPolicy 146
vidéo, progression du chargement
102
view state 157
base state 157
currentState 162
état 157
mx:AddChild 161
mx:SetProperty 160
mx:states 159
target 160
transition 163
ViewStack 125, 261
visible 86
VSlider 518
vue
Expressions 326
Memory Snapshot 333
Problems 321
Variables 325
W
U
UML
conception 366
diagramme de classes 366
unscaleHeight 154
unscaleWidth 154
updateDisplayList 154
URLLoader 395
V
value 80, 81, 106
variable
critique 62
déclarer 19
non affectée 62
surveiller 326
vérification des données 398
version de déploiement 419
verticalAlign 139
W3C (World Wide Web
Consortium) 3
warning 321
WebService 223
Width 136
widthInChars 83, 517
X
XAML 10
xmlns 180
Z
zone
de saisie 17, 371
redimensionnement 517
de texte
redimensionnement automatique 83
Flex 3, framework de référence pour le développement Flash
Open Source, le SDK de Flex offre un véritable environnement en phase avec les bonnes pratiques de génie logiciel
(MVC…) et de gestion de projet (travail collaboratif…). Il propose des bibliothèques de composants graphiques et des
fonctions pour dialoguer avec le serveur, et s’interfacer avec des bases de données via des serveurs PHP/J2EE.
Une bible avec de nombreux cas pratiques et retours d’expérience
Programmation Flex 3 explique aux développeurs web, qu’ils soient ou non rompus à Flash et ActionScript, comment
utiliser le framework Flex pour concevoir et créer des applications web dites « riches » (RIA), à l’instar des applications
Ajax ou Silverlight. Tout en rappelant les langages sur lesquels s’adosse cette technologie (ActionScript, MXML), l’ouvrage passe en revue l’intégralité des techniques de développement Flex : maîtrise de l’environnement de travail, création
d’interfaces interactives et évoluées avec les vues, transitions et thèmes, gestion des données et échanges avec le
serveur via RPC, mais aussi gestion et création des composants, débogage et optimisation. Il les met ensuite en situation avec deux études de cas détaillant la création d’un site e-commerce puis d’un lecteur MP3 tournant sur Adobe Air.
Au sommaire
Pourquoi utiliser Flex ? • Flex dans une architecture trois tiers • Flex et MVC • MXML et Actionscript •
Procédures et fonctions • Programmation objet • Mécanisme client/serveur • Flex SDK et Flex Builder • Gestion
d’un projet • Arborescence d’un projet Flex Builder • Exécution et test • Travail collaboratif • Export et import •
Création d’interfaces graphiques • Composants de contrôles • Boutons • Listes • Zones de texte • Tableaux •
Animations et vidéos Flash • Composants de navigation • Autres contrôles • Dimensionner et positionner •
ApplicationControlBar • Canvas • Hbox • Grid • Panel • TitleWindow • Styles • CSS et ActionScript • Skinning •
Utilisation d’images et de fichiers SWF • États, transitions et effets • Créer ses composants • MXML ou
ActionScript ? • compc • Gestion des données • DataBinding • Validation des données • Accès aux services de
la couche métier • HTTPService ou REST • RemoteObject • Flex et PHP • AMFPHP • HTTPService et
ActionScript • Le générateur de Flex Builder • Flex et J2EE avec BlazeDS • Composants émetteurs et récepteurs • Créer des applications modulaires • Interagir avec le conteneur web • Deep linking • Flex-Ajax Bridge •
Débogage d’une application • Points d’arrêt et exécution pas à pas • Analyse des performances • Optimisation
et déploiement • Réduire la taille des fichiers SWF • Adobe AIR • Flex 4 Gumbo.
A.Vannieuwenhuyze
Ingénieur concepteur dans
une SSII et responsable
d’applications pour
l’association Outcomerea,
spécialisée dans le domaine
de la recherche médicale,
Aurélien Vannieuwenhuyze
s’est d’abord investi dans la
conception et la réalisation
d’applications J2EE.
Pour créer des applications
Internet riches, il a étudié
les frameworks alliant
richesse et rapidité de
réalisation. Son choix s’est
porté sur Flex, avec lequel
il a réalisé des applicatifs
à vocation médicale et des
extranets pour de grandes
entreprises.
R. Pouclet
Passionné de développement
multimédia depuis plusieurs années,
Romain Pouclet se tourne aujourd’hui
vers le développement d’interfaces
riches et de solutions pour supports
mobiles.
À qui s’adresse cet ouvrage ?
@
Sur le site www.editions-eyrolles.com
– Téléchargez le code source des exemples
et cas pratiques du livre
Conception : Nord Compo
– À toute la communauté des concepteurs et développeurs web 2.0 (Flash, PHP, Java, Ajax, XHTML/CSS) qui désirent développer des applications Internet riches.
– Aux webmestres et développeurs connaissant Flash et ActionScript, qui recherchent un framework pour industrialiser la création d’interfaces graphiques pour leurs applications.
– Aux développeurs amenés à créer des applications autonomes exécutables avec ou sans navigateur web.
Flex 3
Applications Internet riches avec Flash ActionScript 3, MXML
et Flex Builder
A. Vannieuwenhuyze
Flex 3
Programmation
Programmation
Programmation
e
Couvr tés
uveau
o
n
s
le
x 4
de Fle
Flex 3
Applications Internet riches
avec Flash ActionScript 3,
MXML et Flex Builder
Aurélien Vannieuwenhuyze