j'essai à l'instant d'utiliser les composants mx de Flex2 dans un
projet AS3 uniquement (pas de mxml) et je me demande si les composants
mx peuvent être utilisé dans cet environnement ? Pour le moment je
parcours l'aide de flex et je ne vois pas si c'est possible d'utiliser
les composants directement dans le code...
J'ai essayé d'attacher un composant Button pour voir dans une classe
Main :
package
{
import flash.display.Sprite;
import mx.controls.Button;
public class Application extends Sprite
{
public function Application()
{
var bt:Button = new Button() ;
trace(bt) ;
bt.visible = true ;
bt.label = "Envoyer" ;
bt.x = 20 ;
bt.y = 20 ;
this.addChild( bt) ;
trace(bt.width + " : " + bt.height) ;
}
}
}
Déjà je me suis retrouvé confronté à un problème au niveau du
projet contenant l'appel d'un composant mx. En effet, il a fallu que
j'ajoute dans les propriétés de mon projet un path
${FRAMEWORKS}/locale/{locale} ...
ActionScript Buid Path / Library Path / add SWC Folder /
${FRAMEWORKS}/locale/{locale}
Sinon j'ai des problèmes de localisation à la compilation !
Pour le reste j'ai inclus dans mes library les swc playglobal.swf,
utilities.swc, flex.swf, framework.swc et même rpc.swf...
Et quand je compile, j'ai bien l'instance de la classe Button qui est
créée mais je n'ai pas de visuel ! Je ne sais pas comment attacher
les assets du Button ?? Ils ne devraient pas s'attacher tout seul via
le swc ?
Du coup je reviens sur mon idée ... les composants MX ne s'utilisent
que dans du MX ? cela m'étonnerait non ?
Je vais continuer à chercher mais j'ai encore rien lu là dessus....
EKA+ :)
tu appel ta class principale "Application"
et ca c'est pas bon amha
il y a deja une class Application utilisée par Flex2
sinon dans prog_actionscript30.pdf / Display programing / Basics...
ils donnent cet exemple
------------
import flash.display.*;
import flash.text.TextFormat;
import flash.text.TextField;
class TextButtonState extends Sprite {
public var label:TextField;
public function TextButtonState(color:uint, labelText:String) {
label = new TextField();
label.text = labelText;
label.x = 2;
var format:TextFormat = new TextFormat("Verdana");
label.setTextFormat(format);
var buttonWidth:Number = label.textWidth + 10;
var background:Shape = new Shape();
background.graphics.beginFill(color);
background.graphics.lineStyle(1, 0x000000);
background.graphics.drawRoundRect(0, 0, buttonWidth, 18, 4);
addChild(background);
addChild(label);
}
}
------------
Le probleme d'appeler ta class principale Application,
c'est que pour le display FLex2 utilise sa class Application
cf cet entete MXML
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns="view.*"
pageTitle="Recent Reviews"
creationComplete="initApp()">
pris dans les samples
donc si Flex2 deja te permet d'utiliser ta propre class Application,
tu as tout le system d'initialisation du display qui apparemment ne se
fait pas
mais bon pas sur, j ai rien testé :)
zwetan
En fait... je l'ai appelé Application sans réfléchir sur le FCNG
mais c'est pas son nom dans mon code ;) Je voulais juste pas mettre le
nom Vegas lol
Du coup cela change pas grand chose ;)
Dans tous les cas que tu crées une classe Application pour lancer ton
application comme class main .. ou que tu utilises un fichier MXML pour
servir de main à ton application, c'est à mon avis 2 choses
différentes pour au final faire le même truc :) Là je viens de
tester le nom Application et cela marche nickel.
Reste que sur ton exemple au dessus récupérer dans le pdf :
prog_actionscript30.pdf tu as pas un composant du package mx importé
dans un applicatif sans MXML :(
Franchement je me demande si le framework MX n'a pas était conçu
uniquement pour le MXML ? Cela m'étonne... j'ai surement pas encore
pigé tout ce que je voudrais à mon avis.. .je vais devoir regarder de
prêt le contenu des classes du package MX pour voir exactement où est
générer le composant et comment ensuite faire en sorte de l'utiliser
hors MXML context :)
EKA+ :)
Aprés moulte recherche... j'ai trouvé une solution qui utilise très
peu de code MXML et qui laisse ensuite le champ libre pour générer
l'application via des composants MX ou pas d'ailleurs ^_^
Donc, il faut bien créer un projet Flex et ensuite créer une classe
de base dans le framework du projet :
<code>
package test
{
import flash.events.* ;
import mx.core.* ;
import mx.controls.*
import mx.events.FlexEvent
import mx.containers.Canvas;
;
public class MainApp extends Application
{
// ---o Constructor
function MainApp()
{
addEventListener(FlexEvent.APPLICATION_COMPLETE, init) ;
_canvas1 = new Canvas() ;
_canvas1.autoLayout = true ;
_canvas1.width = 540 ;
_canvas1.height = 400 ;
_canvas2 = new Canvas() ;
_canvas2.autoLayout = true ;
_canvas2.width = 540 ;
_canvas2.height = 400 ;
_bt = new Button() ;
_bt.x = 10 ;
_bt.y = 10 ;
_bt.width = 150 ;
_bt.label = "Hello World" ;
_bt.addEventListener(MouseEvent.CLICK, _onClick) ;
_ta = new TextArea() ;
_ta.x = _bt.x + _bt.width + 10 ;
_ta.y = _bt.y ;
_ta.width = 300 ;
_ta.height = 150 ;
}
// ----o Public Methods
public function init(e:Event):void
{
_canvas1.addChild(_bt) ;
_canvas2.addChild(_ta) ;
addChild(_canvas1) ;
}
// ----o Private Properties
private var _canvas1:Canvas ;
private var _canvas2:Canvas ;
private var _bt:Button ;
private var _ta:TextArea ;
// ----o Private Methods
private function _onClick(e:Event):void
{
trace("click : " + e) ;
_ta.htmlText = "<b>" + _bt.label + "</b>" ;
removeChild(_canvas1) ;
addChild(_canvas2) ;
}
}
}
</code>
Et ensuite on fait un petit fichier .mxml qui va lancer l'application :
<?xml version="1.0" encoding="utf-8"?>
<test:MainApp
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:test="test.*"
layout="absolute"
backgroundGradientColors="[#4993b6, #32667e]"
/>
Voilà :)
Donc une classe qui hérite de mx.core.Application... il faut un
événement FlexEvent.APPLICATION_COMPLETE pour attendre que
l'application soit bien attachée sur le root et on peut alors attacher
avec un addChild les composants que l'on veut !
Il ne faut surtout pas essayer de faire de addChild dans le
constructeur...
Sur l'exemple que j'ai mi au dessus, on voit bien qu'il est ensuite
facile de créer des Canvas, etc... et de les afficher un peu comme on
veut selon les besoins.
Je vais surement réfléchir un peu et je ferais un tuto à ce sujet
sur mon blog pour ceux que cela intéresse (pendant le week end)
Si quelqu'un trouve mieux ? (avec aucun fichier .mxml par exemple...)
Je suis preneur :D
EKA+ :)
Tu n'es pas obligé d'utiliser un fichier mxml mais il y a une grosse
contrainte, voici le code :
<xml>
package {
import mx.core.*;
import mx.events.FlexEvent;
import mx.effects.easing.Back;
import mx.skins.halo.HaloBorder;
import mx.containers.Panel;
import mx.skins.halo.TitleBackground;
import mx.controls.Label;
public class TestFlashDocument extends Application
{
public function TestFlashDocument()
{
super();
this.layout = "absolute";
this.setStyle("backgroundColor",0xFF0000);
this.setStyle("borderSkin",mx.skins.halo.HaloBorder);
this.setStyle("borderColor",0xFF0000);
this.setStyle("shadowDirection","center");
this.setStyle("shadowDistance",2);
this.setStyle("borderStyle","solid");
this.setStyle("borderThickness",1);
this.setStyle("cornerRadius",5);
this.setStyle("borderSides","left top right bottom");
this.addEventListener(FlexEvent.APPLICATION_COMPLETE, doInit);
}
private function doInit(e:FlexEvent):void {
}
}
}
</xml>
Et comme tu peux le voir tu es obligé de définir pour tous les
composants que tu utilises leurs styles par defaut. Tu peux obtenir les
styles de chaque composants dans la partie de référence de Flex 2
(les classes) ...
Il doit y avoir quelque part un fichier ou autre qui permet d'attribuer
par defaut tous les styles ... ^^
++
[Embed(source="calvin_malin.jpg")]
private var ImageClass:Class;
...
var img:Image = new Image();
img.setStyle("verticalAlign","top");
img.source = ImageClass;
addChild(img);
Et ca marche nickel ;)
var pnl:Panel = new Panel();
pnl.styleDeclaration = StyleManager.getStyleDeclaration("Panel");
addChild(pnl);
Cela ne marche quand meme pas, j'ai pourtant bien ajouté le chemin du
framework.swc et donc pas celui de defaults.css, je passe donc en ligne
de commande au compilateur ceci :
-defaults-css-url "C:\Program Files\Adobe\Flex Builder 2\Flex SDK
2\frameworks\defaults.css"
Je test et pas possible de recuperer le style d'un composant ... :(
A moins d'avoir raté quelque chose je ne vois pas ...
Oui pas facile d'utiliser du composant mx sans le MXML... je cherche
avant tout une solution rapide pour utiliser les composants sans
utiliser trop le MXML pour "gagner du temps" et faire quelques tests
dessus en attendant de mieux maitriser le MXML. Au final je pense que
c'est tout de même mieux d'utiliser (même de façon minimale) la
compilation MXML avec une page MXML simple (au moins)....
En tout cas c'est clair que Adobe a pri une vraie direction avec ses
composants... Pour ma part si je dois faire des composants je les ferai
à la fois compatible MXML et à la fois compatible AS3 seulement (si
c'est possible... j'ai pas encore vu les limites là dessus, faut
rentrer + dans le code à mon avis pour être certain qu'il n'y aura
pas de problème).
EKA+ :)
package {
import mx.core.*;
import mx.events.FlexEvent;
import mx.effects.easing.Back;
import mx.skins.halo.HaloBorder;
import mx.containers.Panel;
import mx.skins.halo.TitleBackground;
import mx.controls.Label;
public class TestFlashDocument extends Application
{
public function TestFlashDocument()
{
super();
layout = "absolute";
styleDeclaration =
StyleManager.getStyleDeclaration("Application");
addEventListener(FlexEvent.APPLICATION_COMPLETE, doInit);
}
private function doInit(e:FlexEvent):void {
var pnl:Panel = new Panel();
pnl.styleDeclaration =
StyleManager.getStyleDeclaration("Panel");
pnl.title = "Hello";
var lbl:Label = new Label();
lbl.styleDeclaration =
StyleManager.getStyleDeclaration("Label");
lbl.text = "Hello world !";
pnl.addChild(lbl);
addChild(pnl);
}
}
}
je trouve ca assez rapide ... mais avant il faut comme je l'ai dit
resoudre le probleme du fichier globals.css
++
Par contre tu as essayer de faire pareil en partant d'une classe main
qui utilise une instance de Application mais par composition ?
EKA+ :)
Non non, je créer un nouveau projet Actionscript et au lieu que ma
classe hérite de Sprite ou MovieClip elle herite directement de
Application ...
++
Au passage j'ai testé les exemples au dessus, j'ai du rater un truc au
niveau de la compilation surement... car cela marche pas :( J'ai une
grosse erreur de type 1009 car les instances ne s'instancient pas ?
Le code au dessus est complet ? Déjà il manque par exemple le import
sur la classe mx.styles StyleManager ;) Tu as peut être oublié de
mettre un bout de code qui fait clocher l'exemple ?
EKA+ :)
j'ai testé ton projet, iteratif.... et ça marche, mais j'ai un
problème : http://flash.media-box.net/index.php?showtopic=58875
et en passant sur ton projet, je me suis dit que j'allais testé ce
trace...
et bas ça ne marche pas :/
soit :
package {
...
private function doInit(e:FlexEvent):void {
var img:Image = new Image();
img.setStyle("verticalAlign","top");
img.source = ImageClass;
addChild(img);
trace("test");
}
}
}
L'image est bien affichée, mais le trace non. Que faire ?
Pour le moment je te conseille pour te prendre le moins la tête
possible d'utiliser un petit fichier MXML de base minimaliste comme je
le mets au dessus dans mon message du Vendredi 21 juil 2006 à 17:01 :)
Pour ma part.. je compte pas me prendre la tête avec flex pour les
composants mx de Adobe et cela ne me dérange en rien de lancer mon
application sur une base de MXML... :) Je considère qu'il faut trop
bidouiller si l'on veut avoir un code full AS3 sans MXML avec des
composants mx.
EKA+ :)
bref si ton trace marche pas c'est qu'il doit toujours y avoir un
probleme de compilation
---
apres pour avoir une Application Flex avec uniquement du code AS3 (cad
sans MXML)
il faut regarder du coté de:
mx.core.FlexModuleFactory
mx.core.FlexApplicationBootstrap
mx.core.SimpleApplication
pas mal de choses undocumented dont
- [ExcludeClass]
ne liste pas la class dans Flex Builder
en gros si on veut laisser une class en public
mais ne pas y donner acces depuis l'IDE on peut
ce qui veut dire que une lib swc peut avoir plein de classes public
sans qu'on le sache...
- [Frame(factoryClass="mx.core.FlexApplicationBootstrap")]
apparemment crée une instance de la class sur la 1ere frame de
l'appli
et execute son ctor
- la function create() qui reutilise la function info()
/**
* @private
*/
public function info():Object
{
return {};
}
et qui si on cherche un peu plus dans les différence class mx.*
on trouve IFlexModuleFactory
qui documente tout ca :D
/**
* @private
* The IFlexModuleFactory interface represents the contract expected
* for bootstrapping Flex applications and dynamically loaded
* modules.
*
* <p>Calling the <code>info()</code> method is legal immediately
after
* the "complete" event is dispatched.</p>
*
* <p>A well-behaved module will dispatch a "ready" event when
* it is safe to call the <code>create()</code> function.</p>
*/
/**
* The <code>create()</code> method is a factory method that
requests
* an instance of a definition known to the module.
*
* An optional set of parameters may be provided to allow
* building factories that can change what they create based
* on their input.
* Passing <code>null</code> indicates that the default
* definition should be created, if possible.
*
* @param parameters An optional arbitrary parameter block.
*
* @return A created instance, or null.
*/
/**
* The <code>info()</code> method returns a block of key/value
pairs
* holding static data known to the module.
* This method always succeeds, but may return an empty object.
*
* @return An object containing key/value pairs
* Some defaults include:
* fonts: a list of embedded font faces
* rsls: a list of runtime shared libraries
* mixins: a list of classes initialized at startup
*/
ici on voit que il faut attendre le ready event et donc ne surement pas
s'attendre
a avoir acces au code de l'appli des la 1ere frame du SWF
avec le joli bonus bien planqué de derriere les fagots
info()["mixins"]
et ils disent "some default"
fonts, rsls, mixins...
il y en a plus que ca ;)
autre petite info , ce dont on avait parlé avec eka sur le fait
d'obtenir une référence vers le _global, et bien en regardant de un
peu plus pres on voit que
si on a une application "toto_test.as" en AS3
au moment ou flex compile cette appli et bien
on retrouve dans _global la ref a cette appli
cad _global.toto_test
et meme si j'ai pas tout testé encore je parierai
que toutes applications loadées se retrouvent aussi dans le _global
bref, une fois le ready event passé pour l'appli principale et/ou
chaque appli loadée
faire un petit for..in sur la ref _global devrait permettre de lister
toutes les applis du SWF
et pendant qu'on y est il y a aussi plein d'autres metadata
undocumented
[Managed], [RequiresLicense], [RemoteClass], [ClassReference], etc.
et meme si je l'ai pas vu [ExcludeMethod] ou dans le genre doit exister
aussi
car par exemple la class Error est accessible
mais la methode getErrorMessage( id:int ):String
n'est pas documentée du tout
le blem c'est que si elle est public (car en private on ne pourrait pas
l'appelé)
comment que ca se fait qu'elle ne soit pas listée dans les methodes ?
surement un metadata quelquepart
note: Error.getErrorMessage permet d'obtenir les messages d'erreur
runtime du player flash ;)
zwetan
en fait, le problème (évident par la suite mais bon) que je
rencontrais semble être qu'on ne peut pas utiliser de composants flex
2 sans être dans un projet flex....
si je crée un projet as pur, il y a tout le temps une erreur de lien
avec les composants visuels... et je n'arrive à rien
dans tous les cas, ça marche en utilisant un projet flex et non as pur
;)
Comme le montre Zwetan au dessus va falloir encore un peu de temps pour
découvrir tout ce qui est non documenté et qui nous permettra de
réaliser quelquechose d'approchant du travail de Adobe tout en restant
indépendant... En attendant au pire suffit donc d'utiliser seulement
la classe Application :)
EKA+ :)