Arhiva pentru luna Februarie, 2008

Feb29th2008

Tutorial III : Declararea Stilurilor in Flex, CSS

Cerinte

Pentru a putea intelege pe deplin acest tutorial sunt necesare oarecare cunostinte de CSS (cascade style-sheet), Flex, nivel de incepator si, desigur, o minte deschisa si multa vointa.

CSS poate fi descris ca o metoda de a controla modul de prezentare a unui document la nivel de formatare. De aceea, cel mai des va fi folosit pentru a controla modul in care continutul va fi afisat in pagina, stiulurile aplicate, de la tipul fontului pana la marimea ferestrelor si a bordurilor. CSS a fost adoptat in totalitate de Adobe pentru a putea controla o componenta a unei aplicatii, ori a aplicatiei la nivel global.

Majoritatea stilurilor definite intr-o aplicatie flex sunt mostenite de componentele ei, astfel se permite programatorului definirea unor reguli de stil de la cel mai intalt nivel pana la baza. Mai mult decat atat, externalizarea stilurilor ajuta la organizarea dezvoltarii unui proiect, astfel incat programatorul sa se poata ocupa de functionalitate, iar designerul sa se poata ocupa de interfata. Aceste stiluri vor fi continute de toate controalele si ferestrele din containerul principal, facand aplicatia foarte dinamica, respectand totodata principiul mostenirii definit nu numai in standardele CSS, dar si in standardele OOP.

Din nefericire, exista componente care nu pot fi accesate, si care vor trebui definite individual pentru fiecare element in parte. Astfel de caracteristici sunt: inaltimea (height) si latimea(width) care apartin unei clase de baza a componentelor, UIComponent.

Ce metode se folosesc pentru a defini stilurile in Flex?

Flex permite definirea stilurilor in 2 moduri esentiale, folosierea selectoarelor globale din CSS ( si selectorii pe care dorim sa ii definim), si managerul de stiluri pe care actionscript-ul il pune la dispozitie folosind clasa StyleManager, definit in pachetul mx.styles.

Desigur, ca si in XHTML, stilurile pot fi continute in interiorul aplicatiei, ori extern reprezentand in fapt, respectarea standardelor web 2.0.

Compilarea stiulurilor

In Flex sunt mai multe metode de a introduce definitii pentru stiuluri, ca si in CSS, este introdus in cod (inline), extern si incorporat. In acelasi timp e de retinut ca sunt caracteristici comune tuturor tagurilor (spre exemplu, tuturor etichetelor sau tuturor butoanelor unei aplicatii), si caracteristice unice, specifice (care fac referire sa zicem la o anume eticheta sau care definesc o clasa de stil ce poata fi folosita pentru anumite componente). Sa vedem un exemplu in care aplicam stiluri:

Actionscript:
  1. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
  2. <mx:Panel title="Panou personalizat" width="400" height="400">
  3. <mx:Label text="Iata o fraza pe care o putem personaliza in functie de preferinte" />
  4. </mx:Panel>
  5. </mx:Application>

Vom introduce stilul utilizand tagurile :

Actionscript:
  1. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
  2. <strong><mx:Styles></strong>
  3. <strong></mx:Styles></strong>
  4. <mx:Panel title="Panou personalizat" width="400" height="400">
  5. <mx:Label text="Iata o fraza pe care o putem personaliza in functie de preferinte" />
  6. </mx:Panel>
  7. </mx:Application>

In aceste taguri vom introduce proprietatea pe care o definim si valoare acesteia :

Actionscript:
  1. <mx:Style>
  2. <strong>Application {</strong>
  3. <strong>backgroundColor: #CCCCCC;</strong>
  4. <strong>}</strong>
  5. </mx:Style>

Aceasta va fi o proprietatea ce va fi mostenita de toate componente aplicatiei Flex. Iata in schimb o proprietate ce nu va mai fi mostenita:

Actionscript:
  1. <mx:Style>
  2. Application {
  3. backgroundColor: #FFCCFF;
  4. <strong>textDecoration: underline;</strong>
  5. }
  6. </mx:Style>

Proprietatea textDecoration nu va fi mostenita in nici un fel, de-a lungul ierarhiei aplicatiei. Pentru a o mosteni la nivelul tuturor componentelor aplicatiei folosim selectorul global:

Actionscript:
  1. <mx:Style>
  2. global  {
  3. fontFamily:'Trebuchet';
  4. fontSize:14px;
  5. textDecoration: underline;
  6. fontWeight: bold;
  7. fontStyle: italic;
  8. }
  9. Application {
  10. textDecoration: underline;
  11. backgroundColor: #FFCCFF;
  12. }
  13. </mx:Style>

O lista completa a selectorilor pentru fiecare dintre componentele unei aplicatii Flex poate fi vazuta aici.
Folosirea Actionscript pentru a defini stilurile

Un alt mod de a defini selectori globali in interiorul unei aplicatii flex este prin intermediul pachetului mx.styles.StyleManager ce va trebui chemat la inceputul scriptului pentru a putea folosi aceasta clasa.

Cu ajutorul metodei getStyleDeclaration(selector:Style) se va putea identifica proprietatea tipului de interfata pe care il setam (buton, panouri, text, etc). Pentru a putea seta aceasta proprietate ce ne intereseaza, vom utiliza metoda setStyle().

Iata un exemplu de folosire a clasei styleManager.

StyleManager.getStyleDeclaration(global).setStyle(fontSize, 12);

Vom pune accent pe codul folosit pentru a defini aceste caracteristici, introdus in aplicatie in interiorul tagurilor . Iata cum definim caracteristicile globale ale unui panou in flex:

Actionscript:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
  3. <mx:Script>
  4. <![CDATA[
  5. import mx.styles.StyleManager;
  6. private function initiazaStil():void {
  7. // stilul global se va aplica la toate controalele din aplicatie
  8. StyleManager.getStyleDeclaration("global").setStyle("fontSize",12);
  9. StyleManager.getStyleDeclaration("global").setStyle("fontStyle","italic");
  10. StyleManager.getStyleDeclaration("global").setStyle("fontWeight","bold");
  11. StyleManager.getStyleDeclaration("global").setStyle("textDecoration", "underline");
  12. StyleManager.getStyleDeclaration("global").setStyle("fontFamily","Arial");
  13. }
  14. ]]>
  15. </mx:Script>
  16. <mx:Panel title="Folosirea clase styleManager din ActionScript">
  17. <mx:Label text="Tex de incercare a stilurilore globale" />
  18. </mx:Panel>
  19. </mx:Application>

Am definit mai sus functia initiazaStil() care va seta toate proprietatile globale ce ne intereseaza, iar pentru a putea chema aceasta functie ne vom folosi de evenimentul de sistem creationComplete() ce va fi chemat la inceputul aplicatiei. Iata cum vor deveni declaratiile aplicatiei:

Pentru cazul in care vom incarca un stil extern, este necesar sa-l aplicam aplicatiei inainte de initializarea acesteia, dar mai ales va trebui sa suprascriem getter-setter-ul aplicatie pentru ca aceasta sa nu porneasca inainte de aplicarea stilului incarcat.

Iata un exemplu:

Actionscript:
  1. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"  preinitialize="loadStyle()">
  2. private function loadStyle():void {
  3. var eventDispatcher:IEventDispatcher = StyleManager.loadStyleDeclarations("exemplu_tema.swf");
  4. eventDispatcher.addEventListener(StyleEvent.COMPLETE, completeHandler);
  5. }
  6. private function completeHandler(event:StyleEvent):void {
  7. //aici pot fi inserate operatiuni de update la diverse componente, daca sunt necesare spre exemplu,  update-uri de styleName
  8. super.initialized = true;
  9. }
  10.  
  11. override public function set initialized(value:Boolean):void {
  12. // asteapta ca CSS-ul sa fie incarcat
  13. }

Completari
Este de notat ca, in ciuda faptului ca flex a integrat foarte bine CSS-ul, nu toate specificatiile pot fi setate prin intermediul stilurilor globale, ci vor trebui definite pentru fiecare element in parte, atunci cand vor fi create. Este cazul inaltimii si latimii panourilor, elementelor height si width, fiind componente ale clasei UIComponent.
In cele din urma, va trebui sa punctez, ca si in CSS si XHTML, o proprietate CSS care este inline va avea prioritate fata de declaratie ei in functia global sau in aplicatie.

Feb27th2008

Adobe Open Source

Ast?zi (miercuri 27 februarie) Adobe a lansat Adobe Open Source . Dintre proiecte face parte Flex 3 SDK, Blaze, Tamarin, Webkit ?i altele. Participarea este liber? ?i v? pute?i implica.

Feb27th2008

Showcase românesc

Membrii grupului sunt invitaţi să publice în această categorie proiectele dezvoltate de ei. Open source, personal sau comercial, la cheie sau încă în lucru, fiecare proiect dezvoltat de tine este important pentru noi toţi.

Reguli de publicare:

  • proiectul poate suporta critici - dar mai ales laude
  • stadiul şi tipul proiectului să fie primele
  • descrieţi fiecare proiect din punct de vedere funcţional, al tehnologiilor folosite;
  • dacă există colaboratori, menţionaţi acest lucru (... şi designerii vor creditul lor);
  • dacă se poate, adăugaţi timpul efectiv de dezvoltare - estimările altora te pot ajuta şi pe tine;
  • nu vă sfiiţi să adăugaţi poze

Vă aştept să contribuiţi şi la setul de reguli dacă lipseşte ceva.

Feb25th2008

Flex 3 Released

Salutare tuturor,

Adobe s-a gandit sa ne faca o surpriza de luni si a lansat varianta finala de la Flex3 Builder, Flex 3 SDK, AIR.

Mai multe informatii aici.

Cat de curand o sa scriu un scurt articol cu diferentele intre Flex 3 si Flex 2.1

Feb24th2008

Tutorial II: Data Binding

În etapa de dezvoltare a unei aplicaţii Flex, una dintre cele mai importante şi mai des utilizate tehnici este data binding – procesul prin care un obiect ce conţine date este „legat” de o componentă. În acest fel se asigură independenţa operaţiunilor cu date de reactualizarea informaţiilor afişate de componentă – concret, atunci când datele din obiectul legat se schimbă, componenta actualizează informaţiile pe care le afişează din acel obiect, lăsându-i programatorului libertatea de a se concentra exclusiv pe prelucrarea datelor. Data binding în Flex deţine puterea: pe lângă legături între obiecte simple, putem crea şi legături între funcţii şi expresii ActionScript – binding reprezentând „rigidizarea” elementelor „flexibile”.

 

În Flex sunt trei posibilităţi de a crea o astfel de legătură: utilizând acoladele {}, folosind tag-ul <mx:Binding> sau folosind ActionScript şi packet-ul BindingUtils. Nu folosim termenul metodă (în locul lui posibilitate) în mod intenţionat, deoarece prezentarea în contextul programării orientate pe obiecte ne obligă la acest lucru.

Cea mai simplă şi mai utilizată manieră, folosind parantezele acoladă ({}), permite legături rapide între proprietăţile obiectelor, spre exemplu :

<mx:Label id="myLabel" text="Hello World"/>

<mx:Label text="{myLabel.text}" />

După cum puteţi observa, componenta sursă trebuie să aibă o denumire (id=”myLabel”) pentru a-i putea accesa proprietăţile, în cazul nostru proprietatea text – pe care o legăm în componenta destinaţie. Ori de câte ori proprietatea text a componentei sursă myLabel se va schimba şi cea de-a doua componentă (destinaţie) va prelua în proprietatea ei (text) valoarea modificată.

A doua manieră, folosind tag-ul MXML <mx:Binding>, exprimă mult mai clar legătura descrisă mai sus, întrucât proprietăţile tag-ului fac referire directă şi în limbaj natural la sursă, respectiv destinaţie:

<mx:Label id="myLabel" text="Hello World"/>

<mx:Label id=”myLabelDest” text="{myLabel.text}" />

<mx:Binding source=" myLabel.text" destination=" myLabelDest.text"/>

De reţinut că această manieră obligă programatorul să denumească ambele componente pentru a le putea accesa. Ca o informaţie suplimentară, toate componentele sunt denumite automat de către compilator, în cazul în care programatorul a omis să-i atribuie un identificator (id).

Ultima dintre posibilităţi poate fi folosită în ActionScript, utilizând clasa mx.binding.utils.BindingUtils : BindingUtils.bindProperty(myLabel, "text", myLabelDest, "text");

Clasa foloseşte o metodă statică (bindProperty) pentru a crea legătura dintre proprietăţi implementate ca variabile sau o metodă specifică setter-getter-elor (bindSetter) dacă este vorba despre proprietăţi implemetate prin intermediul getter-setter. De reţinut : metodele statice acţionează la nivelul clasei în care este definită, pe când metodele în general acţionează la nivelul instanţei clasei.

 

Să pornim un nou proiect, în care să inserăm un ArrayCollection (care este în fapt, un array complex) :

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

<mx:ArrayCollection id="myAC">

<mx:source>

<mx:Object siteURL="http://www.adobe.com" siteNume="Adobe"/>

<mx:Object siteURL="http://www.google.com" siteNume="Google"/>

<mx:Object siteURL="http://www.yahoo.com" siteNume="Yahoo"/>

<mx:Object siteURL="http://flex.akademia.ro" siteNume="ROFUG"/>

<mx:Object siteURL="http://www.badu.ro" siteNume="Badu"/>

</mx:source>

</mx:ArrayCollection>

</mx:Application>

ArrayCollection-ul nostru conţine obiecte care au fiecare definite proprietăţile siteURL şi siteNume. Vom defini o legătură între ArrayCollection şi o etichetă care afişează numărul de elemente pe care le are acesta. Într-un panel, definim eticheta în cauză:

<mx:Panel title="Tutorial II – DataBinding" width="50%" height="50%">

<mx:Label text="Numărul de elemente definite : {myAC.length}" />

</mx:Panel>

Putem observa cu uşurinţă că pe lângă binding-ul definit de noi între proprietatea length a ArrayCollection-ului, eticheta conţine şi text – proprietatea text a etichetei este compusă din concatenarea rezultatului de binding cu o valoare statică, introdusă de noi, rezultatul rulării aplicaţiei fiind eticheta cu textul „Numărul de elemente definite : 5”.

În acelaşi proiect, vom defini o a doua legătură, utilizând maniera tag MXML : între o nouă etichetă şi primul element al ArrayCollection-ului.

Noua etichetă (definită în tag-ul panel-ului):

<mx:Label id="myLabelDest" text="test" />

şi legătura, definită în tag-ul aplicaţiei (dacă am defini-o în tag-ul panel-ului, ar rezulta eroare):

<mx:Binding source="myAC.getItemAt(0).siteURL" destination="myLabelDest.text"/>

Aşa cum puteţi găsi şi în documentaţie, metoda getItemAt întoarce elementul al cărui index este indicat drept parametru, în cazul nostru fiind vorba despre primul element (numărătoarea elementelor în array-uri începe de la 0). Binding-ul citeşte proprietatea siteURL a primului element al ArrayCollection-ului şi îl leagă de proprietatea text a etichetei nou definite – cu riscul de a repeta, modificarea proprietăţii siteURL a elementului în cauză, atrage după sine modificarea conţinutului proprietăţii text a etichetei.

 

Pentru a ne folosi şi de cea de a treia manieră de a crea legături, vom insera cod ActionScript în proiectul nostru, după cum urmează:

 

<mx:Script>

<![CDATA[

 

import mx.binding.utils.BindingUtils;

 

public function facLegatura ():void{

BindingUtils.bindProperty(my_TI, "text", myAC.getItemAt(0), "siteNume");

}

 

]]>

</mx:Script>

 

Bineînţeles, este necesar să adaugăm în cadrul Panel-ului şi următoarele tag-uri, la care codul ActionScript face referire:

 

<mx:TextInput id="my_TI" text=""/>

<mx:Button label="Legătură" click="facLegatura()" />

 

În linii mari, în momentul în care vom face click pe butonul cu eticheta „Legătură”, invocarea metodei facLegatura crează legătura dintre proprietatea siteNume a primului element al ArrayCollection-ului şi proprietatea text a noului TextInput definit. Puteţi observa că în maniera tag <mx:Binding> am făcut legătura accesând direct proprietatea primului element, pe când în cazul legăturii folosind ActionScript, am indicat sursa ca fiind primul element, indicând conform sintaxei, imediat după sursă proprietatea la care facem referire – siteNume.

 

În concluzie, puteţi observa cu uşurinţă că maniera de declarare folosind <mx:Binding> poate ajuta la separarea clară între interfaţă şi nivelul model (cel care se ocupă cu declararea şi procesarea datelor) şi poate crea legături între diverse surse şi aceeaşi destinaţie. Utilizarea clasei BindingUtils ajută la crearea şi gestionarea de legături, dar care poate fi aplicată oriunde într-un proiect complex.

Maniera pe care o veţi folosi va depinde întotdeauna de situaţie: reţineţi că atunci când urmăriţi obţinerea unui rezultat care întârzie să apară (spre exemplu, aveţi în aplicaţie o eroare pe care n-o puteţi depăşi uşor) puteţi schimba oricând maniera de realizare a legăturilor - data binding-ul a fost creat ca să vă ajute, nu să vă încurce.