IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Flex Discussion :

Problème étrange lié à l'utilisation de librairie.


Sujet :

Flex

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Développeur informatique
    Inscrit en
    Mars 2008
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2008
    Messages : 80
    Par défaut Problème étrange lié à l'utilisation de librairie.
    Bonjour à tous,

    J'éprouve des difficultés avec l'utilisation des librairies. Voici ce que je désire faire :

    J'ai développé un grand nombre de petits composants que j'utilise dans toutes mes applications. Plutôt que de les recopier d'un projet à l'autre (ce qui est une très mauvaise pratique), je me dis qu'il serait souhaitable de les rassembler au sein d'une librairie. Cette librairie de composants serait partagée entre toutes mes applications. Bref, il s'agit de la "raison d'être" d'une librairie...

    J'ai donc créé un projet de type "Flex Library Project". Je l'ai nommé "frmawork".

    Dans ce projet, j'ai déposé le code d'un de mes composants. Pour commencer, je teste "la manipulation" avec un seul composant. Le nombre de composants dans la librairie n'a pas d'importance.

    Le schéma ci-dessous montre l'arborescence du projet.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    framework
    |-- bin
    |   `-- framework.swc
    `-- src
        |-- components
        |   `-- UIComponents
        |       `-- DateTimeChooser.as
        `-- interfaces
            |-- IGhostInterface.as
            `-- ISelectorInterface.as
    Ce projet compile dans erreur, ni avertissement. La librairie "framework.swc" est créée dans le répertoire "bin".

    Je fournis à la fin de ce document le code du composant "DateTimeChooser.as". Afin de tester cette librairie, j'ai créé un projet de type "Application". Il porte le nom "framework-testing". L'arborescence du projet est donnée ci-dessous :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    framework-testing
    |-- html-template
    |   |-- AC_OETags.js
    |   |-- history
    |   |   |-- history.css
    |   |   |-- history.js
    |   |   `-- historyFrame.html
    |   |-- index.template.html
    |   `-- playerProductInstall.swf
    |-- libs
    `-- src
        `-- DateTimeChooser.mxml
    Je fournis à la fin de ce document le code de l'application. L'application compile dans erreur, ni avertissement. Cela dit, la phase d'initialisation de l'application ne se déroule pas normalement:

    • Le composant "n'apparaît pas".
    • L'application "n'en finit pas" de s'initialiser.
    • Une trace montre que la fonction exécutée lors de la levée de l'événement "creationComplete" s'exécute "en boucle". Autrement dit, cet évènement semble être lancé un nombre infini de fois.


    Note : La classe "DateTimeChooser" ne pose pas de problème. Si je la teste sans l'inclure dans une librairie, le composant qu'elle implémente se comporte bien.

    Je sèche... J'ai vérifié les propriétés du projet "fremawork-testing". En particulier, j'ai vérifié le chemin vers la librairie...

    Avez-vous une idée?

    Merci,

    Denis

    Pour information

    DateTimeChooser.as

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
     
    package components.UIComponents
    {
       import flash.events.Event;
     
       import interfaces.IGhostInterface;
       import interfaces.ISelectorInterface;
     
       import mx.containers.HBox;
       import mx.controls.DateField;
       import mx.controls.NumericStepper;
       import mx.controls.Spacer;
       import mx.controls.Text;
       import mx.events.CalendarLayoutChangeEvent;
       import mx.events.NumericStepperEvent;
     
       /** Cette classe implémente un composant utilisé pour sélectionner une date et une heure.
        */
     
       public class DateTimeChooser extends HBox implements IGhostInterface, ISelectorInterface
       {
          private var __pickerDisplay:Text           = new Text();
          private var __language:String              = new String();
          private var __enabled:Boolean              = new Boolean();
          private var __dateFrom:Date                = null;
          private var __dateTo:Date                  = null;
          private var __datePicker:DateField         = new DateField();
          private var __hourPicker:NumericStepper    = new NumericStepper();
          private var __minutePicker:NumericStepper  = new NumericStepper();
     
          /** Construit un objet de sélection de la date et de l'heure.
           *  @param enabled Cette valeur détermine l'état initial du composant.
           *         Les valeurs possibles sont :
           *         * true 
           *         * false
           *         Par défaut, le composant est actif.
           *  @param fromDate Objet de type "Date". Cet objet représente la date de "début" du calendrier. La sélection est impossible avant cette date.
           *         Par défaut, cette date n'est pas définie.
           *  @param toDate Objet de type "Date". Cet objet représente la date de "fin" du calendrier. La sélection est impossible après cette date.
           *         Par défaut, cette date n'est pas définie.
           *  @param language Cette chaîne de caractères définit la langue utilisée pour l'affichage de la date.
           *         Les valeurs possibles sont :
           *         * french
           *         * english
           *         La langue utilisée par défaut est l'anglais.
           */
     
          public function DateTimeChooser(enabled:Boolean=true, fromDate:Date=null, toDate:Date=null, language:String='english')
          {
             super();
             __language = language;
             __enabled  = enabled;
             __dateFrom = fromDate;
             __dateTo   = toDate;
             __createTimeChooser();
             __datePicker.addEventListener(CalendarLayoutChangeEvent.CHANGE,  __dateUpdated);
             __hourPicker.addEventListener(NumericStepperEvent.CHANGE,        __updateDisplay);
             __minutePicker.addEventListener(NumericStepperEvent.CHANGE,      __updateDisplay);
          }
     
          /** Crée le composant utilisé pour sélectionner une heure.
           */
     
          private function __createTimeChooser():void
          {
             var hourMinuteSeparator:Text      = new Text();
             var pickerDisplaySeparator:Spacer = new Spacer();
     
             // Configuration du calendrier.
             __datePicker.yearNavigationEnabled       = false;
             __datePicker.showToday                   = true;
             if (__language == 'french')
             {
                __datePicker.dayNames   = new Array('D', 'L', 'M', 'M', 'J', 'V', 'S');
                __datePicker.monthNames = new Array('Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre');
             }
             if (! __enabled) { __datePicker.enabled  = false; }
             if (__dateFrom != null) { __datePicker.disabledRanges = [ {rangeEnd: __dateFrom} ]; }
             if (__dateTo   != null) { __datePicker.disabledRanges.push({rangeStart: __dateTo}); }
     
             // Définition des contraintes d'utilisation des sélecteurs numériques.
             __hourPicker.minimum       = 0;
             __hourPicker.maximum       = 23;
             __minutePicker.minimum     = 0;
             __minutePicker.maximum     = 59;
     
             // Séparateur entre le composant de sélection de l'heure et celui de sélection des minutes.
             hourMinuteSeparator.htmlText = "<b>:</b>";
             hourMinuteSeparator.width    = 10;
             hourMinuteSeparator.setStyle("textAlign", "center");
             hourMinuteSeparator.setStyle("fontSize", "12");
     
             // Séparateur entre le composant de sélection des minutes et le panneau d'affichage.
             pickerDisplaySeparator.width         = 0;
             pickerDisplaySeparator.percentHeight = 100;
     
             // Panneau d'affichage.
             __pickerDisplay.width         = 60;
             __pickerDisplay.htmlText      = '<b>00:00</b>';
             __pickerDisplay.setStyle("textAlign", "center");
             __pickerDisplay.setStyle("fontSize", "12");
     
             // Assemblage         
             this.horizontalScrollPolicy = "off";
             this.verticalScrollPolicy   = "off";
             this.setStyle("verticalAlign", "middle");
             this.addChild(__datePicker);
             this.addChild(__hourPicker);
             this.addChild(hourMinuteSeparator);
             this.addChild(__minutePicker);
             this.addChild(pickerDisplaySeparator);
             this.addChild(__pickerDisplay);
     
             trace ('DateTimeChosser() done');
          }
     
          /** Cette méthode rend le composant éligible à la destruction.
           */
     
          public function destroy():void
          {
             __datePicker.removeEventListener(CalendarLayoutChangeEvent.CHANGE, __dateUpdated);
             __hourPicker.removeEventListener(NumericStepperEvent.CHANGE,       __updateDisplay);
             __minutePicker.removeEventListener(NumericStepperEvent.CHANGE,     __updateDisplay);
          }
     
          /** Cette méthode renvoie les valeurs sélectionnées par l'utilisateur.
           *  @return La méthode renvoie un objet qui contient deux propriétés :
           *          * hour
           *          * minute
           */
     
          public function getSelectedValues():Object
          {
             var values:Object = new Object();
             values['hour']   = __hourPicker.value;
             values['minute'] = __minutePicker.value;
             return values;
          }
     
          /** Cette méthode permet d'initialiser un composant de sélection avec des valeurs.
           *  @param inValues Cet objet contient les valeurs utilisées pour l'initialisation du composant.
           *         L'objet passé en argument de la méthode doit contenir les propriétés suivantes :
           *         * hour
           *         * minute 
           */
     
          public function setValues(inValues:Object):void
          {
             __hourPicker.value   = inValues['hour'];
             __minutePicker.value = inValues['minute'];
          }
     
          /** Ce gestionnaire d'évènement est exécuté lorsque la valeur d'un des composants "NumericStepper" change.
           * 
           * @param event Évènement envoyé lorsque la valeur d'un des composants "NumericStepper" change.
           */
     
          private function __updateDisplay(event:Event):void
          {
             __pickerDisplay.htmlText = '<b>' + __numberToValue(__hourPicker.value) + ':' + __numberToValue(__minutePicker.value) + '</b>';
          }
     
          /** Ce gestionnaire d'évènement est exécuté lorsque la valeur du composant "DateField" change.
           * 
           * @param event Évènement envoyé lorsque la valeur du composant "DateField" change.
           */
     
          private function __dateUpdated(event:Event):void
          {
     
          }
     
          /** Retourne une chaîne de caractères qui représente l'heure, ou les minutes, sur deux caractères.
           * 
           * @param n Nombre entier qui représente l'heure ou les minutes.
           */
     
          private function __numberToValue(n:Number):String
          {
             if (n < 10) { return '0' + n.toString(); }
             return n.toString();
          }
       }
    }
    DateTimeChooser.mxml

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
                creationComplete="init()"
                width="100%"
                layout="horizontal">
     
       <mx:Script>
          <![CDATA[
     
             import components.UIComponents.DateTimeChooser;
     
             private var __picker:DateTimeChooser = null;
     
             private function init():void
             {
                trace ('init()');
                __picker = new DateTimeChooser();
                this.addChild(__picker);
             }
     
          ]]>
       </mx:Script>
     
    </mx:Application>
    IGhostInterface

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    package interfaces
    {
    	/** Cette interface définit les composants de type "Ghost".
    	 * Ces composants sont susceptibles d'être détruits au cours de l'utilisation de l'application.
    	 * Ils présentent tous une méthode destinée à libérer les ressources allouées par le composant.
    	 */
     
    	public interface IGhostInterface
    	{
    		/** Cette méthode libère les ressources allouées au composant.
    		 */
     
    		function destroy():void;
    	}
    }
    ISelectorInterface

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    package interfaces
    {
    	/** Cette interface définit les composants de type "Selector".
    	 *  Ce type de composant est utilisé pour sélectionner des valeurs.
    	 *  Il peut aussi être initialisé à des valeurs de départ.
    	 */
     
    	public interface ISelectorInterface
    	{
    		/** Cette méthode renvoie les valeurs sélectionnées par l'utilisateur.
    		 *  L'organisation de l'objet renvoyé dépend de la nature des informations sélectionnées.
    		 */
     
    		function getSelectedValues():Object;
     
    		/** Cette méthode permet d'initialiser un composant de sélection avec des valeurs.
    		 *  @param inValues Cet objet contient les valeurs utilisées pour l'initialisation du composant.
    		 */
     
    		function setValues(inValues:Object):void;
    	}
    }

  2. #2
    Membre Expert
    Avatar de Jim_Nastiq
    Homme Profil pro
    Architecte, Expert Flex
    Inscrit en
    Avril 2006
    Messages
    2 335
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte, Expert Flex
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 2 335
    Par défaut
    Salut,

    framework.swc c'est le nom de la lib pour le framework flex, peut être y'a t'il conflit , tente de nommer plus précisément ta librairie pour commencer.

    dans ton projet framework-testing, ou est situé la librairie framwork.swc ?

    Pensez vraiment à effectuer une recherche avant de poster, ici et sur un moteur de recherche! c'est la moindre des choses
    Pensez au tag

    Mon Blog sur la techno Flex
    Ma page sur Developpez.com

    Jim_Nastiq

  3. #3
    Membre confirmé
    Profil pro
    Développeur informatique
    Inscrit en
    Mars 2008
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2008
    Messages : 80
    Par défaut
    Citation Envoyé par Jim_Nastiq Voir le message
    Salut,

    framework.swc c'est le nom de la lib pour le framework flex, peut être y'a t'il conflit , tente de nommer plus précisément ta librairie pour commencer.

    dans ton projet framework-testing, ou est situé la librairie framwork.swc ?
    Salut,

    Je te remercie pour ta réponse. Tu avais raison, il y a effectivement un conflit dans l'espace des noms :

    La classe associée à l'application "DateTimeChooser.mxml" porte le même nom que la classe associée au composant de sélection de la date (dans la libraire).

    Du coup, les instructions suivantes n'étaient pas interprétées correctement par le compilateur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    import components.UIComponents.DateTimeChooser;
    private var __picker:DateTimeChooser = null;
    ...
    __picker = new  DateTimeChooser();
    Pour le compilateur, l'objet "__picker" est un objet de la classe de l'application elle-même!

    A+

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    793
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Avril 2009
    Messages : 793
    Par défaut
    Je ne suis pas spécialement choqué par le comportement du compilateur dans ce cas. Il donne une priorité plus élevé à l'espace de nom de l'application qu'à celui des composants importés, c'est assez logique.

  5. #5
    Membre confirmé
    Profil pro
    Développeur informatique
    Inscrit en
    Mars 2008
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2008
    Messages : 80
    Par défaut
    Citation Envoyé par jylaxx Voir le message
    Je ne suis pas spécialement choqué par le comportement du compilateur dans ce cas. Il donne une priorité plus élevé à l'espace de nom de l'application qu'à celui des composants importés, c'est assez logique.
    Salut,

    Pour les personnes qui seraient confrontées au même problème, et qui liraient ce document, j'apporte des détails :

    Le compilateur transforme le MXML suivant en ActionScript :

    Fichier DateTimeChooser.mxml

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal">
    </mx:Application>
    Devient :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    package
    {
       import mx.core.Application;
       public class DateTimeChooser extends Application
       { }
    }
    A+

  6. #6
    Membre confirmé
    Profil pro
    Développeur informatique
    Inscrit en
    Mars 2008
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2008
    Messages : 80
    Par défaut
    Salut à tous,

    Je viens de trouver l'origine du problème! C'est subtil!

    Regardez un peu ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    framework
    |-- bin
    |   `-- framework.swc
    `-- src
        |-- components
        |   `-- UIComponents
        |       `-- DateTimeChooser.as
        `-- interfaces
            |-- IGhostInterface.as
            `-- ISelectorInterface.as
    DateTimeChooser.as

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    public class DateTimeChooser extends HBox implements IGhostInterface, ISelectorInterface
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    framework-testing
    |-- html-template
    |   |-- AC_OETags.js
    |   |-- history
    |   |   |-- history.css
    |   |   |-- history.js
    |   |   `-- historyFrame.html
    |   |-- index.template.html
    |   `-- playerProductInstall.swf
    |-- libs
    `-- src
        `-- DateTimeChooser.mxml
    DateTimeChooser.mxml

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
                                    creationComplete="init()"
                                    width="100%"
                                    layout="horizontal">
    
            <mx:Script>
                    <![CDATA[
    
                            import components.UIComponents.DateTimeChooser;
    
                            private var __picker:DateTimeChooser = null;
    
                            private function init():void
                            {
                                    trace ('init()');
                                    __picker = new DateTimeChooser();
                                    this.addChild(__picker);
                            }
    
                    ]]>
            </mx:Script>
    
    </mx:Application>
    Le nom de la classe qui implémente le composant de sélection (DateTimeChooser) de la date est identique à celui de l'application (DateTimeChooser.mxml).

    Le code ci-dessous est récursif!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
                                    creationComplete="init()"
                                    width="100%"
                                    layout="horizontal">
    
            <mx:Script>
                    <![CDATA[
    
                            import components.UIComponents.DateTimeChooser;
    
                            private var __picker:DateTimeChooser = null;
    
                            private function init():void
                            {
                                    trace ('init()');
                                    __picker = new DateTimeChooser();
                                    this.addChild(__picker);
                            }
    
                    ]]>
            </mx:Script>
    
    </mx:Application>
    J'ai renommé l'application MXML :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    framework-testing
    |-- html-template
    |   |-- AC_OETags.js
    |   |-- history
    |   |   |-- history.css
    |   |   |-- history.js
    |   |   `-- historyFrame.html
    |   |-- index.template.html
    |   `-- playerProductInstall.swf
    |-- libs
    `-- src
        `-- DateTimeChooserTester.mxml
    Et le problème est résolu!

    De mon point de vue, il serait souhaitable d'attendre du compilateur qu'il retourne un message d'avertissement. En effet, le symbole "DateTimeChooser" est défini deux fois.

    Le comportement du compilateur semble indiquer que ce dernier possède des règles implicites, mais non signalées, de résolutions des conflits de nommage.

    A+

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Lazarus] Problème étrange avec l'utilisation de la fonction StrToFloat
    Par ovni76 dans le forum Lazarus
    Réponses: 7
    Dernier message: 07/09/2014, 18h01
  2. Réponses: 4
    Dernier message: 06/03/2008, 10h22
  3. Réponses: 1
    Dernier message: 29/11/2007, 14h46
  4. Problème avec l'utilisation de librairies
    Par Aradesh dans le forum MFC
    Réponses: 3
    Dernier message: 01/08/2005, 15h00
  5. Utiliser une librairie graphique
    Par Troopers dans le forum Linux
    Réponses: 6
    Dernier message: 22/08/2003, 11h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo