Apache Adobe Flex TutorialTutoriaux Adobe Flex & AIR en Français

19oct/095

Flex ActionScript – Stratégies pour la communication entre Composants Flex

Tous les développeurs Flex, débutants et expérimentés, doivent faire face à un défi commun: permettre la communication entre composants Flex de la manière la plus puissante et la plus rapide. Pour permettre la communication entre composants, chaque composant doit connaître l'existence de l'autre composant, pour pouvoir échanger des données. En tant que développeurs, nous voulons suivre les principes de la POO (Programmation Orientée Objet) qui nous disent que chaque composant doit être le plus autonome possible. C'est là que les développeurs doivent cogiter: Comment deux composants Flex peuvent échanger de la data, sans connaître l'existence de l'autre?

Il y a de nombreuses manières d'aborder ce problème, mais pour cet article, on va voir 3 approches différentes pour Adobe Flex, voir leur fonctionnement, les problèmes qu'ils résolvent, et quelles sont leurs limitations.

Tout est une question d'évènement (Events)

Une des réponses possibles à ce problème de POO est d'utiliser le modèle évènementiel de Flash pour permettre à chaque composant de réagir aux évènements des autres. Ce modèle évènementiel permet aux composants de propager (dispatch) des objets de type évènement qui contiennent des informations sur l'information qui les a crée, comme par exemple, le click sur un bouton, ou une modification dans une ComboBox. Le modèle évènementiel permet aussi aux composants d'écouter un type d'évènement spécifique, pour que lorsqu'un changement se produit dans le composant source, l'évènement est propagé et l'écouteur (listener) est informé.

Le problème avec ce modèle est que l'écouteur doit savoir quel composant écouter, pour qu'il puisse recevoir l'évènement lorsqu'il est propagé. Par exemple, dans une application, on a un composant List et un composant DataGrid. Quand l'utilisateur modifie sa sélection dans la List, on veut mettre à jour la DataGrid. Pour cela, on doit écrire un peu de code dans le fichier MXML qui va contenir nos 2 composants. Quand la List propage un évènement de type CHANGE, le code met à jour le dataProvider de la DataGrid. Pour cela, notre code doit accéder à la référence de la List, et à celle de la DataGrid pour pouvoir utiliser la méthode addEventListener() pour écouter les changements:

<mx:Script>
    <![CDATA[
        import mx.events.ListEvent;

        [Bindable] public var dataOne:Array;
[Bindable] public var dataTwo:Array;

        public function handleChangeEvent(event:ListEvent):void {
            myDataGrid.dataProvider = dataTwo;
        }
    ]]>
</mx:Script>
<mx:List id="myList" change=handleChangeEvent(event)" />
<mx:DataGrid id="myDataGrid" dataProvider="{dataOne}" />

Quand la List et la DataGrid sont situées dans le même fichier MXML, comme dans cet exemple, cette fonctionnalité est simple à créer. On écrit seulement un peu de code pour écouter le changement de sélection dans la List et on met ensuite à jour la DataGrid. Cela devient plus difficile quand un des deux composants n'est pas dans le même MXML ou quand l'emplacement du composant est modifié.

Par exemple, disons que notre List est dans une barre d'outil de notre application qui est toujours affichée, mais la DataGrid n'est disponible que dans un onglet spécifique. Comment votre code va-t-il connaître l'emplacement de la DataGrid et de la List? Une pratique possible (mais mauvaise) est de mettre du code dans le fichier MXML de la DataGrid, et de référencer le composant List en remontant dans la hiérarchie par la propriété "parent", comme ceci:

parent.parent.parent.myList.addEventListener()

Une autre solution (toute aussi mauvaise mais "moins pire") est de référencer l'application et ensuite, de descendre dans la hiérarchie:

Application.application.sidebar.myList.addEventListener()

Ce genre de solution marche sur le court terme, mais crée un code fragile, facile à casser avec le plus petit des changements. Que se passera-t-il si vous devez bouger la List ou la DataGrid et que le chemin n'est plus le même? Dans ce cas, le compilateur va lancer une erreur car le chemin n'est plus valide. Au moins, vous sauriez quelle partie du code dysfonctionne, mais ce n'est pas une solution si vous voulez continuer à monter votre application. C'est à ce moment-la que la plupart des développeurs commencent à chercher différentes manières de résoudre ce problème.

Monter jusqu'au sommet

La principale faille de cette première approche est le manque de point d'entrée commun pour faire transiter toute les communications. On veut continuer à utiliser le modèle évènementiel, mais on a besoin d'identifier un point de contact qui va permettre à donner  à notre application de modifier la disposition de nos composants sans affecter les voies de communication. Dans ce cas-là, le meilleur endroit où chercher est le haut de la Display List (liste d'affichage) d'Adobe Flash Player.

La Display List est une représentation hiérarchique de ce qui est affiché dans Flash Player. Tout en haut de la liste d'affichage se trouve la scène (stage),  et tous les composants visuels sont les descendants. Peut importe où les composants sont situés dans votre application, la scène peut être accédée par la propriété "stage". Le stage est un très bon point de départ si vous travaillez avec Adobe Flash Professional, ou dans un projet ActionScript, mais dans Flex, vous n'avez pas besoin de voyager si loin dans la Display List pour cibler l'objet application. L'objet Application est un enfant du stage et le plus haut pour le développement Flex. Tous les composants seront descendants de l'application. L'application peut être accédée par n'importe quel composant en utilisant la syntaxe suivante:

Application.application

Dans l'exemple suivant, notre composant écoute sur l'application, l'évènement ListEvent et met à jour la donnée de la DataGrid quand l'évènement est propagé à travers l'application.

<mx:Script>
    <![CDATA[
        import mx.events.ListEvent;

[Bindable] public var dataOne:Array;
[Bindable] public var dataTwo:Array;

        public function subscribeToListChange():void {
            Application.application.addEventListener(ListEvent.CHANGE, handleListChange);
        }

        public function handleListChange(event:ListEvent):void {
            myDataGrid.dataProvider = dataTwo;
        }
    ]]>
</mx:Script>
<mx:DataGrid id="myDataGrid" dataProvider="{dataOne}" />

La différence entre cette approche est celle utilisant l'évènement ListEvent.CHANGE par défaut est que l'on doit être sur que la propriété "bubbles" de l'évènement propagé est bien à "true" ou notre objet application ne va jamais recevoir l'évènement. Le "Bubbling" est le processus qui permet aux évènements de se diffuser dans la Display List. Par défaut, les évènements Flex sont seulement envoyés directement aux composants inscrits à cet évènement. Mais si on fixe la propriété "bubbles" à true, l'évènement sera diffusé à toute le chaîne jusqu'à ce qu'il atteigne le haut du Stage. En utilisant le "Bubbling", on peut aller dans notre Application.application pour écouter les évènements, en sachant que quand notre List va propager notre évènement "bubbled", il sera passé à l'application.

18oct/090

Flex ActionScript – MultiTouch: Exemples, code source et vidéos

Durant Adobe MAX 2009, Adobe a présenté la nouvelle API Flash Player permettant de gérer le multi-touch sur les plate-formes qui le gèrent (tablette PC sous Windows 7, mobiles, …). Cette API sera comprise dans Flash Player 10.1 et Air 2.0 qui devraient sortir prochainement.

L'application qui a été montrée lors de MAX a été développée par Cynergy Systems et on peut trouver sur leur (très bon) blog, des exemples d'applications crées spécialement pour les plate-formes multi-touch.

On a ainsi plusieurs exemples, des exemples avec de la cartographie (utilisation de ModestMaps), du dessin avec les doigts, ou la création d'une application dédiée. Le code source de ces applications est fourni, vous pourrez donc vous en inspirer quand vous commencerez à coder avec FP 10.1 ;) . Chaque exemple est accompagné d'une petite vidéo pour bien montrer le fonctionnement des Gesture et autre Touch Events).

Multi-Touch Development with Flex

MAX 09 – Le multitouch @ La Fabrick

18oct/090

Flex Error – ArgumentError: Error #1063: Argument count mismatch on mx.core::CrossDomainRSLItem(). Expected 5, got 6 [Résolu]

Voici une erreur que vous pourrez rencontrer si vous travaillez à plusieurs sur des projets Flex ou si vous utilisez des librairies SWC que vous téléchargés sur le web. Cela s'est produit avec un utilisateur de ma librairie, la DataFilterLib que l'on a finalement résolu.

Cette erreur apparaît à l'exécution, vous la verrez apparaître si vous avez le Flash Player Debugger. Si vous ne l'avez pas, l'erreur va se faire de manière silencieuse et vous n'aurez rien à l'écran. Voici l'erreur que vous pouvez avoir:

ArgumentError: Error #1063: Argument count mismatch on mx.core::CrossDomainRSLItem(). Expected 5, got 6

Le descriptif de cette erreur semble impliquer une erreur au niveau de votre code, pour lequel le nombre d'arguments passés à la méthode CrossDomainRSLItem. Cependant, vous n'avez surement même pas utilisé cette méthode dans votre code. Le problème vient en fait d'un problème avec les librairies que vous utilisez. En effet, cette erreur se produit si vous utilisez des versions du Flex SDK différentes de celles utilisées pour compiler la librairie SWC.

Par exemple, prenons un développeur qui utilise un projet Flex Library et exporte un SWC avec un compilateur Flex 3.2. Vous tentez ensuite d'utiliser ce SWC dans un projet Flex ayant une version type 3.0 ou 3.4. A ce moment-à, il y a un conflit au niveau des RSLs. Pour résoudre ce conflit, accordez vos espaces de travail pour que tout le monde compile ses projets avec la même version du SDK Flex (la plus à jour).

Si vous utilisez une librairie SWC externe, vous devrez obtenir les sources du projet (avec SVN par exemple pour les projets hébergés sous Google Code). Si vous ne pouvez pas avoir les sources, arrangez vous pour être au point avec leur version du SDK.

18oct/090

Flex Library – Youtube Player AS3 API

Google a sorti il y a quelques jours, l'API ActionScript 3 officielle pour l'intégration de vidéos Youtube. En utilisant cette API, vous pourrez ainsi intégrer facilement des vidéos Youtube dans vos applications Flex. Cette nouvelle API est "Chromeless", ce qui signifie que vous pourrez avoir les vidéos Youtube  sans la barre d'outils qui va avec (mais avec le logo Youtube quand même). Vous pourrez ainsi designer votre propre barre d'outils (en utilisant le Open Source Media Framework par exemple).

Avant cette sortie, les développeurs AS3 devaient utiliser des librairies qui faisaient le lien entre l'API AS2 native et leur code ActionScript 3. Avec la sortie officielle de cette API AS3, plus besoin de passer par des manipulations douteuses. Vous pourrez vous concentrer sur le développement et ne plus vous soucier de la gestion d'un code cross-langage.

Voir l'annonce officielle sur le API Youtube Blog

Voir la documentation sur l'API Youtube AS3

16oct/092

Flex Tips – Afficher simplement l'icon d'un Button

Le composant Flex Button permet d'afficher simplement un icône grâce à la propriété de style "icon". Vous pouvez faire pointer cette propriété vers un fichier image (gif, png, ...) comme ceci:

<mx:Button id="b1"
 label="Click Me"
 icon="@Embed('/assets/icons/icon.png')"/>

Vous aurez donc un bouton avec le label "Click Me" et un icône à gauche de base. Supposons maintenant que dans votre interface Flex, vous ayez besoin d'un petit bouton, sans label, mais avec simplement un pictogramme. Vous pouvez créer une mx:Image avec quelques propriétés pour la faire ressembler à un bouton mais ce n'est pas très pratique et vous pourriez avoir besoin des comportements spécifiques de la classe Button.

Si vous supprimer le label (voir exemple plus bas), vous aurez toujours votre bouton avec son look habituel, ce qui est gênant. Pour supprimer cette skin et avoir un Button très propre avec simplement l'icône, il vous suffit de fixer la propriété de style "skin" à null avec un simple Data Binding:

<mx:Button id="b3"
 label=""
 skin="{null}"
 icon="@Embed('/assets/information.png')"/>

A ce moment-là, vous n'aurez toujours pas un vrai comportement bouton puisque le curseur main a disparu. Pour le faire apparaître, il suffit de fixer les propriété buttonMode et useHandCursor à true:

<mx:Button id="b4"
 label=""
 skin="{null}"
 useHandCursor="true"
 buttonMode="true"
 icon="@Embed('/assets/information.png')"/>

Application Exemple

Flex Source Code Download: Télécharger le code source complet de l'application

This movie requires Flash Player 11

Remplis sous: Button, Skin Lire la suite