Arhiva pentru luna Martie, 2008

Mar25th2008

Update de securitate la Adobe Flash Player

Adobe ne-a pregatit un update de securitate la Flash Player. Update-ul trebuie sa rezolve problemele legate de DNS rebinding, cross-domain exploits si cod cross-site.

Odata cu acest update fisierul de socket policy nu mai este optional (asa cum este in 9,0,115,0)

Pentru mult mai multe detalii si a afla daca aplicatia voastra ar putea avea probleme in urma acestui update puteti citi stirea aici.

Mar13th2008

Primul Flex Camp Romania pe 2008 pe 16 aprilie

Logo Flex Camp

Da… ati auzit bine. Pe 16 aprilie 2008 la sediul Adobe Romania (Anchor Plaza, Bdul. Timisoara, nr. 26Z, Bucharest) va avea loc primul Flex Camp Romania din 2008. Ne bucuram de aceasta intalnire si speram ca nici un scaun, din cele 70-80 ce vor fi in sala, sa nu fie gol.

Pentru inregistrare: http://www.eventbrite.com/event/103813509

Mai multe informatii aici si pe myadobe.ro.

Ne vedem acolo!

Mar11th2008

Prima intalnire a grupului

Astazi a fost prima intalnire a grupului. Printre participanti au fost prezenti: Bogdan Dinu (nasu’ grupului), Cristian Ivascu (omul din interior), echipa Flexer (Stelian Crisan, Andrei Ionescu si Virgil Cristea - qBiC), Costin Aldea, Iulia. Daca am uitat pe cineva imi pare rau. Si alte persoane au fost asteptate dar nu au aparut.

S-a discutat ce se va face in continuare, cand si unde va fi urmatoarea intalnire. Cand se va stii sigur ceva referitor la urmatoarea intalnire va vom anunta prin intermediul blog-ului. Am facut primii pasi in a deveni o comunitate mare.Una din deciziile luate a fost alegeare la un interval de 3 luni a pozitiilor membrilor din grup.

Poze de la intalnire:

Bogdan Dinu

bogdan-dinu.jpg

Cristian Ivascu

cristian-ivascu.jpgcristian-ivascu-2.jpg

Costin Aldea

flex-meeting-01-005-copy.jpgflex-meeting-01-011-copy.jpg

Iulia noul webmaster

flex-meeting-01-009-copy.jpg

Echipa Flexer: Stelian Crisan si Virgil Cristea, Andrei Ionescu, Stelian Crisan, Virgil Cristea

flexer-team-1.jpgflexer-team-2.jpgstelian-crisan.jpgvirgil-cristea.jpg

Mar3rd2008

Prima întâlnire a grupului

harta_intalnire.jpgPrima întâlnire a Flex User Group România va avea loc marţi, 11 martie 2008, orele 18.00-20.00 (GMT+2) - moment în care vom instanţia pentru prima dată această clasă. Pentru că este prima dată când grupul nostru se va întâlni, locul întâlnirii (private static var) va fi în faţa clădirii Adobe România, Anchor Plaza, Bd. Timisoara, nr. 26 Z, Bucureşti, sector 6, cod poştal 061331 (langa mall-ul Plaza Romania) urmând să ne îndreptăm ulterior spre un spaţiu ([Bindable] public var) în care să ne cunoaştem. Participarea este liberă (new ArrayCollection), iar eu mi-aş dori să fie şi numeroasă pentru a ne putea plasa hotărât pe harta Adobe a lumii. Ora de încheiere a întâlnirii este opţională şi se va termina când garbage collector-ul va hotărâ să ne strângă pe la casele noastre.

Lăsând gluma la o parte, pe scurt:

ce : prima întâlnire RoFUG

unde : Anchor Plaza, Bd. Timisoara, nr. 26 Z, Bucureşti

când : 11 martie 2008, orele 18.00 (GMT+2)

ce trebuie să faceţi: să veniţi, şi să trimite-ţi înainte un mail la badu [at] badu [punct] ro pentru a confirma participarea.

Ca principal subiect de discuţie, vă rog să vă gândiţi serios la bunătăţile şi neajunsurile pe care Flex le oferă şi mai ales la ce vă doriţi pe viitor de la el.

[Adăugare 7 Martie 2008] : Suntem membri oficiali ai Adobe User Group !

Mar2nd2008

Tutorial IV : Evenimente

Flexibilitate şi asincronicitatea sunt virtuţile pe care programarea orientată pe obiecte şi eveniment le accentuează. Limbajele în care se programează interfeţe grafice dau posibilitatea de a gestiona evenimentele, asemenea sistemelor de operare - programe dirijate de evenimente pe cel puţin două nivele. La cel mai de jos nivel, întreruperile se comportă ca nişte handlere de evenimente hardware, cu procesorul în rol de dispecer. Coordonarea proceselor se face transmiţând către procese utilizator date şi facilitând accesul la întreruperile software. În general, handlerele de eveniment sunt apelate ca răspuns la stimuli externi, spre exemplu mouse-ul sau tastatura. Tot handlerele de evenimente folosesc o coadă a evenimentelor folosind structuri de tipul primul intrat primul ieşit (FIFO) pentru a reţine evenimentele care nu au fost procesate.
Flex nu face excepţie de la regulile de bază ale programării orientate pe obiect şi eveniment, astfel că evenimentele reprezintă o parte esenţială a dezvoltării de aplicaţii. Modelul evenimentelor Flex este bazat pe DOM (Document Object Model) de nivel 3, prin care W3C defineşte o platformă generică şi un sistem de evenimente independent de limbaj ce permite adăugarea handlerelor de eveniment, descrie structura în model arborescent şi defineşte informaţiile contextuale pentru fiecare eveniment (detalii folosite în gestionarea evenimentului respectiv).
Componentele au definite evenimente native care pot fi generate şi totodată ascultă alte evenimente. Într-o aplicaţie Flex, evenimentele sunt gestionate cu ActionScript, scris bineînţeles în tag sau în clasele care sunt instanţiate. Toate controalele şi containerele Flex sunt subclase ale DisplayObject şi sunt dispuse într-o ierarhie de obiecte vizibile cunoscute ca display list. Această listă conţine toate elementele pe care playerul le va desena pe ecran - obiectele dispuse arborescent corespund nodurilor din structura DOM şi sunt parcurse de evenimente generate de player. Atunci când un eveniment este creat, există trei faze pe care Flex le foloseşte pentru a determina dacă există ascultători : faza de capturare, în care playerul verifică fiecare nod începând de la nodul rădăcină până la părintele direct al nodului ţintă pentru a vedea dacă este înregistrat un ascultător pentru a trata evenimentul ; faza ţintă, în care evenimentul este trimis nodului ţintă ; faza bulelor, în care playerul verifică în ordinea inversă fazei de capturare - începe de la părintele direct al nodului ţintă şi sfârşeste la nodul rădăcină, căutând ascultători.
Evenimentele se clasifică astfel: evenimente de sistem, care se propagă atunci când codul este executat şi evenimente propagate de utilizator - care apar în momentul în care utilizatorul interacţionează cu aplicaţia (butoane, elementele formelor, etc). Gestionarea evenimentelor de sistem presupune ascultarea evenimentelor la execuţia codului, fără a fi necesară aşteptarea interacţiunii utilizatorului cu aplicaţia. Trei dintre cele mai importante evenimente de sistem, moştenite de orice obiect care reprezintă o subclasă a UIObject sunt creationComplete, initialize şi show.
Să parcurgem următorul exemplu:

Actionscript:
  1. </mx><mx xmlns:mx="http://www.adobe.com/2006/mxml" creationcomplete="evenimente_txt.text += '\n a apărut evenimentul creationComplete al aplicaţiei'" initialize="evenimente_txt.text += '\n a apărut evenimentul initialize al aplicaţiei'">
  2. </mx><mx title="Gestionarea evenimentelor de sistem">
  3. </mx><mx editable="false" height="100%" width="100%" id="evenimente_txt">
  4. </mx>

Exemplu se foloseşte de evenimentele de sistem creationComplete (atunci când un constructorul unui obiect, subclasă a lui UIObject, şi-a terminat execuţia şi acesta este "desenat" pe ecran) şi de initialize (momentul în care un obiect, subclasă a lui UIObject, şi-a terminat execuţia constructorului, dar obiectul nu este desenat pe ecran). Aceleaşi evenimente pot fi capturate şi pentru componenta Panel:

Actionscript:
  1. <mx title="Gestionarea evenimentelor de sistem">
  2. creationComplete="eveniment_txt.text += ('\n componenta Panel, evenimentul creationComplete ')"
  3. initialize="eveniment_txt.text += ('\n componenta Panel, evenimentul initialize')"&gt;

Exemplul se foloseşte de scrierea codului ActionScript în maniera numită inline, adică nu definim un handler de eveniment care să includă codul ActionScript întrucât operaţiunile pe care le facem sunt simple. În momentul execuţiei codului de mai sus, putem observa că ierarhia evenimentelor de sistem face în aşa fel încât evenimentele aplicaţiei sunt întotdeauna lansate ultimele - logica fiind simplă : aplicaţia este ultima care anunţă evenimentele de sistem, întrucât obiectele pe care le conţine trebuie să anunţe primele aceste evenimente, ele făcând parte din aplicaţie.
Din acest motiv, creationComplete şi initialize ale aplicaţiei, pot fi folosite pentru a întreprinde acţiuni cum ar fi cereri de date către server.
Să ne ocupăm şi de evenimentele care provin din acţiunile utilizatorului, handlerul de eveniment va fi scris în interiorul tag-ului întrucât

Actionscript:
  1. </mx><mx xmlns:mx="http://www.adobe.com/2006/mxml">
  2. </mx><mx title="Gestionarea evenimentelor utilizator">
  3. </mx><mx id="myLabel" text="apăsaţi pe buton!">
  4. </mx><mx>
  5. </mx><mx id="myButton" label="faceţi click!" click="handlerButon()">
  6. </mx><mx label="Legătura 1" click="handlerLinkButton()">
  7. </mx>
  8.  
  9. <mx>
  10. &lt;![CDATA[
  11. private function handlerButon():void {
  12. myLabel.text="Butonul a fost apăsat!";
  13. }
  14. private function handlerLinkButton():void {
  15. myLabel.text = "Legătura 1 a fost accesată!";
  16. }
  17. ]]&gt;
  18. </mx>

După cum se poate observa, fiecare dintre butoane are handler-ul lui de eveniment, care este chemat în momentul în care utilizatorul întreprinde acţiunea de a apăsa butonul stânga al mouse-ului deasupra butonului în cauză. Este de la sine înţeles că putem folosi un handler unificat, să zicem pentru toate butoanele dintr-un panel, iar în funcţie de identificarea acestora să tratăm evenimentele.
Clasa flash.events.Event conţine informaţii despre evenimentul apărut - de fiecare dată când un eveniment apare, clasa generează automat un obiect care conţine informaţii despre eveniment şi care poate fi folosit în handler. Handler-ul trebuie să aibă drept parametru un astfel de obiect făcând astfel posibil să accesăm proprietăţile în cadrul lui. Câteva dintre proprietăţile obiectelor eveniment sunt comune diverselor tipuri de evenimente, aşa cum unele proprietăţi sunt specifice respectivului eveniment.
Proprietăţile comune sunt: type de tip String - conţine numele evenimentului apărut ; target de tip Event - conţine instanţa componentei care a propagat evenimentul ; target.id de tip String - conţine numele instanţei (definit prin proprietatea id) şi care poate fi folosit atunci când definim un handler comun, aşa cum am menţionat anterior.
Parametrul handler-ului poate fi în general obiect al clasei flash.event.Event sau se poate folosi o subclasă specifică evenimentului respectiv, aşa cum sunt MouseEvent şi DataEvent. Reţineţi că pentru a putea folosi aceste subclase, este necesar să le importaţi înainte de folosire : import flash.events.MouseEvent; clasa flash.event.Event este implicit inclusă în aplicaţie, din acest motiv ea nu trebuie importată înainte de folosire.

Vom modifica exemplul de mai sus pentru a folosi cele prezentate, înlocuind eticheta myLabel cu o componentă TextArea (myTA) care să ne permită să vizualizăm detalii despre evenimentul apărut:

Actionscript:
  1. <mx xmlns:mx="http://www.adobe.com/2006/mxml">
  2. </mx><mx title="Gestionarea evenimentelor utilizator">
  3. </mx><mx id="myTA">
  4. </mx><mx>
  5. </mx><mx id="myButton" label="faceţi click!" click="handlerButon(event)">
  6. </mx><mx label="Legătura 1" click="handlerLinkButton(event)">
  7. </mx>
  8.  
  9. <mx>
  10. &lt;![CDATA[
  11. private function handlerButon(e:Event):void {
  12. myTA.text="Butonul a fost apăsat!";
  13. myTA.text+= "\n\n\t Tip eveniment: " + e.type;
  14. myTA.text+= "\n\n\t Ţintă eveniment: " + e.target;
  15. myTA.text+= "\n\n\t ID ţintă: " + e.target.id;
  16. }
  17. private function handlerLinkButton(e:Event):void {
  18. myTA.text = "Legătura 1 a fost accesată!";
  19. myTA.text+= "\n\n\t Tip eveniment: " + e.type;
  20. myTA.text+= "\n\n\t Ţintă eveniment: " + e.target;
  21. myTA.text+= "\n\n\t ID ţintă: " + e.target.id;
  22. }
  23. ]]&gt;
  24. </mx>

Aşa cum am menţionat anterior, putem folosi o subclasă a clasei Event, modificând codul handler-elor după cum urmează:

Actionscript:
  1. <mx>
  2. &lt;![CDATA[
  3. import flash.events.MouseEvent;
  4. private function handlerButon(e:MouseEvent):void {
  5. myTA.text="Butonul a fost apăsat!";
  6. myTA.text+= "\n\n\t Tip eveniment: " + e.type;
  7. myTA.text+= "\n\n\t Ţintă eveniment: " + e.target;
  8. myTA.text+= "\n\n\t ID ţintă: " + e.target.id;
  9. }
  10. private function handlerLinkButton(e:MouseEvent):void {
  11. myTA.text = "Legătura 1 a fost accesată!";
  12. myTA.text+= "\n\n\t Tip eveniment: " + e.type;
  13. myTA.text+= "\n\n\t Ţintă eveniment: " + e.target;
  14. myTA.text+= "\n\n\t ID ţintă: " + e.target.id;
  15. }
  16. ]]&gt;
  17. </mx>

De această dată, am folosit clasa MouseEvent pentru că este strict specifică evenimentelor apărute ca urmare a interacţiunii utilizatorului prin intermediul mouse-ului. Tipurile stricte asigură programatorul că în momentul compilării, proprietăţile care nu fac parte din clasa respectivă vor atrage după sine un mesaj de eroare şi totodată, imbunătăţeşte performanţele aplicaţiei.

Următorul pas pe care îl vom face este acela de a crea un ascultător pentru un anumit eveniment, folosind direct limbajul ActionScript. Obiectelor li se pot "ataşa" ascultători de evenimente folosind metoda addEventListener() care face parte din clasa EventDispatcher. Înregistrarea unui handler pe această cale permite controlul avansat al gestiunii de evenimente, permiţând spre exemplu să gestionăm evenimente pentru mai multe componente (crescând flexibilitatea codului) sau să adăugăm mai mulţi ascultători aceleiaşi componente.
Sintaxa generală pentru a adăuga un ascultător este : numele_instanţei.addEventListener(tipEveniment:String, numeAscultător:Function, foloseşteFazaCapture:Boolean, prioritate:int, referinţăSlabă:Boolean) - în care parametrii sunt tipul evenimentului, numele funcţiei ascultător (chemată atunci când evenimentul pe care-l ascultăm apare), foloseşteFazaCapture arată dacă ascultătorul va intra în acţiune în faza de capturare (descrisă mai sus) sau în faza ţintă/bulelor. Valoarea implicită a acestui parametru este false indicând că ascultătorii funcţionează corect în fazele ţintă şi bulelor - montarea unui ascultător pentru faza de capturare fiind folositoare pentru evenimente de tip low-level, doar atunci când se defineşte o componentă ce gestionează astfel de evenimente.
Parametrul prioritate indică prioritatea pe care o are ascultătorul şi se foloseşte pentru cazul în care montăm mai mulţi ascultători pentru acelaşi eveniment, aceleiaşi componente - stabilind astfel ordinea în care ascultătorii sunt chemaţi în cazul apariţiei evenimentului în cauză. Valoarea implicită este 0. Parametrul referinţăSlabă stabileşte dacă ascultătorul va fi colectat de garbage-collector sau nu (referinţăSlabă, implicit false indică faptul că ascultătorul nu va fi colectat).

Despre garbage-collector, în câteva cuvinte : este acel proces responsabil pentru dealocărea memoriei utilizate de obiecte care nu mai sunt folosite de aplicaţie. Dacă celelalte obiecte active nu au referinţă spre un terţ obiect, acesta din urmă va fi considerat inactiv şi în consecinţă el va ajunge în garbage-collector. O explicaţie mai bună ar fi că atunci când lucrăm cu obiecte ce au tipuri care nu sunt primitive (altele decât Boolean, String, uint, int, Number) vom folosi întotdeauna referinţa către obiecte şi nu obiectele însele - astfel încât atunci când ştergem o "variabilă" de fapt ştergem referinţa către un obiect, nu obiectul în sine. Exemplu:

Actionscript:
  1. // facem o referinţă a unui nou obiect
  2. var referinta:Object = {proprietate:"o valoare"}
  3. // copiem referinţa creată
  4. var copieReferinta:Object = a;
  5. // acum ştergem referinţa
  6. delete(referinta);
  7. // verificăm dacă obiectul este încă referinţă în copia referinţei
  8. trace(copieReferinta.proprietate);

Aşa cum veţi observa, copia referinţei va întoarce valoarea proprietăţii ("o valoare"), ca dovadă a faptului că obiectul pe care prima referinţă îl indica nu a fost şters, chiar dacă referinţa a fost ştearsă. Acest obiect va ajunge în garbage-collector odată ce nu va mai exista nici o referinţă către el.
Este foarte important ca în faza de dezvoltare a unei aplicaţii, programatorul să definească obiectele cât mai inerte cu putinţă, întrucât nu există nici un control asupra garbage-collector-ului, fapt care atrage după sine comportamente nedorite ale aplicaţiei în momentul în care nu există nici o referinţă către un anume obiect. Mai multe informaţii despre strategii de gestiune a resurselor puteţi citi aici (articol în limba engleză).

Revenind la evenimente, să aplicăm ceea ce-am prezentat:

Actionscript:
  1. <mx xmlns:mx="http://www.adobe.com/2006/mxml" creationcomplete="init()">
  2. </mx><mx>
  3. &lt;![CDATA[
  4. // importăm, aşa cum am spus, clasa evenimentului specific
  5. import flash.events.MouseEvent;
  6. private function init():void {
  7. //montăm evenimentul în momentul în care constructorul aplicaţiei şi-a închieat execuţia
  8. //şi aplicaţia a fost desenată
  9. unButton.addEventListener("click",unClickHandler);
  10. //schimbăm eticheta pentru a şti că ascultătorul este montat
  11. unLabel.text = "Ascultătorul este montat!";
  12. }
  13. private function unClickHandler(e:MouseEvent):void {
  14. //handler-ul de eveniment montat la butonul unButton
  15. unLabel.text="Butonul a fost apăsat!";
  16. }
  17. ]]&gt;
  18. </mx>
  19. <mx title="Exemplu montare ascultător">
  20. </mx><mx id="unLabel" text="Priveşte aici...">
  21. </mx><mx id="unButton" label="Execută">
  22. </mx>

După cum se observă cu uşurinţă, prin folosirea metodei addEventListener() s-au separat complet partea VIEW de partea CONTROLLER ale aplicaţiei. Termenii VIEW şi CONTROLLER fac referire la modelul de dezvoltare (design-pattern) MVC : Model-View-Controller. În aplicaţii complexe care lucrează cu cantităţi apreciabile de date, este de preferat să separăm datele (model) de interfaţa cu utilizatorul (view) astfel încât schimbările aduse interfeţei să nu interfereze cu schimbările datelor, totodată reorganizarea datelor să nu afecteze interfaţa. MVC rezolvă această problemă prin separea accesului la date şi logistica organizării datelor de nivelul în care se prezintă datele utilizatorului şi interacţiunea pe care interfaţa trebuie să o asigure, legătura dintre acestea fiind ţinută printr-un intermediar : controller-ul.
Modul în care Flex gestionează modelele de date se bazează pe MVC.

În continuare, vom descrie o clasă ActionScript externă care defineşte metode ce pot funcţiona ca şi ascultători - chiar dacă clasele ActionScript nu se pot comporta ca ascultători, metodele pe care o clasă le defineşte pot fi folosite în acest scop. Este suficient să creăm o clasă simplă, cu un constructor vid dar care importă flash.events.Event şi defineşte metodele pe care le vom folosi pe post de ascultători.

Actionscript:
  1. package ro.flexug.tutorial4{
  2. import flash.events.Event;
  3. import mx.controls.Alert;
  4. public class Ascultator{
  5. public function Ascultator(){
  6. }
  7. public static function metodaHandler(event:Event):void{
  8. Alert.show("Butonul a fost apăsat!");
  9. }
  10. }
  11. }

Considerăm cunoscute toate noţiunile ce sunt necesare pentru declararea pachetului şi clasei în cauză (vezi tutorialul I). Folosindu-ne de codul de mai sus, vom crea aplicaţia bazată pe exemplul anterior:

Actionscript:
  1. <mx xmlns:mx="http://www.adobe.com/2006/mxml" creationcomplete="init()">
  2. </mx><mx>
  3. &lt;![CDATA[
  4. import flash.events.MouseEvent;
  5. import ro.flexug.tutorial4.Ascultator;
  6. private function init():void {
  7. unButton.addEventListener(MouseEvent.CLICK,unClickHandler);
  8. unLabel.text = "Ascultătorul este montat!";
  9. //aici adăugăm ascultătorul bazat pe clasă
  10. unButton.addEventListener(MouseEvent.CLICK,Ascultator.metodaHandler);
  11. }
  12. private function unClickHandler(e:MouseEvent):void {
  13. //handler-ul de eveniment montat la butonul unButton
  14. unLabel.text="Butonul a fost apăsat!";
  15. }
  16. ]]&gt;
  17. </mx>
  18. <mx title="Exemplu montare ascultător">
  19. </mx><mx id="unLabel" text="Priveşte aici...">
  20. </mx><mx id="unButton" label="Execută">
  21. </mx>

Aşadar, avand metodaHandler() definită static aceasta poate fi invocată fără a instanţia clasa în ActionScript.