Flex/ Flex 3/ Flex 3 para Flex 4/ Flex 4

Flex 3 para Flex 4: AC_OETags vs. SWFObject

Não ocorreram só mudanças na parte do SDK apenas, o Wrapper que envolve o SWF produzido pelo Flash Builder também mudou. Os engenheiros do SDK notaram que é muito complicado manter o formato AC_OETags em diferentes browsers sem ter que alterá-lo. E também mais complicado ainda é adicionar parametros, adicionar variáveis, uma gama de pequenas dificuldades que acabam gerando algum certo tipo de stress seu na hora de publicar seu projeto.

A grande vantagem do SWFObject é que é um projeto mantido pelo Google, Open-source e continua constantemente sendo atualizado a cada 12 meses de ciclo. É um projeto que faz examente a mesma coisa que o AC_OETags faz, porém de forma mais simples.

No Flex 3 para você embedar uma aplicação Flex ou um SWF feito em Flash Builder, você provavelmente teria isso aqui como código gerado.
Read More

Flex/ Flex 3/ Flex 3 para Flex 4

Flex 3 para Flex 4: Scrollers, Alguém tem que usar o scroll

Arrrghh!!! Eu já vi gente xingando o Flex 4 em e-mails, dizendo que não consegue colocar scrolls nos containers, no application. Eu sei, eu entendo suas frustrações, tudo que é novo e difícil de fazer é irritante.
Tenha em mente o seguinte, no Flex 3, tudo que é container tem automaticamente um scroll herdado diretamente na classe, essa técnica é absurdamente fantástica, você não tem a preocupação em ajustar a tela, ela simplesmente acompanha o fluxo e cria um scroll para você, seja ele vertical ou horizontal.
Também no Flex 3 você facilmente habilitava ou desabilitava o scroll dos containers, seja ele qual for.

Por exemplo, veja esse código abaixo onde eu desabilito todas as barras de scroll.

1
2
3
4
5
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
	verticalScrollPolicy="off" horizontalScrollPolicy="off">
 
</mx:Application>

Ai, se você decide que apenas a barra vertical (scroll) seja exibida você faz assim.

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
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="loop()" layout="vertical"  horizontalScrollPolicy="off">
 
<mx:Script>
		<![CDATA[
			import mx.controls.Label;
			import mx.containers.Canvas;
 
				/**
				 * Função apenas para gerar conteúdo para Área de Scroll
				 * */
				private function loop():void
				{
					var i:uint=0;
					for (i;i<99;i+=1){
						var obj:Canvas = new Canvas();
						var lbl:Label = new Label();
						lbl.setStyle('fontSize',20);
						lbl.text = "Panel Color item " + i;
						obj.width = this.width;
						obj.height = 50;
						obj.setStyle('backgroundColor',Math.random()*0xffffff);
						obj.addChild(lbl);
						this.addChild(obj);
					}
				}
 
 
		]]>
</mx:Script>
</mx:Application>

Resultado do código acima.
flex3scroll

Facilmente a famosa barrinha de rolagem vai aparecer apenas na vertical, e você vai conseguir rolar sobre o conteúdo.
Por padrão o scrollPolicy sempre é auto, ou seja, o que vier, agente aguenta e cria uma barrinha de rolagem para te ajudar.

Como é no Flex 4?

No Flex 4 é bem diferente do que você faz no Flex 3. Ao invés de você ter uma barra de rolagem aninhada ao código do container, você simplesmente esquece isso. A arquitetura atual do Flex 4 é baseada em composição.

Composição: Imagine vários blocos de lego, cada um deles é um componente que gera um brinquedo, boneco, castelo, carro que nesse caso são equivalentes a containers, então você compõe cada bloco do lego que é um diferente do outro, em um só componente principal. É assim que tudo funciona. Ou um outro exemplo bem louco é “assista o filme transformers 2”, a hora em que o avião doa peças para Optimus Prime e ele tem mais poderes. A grande sacada de composição é que tudo é plugável e desplugável.

Já que, composição agora é fichinha para você; Voltamos ao assunto. Então tudo no Flex 4 é feito disso, logicamente qualquer container é composto. Por um Group e Skin.
Existem 2 formas de você acrescentar um Scroller à qualquer container, que são:

Por Skin:

O Application possui uma Skin que define essa aparência dele, que está localizado no pacote spark.skins.spark.ApplicationSkin, basta copiar o conteúdo desse skin e criar um novo através do menu do Flash Builder File > New > MXML Skin. Detalhe é que o atual Flash Builder não consegue localizar o ApplicationSkin, então você pode criar qualquer componente Skin, depois remover o conteúdo e colar o conteúdo que você copiou do ApplicationSkin.

ApplicationSkin padrão é assim:

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
<?xml version="1.0" encoding="utf-8"?>
 
<!--
 
ADOBE SYSTEMS INCORPORATED
Copyright 2008 Adobe Systems Incorporated
All Rights Reserved.
 
NOTICE: Adobe permits you to use, modify, and distribute this file
in accordance with the terms of the license agreement accompanying it.
 
-->
 
<!--- The default skin class for the Spark Application component.
 
@see spark.components.Application
 
@langversion 3.0
@playerversion Flash 10
@playerversion AIR 1.5
@productversion Flex 4
-->
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
		xmlns:fb="http://ns.adobe.com/flashbuilder/2009" alpha.disabled="0.5" alpha.disabledWithControlBar="0.5">
 
	<fx:Metadata>
		<![CDATA[
		/**
		* A strongly typed property that references the component to which this skin is applied.
		*/
		[HostComponent("spark.components.Application")]
		]]>
	</fx:Metadata>
 
	<fx:Script fb:purpose="styling">
		<![CDATA[
			/**
			 *  @private
			 */
			override protected function updateDisplayList(unscaledWidth:Number,
														  unscaledHeight:Number) : void
			{
				bgRectFill.color = getStyle('backgroundColor');
				super.updateDisplayList(unscaledWidth, unscaledHeight);
			}
		]]>
	</fx:Script>
 
	<s:states>
		<s:State name="normal" />
		<s:State name="disabled" />
		<s:State name="normalWithControlBar" />
		<s:State name="disabledWithControlBar" />
	</s:states>
 
	<!-- fill -->
	<!---
	A rectangle with a solid color fill that forms the background of the application.
	The color of the fill is set to the Application's backgroundColor property.
	-->
	<s:Rect id="backgroundRect" left="0" right="0" top="0" bottom="0"  >
		<s:fill>
			<!--- @private -->
			<s:SolidColor id="bgRectFill" color="#FFFFFF"/>
		</s:fill>
	</s:Rect>
 
	<s:Group left="0" right="0" top="0" bottom="0">
		<s:layout>
			<s:VerticalLayout gap="0" horizontalAlign="justify" />
		</s:layout>
 
		<!---
		@private
		Application Control Bar
		-->
		<s:Group id="topGroup" minWidth="0" minHeight="0"
				 includeIn="normalWithControlBar, disabledWithControlBar" >
 
			<!-- layer 0: control bar highlight -->
			<s:Rect left="0" right="0" top="0" bottom="1" >
				<s:stroke>
					<s:LinearGradientStroke rotation="90" weight="1">
						<s:GradientEntry color="0xFFFFFF" />
						<s:GradientEntry color="0xD8D8D8" />
					</s:LinearGradientStroke>
				</s:stroke>
			</s:Rect>
 
			<!-- layer 1: control bar fill -->
			<s:Rect left="1" right="1" top="1" bottom="2" >
				<s:fill>
					<s:LinearGradient rotation="90">
						<s:GradientEntry color="0xEDEDED" />
						<s:GradientEntry color="0xCDCDCD" />
					</s:LinearGradient>
				</s:fill>
			</s:Rect>
 
			<!-- layer 2: control bar divider line -->
			<s:Rect left="0" right="0" bottom="0" height="1" alpha="0.55">
				<s:fill>
					<s:SolidColor color="0x000000" />
				</s:fill>
			</s:Rect>
 
			<!-- layer 3: control bar -->
			<!--- @copy spark.components.Application#controlBarGroup -->
			<s:Group id="controlBarGroup" left="0" right="0" top="1" bottom="1" minWidth="0" minHeight="0">
				<s:layout>
					<s:HorizontalLayout paddingLeft="10" paddingRight="10" paddingTop="7" paddingBottom="7" gap="10" />
				</s:layout>
			</s:Group>
		</s:Group>
 
		<!--- @copy spark.components.SkinnableContainer#contentGroup -->
		<s:Group id="contentGroup" width="100%" height="100%" minWidth="0" minHeight="0" />
	</s:Group>
</s:Skin>

Veja que logo aqui, no finalzinho existe, um componente Group chamado contentGroup. É ai que o conteúdo do Application fica guardado, então claro vamos aplicar um Scroll nesse camarada, o que resulta no seguinte conteúdo.

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
<?xml version="1.0" encoding="utf-8"?>
 
<!--
 
ADOBE SYSTEMS INCORPORATED
Copyright 2008 Adobe Systems Incorporated
All Rights Reserved.
 
NOTICE: Adobe permits you to use, modify, and distribute this file
in accordance with the terms of the license agreement accompanying it.
 
-->
 
<!--- The default skin class for the Spark Application component.
 
@see spark.components.Application
 
@langversion 3.0
@playerversion Flash 10
@playerversion AIR 1.5
@productversion Flex 4
-->
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
		xmlns:fb="http://ns.adobe.com/flashbuilder/2009" alpha.disabled="0.5" alpha.disabledWithControlBar="0.5">
 
	<fx:Metadata>
		<![CDATA[
		/**
		* A strongly typed property that references the component to which this skin is applied.
		*/
		[HostComponent("spark.components.Application")]
		]]>
	</fx:Metadata>
 
	<fx:Script fb:purpose="styling">
		<![CDATA[
			/**
			 *  @private
			 */
			override protected function updateDisplayList(unscaledWidth:Number,
														  unscaledHeight:Number) : void
			{
				bgRectFill.color = getStyle('backgroundColor');
				super.updateDisplayList(unscaledWidth, unscaledHeight);
			}
		]]>
	</fx:Script>
 
	<s:states>
		<s:State name="normal" />
		<s:State name="disabled" />
		<s:State name="normalWithControlBar" />
		<s:State name="disabledWithControlBar" />
	</s:states>
 
	<!-- fill -->
	<!---
	A rectangle with a solid color fill that forms the background of the application.
	The color of the fill is set to the Application's backgroundColor property.
	-->
	<s:Rect id="backgroundRect" left="0" right="0" top="0" bottom="0"  >
		<s:fill>
			<!--- @private -->
			<s:SolidColor id="bgRectFill" color="#FFFFFF"/>
		</s:fill>
	</s:Rect>
 
	<s:Group left="0" right="0" top="0" bottom="0">
		<s:layout>
			<s:VerticalLayout gap="0" horizontalAlign="justify" />
		</s:layout>
 
		<!---
		@private
		Application Control Bar
		-->
		<s:Group id="topGroup" minWidth="0" minHeight="0"
				 includeIn="normalWithControlBar, disabledWithControlBar" >
 
			<!-- layer 0: control bar highlight -->
			<s:Rect left="0" right="0" top="0" bottom="1" >
				<s:stroke>
					<s:LinearGradientStroke rotation="90" weight="1">
						<s:GradientEntry color="0xFFFFFF" />
						<s:GradientEntry color="0xD8D8D8" />
					</s:LinearGradientStroke>
				</s:stroke>
			</s:Rect>
 
			<!-- layer 1: control bar fill -->
			<s:Rect left="1" right="1" top="1" bottom="2" >
				<s:fill>
					<s:LinearGradient rotation="90">
						<s:GradientEntry color="0xEDEDED" />
						<s:GradientEntry color="0xCDCDCD" />
					</s:LinearGradient>
				</s:fill>
			</s:Rect>
 
			<!-- layer 2: control bar divider line -->
			<s:Rect left="0" right="0" bottom="0" height="1" alpha="0.55">
				<s:fill>
					<s:SolidColor color="0x000000" />
				</s:fill>
			</s:Rect>
 
			<!-- layer 3: control bar -->
			<!--- @copy spark.components.Application#controlBarGroup -->
			<s:Group id="controlBarGroup" left="0" right="0" top="1" bottom="1" minWidth="0" minHeight="0">
				<s:layout>
					<s:HorizontalLayout paddingLeft="10" paddingRight="10" paddingTop="7" paddingBottom="7" gap="10" />
				</s:layout>
			</s:Group>
		</s:Group>
 
		<s:Scroller  id="scroller" width="100%" height="100%" hasFocusableChildren="true" horizontalScrollPolicy="off">
		<!--- @copy spark.components.SkinnableContainer#contentGroup -->
		<s:Group id="contentGroup" width="100%" height="100%" minWidth="0" minHeight="0" />
		</s:Scroller>
	</s:Group>
</s:Skin>

Seto a largura e altura em 100% e habilio o hasFocusableChildren para true,fazendo ele não perder o foco no objeto quando estiver navegando. E por último eu desabilito o scroll horizontalmente.

Uffa, feito o Skin, como eu aplico agora no Application ?

Lá no Application é super simples, através da propriedade de registro skinClass você apresenta o diretório e o arquivo de Skin que você criou. Desse jeito aqui.

1
2
<?xml version="1.0" encoding="utf-8"?>
<s:Application skinClass="com.riacycle.skins.ScrollerSkin" xmlns:fx="http://ns.adobe.com/mxml/2009"

Nesse meu caso eu criei um Path com o nome “com.riacycle.skins”, onde guardo meus Skins personalizados. O resto agora é lenda, basta repetir o código do Flex 3 no Flex 4, atento apenas as mudanças que você já sabe, ficando o código da Aplicação dessa maneira.

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
<?xml version="1.0" encoding="utf-8"?>
<s:Application skinClass="com.riacycle.skins.ScrollerSkin" xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" creationComplete="loop()" >
	<fx:Declarations>
		<!-- Place non-visual elements (e.g., services, value objects) here -->
	</fx:Declarations>
 
 
	<s:layout>
		<s:VerticalLayout/>
	</s:layout>
		<fx:Script>
		<![CDATA[
			import com.riacycle.skins.ScrollerSkin;
 
			import mx.containers.Canvas;
 
			import spark.components.Label;
			import spark.skins.spark.ApplicationSkin;
				/**
				 * Função apenas para gerar conteúdo para Área de Scroll
				 * */
				private function loop():void
				{
					var i:uint=0;
					for (i;i<99;i+=1){
						var obj:Canvas = new Canvas();
						var lbl:Label = new Label();
						lbl.setStyle('fontSize',20);
						lbl.text = "Panel Color item " + i;
						obj.width = this.width;
						obj.height = 50;
						obj.setStyle('backgroundColor',Math.random()*0xffffff);
						obj.addElement(lbl);
						this.addElement(obj);
					}
				}
 
 
		]]>
	</fx:Script>
</s:Application>

Assim, você pode ter essa maneira simples, usando Skin, ou se você quer eliminar o uso do Skin, você simplesmente cria um Group e um Scroll que o abrace para gerar o mesmo comportamento.
Ficando o código assim:

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
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="995" minHeight="600" creationComplete="loop()"  width="100%" height="100%">
	<fx:Declarations>
		<!-- Place non-visual elements (e.g., services, value objects) here -->
	</fx:Declarations>
 
	<fx:Script>
		<![CDATA[
			import com.riacycle.skins.ScrollerSkin;
 
			import mx.containers.Canvas;
 
			import spark.components.Label;
			import spark.skins.spark.ApplicationSkin;
			/**
			 * Função apenas para gerar conteúdo para Área de Scroll
			 * */
			private function loop():void
			{
				var i:uint=0;
				for (i;i<99;i+=1){
					var obj:Canvas = new Canvas();
					var lbl:Label = new Label();
					lbl.setStyle('fontSize',20);
					lbl.text = "Panel Color item " + i;
					obj.width = this.width;
					obj.height = 50;
					obj.setStyle('backgroundColor',Math.random()*0xffffff);
					obj.addElement(lbl);
					grupo.addElement(obj);
				}
			}
 
 
		]]>
	</fx:Script>
	<s:Scroller width="100%" height="100%">
		<s:Group id="grupo" height="100%">
			<s:layout>
				<s:VerticalLayout/>
			</s:layout>
		</s:Group>
	</s:Scroller>
</s:Application>

Super simples, tem mais coisa que gostaria de falar sobre Scrolls, mais eu deixo para um outro post mais específico.

Flex/ Flex 3/ Flex 3 para Flex 4/ Flex 3 SDK/ Flex 4

Flex 3 para Flex 4: Namespaces

Houve uma grande polêmica quando estavam fazendo o novo Flex 4 à mais ou menos 1 ano atrás. Quando estavam falando dos novos namespaces e prefixos. Melhorou um pouco do que eles haviam criado devido a comunidade de desenvolvedores reclamarem por causa do problema, eles voltaram atrás e fizeram direito.

No Flex 3 você tem apenas 1 namespace original para criar aplicações Flex, que é:

1
xmlns:mx="http://www.adobe.com/2006/mxml"

Ele define tudo que seu aplicativo precisa para acessar componentes e classes originais do Framework em seu todo.
Só que agora é que vem um grande diferencial do que você estava acostumado a fazer no Flex 3 para o Flex 4. No Flex 4 tudo mudou, temos agora um namespace para cada parte do SDK, isso se da ao fato que temos agora uma nova forma de criar interfaces no Flex 4, através de Skins e o Flash Catalyst é um grande influenciador nesse sentido, além dos seus próprios namespaces o SDK do Flex 4 em sí, vem com vários namespaces pré-definidos, então para não prolongar mais e mais, focarei apenas no SDK.

No Flex 4 temos os seguintes namespaces:

1
2
3
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"

Tais namespaces representam cada parte do SDK por completo, os novos componentes do Flex 4 ficam no namespace com prefixo S, e os elementos core do SDK ficam no prefixo FX. Já os conhecidos componentes do Flex 3 continuaram no pacote de prefixo mx.

Cada namespace tem suas próprias propriedades, estilos, efeitos e vez ou outra você pode ficar empacado em achar que funciona no Flex 4, muito cuidado nesse aspecto por que mudou muita coisa mesmo para componentes do Flex 3 funcionarem perfeitamente no Flex 4.

Então uma aplicação típica no Flex 3 ficaria assim:

1
2
3
4
5
6
7
8
9
10
< ?xml version="1.0" encoding="utf-8"?>
<mx :Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" >
 
 
	</mx><mx :Script>
		< ![CDATA[
 
 
		]]>
	</mx>

No Flex 4 uma típica aplicação ficaria assim:

1
2
3
4
5
6
7
8
9
10
11
12
13
< ?xml version="1.0" encoding="utf-8"?>
<s :Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
	<fx :Declarations>
	</fx>
 
	<fx :Script>
		< ![CDATA[
 
		]]>
	</fx>
</s>
Flex/ Flex 3/ Flex 3 para Flex 4/ Flex 4

Flex 3 para Flex 4 : Escopo do aplicativo

Uma das caracteristicas de frameworks RAD (Rapid Application Development) é a fácil abstração da API. Você deve ter em seu aplicativo Flex 2/3 de pequeno e médio porte muito uso do parentApplication, parentDocument, outerDocument. Esse mecanismo ajuda você acessar propriedades já existentes no Application principal e compartilhar métodos entre componentes, fazendo assim uma representação meia boca de interface.

Então você estava acostumado a fazer assim no Flex 3:

parentApplication:

Application principal

1
2
3
4
5
6
7
8
9
10
11
12
13
< ?xml version="1.0" encoding="utf-8"?>
<mx :Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:ns1="*">
 
 
	</mx><mx :Script>
		< ![CDATA[
 
 
			public var VALOR_DECLARADO:String = "Oba Flex 3/4";
		]]>
	</mx>
	<ns1 :Teste x="120" y="38">
	</ns1>

E nos componentes você acessar a variável VALOR_DECLADO dessa forma:

Componente acessando a variável:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
< ?xml version="1.0" encoding="utf-8"?>
<mx :Panel creationComplete="teste()" xmlns="*" xmlns:mx="http://www.adobe.com/2006/mxml" width="196" height="244">
 
 
	</mx><mx :Script>
		< ![CDATA[
			import mx.core.Application;
 
			private function teste():void
			{
				this.title = parentApplication.VALOR_DECLARADO;
			}
 
		]]>
	</mx>

Você pode acessar tudo que quiser, desde que os métodos no Application principal esteja público.

No Flex 4, como temos 2 tipos de Application, seja ele mx.core.Application ou spark.core.Application, eles mudaram esse acesso, passando de uma forma simples de parentApplication para um singleton (topLevelApplication), onde você pode acessar da mesma forma que você usava, só que agora usando a classe reservada para isso FlexGlobals.

Então o mesmo exemplo no Flex 4 você teria isso aqui:

Application

1
2
3
4
5
6
7
8
9
10
11
12
13
< ?xml version="1.0" encoding="utf-8"?>
<s :Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
	<fx :Declarations>
	</fx>
 
	<fx :Script>
		< ![CDATA[
				public var VALOR_FLEX_4:String = "Ola Flex 4";
		]]>
	</fx>
</s>

Componente acessando a variável VALOR_FLEX_4:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
< ?xml version="1.0" encoding="utf-8"?>
<s :Panel xmlns:fx="http://ns.adobe.com/mxml/2009"
		 xmlns:s="library://ns.adobe.com/flex/spark"
		 xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300" creationComplete="panel1_creationCompleteHandler(event)">
	<fx :Declarations>
		<!-- Place non-visual elements (e.g., services, value objects) here -->
	</fx>
 
	<fx :Script>
		< ![CDATA[
			import mx.core.FlexGlobals;
			import mx.events.FlexEvent;
 
 
 
			protected function panel1_creationCompleteHandler(event:FlexEvent):void
			{
				this.title = FlexGlobals.topLevelApplication.VALOR_FLEX_4;
			}
 
		]]>
	</fx>
</s>

O parentDocument continua a mesma coisa, então você não encontrará problemas relacionado a isso em seu processo de migração para o Flex 4. Saiba mais dicas aqui na documentação oficial.

AIR 2.0/ Flash Player/ Flex/ Flex 3

Capturando erros no seu aplicativo RIA no FP 10.1 e AIR 2.0

É tão bom quando você tem alguns minutos livres durante a semana para escrever alguma coisa no blog, que ultimamente tem sido tão deixado de lado!
Uma das grandes novidades do Flash Player 10.1 é a possibilidade de capturar todos os erros gerados pela sua aplicação RIA.
Comumente, desenvolvedores e inclusive nós, tinhamos o hábito de capturar os erros apenas comuns em uma aplicação, por exemplo: IOError, Load Errors, Event Erros, Converter Errors, porém querendo ou não acaba escapolindo do nosso controle uns errinhos como 1009,1056,2048 etc. Esses erros é de tirar o fôlego quando se trata de experiência do usuário, e principalmente quando se tem vários deles.

Infelizmente, isso já era para estar pronto desde a versão 9. Como não tinha, faziamos isso como comentei acima. O que, torna uma tarefa repetitiva e acaba virando um saco fazer sempre aquilo, embora você tente ao máximo re-utilizar seu código.

Contudo, para a grande saúde mental de desenvolvedores, a Adobe decidiu criar esse tipo de captura, dando ao desenvolvedor a oportunidade de verificar quais erros estavam ou estão sendo gerados tanto em backgrounds não mostrados no Stacker ou mostrados.

Nem tudo é um mar de rosas, esse tipo de captura de evento só funciona se seu navegador estiver com o Flash Player do tipo debug, inclusive acaba ficando disponivel apenas para usuarios desenvolvedores, impossibilitando assim você de logar automaticamente um erro e captura-lo e adiciona-lo a uma base de análise, que é comumente feito em sistemas enterprise.

Como era feito a captura de erros até então no Flash Player 9 e 10:

Geralmente como nossos requisitos sempre são simples, nada tão complexo, preferimos usar não a classe padrão de Log de erro do SDK do Flex, por que é além do que agente precisa, e como também existem outras ferramentas e frameworks no mercado para log de erros.

A classe LogManager ela adiciona os erros a um arrayCollection:

package com.igorcosta.debug
{
	import mx.collections.ArrayCollection;
 
	public class LogManager
	{
		[Bindable]private static var _arrError:ArrayCollection = new ArrayCollection();
 
 
		public static function get errors():ArrayCollection
		{
			return _arrError;
		}
		public function LogManager()
		{
 
		}
 
		public static function addError(error:LogError):void
		{
				_arrError.addItem(error);
		}
 
	}
}

E a classe que agente costuma chamar de LogError, nada mais é que um VO/DTO, etc:

package com.igorcosta.debug
{
 
	public class LogError
	{
		public function LogError()
		{
		}
		public var stack:String;
		public var name:String;
		public var ID:String;
		public var message:String;
	}
}

Ai para usarmos em um simples teste de erro, veja o aplicativo que fizemos para esse post. Acho que vai ajudar vocês a melhor enxergar como é penoso o trabalho de capturar os eventos.

< ?xml version="1.0" encoding="utf-8"?>
<application xmlns="http://www.adobe.com/2006/mxml" layout="vertical">
 
 
	<script>
		< ![CDATA[
			import mx.controls.Label;
			import com.igorcosta.debug.LogManager;
			import mx.utils.ObjectUtil;
			import com.igorcosta.debug.LogError;
 
 
 
			public var err:LogError;
 
			public function provocarErro(tipo:uint):void
			{
				switch(tipo){
 
						case 1:
 
							try{
								throw new IOError("I/O Error, de leitura ou escrita");
							}catch(erro:IOError){
									err = new LogError();
									err.stack = erro.getStackTrace();
									err.message = erro.message;
									err.ID = String(erro.errorID);
									err.name = erro.name;
									LogManager.addError(err);
							}
							break;
					   case 2:
					   		try{
					   			var temp:Label;
					   			temp.text = 'test';
					   		}catch(erro:Error){
					   				err = new LogError();
					   				err.stack = erro.getStackTrace();
									err.message = erro.message;
									err.ID = String(erro.errorID);
									err.name = erro.name;
									LogManager.addError(err);
 
					   		}
					   break;
					   case 3:
					   		try{
					   				stackTest();
					   		}catch(erro:Error){
					   				err = new LogError();
					   				err.stack = erro.getStackTrace();
									err.message = erro.message;
									err.ID = String(erro.errorID);
									err.name = erro.name;
									LogManager.addError(err);
 
					   		}
				}
			}
			private function stackTest():void
			{
					stackTest();//loop de funcao da um erro de StackOverflow
			}
		]]>
	</script>
 
 
	<hbox width="100%">
		<button label="Provocar erro 1009" click="provocarErro(2)"/>
		<button label="Provocar erro IO" click=" provocarErro(1)"/>
		<button label="Provocar erro Stack Overflow" click=" provocarErro(3)"/>
	</hbox>
	<datagrid dataProvider="{LogManager.errors}" x="103" y="160" width="743" height="308">
		<columns>
			<datagridcolumn headerText="Nome do Erro" dataField="stack"/>
			<datagridcolumn headerText="Nome do Erro" dataField="name"/>
			<datagridcolumn headerText="Mensagem de erro" dataField="message"/>
			<datagridcolumn headerText="ID do erro" dataField="ID"/>
		</columns>
	</datagrid>
 
</application>

Capturando erros gerais ou “Global Error handler” no Flash Player 10.1 e AIR 2.0:

Agora usando o mesmo aplicativo, podemos capturar qualquer tipo de erro gerado pelo Flash Player, ou mau uso do código. Um detalhe é que o novo recurso do Flash Player o Uncaught Error e Uncaught Error Event, são passíveis de receber qualquer erro ocorrido no swf compilado. Veja o exemplo abaixo:

< ?xml version="1.0" encoding="utf-8"?>
<mx :Application xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="completou()" layout="vertical">
 
    </mx><mx :Script>
        < ![CDATA[
        	import mx.controls.Label;
        	import com.igorcosta.debug.LogError;
        	import com.igorcosta.debug.LogManager;
            private function completou():void
            {
                loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, capturarErros);
            }
 
            private function capturarErros(e:UncaughtErrorEvent):void
            {
 
	        	if(e.error is Error){
 
	        		Error(e.error).getStackTrace();
	            	LogManager.addError(e.error as Error);
	         	}
	         	if(e.error is ErrorEvent){
	         		LogManager.addErrorEvent(e.error as ErrorEvent);
	         	}
 
            }
 
             private function identifica(e:MouseEvent):void
            {
 
                var minhaVar:Label;
                try
                {
                   minhaVar.text = " Ola Mundo" ;
                }
                catch (e:Error)
                {
                  // capturou o erro
                  minhaVar as Boolean;
                  trace(minhaVar.text);
                }
            }
        ]]>
    </mx>
     <mx :HBox width="100%" >
     <mx :Button label="Causar erro de  acesso indefinido" click="identifica(event);"/>
    </mx>
 
 
 
 
	<mx :DataGrid width="100%" dataProvider="{LogManager.errors}" x="29" y="182">
		</mx><mx :columns>
			<mx :DataGridColumn headerText="ID do Erro" dataField="errorID"/>
			<mx :DataGridColumn headerText="Nome do erro" dataField="name"/>
			<mx :DataGridColumn headerText="Mensagem de erro" dataField="message"/>
		</mx>

Lembrando que para você usar em seu projeto esse recurso do UncaughtError e UncaughtErrorEvent, você precisa ter o playerglobal.swc do Flash player 10.1, tanto para o Flash Player quanto para o AIR 2.0.

Os códigos fontes de ambos os aplicativos vocês podem baixar diretamente aqui.

Comunidade/ Dicas/ Flex/ Flex 3/ Flex 4/ Flex Componentes/ Notícias

Tour de Flex aprenda por diversos exemplos

Particularmente nós acreditamos que o caminho mais curto de se aprender um conceito é vendo por exemplos.
E quando você se depara com uma documentação completamente técnica e nenhum exemplo vivo disso, chega a dar preguiça e acaba nem se quer terminando de ler o que havia começado.
Isso tem acontecido muito até a versão 3.0 do SDK do Flex, porém notamos uma ligeira mudança na maneira da equipe responsável pela documentação ver isso com outros olhos. Quem já anda lendo como nós a documentação do Flex 4, percebe que o conteúdo da linguagem de referência do Flex 4 possui uma quantidade extra de exemplos o que torna o aprendizado mais fácil.
Tornando o aprendizado mais fácil por meio de exemplos é o que o Tour de Flex promete, ele ajuda você a encurtar seu caminho no aprendizado e adotar mais rápido alguns exemplos e técnicas não apenas com o SDK do Flex, mas inclui exemplos de outros projetos open-sources e integração com terceiros.

Atualmente o Tour de Flex possui mais de 200 exemplos, os quais fica fácil aprender. Quem não lembra quando lançamos em 2006 os “40 projetos open-source”, explorando os recursos do SDK do Flex 2? Só no link direto foram mais de 2.400 downloads, o que nos faz pensar que realmente por exemplo o conceito aprende-se muito mais rápido.

É por isso que a partir de hoje, vamos colocar o badge para quem estiver visitando o blog, conhecer o projeto Tour de Flex e ir explorando os recursos do Flex 3.0 e já com alguns exemplos do Flex 4.0.

Actionscript Frameworks/ AS 3.0/ Eventos/ Flex/ Flex 3/ Flex 3 SDK/ RIA/ Sexta-Flex Talkshow

Gravação da palestra – "Advanced data visualization" disponível

Quem compareceu ao último sextaflex não pode reclamar, foi excelente o evento e o Michel Vandaniker mandou ver no Axiis para todos os 18 participantes ao total presente no evento on-line.
Caso você por algum motivo que seja perdeu e quer acessar, você pode acessar o link da gavação abaixo.

http://experts.na3.acrobat.com/p38851909/

Obrigado a todos que compareceram.

Nesta semana dia 16/10 não haverá sextaflex por motivo de força maior. Não somos muito de reclamar das coisas, mais tem sido bem corrido, em resumo todo mundo decidiu usar Flex de uma única vez e nesse final de ano.

Na próxima semana já temos engatado mais 1 palestrante nacional e vai falar de seus cases e você vai conhecer novas empresas que produzem RIA com qualidade. Queremos mostrar e dar vitrine para todas as minúsculas até as golias das empresas Brasileiras o espaço para ir falando de suas dificuldades e sucessos com a escolha do Flex. Afinal Flex não é só flores.

AS 3.0/ Flex/ Flex 3/ Flex 3 Open-Source/ Flex 3 SDK/ Flex Componentes/ Flex Hacks

Como posicionar o Alert nos valores x e y que eu queira?

Com as mesmas palavras recebidas no título do e-mail enviado pelo Carlos Brandão sobre suas dificuldades em posicionar o componente Alert, escrevemos o título deste post.
Sem dúvidas é um problema simples, antigo e de fácil resolução. Porém muitos desenvolvedores acabam no final achando mais cômodo colocar o Alert em sua posição original, no centro da tela.

Em via das dúvidas, o mais correto seria imitar o Delphi, C#, Swing. Em deixar o desenvolvedor alertar alguma mensagem na posição que ele queira; Já que nativamente se você colocar o parent ele posiciona no container desejado o alerta na posição central referente ao tamanho e posição daquele container. No ambito de melhor experiência é bem mais agradável mostrar a mensagem de alerta onde o usuário esta usando naquele momento.

O Alert é um componente baseado em Panel, uma vez que ele possui apenas 1 método estático chamado show, ele cria 1 popUp por vez usando o PopUpManager direto no global do Application , comportamento esse que é padrão. Se você já é um usuário avançado do Flex com toda certeza você já deve ter implementado isso, analisando o código fonte do SDK.
Como ele é baseado em um Panel e por sua vez é herdado do UIComponent, ele possui tamanho, posição, cor, propriedades do Panel como a propriedade status, em fim uma gama de novas propriedades que podem ser usadas.

Para ajudar o Carlos, segue uma classe simples que faz todo esse trabalho, é definida por uma propriedade booleanada chamada posicionar que por padrão é false para deixar o mesmo comportamento original do Alert, e caso ela venha a ser alterada para true e suas posições x e y forem alteradas, ela fará um novo posicionamento do Alert para o local que você precisa. Veja como isso pode ser feito.

Classe utilitária para criação do Alerta costumizado.

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
package org.igorcosta.alert
{
	import flash.display.Sprite;
 
	import mx.controls.Alert;
	import mx.managers.PopUpManager;
 
	public class Alerta
	{
		/**
		 * @Author www.igorcosta.org
		 * */
		public function Alerta()
		{
			super();
		}
		/**
		 * @public
		 *
		 * Método estático que cria um Alert na posição desejada pelo usuário.
		 *
		 * Por padrão é desabilitado o posicionamento, caso você queira usar o posicionamento você
		 * deve passar o parametro posicionar como true e definir os pontos x e y para se Alert.
		 * vale resaltar que os valores para o posicionamento de x e y são por padrão iguais a 0.
		 * Caso você defina apenas os valores de x e y e deixar o valor original de posicionar como false
		 * não ocorrerá as mudanças.
		 * @return Alert
		 * */
		public static function show(mensagem:String,titulo:String,posicionar:Boolean=false,xPos:Number=0,yPos:Number=0,flags:uint=4,parent:Sprite=null,closehandler:Function =null,icon:Class = null,defaultbuttonFlag:uint =4):Alert{
			var alerta:Alert = Alert.show(mensagem,titulo,flags,parent,closehandler,icon,defaultbuttonFlag);
			Alert.yesLabel = 'Sim';
			Alert.noLabel = 'Não';
			Alert.cancelLabel = 'Cancelar';
			Alert.okLabel = 'OK';
			if(posicionar ==true){
			PopUpManager.centerPopUp (alerta);
			var internalX:Number = xPos;
			var internalY:Number = yPos;
			alerta.move(internalX,internalY);
			}else{
				PopUpManager.centerPopUp (alerta);
			}
 
		return alerta;
		}
	}
}

Aplicação da classe:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
< ?xml version="1.0" encoding="utf-8"?>
<mx :Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 
	</mx><mx :Script>
		< ![CDATA[
			import org.igorcosta.alert.Alerta;
 
			public function alertar(e:MouseEvent):void{
				Alerta.show('mensagem de boas vindas','teste',true,e.currentTarget.x,e.currentTarget.y);
			}
		]]>
	</mx>
	<mx :Button id="btn" click="alertar(event)" x="31" y="23" width="61" height="32" label="Click"/>
	<mx :Button id="btn0" click="alertar(event)" x="538" y="23" width="61" height="32" label="Click"/>
	<mx :Button id="btn1" click="alertar(event)" x="538" y="338" width="61" height="32" label="Click"/>
	<mx :Button id="btn2" click="alertar(event)" x="31" y="338" width="61" height="32" label="Click"/>
AMFPHP/ Flex 3

Novo livro Flex no mercado

O Daniel Schmitz, que palestrou na Flex Mania, acaba de lançar mais um livro de sua autoria.

O livro é Desenvolvendo sistemas com Flex e PHP. E para dar essa força, o Daniel tem um código promocional do livro que lhe dá 20% de desconto na compra feita direto no site da editora Novatec.

Código promocional:

flex.etc.br

Quer saber mais sobre o Livro e o Daniel? visite o site dele.

Flex/ Flex 3/ Flex 3 how to

#6 Flex How to: Habilitando acesso da aplicação por teclado

Ter acesso à execução de operações por teclado em sua aplicação RIA com Flex é essencial, uma aplicação ótima tem que deixar isso de fácil uso para o usuário final.
No Flash Player a classe responsável por isso é o KeyBoard que possui várias variáveis, constantes pré-definidas que mapeiam todo seu teclado; A Classe está localizada em flash.ui.KeyBoard, outras classes existentes que também faz parte do esquema de teclado é a KeyEquevalent(Apenas para AIR) e KeyLocation.

Embora em Flex para web usemos apenas o KeyBoard e junto a ele os disparos de eventos pelo KeyBoardEvent que possuim duas constantes definidas(KEY_DOWN,KEY_UP), que faz a interpretação de teclas pressionadas ou não.
Cada tecla é mapeada por códigos únicos, esses códigos são universais em qualquer teclado multimídia ou normal, esses códigos por tecla estão descritos na classe KeyBoard.

Prática 01:
Exemplo abaixo mostra como capturar cada código no Flex. Nele adicionamos dois listeners de eventos um capturando o exato momento que a tecla está pressionada e quando ela é solta.

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
< ?xml version="1.0" encoding="utf-8"?>
<mx :Application applicationComplete="init()" xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 
</mx><mx :Script>
	< ![CDATA[
		import mx.controls.Alert;
 
		public function init():void {
			stage.addEventListener(KeyboardEvent.KEY_DOWN,teclaPressionada);
		    stage.addEventListener(KeyboardEvent.KEY_UP,teclaSolta);
		}
		private var check:Boolean = false;
		public function teclaPressionada(e:KeyboardEvent):void {
				if(!check){
					check = true;
					Alert.show('Codigo caracter : '+e.charCode +'n'+
					'Codigo da tecla : '+ e.keyCode.toString());
				}
		}
		private function teclaSolta(event:KeyboardEvent):void {
			check = false;
			Log.text += 'Tecla pressionada!'+ 'n';
		}
	]]>
</mx>
<mx :TextArea id="Log" width="200" height="100"/>

Prática 02:

Como identifica a combinação de Ctrl + F1 para pedir ajuda.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
< ?xml version="1.0" encoding="utf-8"?>
<mx :Application applicationComplete="init()" xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 
</mx><mx :Script>
	< ![CDATA[
		import mx.controls.Alert;
 
		public function init():void {
			stage.addEventListener(KeyboardEvent.KEY_DOWN,teclaPressionada);
		    stage.addEventListener(KeyboardEvent.KEY_UP,teclaSolta);
		}
		public function teclaPressionada(e:KeyboardEvent):void {
				if(e.ctrlKey){
						if(e.keyCode == Keyboard.F1){
							Alert.show('Help');
						}
				}
		}
		private function teclaSolta(event:KeyboardEvent):void {
			Log.text += 'Help acionado';
		}
	]]>
</mx>
<mx :TextArea id="Log" width="200" height="100"/>

Prática 03:

Verificando se a tecla CapsLock está ativa ou não. Isso é bem útil em telas de login.Onde você pode também colocar o listener no textInput quando o usuário for dar o focus, ou direto no stage da App.

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
< ?xml version="1.0" encoding="utf-8"?>
<mx :Application applicationComplete="init()" xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 
</mx><mx :Script>
	< ![CDATA[
		import mx.controls.Alert;
		import flash.ui.Keyboard;
 
		public function init():void {
			if(Keyboard.capsLock){
				Log.text +='Caps lock ativada' +'n';
			}else{
				Log.text += 'Caps lock desativada'+'n';
			}
			stage.addEventListener(KeyboardEvent.KEY_UP,verifica,true);
		}
		public function verifica(e:KeyboardEvent):void {
				if(e.keyCode == Keyboard.CAPS_LOCK){
						if(Keyboard.capsLock){
								Log.text +='Ativou'+'n';
						}else {
							Log.text +='Desativou'+'n';
						}
				}
		}
	]]>
</mx>
<mx :TextArea id="Log" width="200" height="100"/>

Prática 04:

Como combinar clique de Mouse com Shift,Alt e Ctrl por exemplo, quando queremos selecionar um lote de itens.

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
< ?xml version="1.0" encoding="utf-8"?>
<mx :Application applicationComplete="init()" xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 
</mx><mx :Script>
	< ![CDATA[
		import mx.collections.ArrayCollection;
		import mx.controls.Alert;
		import flash.ui.Keyboard;
		import mx.containers.Panel;
 
		public function init():void {
				 stage.addEventListener(KeyboardEvent.KEY_UP,deleta);
		}
		public var itens:ArrayCollection = new ArrayCollection();
		public function seleciona(event:MouseEvent):void {
				if(event.shiftKey){
						itens.addItem(event.currentTarget);
				}
				else{
					itens.removeAll();
				}
		}
		public function deleta(e:KeyboardEvent):void {
			if(e.keyCode == Keyboard.DELETE){
						if(itens.length <=0){
							Alert.show('Nada para deletar');
						}else{
							for each( var item:Object in itens){
								this.removeChild(item as DisplayObject);
						}
					}
			}
		}
	]]>
</mx>
 
 
		<mx :Panel title="a" click="seleciona(event)" width="100" height="100" x="59" y="76"/>
		<mx :Panel title="b" click="seleciona(event)" width="100" height="100" x="167" y="76"/>
		<mx :Panel title="c" click="seleciona(event)" width="100" height="100" x="275" y="76"/>
		<mx :Panel title="d" click="seleciona(event)" width="100" height="100" x="392" y="76"/>