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

31mai/100

Flex MenuBar – Bug lors de l'utilisation de sous-menus multiples ne comportant qu'un enfant

Voici un bug de Flex 3 "quasi" impossible à corriger. Après y avoir passé une après-midi complète, j'ai trouvé une solution de remplacement, pas très belle mais qui fonctionne (sous certaines conditions). J'ai pourtant bien cherché sur le net, il semble que personne ne soit tombé sur ce bug, pourtant facile à reproduire.

Si vous avez une solution plus "propre", n'hésitez pas à la soumettre :) .

Le Bug en question se produit lors de l'utilisation d'un composant MenuBar. Celui-ci prend un dataProvider hiérarchique (XML ou ArrayCollection).

Notez que les classes suivantes ont été créées pour l'exemple. Dans la vraie vie, on fera peut-être plus attention sur certains points.

Dans notre exemple, on va prendre la classe Model suivante:

package {
  import mx.collections.ArrayCollection;

  [Bindable]
  [DefaultProperty("children")]
  public class MenuItem {
    public function MenuItem() {
    }

    public var label:String = null;
    public var type:String = null;
    public var children:ArrayCollection = null;

  }
}

On a ensuite notre application utilisant une MenuBar. Celle-ci est remplie avec des MenuItem, de manière hiérarchique:

  • Menu 1
  • Menu 2
    • Sub Item 1
      • Sub Sub Menu 1
        • Sub Sub Sub Menu 1
  • Menu 3

Dans notre application, on construit donc ce menu:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*"
                viewSourceURL="srcview/index.html">
  <mx:MenuBar>
    <local:MenuItem label="Menu 1"/>
    <local:MenuItem label="Menu 2">
      <mx:ArrayCollection>
        <local:MenuItem label="Sub Menu 1">
          <mx:ArrayCollection>
            <local:MenuItem label="Sub Sub Menu 1">
              <mx:ArrayCollection>
                <local:MenuItem label="Sub Sub Sub Menu 1"/>
              </mx:ArrayCollection>
            </local:MenuItem>
          </mx:ArrayCollection>
        </local:MenuItem>
      </mx:ArrayCollection>
    </local:MenuItem>
    <local:MenuItem label="Menu 3"/>
  </mx:MenuBar>
</mx:Application>

Et voici le résultat:

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

This movie requires Flash Player 11

Vous l'avez peut-être remarqué, on a perdu "Sub Sub Menu 1" en route! Mais voici un deuxième exemple plus troublant. On rajoute un item au même niveau que Sub Sub Menu 1, que l'on va appeler Sub Sub Menu 2:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*"
                viewSourceURL="srcview/index.html">
  <mx:MenuBar>
    <local:MenuItem label="Menu 1"/>
    <local:MenuItem label="Menu 2">
      <mx:ArrayCollection>
        <local:MenuItem label="Sub Menu 1">
          <mx:ArrayCollection>
            <local:MenuItem label="Sub Sub Menu 1">
              <mx:ArrayCollection>
                <local:MenuItem label="Sub Sub Sub Menu 1"/>
              </mx:ArrayCollection>
            </local:MenuItem>
            <local:MenuItem label="Sub Sub Menu 2"/>
          </mx:ArrayCollection>
        </local:MenuItem>
      </mx:ArrayCollection>
    </local:MenuItem>
    <local:MenuItem label="Menu 3"/>
  </mx:MenuBar>
</mx:Application>

Voici le résultat:

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

This movie requires Flash Player 11

Notre "Sub Sub Menu 1" est de retour... C'est à partir de ce moment, qu'il faut commencer à s'accrocher car comme vous l'avez vu, on utilise le composant de base de Flex 3 MenuBar. Pour trouver la cause du problème, il va donc falloir aller fouiller dans le code source de Flex à grands coups de point d'arrêt.

30mai/102

Flex 4 – (3) Différence entre éléments graphiques et éléments visuels (IVisualElement et DisplayObject)

On commence ici à mettre les mains dans Flex 4 :) . Avant de se lancer dans du développement Flex 4, il est primordial de comprendre ce qui a changé par rapport à Flex 3 pour faciliter la migration. Si vous n'avez jamais utilisé Flex 3 et que vous vous lancez dans Flex 4, il est indispensable de comprendre ce qui se passe derrière votre code.

On va commencer par un point pas si facile à comprendre mais qui est la base du DOM (Document Object Model) de Flex 4. Sans avoir compris ce point, vous aurez du mal à comprendre pourquoi il est plus facile de créer des skins et des composants avec Flex 4 qu'avec Flex 3.

Dans cet article, on va donc parler du DOM Tree alias Display List qui est en fait l'organisation hiérarchique de vos éléments. C'est un point primordial car pour retrouver vos composants, il va falloir savoir comment ils sont organisés.

Plusieurs articles en anglais peuvent vous aider à comprendre ce nouveau modèle DOM:

Pour vous faciliter la vie, je vais essaie d'expliquer au mieux, même si c'est parfois laborieux, accrochez-vous ;)

Elements et Children

Avec Flex 3, tous les enfants d'un conteneur étaient des "children". Pour parcourir tous les composants d'un conteneur, pas de souci, il suffit d'utiliser les méthodes getChildren() ou getChildAt(idx:int). Pour ajouter un composant, il suffisait d'appeler la méthode addChild(do:DisplayObject) sur le conteneur pour lui ajouter un compoant.

Avec Flex 4, vous pourrez voir que vous avez une nouvelle méthode: addElement(element:IVisualElement).

Alors quelle est la différence entre un Element et un Child?

  • Un Element est un objet qui implémente IVisualElement
  • Un Child est un objet qui hérite de DisplayObject

Alors comment savoir si un composant est un Element ou un Child (ou les deux)?

Tout d'abord, la classe UIComponent hérite de DisplayObject, donc tous les UIComponent sont des DisplayObject et sont donc des Child.

La classe UIComponent implémente aussi IVisualElement donc tous les UIComponents sont considérés comme des Element.

ui_comp

Cependant, cela ne signifie pas que tous les DisplayObject sont des Element. En effet, c'est bien UIComponent qui implémente IVisualElement et pas DisplayObject:disp_obj
Peu de composants sont en fait seulement des Element et pas des Child. Principalement, on retrouve les primitives Spark telles que Rect, Ellipse et Path. Ces 3 classes héritent de FilledElement et donc de GraphicElement qui implémente IVisualElement.
Dans le language utilisé dans les docs, ces Element "purs" (Rect, Path, Bitmap) sont appelés "graphic element".  Les "visual element" comportent, eux, les composants (Flex 3/4) et les "graphic element". Comme l'un contient l'autre, il est rapide de se mélanger les pinceaux ;)

30mai/1010

Flash vs HTML5 – Comparaison de performances: i lol'd

Ce matin sur les feeds Adobe sont apparus plusieurs articles qui m'attirent toujours l'oeil:

Le premier lien présente une vidéo de Ryan Stewart sur la navigation dans le navigateur Android avec le player Flash. Vous l'avez sûrement déjà vue ;) . La deuxième est une vidéo de Michael Chaize, l'évangelist Adobe Français avec une comparaison plutôt objective des performances HTML5 / Flash:

Vous l'aurez déviné, les performances du Canvas HTML5 sont plutôt médiocres comparées à celles de Flash.

Le deuxième lien présente les "Top" démos du couple HTML5 / JavaScript. Alors, perso, quand on me dit Top, je m'attends à de l'impressionnant et du performant, une vitrine pour le HTML5.

HTML5 et la 3D/Effet tissu

Premier lien, une démonstration d'un effet "tissu" en JS, plutôt cool comme démonstration:

Cela m'a rappelé une autre démonstration lors de la sortie de Flash Player 10:

demo-fp10

D'un point de vue performances, les 2 prennent 30-40% du CPU en permanence mais il faut noter que la démo Flash peut jouer de la vidéo sur le "tissu". C'est plutôt inutile mais je doute que ce soit possible avec HTML5/JS, même avec beaucoup de volonté.

Remplis sous: Exemple Lire la suite
29mai/100

Flex 4 – (2) Création de composants Flex ré-utilisables, les meilleures techniques

La création de composants est un must quand on travaille avec Flex. Mais autant faut-il savoir les créer de la meilleures manière afin qu'ils puissent être ré-utilisés et faciliter la maintenance de votre code.

A ce propos, Tom Sugden a écrit un très bon article qui explique bien les meilleures manières pour faire un bon composant Flex:

Writing Genuinely Reusable Flex Components

Pour faire simple, je vais traduire cet article, et rajouter quelques commentaires et suggestions...

Pour de gros projets, en entreprise, on se retrouve souvent à extraire un ensemble de composants réutilisables dans un projet Flex Library. En théorie, les mêmes composants peuvent être utilisés dans plusieurs modules et/ou dans des applications Flex / Air. Cela permet d'avoir une base de code solide et facile à maintenir pour un développement plus rapide.

Cependant, dans la pratique, certaines erreurs de conception sont faites, qui limitent la ré-utilisabilité des composants. Cet article explique comment créer un composant totalement ré-utilisable et met en avant certaines techniques du SDK Flex qui peuvent être appliquées à vos propres composants.

Comment définir un composant "vraiment" réutilisable?

Il y a différents niveaux de ré-utilisabilité, mais un composant ré-utilisable devrait toujours pouvoir faire le rendu de n'importe quel type de donnée. Il devrait pouvoir fonctionner avec un tableau d'objets basiques (type Object) ou une collection d'objet de type Kangaroo par exemple.

Le composant Flex DataGrid permet de faire cela:

<mx:DataGrid dataProvider="{ kangaroos }">
 <mx:columns>
 <mx:DataGridColumn headerText="Name" dataField="name"/>
 <mx:DataGridColumn headerText="Weight" labelFunction="calculateWeight"/>
 </mx:columns>
</mx:DataGrid>

Notez que les propriétés "dataField" et "labelFunction" indiquent au composant comment récupérer sa donnée depuis les objets de type Kangaroo, sans imposer de dépendance. On a ici deux mécanismes possibles pour rendre un composant vraiment ré-utilisable. Même si le développeur n'as pas le contrôle sur la classe Kangaroo (si elle fait partie d'une librairie externe par exemple), il peuvent tout de même être rendu dans une DataGrid.

L'Anti-Pattern Data Interface

Une des erreurs courantes est d'obliger la donnée qui va être rendue par un composant à implémenter une interface spécifique. Par exemple, on va prendre le composant DistributionBar qui fait le rendu d'un graphique comme celui-ci:

DistributionBar

On affiche un certain nombre de régions de tailles différentes, chacune contenant un label. Il est tentant de configurer ce composant pour qu'il utilise un tableau d'objet IRegion:

public interface IRegion
{
 function get label() : String;
 function get size() : int;
}

Le composant pourra ensuite extraire les informations de taille et de label pour chaque région par cette interface. L'argument en faveur de cette démarche est que l'interface découple le composant de l'objet concret qui est rendu. N'importe quel objet peut être rendu tant qu'il implémente IRegion, mais c'est dans le "tant que" que réside la faille de conception.

En imposant l'utilisation de l'interface IRegion, la ré-utilisabilité du composant est limitée. L'interface doit être implémentée par les classes du Model avant de pouvoir être rendue par le composant. Encore pire, si vos models sont produits par une autre librairie (dont vous pouvez ne pas avoir les sources) ou par une autre équipe, il se peut que vous ne puissiez pas changer les classes, elles devront donc être "wrappées" (encapsulées dans d'autres objets qui implémentent IRegion).

Pour ces raisons, le composant n'est pas vraiment ré-utilisable.

Notez que cette considération est importante pour les composants qui doivent être complètement ré-utilisables comme les DataGrid ou les List Flex. Pour des composants plus "métiers" ou le fait de pouvoir instancier son composant sans configurer trop de propriétés, on pourra utiliser le "pattern Data Interface". Parfois, il vaut mieux passer du temps à créer un composant qui soit ré-utilisable mais parfois il est plus aisé/rapide de créer plusieurs composants (par héritage) pour des besoins métiers spécifiques.

Les composants ré-utilisables du SDK Flex

Le SDK Flex contient de nombreux composants ré-utilisables, utilisant plusieurs approches:

  1. Data Fields
  2. Data Functions
  3. Data Descriptor
  4. Factory Objects

Ces approches et ces techniques peuvent être appliquées à vos propres composants pour les rendre ré-utilisables.

28mai/103

Open Source Media Framework – Sortie d'OSMF en version 1.0 et Webinar gratuit

Non, le projet Flex 4 "fil rouge" Flex Tutorial n'est pas mort ^^. Le blog a juste été en "stand by" pendant quelques semaines pour cause de beaucoup de travail à côté (et oui, écrire pour FT n'est pas mon job à plein temps :P ). Mais certaines deadline étant passées, il va redémarrer progressivement avec notamment, le démarrage du fil rouge et des relais d'informations qui ne sont pas fait par les autres blogs FR.

Voilà une annonce qui en fait partie, celle de la sortie d'OSMF (Open Source Media Framework) en version 1.0, stable donc. Toutes les informations sur le site officiel:

Open Source Media Framework en version 1.0

Pour la sortie de cette version 1.0, Adobe vous invite à participer à un Webinar gratuit le 9 Juin:

webinar

Seul problème pour nous français, ce webinar est à 11am P.S.T, ce qui fait 2h du matin 20h pour nous si je ne me trompe pas. Si vous voulez y participer, vous pouvez vous inscrire ici:

Inscription Webinar OSMF Adobe

En une video issue de l'Adobe TV pour vous mettre en bouche sur les capacités d'OSMF qui seront mises en avant dans le futur fil rouge:

Remplis sous: OSMF 3 Commentaires