Vous êtes sur la page 1sur 63

Universidad de Cdiz

Adobe Flex SDK y Flex Builder 3

lvaro Martnez del Val 23/03/2010

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Contenido
1. Adobe Flex SDK y Flex Builder ............................................................................................... 4 1.1. 1.2. 2. 3. 4. 5. 6. 7. 8. 9. 10. Adobe Flex SDK.............................................................................................................. 4 Flex Builder .................................................................................................................... 4

Primera aplicacin ................................................................................................................. 5 MXML vs AS ........................................................................................................................... 6 Modo de depuracin ............................................................................................................. 7 Creando un formulario .......................................................................................................... 7 Creando un componente complejo .................................................................................... 13 Creando el modelo en el cliente ......................................................................................... 16 Visualizacin de datos (DataGrid) ....................................................................................... 19 Programando con eventos .................................................................................................. 23 Arquitectura de una aplicacin web con Adobe Flex SDK .............................................. 26 Cliente ..................................................................................................................... 26 Servidor ................................................................................................................... 27 Comunicacin cliente servidor (Intefaz Http) ...................................................... 27 BlazeDS .................................................................................................................... 30 Productor Consumidor (Message Service) ....................................................... 30 Objeto Remoto (Remoting Service) .................................................................... 35 Proxy Service ....................................................................................................... 40 Localizacin de aplicaciones .................................................................................... 42 Paso de parmetros http a un swf .......................................................................... 48

10.1. 10.2. 10.3. 10.4. 10.4.1. 10.4.2. 10.4.3. 10.5. 10.6. 11.

Creacin de un html que envuelva a el swf .................................................................... 49 Paso de variables ..................................................................................................... 50

11.1. 12.

Otras caractersticas de Adobe Flex SDK ......................................................................... 50 Comunicacin con interfaces externas (javascript) ................................................ 50

12.1. 13. 14.

SharedObjects ................................................................................................................. 51 Adobe AIR ........................................................................................................................ 54 Creando una aplicacin con Adobe AIR .................................................................. 54

14.1.

Anexo I: Instalacin de Adobe Flex SDK ...................................................................................... 62 Anexo II: Creando y compliando una aplicacin AIR con Adobe Flex SDK .................................. 62

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Tabla de ilustraciones
Ilustracin 1: Entorno Flex Builder ................................................................................................ 4 Ilustracin 2: Editor de texto MXML ............................................................................................. 5 Ilustracin 3: Editor visual de mxml .............................................................................................. 5 Ilustracin 4: Ventana de creacin de proyecto (Flex Builder) ..................................................... 6 Ilustracin 5: Flex Builder, perspectiva de depuracin ................................................................. 7 Ilustracin 6: Proyecto FormularioVehiculos ................................................................................ 8 Ilustracin 7: Ventana de creacin de nuevo componente (Flex Builder) .................................... 9 Ilustracin 8: Editor textual MXML ............................................................................................. 10 Ilustracin 9: Editor visual ........................................................................................................... 10 Ilustracin 10:Ventana de componentes .................................................................................... 11 Ilustracin 11: Formulario de insercin de coches ..................................................................... 12 Ilustracin 12: Ejemplo de formulario......................................................................................... 15 Ilustracin 13: Formulario + Datagrid (1) .................................................................................... 20 Ilustracin 14: Formulario + DataGrid (2) ................................................................................... 20 Ilustracin 15: Ventana de propiedades A-Z de un componente (Flex Builder) ......................... 23 Ilustracin 16: Ejemplo insercin de datos (1) ............................................................................ 26 Ilustracin 17: Ejemplo insercin de datos (2) ............................................................................ 26 Ilustracin 18: Buscador de Yahoo de prueba ............................................................................ 27 Ilustracin 19: Proyecto Flex con BlazeDS .................................................................................. 32 Ilustracin 20: Proyecto Flex con BlazeDS .................................................................................. 33 Ilustracin 21: Ventana de propiedades de compilacin (Flex Builder) ..................................... 43 Ilustracin 22: Ventana de propiedades de archivo (Flex Builder) ............................................. 45 Ilustracin 23: Vista de diseo del componente Historico.mxml ............................................... 52 Ilustracin 24: Componente chat1.mxml modificado................................................................. 53 Ilustracin 25: Ventana de creacin de proyecto Adobe AIR ..................................................... 55 Ilustracin 26: Prueba del editor de texto .................................................................................. 61

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

1. Adobe Flex SDK y Flex Builder


1.1. Adobe Flex SDK
Adobe Flex SDK es un framework opensource de Adobe que nos permite crear complejas aplicaciones cliente con ActionScript, adems nos permite crear aplicaciones escritorio utilizando Adobe AIR. Es gratuito y funciona en Windows, Linux y Mac. Instalacin de Flex SDK:

1.2.

Flex Builder

Flex Builder es un entorno de desarrollo integrado (IDE) basado en Eclipse y desarrollado por Adobe. Nos permite crear proyectos utilizando Flex SDK, tal como Eclipse hace con otros lenguajes. Las principales ventajas que ofrece son: Reconocimiento dinmico de errores. Deteccin de libreras. Edicin de archivos ActionScript y mxml Interfaz visual para el diseo de componentes, utilizando la extensin MXML de Flex SDK, que consiste en un lenguaje XML en el que definir un conjunto de componentes Flex, permitiendo aadir cdigo ActionScript.

El principal problema es que Flex Builder es una herramienta de pago, aunque es posible conseguir una licencia para educacin en la pgina de Adobe, proporcionando una identificacin que nos acredite como estudiantes o profesores. En la ilustracin inferior se puede ver el entorno Flex Builder:

Ilustracin 1: Entorno Flex Builder

Editor de texto para archivos MXML: 4

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Ilustracin 2: Editor de texto MXML

Vista de diseo (visual) para el archivo MXML:

Ilustracin 3: Editor visual de mxml

2. Primera aplicacin
Para crear un nuevo proyecto hacemos clic en File/New/Flex Project Se nos abrir una ventana en la que introducir el nombre del proyecto y en la que podremos elegir el tipo: 5

Adobe Flex SDK y Flex Builder 3 Web application (Funciona con Flash Player) Desktop application (Funciona con Adobe Air)

Universidad de Cdiz

Para empezar crearemos una aplicacin Web, por defecto. Introducimos un nombre para el proyecto, por ejemplo Prueba, y pusamos Finish:

Ilustracin 4: Ventana de creacin de proyecto (Flex Builder)

3. MXML vs AS
En un proyecto Flex podemos aadir clases ActionScript o componentes MXML. Las clases ActionScript son como cualquier clase de un lenguaje orientado a objetos, permiten herencia, definir interfaces, etc. Las clases ActionScript son principalmente utilizadas para definir el modelo de la aplicacin, si bien es posible utilizar ActionScript para crear directamente vistas, no es lo ms indicado, ya que las clases ActionScript no pueden ser visualizadas con el editor grfico de Flex Builder. Por otro lado, los componentes MXML son ficheros XML que siguen una determinada sintaxis basada en etiquetas con los nombres de los elementos de Flex SDK, es algo parecido a un fichero html pero mucho ms potente y en el que se puede incorporar cdigo ActionScript. La principal ventaja de los ficheros MXML es que pueden ser visualizados con el editor grfico de Flex Builder, pudiendo crear interfaces fcilmente. Los componentes MXML son utilizados para definir la vista de la aplicacin. Ms adelante veremos ejemplos de uso de unos y otros. 6

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

4. Modo de depuracin
Flex Builder tiene, al igual que Eclipse, perspectiva de depuracin, a la que se accede a travs del botn Open perspective en la parte superior izquierda:

Ilustracin 5: Flex Builder, perspectiva de depuracin

El modo de depuracin nos permite aadir breakpoints al cdigo y aadir el comando trace() a nuestro cdigo ActionScript, que imprime cualquier cadena de caracteres que le pasemos como parmetro, y la muestra por la consola de depuracin.

5. Creando un formulario
Vamos a crear un primer proyecto en el que construiremos un formulario simple utilizando MXML. Primero creamos un proyecto con Flex Builder. Pulsamos File\New\Flex Project y le damos el nombre FormularioVehiculos. Pulsamos Finish:

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Ilustracin 6: Proyecto FormularioVehiculos

Vamos a aadir un componente MXML al proyecto, por lo que pulsamos File\New\MXML Component:

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Ilustracin 7: Ventana de creacin de nuevo componente (Flex Builder)

Si nos fijamos, en la parte inferior de la ventana que se abre tenemos tres atributos: Filename Nombre del componente

Base don Es el elemento grfico en el que estar basado el componente, por defecto es Canvas, que representa un fondo vaco en el que se pueden aadir libremente elementos, como veremos a continuacin. Alternativas similares a Canvas son HBox, que es parecido pero limitando la colocacin de los elementos de forma horizontal; VBox, limita la colocacin de los objetos pero de forma vertical, o Panel, que es como Canvas pero con una barra de ttulo, etc. Width y Height Anchura y altura iniciales.

Como nombre introducimos FormularioCoche, y dejamos las dems opciones por defecto. Se nos abrir directamente el editor textual del MXML:

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Ilustracin 8: Editor textual MXML

De momento no nos interesa, ya que vamos a construir un formulario simple, por lo que podemos utilizar directamente el editor visual; pulsamos la pestaa Design en la parte superior del editor:

Ilustracin 9: Editor visual

Podemos ver el elemento Canvas en el centro, vaco de momento, y a la derecha la ventana de propiedades; si no se ve debemos hacer clic en Windows\Flex Properties. Vamos a aadir los elementos necesarios para construir un formulario que nos permita insertar coches, para ello debemos tener abierta la pestaa de componentes Components, si no la vemos debemos hacer clic en Window\Components, y aparecer algo como lo mostrado en la imagen inferior:

10

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Ilustracin 10:Ventana de componentes

Los componentes que nos interesan son TextInput, que es como su nombre indica un campo de texto y el componente Label, que es una etiqueta de texto. Aadimos los elementos hasta tener algo parecido a lo mostrado en la siguiente imagen:

11

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Ilustracin 11: Formulario de insercin de coches

El cdigo es el siguiente: <mx:Script>


<![CDATA[ import modelo.Coche; private var coche:Coche; public function getCoche():Coche { return new Coche(marca.text, modelo.text, combustible.text, parseInt(cilindrada.text), parseInt(potencia.text), parseInt(puertas.int)); } ]]> </mx:Script> <?xml version="1.0" encoding="utf-8"?> <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="316"> <mx:Label x="82.5" y="19" text="Formulario de insercin de coches:" fontWeight="bold" fontSize="12"/> <mx:Label x="100" y="62" text="Marca:"/> <mx:TextInput x="150" y="60"/> <mx:Label x="92" y="88" text="Modelo:"/> <mx:TextInput x="150" y="86"/> <mx:Label x="62" y="114" text="Combustible:"/> <mx:TextInput x="150" y="112"/> <mx:Label x="74" y="142" text="N Puertas:"/>

12

Adobe Flex SDK y Flex Builder 3


<mx:TextInput x="150" y="140"/> <mx:Label x="76" y="168" text="Cilindrada:"/> <mx:TextInput x="150" y="166"/> <mx:Label x="85" y="194" text="Potencia:"/> <mx:TextInput x="150" y="192"/> </mx:Canvas>

Universidad de Cdiz

Ya tenemos nuestro primer componente, pero de poco nos sirve ya que ni siquiera est enlazado con el archivo principal de la aplicacin, que se debera llamar FormularioVehiculos.mxml.

6. Creando un componente complejo


Ahora vamos a abrir el archivo Main de nuestro proyecto, FormularioVehiculos.mxml y nos colocamos en la vista de diseo (editor visual):

Vamos a aadir un componente denominado TabNavigator, que se encuentra en la carpeta Navigators de la ventana Components y lo vamos a colocar en la posicin (0,0). Adems vamos a asignarle los valores width=100% y height=100%:

Le damos el nombre Insercin de coches en el atributo Label de la ventana de propiedades, deberamos tener algo como esto:

13

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Ahora vamos a colocarle el formulario que antes hemos creado, nos vamos a la ventana Components y abrimos la carpeta Custom, ah debe aparecer FormularioCoches; lo arrastramos dentro:

14

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Ilustracin 12: Ejemplo de formulario

Ahora si pulsamos Run en la barra de herramientas resultado.

ejecutar podremos ver el

Como hemos aadido un componente TabNavigator vamos a aprovechar y a crear una nueva pestaa muy parecida pero en este caso un formulario para motos que llamaremos FormularioMoto, el cdigo es el siguiente:
<?xml version="1.0" encoding="utf-8"?> <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="316"> <mx:Label x="100" y="62" text="Marca:"/> <mx:TextInput x="150" y="60"/> <mx:Label x="92" y="88" text="Modelo:"/> <mx:TextInput x="150" y="86"/> <mx:Label x="62" y="114" text="Combustible:"/> <mx:TextInput x="150" y="112"/> <mx:Label x="50" y="142" text="Tiene marchas:"/> <mx:Label x="76" y="168" text="Cilindrada:"/> <mx:TextInput x="150" y="166"/> <mx:Label x="85" y="194" text="Potencia:"/> <mx:TextInput x="150" y="192"/> <mx:Label x="82.5" y="19" text="Formulario de insercin de motos:" fontWeight="bold" fontSize="12"/> <mx:ComboBox x="150" y="140" cornerRadius="0"> <mx:Array> <mx:String>S</mx:String>

15

Adobe Flex SDK y Flex Builder 3


<mx:String>No</mx:String> </mx:Array> </mx:ComboBox> </mx:Canvas>

Universidad de Cdiz

Ahora aadimos una nueva pestaa a FormularioVehiculos y aadiremos nuestro nuevo componente:

Si volvemos a ejecutar podemos ver que tenemos un pequeo navegador que nos permite viajar entre nuestros dos componentes:

El problema es que ahora mismo de poco nos sirve nuestra aplicacin.

7. Creando el modelo en el cliente


Vamos a crear el modelo de nuestra aplicacin, en este caso tenemos dos formularios, uno para la insercin de coches y otro para la insercin de motos. Primero creamos una nueva carpeta denominada modelo dentro de la carpeta src del proyecto. Hacemos clic en File\New\ActionScript class y nombramos a nuestra nueva clase Vehiculo. El cdigo de Vehiculo ser as:
package modelo { public class Vehiculo extends Object { public var marca:String; public var model:String;

16

Adobe Flex SDK y Flex Builder 3


public var combustible:String; public var cilindrada:int; public var potencia:int;

Universidad de Cdiz

public function Vehiculo(marca:String, model:String, combustible:String, cilindrada:int, potencia:int) { this.marca = marca; this.model = model; this.combustible = combustible; this.cilindrada = cilindrada; this.potencia = potencia; } public function getMarca():String { return this.marca; } public function setMarca(marca:String):void { this.marca = marca; } public function getModel():String { return this.model; } public function setModel(model:String):void { this.model = model; } public function getCombustible():String { return this.combustible; } public function setCombustible(combustible:String):void { this.combustible = combustible; } public function getCilindrada():int { return this.cilindrada; } public function setCilindrada(cilindrada:int):void { this.cilindrada = cilindrada; } public function getPotencia():int { return this.potencia; } public function setPotencia(potencia:int):void {

17

Adobe Flex SDK y Flex Builder 3


this.potencia = potencia; } } }

Universidad de Cdiz

Ahora vamos a crear una nueva clase ActionScript Coche que herede de vehculo y que aada el atributo nPuertas de tipo int y sus correspondientes get y set:
package modelo { public class Coche extends Vehiculo { public var puertas:int; public function Coche(marca:String, model:String, combustible:String, cilindrada:int, potencia:int, puertas:int) { super(marca, model, combustible, cilindrada, potencia); this.puertas = puertas; } public function getPuertas():int { return this.puertas; } public function setPuertas(puertas:int):void { this.puertas = puertas; } } }

Finalmente aadimos una clase ActionScript Moto que herede tambin de vehculo y que aada el atributo tieneMarchas de tipo Boolean y sus correspondientes get y set:
package modelo { public class Moto extends Vehiculo { public var marchas:Boolean = false; public function Moto(marca:String, model:String, combustible:String, cilindrada:int, potencia:int, marchas:Boolean) { super(marca, model, combustible, cilindrada, potencia); this.marchas = marchas; } public function getMarchas():Boolean { return this.marchas; } public function setPuertas(marchas:Boolean):void { this.marchas = marchas; }

18

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

} }

Como se puede suponer a priori, las clases del modelo se utilizarn para el manejo de los datos.

8. Visualizacin de datos (DataGrid)


Hasta ahora hemos construido dos formularios, uno para coches y otro para motos, el modelo correspondiente y un navegador para viajar entre los dos formularios, pero nuestra aplicacin todava no tiene ninguna utilidad. Para dotarle de utilidad vamos a aadir en FormularioVehiculos a la derecha de cada formulario un DataGrid, que es un componente que muestra un conjunto de datos formateado en forma de tabla. El componente DataGrid se encuentra en la carpeta Controls de la ventana Components. Por defecto el componente DataGrid se nos aadir en el cdigo de esta forma:
<mx:DataGrid> <mx:columns> <mx:DataGridColumn headerText="Column 1" dataField="col1"/> <mx:DataGridColumn headerText="Column 2" dataField="col2"/> <mx:DataGridColumn headerText="Column 3" dataField="col3"/> </mx:columns> </mx:DataGrid>

Pero eso no nos interesa, as que lo dejamos vaco:


<mx:DataGrid> </mx:DataGrid>

Establecemos sus propiedades de altura y anchura al 100% y les damos a cada uno un nombre, en el atributo ID de la ventana de propiedades; coches y motos respectivamente. Deberemos tener algo como esto:

19

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Ilustracin 13: Formulario + Datagrid (1)

Ilustracin 14: Formulario + DataGrid (2)

20

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

El cdigo de FormularioVehiculos quedara como se muestra a continuacin:


<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:ns1="*"> <mx:TabNavigator x="0" y="0" width="100%" height="100%" id="navegador"> <mx:Canvas label="Insercin de coches" width="100%" height="100%"> <ns1:FormularioCoche id="formularioCoche"> </ns1:FormularioCoche> <mx:DataGrid id="coches" x="408" y="0"> </mx:DataGrid> </mx:Canvas> <mx:Canvas label="Insercin de motos" width="100%" height="100%"> <ns1:FormularioMoto id="formularioMoto"> </ns1:FormularioMoto> <mx:DataGrid x="408" y="0"> </mx:DataGrid> </mx:Canvas> </mx:TabNavigator> </mx:Application>

Ahora vamos a editar nuestros componentes FormularioCoche y FormularioMoto de forma que cada vez que introduzcamos los datos creemos un objeto de tipo Coche y un objeto de tipo Moto respectivamente. Abrimos el componente FormularioCoche y a cada uno de los campos a rellenar le damos el mismo ID que los atributos de la clase coche:
<?xml version="1.0" encoding="utf-8"?> <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="316"> <mx:Label x="100" y="62" text="Marca:"/> <mx:TextInput x="150" y="60" id="marca"/> <mx:Label x="92" y="88" text="Modelo:"/> <mx:TextInput x="150" y="86" id="model"/> <mx:Label x="62" y="114" text="Combustible:"/> <mx:TextInput x="150" y="112" id="combustible"/> <mx:Label x="74" y="142" text="N Puertas:"/> <mx:TextInput x="150" y="140" id="puertas"/> <mx:Label x="76" y="168" text="Cilindrada:"/> <mx:TextInput x="150" y="166" id="cilindrada"/> <mx:Label x="85" y="194" text="Potencia:"/> <mx:TextInput x="150" y="192" id="potencia"/> <mx:Label x="82.5" y="19" text="Formulario de insercin de coches:" fontWeight="bold" fontSize="12"/> </mx:Canvas>

Hacemos lo mismo con el componente FormularioMoto:


<?xml version="1.0" encoding="utf-8"?> <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="316"> <mx:Label x="100" y="62" text="Marca:"/> <mx:TextInput x="150" y="60" id="marca"/> <mx:Label x="92" y="88" text="Modelo:"/> <mx:TextInput x="150" y="86" id="model"/> <mx:Label x="62" y="114" text="Combustible:"/>

21

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

<mx:TextInput x="150" y="112" id="combustible"/> <mx:Label x="50" y="142" text="Tiene marchas:"/> <mx:Label x="76" y="168" text="Cilindrada:"/> <mx:TextInput x="150" y="166" id="cilindrada"/> <mx:Label x="85" y="194" text="Potencia:"/> <mx:TextInput x="150" y="192" id="potencia"/> <mx:Label x="82.5" y="19" text="Formulario de insercin de motos:" fontWeight="bold" fontSize="12"/> <mx:ComboBox x="150" y="140" cornerRadius="0" id="marchas"> <mx:Array> <mx:String>S</mx:String> <mx:String>No</mx:String> </mx:Array> </mx:ComboBox> </mx:Canvas>

Ahora vamos a crear en cada uno de los formularios un mtodo que nos devuelva un objeto Coche o Moto respectivamente con los datos de cada uno de los campos. Para aadir cdigo ActionScript a un componente MXML debemos escribir lo siguiente y lo colocamos justo encima de la ltima etiqueta de cierre del MXML:
<mx:Script> <![CDATA[ ]]> </mx:Script>

Dentro podemos aadir cdigo ActionScript. El mtodo que devuelve un coche sera as:
<mx:Script> <![CDATA[ import modelo.Coche; public function getCoche():Coche { return new Coche(marca.text, model.text, combustible.text, parseInt(cilindrada.text), parseInt(potencia.text), parseInt(puertas.int)); } ]]> </mx:Script>

El mtodo que devuelve una moto sera muy similar:


<mx:Script> <![CDATA[ import modelo.Moto; public function getMoto():Moto { var marchasAux:Boolean = false; if(marchas.selectedItem == "S") { marchasAux = true; } return new Moto(marca.text, model.text, combustible.text, parseInt(cilindrada.text), parseInt(potencia.text), marchasAux); } ]]> </mx:Script>

22

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Para evitar introducir valores no numricos en los campos numricos introducimos \0-9\ en el atributo restrict de potencia, cilindrada y puertas:

Ilustracin 15: Ventana de propiedades A-Z de un componente (Flex Builder)

9. Programando con eventos


Ya hemos aadido la gestin con el modelo, pero nos falta la insercin y visualizacin de datos en el cliente. Para poder insertar los datos vamos a aadir un botn de insercin justo debajo de los formularios de coche y moto, pero no en sus respectivos componentes, sino en FormularioVehiculo:

23

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Aadiremos un evento clic a cada uno de los botones, de forma que cada vez que pulsemos uno se devuelva un objeto Coche o un Objeto Moto, con los datos del formulario, adems aadimos un identificador al componente FormularioCoche y otro a FormularioMoto dentro de FormularioVehiculo, y a cada uno de los DataGrid aadidos: Abrimos el editor de texto de FormularioVehiculo y los cambios a realizar son:
<ns1:FormularioCoche id="formularioCoche"> </ns1:FormularioCoche> <ns1:FormularioMoto id="formularioMoto"> </ns1:FormularioMoto> <mx:DataGrid id="coches" x="408" y="0"> </mx:DataGrid> <mx:DataGrid x="408" y="0" id="motos"> </mx:DataGrid> <mx:Button label="Insertar" click="insertarCoche()"/> <mx:Button label="Insertar" click="insertarMoto()"/>

El cdigo nos debe quedar as:


<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:ns1="*"> <mx:TabNavigator x="0" y="0" width="100%" height="100%" id="navegador"> <mx:Canvas label="Insercin de coches" width="100%" height="100%"> <ns1:FormularioCoche id="formularioCoche"> </ns1:FormularioCoche>

24

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

<mx:Button label="Insertar" click="insertarCoche()" x="182" y="233"/> <mx:DataGrid id="coches" x="408" y="0"> </mx:DataGrid> </mx:Canvas> <mx:Canvas label="Insercin de motos" width="100%" height="100%"> <ns1:FormularioMoto id="formularioMoto"> </ns1:FormularioMoto> <mx:Button label="Insertar" click="insertarMoto()" x="180" y="232"/> <mx:DataGrid x="408" y="0" id="motos"> </mx:DataGrid> </mx:Canvas> </mx:TabNavigator> </mx:Application>

Ahora aadimos la correspondiente etiqueta:


<mx:Script> <![CDATA[ ]]> </mx:Script>

Justo encima de </mx:Application> y creamos los mtodos insertarMoto() e insertarCoche(), de forma que el cdigo nos quede as:
<mx:Script> <![CDATA[ import mx.collections.ArrayCollection; import modelo.Moto; import modelo.Coche; private var arrayCoches:Array = new Array(); private var arrayMotos:Array = new Array(); private function insertarCoche():void { // Obtenemos una variable coche var coche:Coche = this.formularioCoche.getCoche(); // La insertamos en el DataGrid de coches arrayCoches.push(coche); coches.dataProvider = arrayCoches; } private function insertarMoto():void { // Obtenemos una variable moto var moto:Moto = this.formularioMoto.getMoto(); // La insertamos en el DataGrid de motos arrayMotos.push(moto); motos.dataProvider = arrayMotos; } ]]> </mx:Script>

Debido a que las clases Coche y Moto heredan de la clase Objeto, sus atributos quedan directamente parseados en el DataGrid correspondiente:

25

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Ilustracin 16: Ejemplo insercin de datos (1)

Ilustracin 17: Ejemplo insercin de datos (2)

Ya tenemos una aplicacin cliente, con un modelo asignado y gestin de datos, pero no tenemos conexin con un servidor donde guardar los datos de forma duradera. Como veremos a continuacin existen varias formas de crear una aplicacin cliente servidor en Flex.

10. Arquitectura de una aplicacin web con Adobe Flex SDK


La arquitectura de cualquier aplicacin web implementada con Adobe Flex SDK es a priori como la de cualquier aplicacin web, tenemos un cliente (implementado en shockwave/flash) y un servidor implementado a priori en cualquier lenguaje (esto depender tambin de la tecnologa que queramos usar). La principal diferencia es que gracias a Flex SDK y a su tecnologa similar a AJAX, podemos gestionar los datos recibidos desde el servidor sin necesidad de estar cambiando de pgina, incluso podemos definir una compleja estructura basada en objetos con la que gestionar nuestra informacin y cambiar el estado de nuestra interfaz de forma dinmica en el cliente sin necesidad de invocar a una nueva vista.

10.1. Cliente
El cliente estar programado mediante Flex SDK, obteniendo como resultado un objeto swf (shockwave\flash), que actuar como nica interfaz, sin necesidad de estar construyendo un conjunto de vistas diferente. El cliente podr hacer llamadas asncronas al servidor, con las que actualizar sus datos, estas llamadas se podrn realizar de varias formas, como veremos a continuacin.

26

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

10.2. Servidor
El servidor se construir como en cualquier otra aplicacin web, excluyendo de su programacin cualquier clase de vista, y por lo tanto cualquier redireccin a una vista. La programacin del servidor se limitar a la recepcin, emisin y gestin de datos, ya que la base de datos que utilicemos slo podr ser manipulada de esta forma.

10.3. Comunicacin cliente servidor (Intefaz Http)


La forma ms comn de acceso al servidor es mediante el uso de la interfaz Http que Flex SDK nos ofrece mediante su clase HttpService. HttpService nos permite realizar llamadas http GET, POST, PUT y DELETE, establecer tanto la cabecera como el cuerpo de la llamada y recibir los datos de respuesta de forma asncrona. Como ejemplo vamos a construir una pequea aplicacin que consistir en un sencillo buscador web basado en la API de yahoo http://developer.yahoo.com/search/web/V1/webSearch.html Primer, paso, crear la interfaz grfica: Vamos a crear una sencilla interfaz grfica con la que poder introducir los parmetros de la bsqueda, la interfaz tendr los siguientes elementos: 1. 2. 3. 4. 5. 6. Input de texto para introducir las palabras de bsqueda. Lista en forma de comboBox con la que seleccionar el nmero de resultados. Lista en forma de comboBox con la que seleccionar el idioma de los resultados. Lista en forma de comboBox con la que seleccionar el formato de los resultados. Botn para confirmar la bsqueda. Un elemento DataGrid que se rellenar con los resultados obtenidos.

El resultado deber ser algo como esto:

Ilustracin 18: Buscador de Yahoo de prueba

Una vez que tenemos la interfaz grfica implementada, tenemos que realizar la llamada al servidor, que en este caso ser el servidor de Yahoo. Para ello utilizaremos la interfaz http de Flex SDK, HttpService. Primero, aadimos un evento click al botn de bsqueda, de forma que al pulsar el botn realicemos una llamada:
<mx:Button label="Buscar" click="buscar()"/>

27

Adobe Flex SDK y Flex Builder 3 Ahora implementamos el mtodo buscar:

Universidad de Cdiz

private function buscar():void { var servicio:HTTPService = new HTTPService(); servicio.url = "http://search.yahooapis.com/WebSearchService/V1/webSearch?appid=Yahoo Demo"; servicio.method = "GET"; servicio.request = { query:palabrasClave.text, laguage:languageCB.text, results:nResultadosCB.selectedItem, format:formatCB.selectedItem }; servicio.resultFormat = "xml"; // Aadimos los manejadores para procesar la respuesta servicio.addEventListener(ResultEvent.RESULT, manejadorObtener); servicio.addEventListener(FaultEvent.FAULT, manejadorErrorObtener); // Enviamos servicio.send(); }

En el mtodo buscar estamos realizando dos cosas: 1. Creando un objeto HttpService y asignndole los parmetros de llamada: URL http://search.yahooapis.com/WebSearchService/V1/webSearch?appid=YahooDemo Method GET ResultFormat text/xml 2. Aadiendo dos manejadores, ya que la respuesta es asncrono y deberemos crear manejadores que estn escuchando hasta que recibamos respuesta: Uno para el resultado: servicio.addEventListener(ResultEvent.RESULT, manejadorObtener) Otro para el caso de error: servicio.addEventListener(FaultEvent.FAULT, manejadorErrorObtener) El siguiente paso es implementar los manejadores: El manejador de error es muy sencillo, slo sirve para indicarnos que se ha producido un error en la llamada:
private function manejadorErrorObtener(event:FaultEvent):void { Alert.show("Error al obtener el listado de videos"); }

El manejador del resultado es algo ms complejo, ya que debe recoger la respuesta, en formato XML y procesarla de forma que se muestren los resultados correctamente:
private function manejadorObtener(event:ResultEvent):void { var response:String = event.result.toString(); var xmlDoc:XMLDocument; try { // Comprobamos si el resultado es un XML xmlDoc = new XMLDocument(response);

28

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

// Procesamos el XML var decoder:SimpleXMLDecoder = new SimpleXMLDecoder(true); var resultObj:Object = decoder.decodeXML(xmlDoc); resultados.dataProvider = resultObj.ResultSet.Result; } catch(error:Error) { Alert.show("Error en el formato de la respuesta"); } }

Lo que estamos haciendo con este mtodo es capturar la respuesta, que viene en el objeto event de entrada y procesarla como un XML. Por defecto, en ActionScript, cualquier objeto cuyo contenido es un XML es tratado como un Array, en este caso la estructura es:
<ResultSet> <Result></Result> <Result></Result> </ResultSet>

Es decir, tenemos un nodo ResultSet con un conjunto de nodos hijos Result, por lo que si accedemos a resultObj.ResultSet, lo que nos devuelve es un array de un solo elemento, el nodo ResultSet, y si accedemos a resultObj.ResultSet.Result, lo que obtenemos es un array con tantos elementos como nodos Result existan. De hecho, podramos recorrerlo de esta forma:
for(var i:int = 0; i < resultObj.ResultSet.Result.length; i++) { Alert.show(resultObj.ResultSet.Result[i]); }

El ejemplo de buscador es un caso muy sencillo, pero puede ser extendido a cualquier modelo, pudiendo crear cualquier aplicacin web basada en la comunicacin entre el cliente y el servidor utilizando objetos HttpService. El principal inconveniente de utilizar HttpService es que el servidor destino debe contener en su directorio raz un archivo crossdomain.xml como el siguiente:
<?xml version="1.0"?> <!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"> <cross-domain-policy> <site-control permitted-cross-domain-policies="master-only"/> <allow-access-from domain="*" secure="false"/> <allow-http-request-headers-from domain="*" headers="SOAPAction"/> </cross-domain-policy>

Esto es necesarios para que nuestro objeto shockwave/flash pueda recibir las respuestas del servidor y viceversa. Otra funcionalidad que puede ser necesaria en nuestra aplicacin cliente-servidor, es la de descarga y subida de archivos, esto se consigue fcilmente mediante la combinacin de las clases URLRequest y FileReference, la nica particularidad es que el objeto FileReference utilizado debe ser una variable de la clase.

29

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

10.4. BlazeDS
BlazeDS es una tecnologa opensource desarrollada por Adobe y basada en servidor Java, de hecho utilizada tomcat como base. BlazeDS permite la comunicacin de aplicaciones Web y de Escritorio (Adobe AIR) creadas con Flex con un servidor java de cuatro formas distintas: Paso de mensajes (Message Service) Objeto Remoto (Remoting Service) Proxy Service

BlazeDS puede descargarse desde la pgina: http://flexorg.wip3.adobe.com/blazeds/3.0.x/milestone/3978/blazeds-turnkey-3.2.0.3978.zip Su instalacin es como la de cualquier tomcat, slo hace falta extraerlo en un directorio destino. 10.4.1. Productor Consumidor (Message Service) La arquitectura productor consumidor se basa en un productor, que enva mensajes (pull) y un consumidor que los recibe (push). Esta estructura es la utilizada para aplicaciones como chats, en las que un consumidor, el servidor, recibe los mensajes de un conjunto de clientes, que son los productores y que a su vez pueden acceder a los mensajes publicados por sus compaeros. Si bien esta estructura puede tener otros usos, siendo el ejemplo ms sencillo de modelo productor consumidor un chat, vamos a implementar uno utilizando BlazeDS y Flex Builder. Primero crearemos la parte del servidor: Si accedemos al directorio de BlazeDS, podemos observar que dentro hay una carpeta tomcat. La estructura del tomcat se ha respetado y dentro podremos encontrar la carpeta webapps donde se encuentran nuestras aplicaciones web. En este caso podemos encontrar una carpeta con aplicaciones de ejemplo samples y una carpeta denominada blazeds en la que se encuentra una estructura genrica que define servicios para paso de mensajes, comunicacin con objetos remotos y por proxy. En este caso vamos a crear una nueva carpeta dentro de webapps que llamaremos chat. Dentro de esa carpeta copiaremos el contenido del directorio blazeds. Si accedemos a WEB-INF/flex podemos ver cuatro xmls: messaging-config.xml para la definicin del servicio de mensajes proxy-config.xml para la definicin del servicio de proxy remoting-config.xml para la definicin del servicio de objetos remotos services-config.xml para la definicin global de servicios

En nuestro caso, como queremos crear un servicio de mensajes, ya que vamos a implementar una estructura de comunicacin push/pull, deberemos editar los ficheros messagingconfig.xml y services-config.xml. En messaging-config.xml aadimos lo siguiente:
<?xml version="1.0" encoding="UTF-8"?> <service id="message-service" class="flex.messaging.services.MessageService"> <adapters> <adapter-definition id="actionscript" class="flex.messaging.services.messaging.adapters.ActionScriptAdapter" default="true" />

30

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

<!-- <adapter-definition id="jms" class="flex.messaging.services.messaging.adapters.JMSAdapter"/> --> </adapters> <default-channels> <channel ref="my-polling-amf"/> </default-channels> <destination id="chat"/> </service>

Aadimos la lnea <destination id="chat"/> justo encima de la etiqueta </service>. Esta lnea indica que el servicio destino se va a denominar chat. En el cliente se deber especificar el id de destino. El canal de comunicacin viene definido en el archivo services-config.xml, en este caso, utilizaremos el definido por defecto.
<channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel"> <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/a mf" class="flex.messaging.endpoints.AMFEndpoint"/> </channel-definition>

Ya tenemos la parte del servidor implementada, no necesitamos nada ms, ya que de ello se ocuparn las libreras definidas en BlazeDS. Ahora debemos crear la parte del cliente: Para ello creamos un nuevo proyecto con Flex Builder, presionamos File/New/Flex Project:

31

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Ilustracin 19: Proyecto Flex con BlazeDS

En Application server type marcamos J2EE y seleccionamos Use remote object Access service y LiveCycle Data Services. Pulsamos Next. Ahora es cuando necesitamos introducir los datos del servidor:

32

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Ilustracin 20: Proyecto Flex con BlazeDS

En Root folder introducimos el directorio de blazeds dentro de la carpeta webapps, quedara BlazeDS_HOME/tomcat/webapps/blazeds. En Roo URL introducimos la URL destino, en este caso, como BlazeDS viene configurado en el puerto 8400, la URL ser: http://localhost:8400/blazeds. Finalmente en Context root introducimos el directorio raiz de la aplicacin web, en este caso /blazeds. Pulsamos Finish para terminar. Ahora debemos editar el mxml principal de nuestra aplicacin, en este caso chat.mxml. En el que aadiremos lo siguiente: Primero el productor y el consumidor de mensajes:
<mx:Consumer id="consumer" destination="chat" message="messageHandler(event.message)"/> <mx:Producer id="producer" destination="chat"/>

En el atributo destination, debemos aadir el destino que anteriormente hemos especificado, en este caso chat. 33

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Aadimos los controles que nos permitirn crear la interfaz grfica del chat. Un panel de texto donde visualizar los mensajes enviados. Un input de texto donde escribir nuestros mensajes y un botn para el envo.
<mx:Panel title="Chat" width="100%" height="100%"> <mx:TextArea id="log" width="100%" height="100%"/> <mx:ControlBar> <mx:TextInput id="msg" width="100%" enter="send()"/> <mx:Button label="Send B" click="send()"/> </mx:ControlBar> </mx:Panel>

En el botn aadimos al evento click el mtodo send() que ahora definiremos, para ello aadiremos al mxml cdigo ActionScript:
<mx:Script> <![CDATA[ import mx.messaging.messages.AsyncMessage; import mx.messaging.messages.IMessage; private function send():void{ var message:IMessage = new AsyncMessage(); message.body.chatMessage = msg.text; producer.send(message); msg.text = ""; } private function messageHandler(message:IMessage):void{ log.text += message.body.chatMessage + "\n"; } ]]> </mx:Script>

El mtodo send enviar un mensaje asncrono al servidor (AsyncMessage), por lo que deberemos aadir un manejador para capturar la respuesta (messageHandler) y mostrarla en el rea de texto, ya que al ser asncrono puede llegar en cualquier momento y se la asignaremos al consumidor. El ltimo aadido ser la siguiente sentencia creationComplete="consumer.subscribe(), que deberemos aadir a la etiqueta mx:Application, y que suscribe inmediatamente la aplicacin como consumidora de datos en el momento en que se crea. Finalmente tendremos que tener un mxml como el que se muestra a continuacin:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="consumer.subscribe()"> <mx:Script> <![CDATA[ import mx.messaging.messages.AsyncMessage; import mx.messaging.messages.IMessage; private function send():void{ var message:IMessage = new AsyncMessage(); message.body.chatMessage = msg.text; producer.send(message); msg.text = ""; } private function messageHandler(message:IMessage):void{ log.text += message.body.chatMessage + "\n"; } ]]>

34

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

</mx:Script> <mx:Consumer id="consumer" destination="chat" message="messageHandler(event.message)"/> <mx:Producer id="producer" destination="chat"/> <mx:Panel title="Chat" width="100%" height="100%"> <mx:TextArea id="log" width="100%" height="100%"/> <mx:ControlBar> <mx:TextInput id="msg" width="100%" enter="send()"/> <mx:Button label="Send B" click="send()"/> </mx:ControlBar> </mx:Panel> </mx:Application>

Ya slo hace falta probar el chat, para lo que presionamos el botn de ejecucin de Flex Builder. Adems debemos tener arrancado el servidor tomcat. Para aadir funcionalidad en la parte del servidor, podemos crear una clase java que se subscriba al canal, de forma que podamos modificar los datos en el servidor. 10.4.2. Objeto Remoto (Remoting Service) Mediante el servicio de objeto remoto (Remoting Service) podemos invocar desde nuestro cliente Flex a objetos java en el servidor, pudiendo llamar a mtodos del objeto y pudiendo obtener un tipo primitivo, un array, un objeto, una coleccin de objetos, etc. Para ello debemos definir una intefaz comn del objeto tanto en el cliente como en el servidor. Vamos a observar el ejemplo de BlazeDS en BlazeDS_HOME/tomcat/webapss/samples/inventory en el que desde el cliente invocamos a un objeto Producto, que contiene una serie de atributos (en este caso estticos, aunque el objeto Producto podra acceder a una base de datos). Primero analizaremos la parte del servidor: Dentro del directorio inventory, abrimos la carpeta WEB-INF/flex y observamos el archivo remoting-config.xml, la parte importante es la siguiente:
<destination id="product"> <properties> <source>ProductService</source> </properties> </destination>

En el XML se ha aadido un destino, al que referenciaremos desde Flex, llamado product y aadimos una propiedad source llamada ProductService, que es una clase java con un conjunto de mtodos que utilizan la clase Product. El canal utilizado en este caso est definido en services-config.xml, se utilizar el canal creado por defecto para comunicacin de objetos remotos:
<channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel"> <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/a mf" class="flex.messaging.endpoints.AMFEndpoint"/> </channel-definition>

Una vez configurado el servidor vamos a analizar la implementacin del mismo, tenemos dos clases Product.java y ProductService.java dentro de la carpeta BlazeDS_HOME\tomcat\webapps\samples\WEB-INF\src\flex\samples\product.

35

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Si abrimos Product.java podemos observar que la clase implementa la interfaz Serializable, esto es necesario debido a que Product.java va a ser un objeto que se va a enviar entre el cliente y el servidor, a travs del servicio de objeto remoto. Por otro lado si abrimos ProductService.java podemos ver que contiene un conjunto de mtodos pblicos, estos mtodos podrn ser invocados desde el cliente Flex. Los mtodos podrn devolver tipos primitivos, arrays, cadenas de texto o incluso objetos Product y colecciones de objetos Product, para lo que tendremos que definir una clase Product.as equivalente en el servidor. Finalmente necesitamos dos clases auxiliares para la conexin con la base de datos de ejemplo de BlazeDS que no vamos a analizar y que se encuentran en BlazeDS_HOME\tomcat\webapps\inventory\WEB-INF\classes\flex\samples\: ConnectionHelper.java DAOException.java

Con todo esto ya est definida por completo la parte del servidor. Ahora vamos a analizar la parte del cliente: Para poder analizar mejor la parte del cliente vamos a crar un proyecto llamado inventory de la siguiente forma. En la pantalla de creacin de proyecto, en Application server type marcamos J2EE y seleccionamos Use remote object Access service y LiveCycle Data Services. Pulsamos Next. Ahora es cuando necesitamos introducir los datos del servidor. Introducimos los mismos datos que en la imagen mostrada a continuacin, de acuerdo a la configuracin de nuestro equipo:

36

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

El cdigo del cliente se encuentra en BlazeDS_HOME\tomcat\webapps\samplesWEB-INF\flexsrc\flex-src.zip. Podemos extraer su contenido en el worspace de Flex Builder, o podemos extraerlo y copiar el contenido de la carpeta inventory dentro de flex-src.zip en nuestro proyecto Flex. En inventory tenemos el siguiente contenido: Directorio assets Contiene un conjunto de imgenes a utilizar en el cliente styles.css Es una hoja de estilo utilizada en el cliente Product.as Es la clase equivalente a Product.java y que utilizaremos para manejar los objetos Product que recibamos del servidor, as como para enviar objetos Product al servidor.

Si observamos el cdigo de product podemos ver lo siguiente:


package { [Bindable] [RemoteClass(alias="flex.samples.product.Product")] public class Product { public function Product() {

37

Adobe Flex SDK y Flex Builder 3


} public public public public public public } }

Universidad de Cdiz

var var var var var var

productId:int; name:String; category:String; price:Number = 0; description:String; qtyInStock:int = 0;

Hemos aadido una etiqueta [Bindable], lo que conseguimos con esto es que si el objeto Product cambia, todos los dems objetos que lo tengan asociados, estarn escuchando para actualizar tambin los datos. Tambin se ha aadido una etiqueta [RemoteClass(alias="flex.samples.product.Product")], lo que se consigue con esto es asociar la clase Product.as a la clase Product.java. Lo nico que necesitamos es que en ambas clases exista un conjunto de atributos equivalente. Inventory.mxml Es el mxml de la aplicacin ProductForm.mxml Es un formulario con un conjunto de campos que permiten visualizar un producto.

Vamos a analizar el cdigo de la clase ProductForm.mxml: Vemos que la clase tiene asociada una variable Product con una etiqueta [Bindable]
[Bindable] public var product:Product;

Con esto conseguimos que cuando se realice un cambio sobre la variable Product, se actualice inmediatamente en ProductForm.mxml.
private function save():void { if (nameValidator.validate().type == ValidationResultEvent.INVALID) return; product.name = productName.text; product.category = category.text; product.price = Number(price.text); product.qtyInStock = parseInt(qtyInStock.text); product.description = description.text; if (product.productId > 0) srv.update(product); else srv.create(product); } private function createResult(event:ResultEvent):void { product = event.result as Product; label = product.name; } private function removeResult(event:ResultEvent):void { parent.removeChild(this); }

En el mtodo save, cogemos los campos del formulario y llamamos a los mtodos srv.update(product) srv.create(product), siendo srv una referencia a una variable 38

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

RemoteObject, en este caso ser un objeto remoto ProductService.java como veremos ms adelante, y los mtodos create y update, mtodos de la interfaz de ProductService.java. Tambin tenemos dos mtodos que reciben un evento como parmetro, createResult y removeResult; estos mtodos son utilizados cuando se realiza una llamada create o remove sobre el objeto remoto srv (mtodos implementados en ProductService.java), de forma que actualicemos el estado del formulario actual. Finalmente, tenemos el objeto remoto:
<mx:RemoteObject id="srv" destination="product"> <mx:method name="create" result="createResult(event)"/> <mx:method name="remove" result="removeResult(event)"/> </mx:RemoteObject>

El atributo destination hace referencia al destino que anteriormente habamos aadido en remoting-config.xml. Tambin se han aadido dos mtodos: create y remove, que hacen referencia a los mtodos create y remove de ProductService.java, y que tienen asociados dos manejadores de eventos, createResult y removeResult. SearchPopup.mxml Es una lista que muestra de forma dinmica los productos que coinciden con los parmetros de bsqueda, en este caso se ha implementado una bsqueda por nombre.

Vamos a analizar el cdigo de SearchPopup.mxml: Bsicamente SearchPopup.mxml es un objeto List, que tiene asociado un manejador para tratar los eventos click y keydown:
<mx:List xmlns:mx="http://www.adobe.com/2006/mxml" dropShadowEnabled="true" currentState="hidden" labelField="name" keyDown="searchKeyDownHandler(event)" click="openSelectedItem()">

Como anteriormente, tambin tenemos un objeto remoto con el atributo destination apuntando a product:
<mx:RemoteObject id="srv" destination="product" result="resultHandler(event)"/>

El nico mtodo que invoca al objeto remoto es el mtodo pblico search:


public function search(searchStr:String):void { dataProvider = null; srv.getProduct(searchStr); if (currentState == "hidden") currentState = ""; }

Lo que se hace aqu es invocar al mtodo getProduct de ProductService.java, y actualizar el contenido del objeto List por medio del manejador resultHandler:
private function resultHandler(event:ResultEvent):void { dataProvider = event.result as ArrayCollection; if (dataProvider && dataProvider.length > 0) { selectedIndex = 0; }

39

Adobe Flex SDK y Flex Builder 3


}

Universidad de Cdiz

El contenido de la lista se actualiza siempre que actualizamos el atributo dataprovider. 10.4.3. Proxy Service El servicio de proxy es similar a la interfaz HttpService mostrada anteriormente pero con la ventaja de que el servidor llamado no necesita incluir un archivo crossdomain.xml, esto se soluciona principalmente utilizando un proxy entre la llamada HttpService y el servidor, cosa que se puede hacer fcilmente en cualquier servidor. En BlazeDS tenemos un pequeo ejemplo de utilizacin del proxy service en la carpeta BlazeDS_HOME/tomcat/webapps/samples/testdrive-httpservice. Vamos a analizarlo. Parte del servidor: Vamos a analizar los archivos de configuracin del servidor en WEB-INF\flex. Primero analizaremos el archivo proxy-config.xml, la parte que nos interesa es la siguiente:
<destination id="catalog"> <properties> <url>/{context.root}/testdrive-httpservice/catalog.jsp</url> </properties> </destination>

La URL hace referencia a un archivo jsp que se encuentra en el mismo servidor y que llama a la base de datos devolviendo un XML con una lista de productos. La referencia al canal http la encontramos en:
<default-channels> <channel ref="my-http"/> <channel ref="my-amf"/> </default-channels>

El canal http para la comunicacin se encuentra definido en el archivo services-config.xml que es donde se encuentran definidos todos los canales para los diferentes servicios, en este caso el canal http presenta el siguiente aspecto:
<channel-definition id="my-http" class="mx.messaging.channels.HTTPChannel"> <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/h ttp" class="flex.messaging.endpoints.HTTPEndpoint"/> </channel-definition>

Al igual que en el ejemplo anterior se utilizan las clases Product.java que ser el modelo, y la clase ProductService.java que contendr la interfaz del servicio. Ambas clases se pueden encontrar dentro de BlazeDS, en la carpeta: BlazeDS_HOME\tomcat\webapps\samples\WEB-INF\src\flex\samples\product Cliente: El cliente va a consistir en dos archivos, un MXML que muestra la lista de productos utilizando un componente DataGrid y un jsp que como hemos mencionado antes devuelve un XML con los productos que se encuentran en la base de datos. El cdigo del cliente se encuentra en BlazeDS_HOME\tomcat\webapps\samplesWEB-INF\flexsrc\flex-src.zip, en la carpeta testdrive-httpservice. Vamos a crear un proyecto en Flex Builder al que nombraremos testdrive-httpservice.

40

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

En la pantalla de creacin de proyecto, en Application server type marcamos J2EE y seleccionamos Use remote object Access service y LiveCycle Data Services. Pulsamos Next. En la siguiente pantalla introducimos los datos tal como aparece en la imagen, pero adaptados a nuestro equipo:

Ahora podemos copiar el contenido de la carpeta testdrive-httpservice de BlazeDS_HOME\tomcat\webapps\samplesWEB-INF\flex-src\flex-src.zip en nuestro proyecto o extraerlo en el directorio del mismo. Vamos a analizar el cdigo del cliente: Vemos que hay dos archivos, el jsp (catalog.jsp) que mencionamos antes, cuyo cdigo es:
<%@page import="flex.samples.product.ProductService, flex.samples.product.Product, java.util.List"%> <?xml version="1.0" encoding="utf-8"?> <catalog> <% ProductService srv = new ProductService(); List list = null; list = srv.getProducts(); Product product;

41

Adobe Flex SDK y Flex Builder 3


for (int i=0; i<list.size(); i++) { product = (Product) list.get(i); %>

Universidad de Cdiz

<product productId="<%= product.getProductId()%>"> <name><%= product.getName() %></name> <description><%= product.getDescription() %></description> <price><%= product.getPrice() %></price> <image><%= product.getImage() %></image> <category><%= product.getCategory() %></category> <qtyInStock><%= product.getQtyInStock() %></qtyInStock> </product> <% } %> </catalog>

El XML devuelto tiene la estructura:


<catalog> <product></product> <product></product> </catalog>

Es decir, un objeto catalog compuesto por n objetos product. El cdigo archivo MXML (main.mxml) es el siguiente:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" backgroundColor="#FFFFFF"> <mx:HTTPService id="srv" destination="catalog" useProxy="true"/> <mx:DataGrid dataProvider="{srv.lastResult.catalog.product}" width="100%" height="100%"/> <mx:Button label="Get Data" click="srv.send()"/> </mx:Application>

Vemos que slo est compuesto por un elemento HTTPService (srv), con el atributo destination igual a catalog que como hemos visto antes en el archivo de configuracin del proxy proxy-config.xml apunta a catalog.jsp; y el atributo useProxy a true, de forma que no sea necesario un archivo crossdomain.xml en el servidor. El objeto DataGrid se rellena automticamente debido a que el atributo dataprovider apunta directamente al conjunto de productos en forma de XML devuelto por catalog.jsp: dataProvider="{srv.lastResult.catalog.product}" Ya que como hemos visto en ejemplos anteriores, el componente Object de ActionScript, al recibir un XML, lo parsea automticamente, en este caso srv.lastResult devuelve un objeto de tipo Object que se puebla directamente con los datos devueltos por la respuesta.

10.5. Localizacin de aplicaciones


Las aplicaciones creadas con Flex SDK disponen de gestin de localizacin, es decir, podemos adaptar nuestras aplicaciones a distintos idiomas. Las localizaciones disponibles por defecto son en_US y jp_JP. Si queremos aadir nuevas localizaciones a Flex SDK debemos crear una carpeta con el nombre de la localizacin en Flex_SDK_HOME\frameworks\locale, en nuestro caso vamos a aadir la carpeta es_ES (espaol de Espaa).

42

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

El siguiente paso es ejecutar el comando copylocale desde Flex_SDK_HOME\frameworks\locale, que se encuentra en Flex_SDK_HOME\bin, de la siguiente forma: >copylocale en_US es_ES Una vez que tenemos nuestra carpeta, debemos aadirla a los parmetros de compilacin del proyecto en Flex Builder. En este caso vamos a abrir nuestro proyecto yahoo, hacemos clic derecho sobre el proyecto y abrimos la ventana de propiedades, y en la ventana de propiedades nos colocamos en Flex Compiler:

Ilustracin 21: Ventana de propiedades de compilacin (Flex Builder)

Podemos ver que en el atributo Additional compiler arguments se ha aadido el parmetro locale en_US, para que a la hora de compilar reconozca el castellano, debemos aadir: es_ES -source-path=../locale/{locale} De forma que nos quede as:

43

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Nota: Si estamos usando directamente Adobe Flex SDK, cada vez que compilemos con mxmlc debemos pasar los parmetros de localizacin: >mxmlc locale=en_US,es_ES -source-path=../locale/{locale} Ejemplo.mxml El siguiente paso es crear una carpeta denominada locale en el directorio de nuestro proyecto. En esa carpeta debemos por cada idioma, una carpeta con su nombre, en nuestro caso la estructura sera:
>Directorio del Proyecto >locale >en_US >es_ES

Dentro de cada carpeta de localizacin debemos aadir un archivo .properties (los dos con el mismo nombre), por ejemplo, myBundle.properties:
>Directorio del Proyecto >locale >en_US >myBundle.properties >es_ES >myBundle.properties

En estos archivo tendremos los mensajes de nuestra aplicacin en cada uno de los idiomas, en nuestro caso queremos que los siguiente mensajes aparezcan en ambos idiomas: Buscar, NResultados, Idioma, Formato, DEMO BUSCADOR DE YAHOO: En la carpeta, es_ES editamos myBundle.properties: 44

Adobe Flex SDK y Flex Builder 3


buscar=buscar idioma=idioma nResultados=NResultados formato=Formato titulo=DEMO BUSCADOR DE YAHOO

Universidad de Cdiz

En la carpeta en_US editamos myBundle.properties:


buscar=search idioma=language nResultados=NResults formato=Format titulo=YAHOO SEARCH ENGINE DEMO

Debemos tener cuidado con la codificacin de los archivos de propiedades, ya que puede que no nos reconozca los acentos u otros caracteres especiales, para evitar problemas, nos metemos en las propiedades de cada uno y seleccionamos en Text file enconding UTF-8:

Ilustracin 22: Ventana de propiedades de archivo (Flex Builder)

Ahora debemos aadir a nuestro mxml principal, la siguiente etiqueta, justo debajo de <mx:Application>:
<mx:Metadata> [ResourceBundle("myBundle")] </mx:Metadata>

El ltimo paso es editar los label de nuestra aplicacin para que aparezcan en el idioma adecuado, de forma que sustituyamos el texto de cada una por lo siguiente, por ejemplo para Buscar: @Resource(bundle='myBundle', key='buscar') 45

Adobe Flex SDK y Flex Builder 3 para idioma: @Resource(bundle='myBundle', key=idioma)

Universidad de Cdiz

La estructura @Resource(bundle=archivo de propiedades, key=key) se utiliza dentro de las etiquetas en un archive mxml, si queremos hacerlo en un archive ActionScript (.as) debemos utilizar los siguiente: resourceManager.getString("archivo de propiedades", "key") Si editamos todas nuestras etiquetas, el cdigo resultante es el siguiente:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" backgroundGradientAlphas="[1.0, 1.0]" backgroundGradientColors="[#D2E0FA, #F1F290]"> <mx:Metadata> [ResourceBundle("myBundle")] </mx:Metadata> <mx:Text x="10" y="10" text="@Resource(bundle='myBundle', key='titulo')" fontWeight="bold" fontSize="15"/> <mx:HBox x="10" y="42" width="100%"> <mx:TextInput id="palabrasClave"/> <mx:Button label="@Resource(bundle='myBundle', key='buscar')" click="buscar()"/> </mx:HBox> <mx:HBox x="10" y="72" width="100%" backgroundColor="#6F98F4"> <mx:Label text="@Resource(bundle='myBundle', key='nResultados')" fontWeight="bold"/> <mx:ComboBox id="nResultadosCB" cornerRadius="0"> <mx:Array> <mx:String>10</mx:String> <mx:String>20</mx:String> <mx:String>30</mx:String> <mx:String>40</mx:String> <mx:String>50</mx:String> </mx:Array> </mx:ComboBox> <mx:Label text="@Resource(bundle='myBundle', key='idioma')" fontWeight="bold"/> <mx:ComboBox cornerRadius="0" id="languageCB"> <mx:Array> <mx:String>es</mx:String> <mx:String>en</mx:String> <mx:String>fr</mx:String> <mx:String>de</mx:String> </mx:Array> </mx:ComboBox> <mx:Label text="@Resource(bundle='myBundle', key='formato')" fontWeight="bold"/> <mx:ComboBox id="formatCB"> <mx:Array> <mx:String>any</mx:String> <mx:String>html</mx:String> <mx:String>msword</mx:String> <mx:String>pdf</mx:String> <mx:String>ppt</mx:String> <mx:String>rrs</mx:String> <mx:String>txt</mx:String> <mx:String>xls</mx:String> </mx:Array>

46

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

</mx:ComboBox> </mx:HBox> <mx:DataGrid x="10" y="102" id="resultados" width="100%" height="100%"> </mx:DataGrid> <mx:Image x="264" y="10" source="img/logoyahoo.png"/> <mx:Script> <![CDATA[ import mx.collections.ArrayCollection; import mx.rpc.xml.SimpleXMLDecoder; import mx.rpc.events.FaultEvent; import mx.controls.Alert; import mx.rpc.events.ResultEvent; import mx.rpc.http.HTTPService; private function buscar():void { // Debemos obtener la estructura por http var servicio:HTTPService = new HTTPService(); servicio.url = "http://search.yahooapis.com/WebSearchService/V1/webSearch?appid=Yahoo Demo"; servicio.method = "GET"; var adult_ok:int = 0; servicio.request = { query:palabrasClave.text, laguage:languageCB.text, results:nResultadosCB.selectedItem, format:formatCB.selectedItem }; servicio.resultFormat = "xml"; // Aadimos los manejadores para procesar la respuesta servicio.addEventListener(ResultEvent.RESULT, manejadorObtener); servicio.addEventListener(FaultEvent.FAULT, manejadorErrorObtener); // Enviamos servicio.send(); } private function manejadorObtener(event:ResultEvent):void { var response:String = event.result.toString(); var xmlDoc:XMLDocument; try { // Comprobamos si el resultado es un XML xmlDoc = new XMLDocument(response); // Procesamos el XML var decoder:SimpleXMLDecoder = new SimpleXMLDecoder(true); var resultObj:Object = decoder.decodeXML(xmlDoc); resultados.dataProvider = resultObj.ResultSet.Result; } catch(error:Error) { Alert.show("Error en el formato de la respuesta");

47

Adobe Flex SDK y Flex Builder 3


} }

Universidad de Cdiz

private function manejadorErrorObtener(event:FaultEvent):void { Alert.show("Error al obtener el listado de videos"); } ]]> </mx:Script> </mx:Application>

Si ejecutamos nuestra aplicacin, veremos que se muestra en espaol, esto es debido a que el swf reconoce la regin donde nos encontramos. Ms adelante, veremos como poder seleccionar el idioma del swf pasndole parmetros http.

10.6. Paso de parmetros http a un swf


Un objeto shockwave/flash puede recibir parmetros http por medio del mtodo GET, ya que solamente los puede recibir leyndolos de la URL por la que es invocado. En nuestro caso vamos a aadir un parmetro lang a nuestra demo de buscador de yahoo con el fin de poder seleccionar el idioma que muestre la aplicacin. Vamos a crear un mtodo init dentro de yahoo.mxml que se lance inmediatamente despus que la aplicacin se haya cargado en el navegador, para ello tenemos que hacer dos cosas: 1. Asociar al evento creationComplete el mtodo init(). Esto lo hacemos en la etiqueta <mx:Application> aadiendo creationComplete=init(), de forma que tengamos:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()">

2. Ahora debemos crear un mtodo init() dentro del espacio para aadir cdigo ActionScript, el mtodo init comprobar que existe un parmetro lang y posteriormente comprobar su valor:
private function init():void { // Variables flashVars var params:Object = this.parameters; // Si nos han pasado un parmetro con el lenguaje if(params.lang) { var language:String = params.lang; if(language == "en" || language.substr(0,2) == "en") { language = "en_US"; } else if(language == "es" || language.substr(0,2) == "es") { language = "es_ES"; } // Recorremos todos los lenguages que se encuentran en el gestor de recursos for(var i:int = 0; i < resourceManager.localeChain.length; i++) {

48

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

// Si el lengauge est contenido dentro de nuestro gestor de recursos if(language == resourceManager.localeChain[i]) { // Establecemos el lenguage de la aplicacin resourceManager.localeChain = [language]; } } } }

Las variables recibidas en el swf, llamadas FlashVars, se acceden a travs del atributo de la aplicacin parameters. Fuera del main podemos acceder a las variables invocando Application.application.parameters. Las variables se devuelven en forma de Object flash, es decir es un objeto con un conjunto de atributos del que no sabemos a priori los nombres. Podramos obtener los nombres de todas las variables y sus valores de la siguiente forma:
var item:String; var arrColl:ArrayCollection = new ArrayCollection(); /* Populate the ArrayCollection object with the FlashVars. */ for (item in params) { Alert.show("Parmetro: " + item + " Valor: " + params[item]); }

Este cdigo, aadido al final del mtodo init, muestra en ventanas de aviso, los parmetros recibidos y sus correspondientes valores. Si abrimos directamente el swf del buscador con un navegador y aadimos al final parmetros http, veremos cmo se nos muestran en pantalla. Adems, si pasamos un parmetro lang con un valor correcto podremos seleccionar el idioma de la interfaz. Pero esto no es del todo til, ya que normalmente los objetos shockwave/flash vienen embebidos en archivos html, o archivos jsp, php, etc. En este caso, lo que tenemos que hacer es pasar los parmetros recibidos en el html, a nuestro swf. Esto se consigue capturando las variables a travs de cdigo java o php dentro del html que envuelve al swf, como veremos a continuacin.

11.

Creacin de un html que envuelva a el swf

El html que envuelve un swf, tiene tres funciones principales: 1. Aadir ms contenido a la pgina. 2. Comprobar si el usuario tiene una versin adecuada de Flash player. 3. Pasar variables al objeto swf. Por defecto, Flex Builder nos genera un html que envuelve el objeto swf generado. El html tiene cdigo javascript que nos permite comprobar si el usuario tiene una versin compatible de Flash player, y en caso de que lo tenga lanza el swf. Tambin tiene cdigo no javascript que permite embeber un swf en un html:
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="yahoo" width="100%" height="100%" codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swf lash.cab"> <param name="movie" value="yahoo.swf" /> <param name="quality" value="high" /> <param name="bgcolor" value="#869ca7" /> <param name="allowScriptAccess" value="sameDomain" />

49

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

<embed src="yahoo.swf" quality="high" bgcolor="#869ca7" width="100%" height="100%" name="yahoo" align="middle" play="true" loop="false" quality="high" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer"> </embed> </object>

El problema de este cdigo html, es que no detecta que no tengamos instalado Flash player o que no tengamos instalada la versin adecuada.

11.1. Paso de variables


Como se ha comentado antes, se pueden enviar variables a nuestro objeto shockwave/flash desde el archivo que lo envuelve, si lo hacemos en un archivo html slo podremos pasarle variables estticas previamente definidas, pero si lo hacemos en un archivo con capacidades dinmicas, por ejemplo un .jsp o un php, podemos pasarle las variables que queramos, por ejemplo, vamos a crear un .jsp que envie el parmetro lang a nuestro swf:
<html> <head> <style> body { margin: 0px; overflow:hidden } </style> </head> <% String lang = (String) request.getParameter("lang"); %> <body scroll="no"> <object classid="clsid:D27CDB6E-AE6D-11cf-96B8444553540000" id="yahoo" width="100%" height="100%" codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swf lash.cab"> <param name="movie" value="yahoo.swf?lang=<%= lang%>" /> <param name="quality" value="high" /> <param name="bgcolor" value="#869ca7" /> <param name="allowScriptAccess" value="sameDomain" /> <embed src="yahoo.swf?lang=<%= lang%>" quality="high" bgcolor="#869ca7" width="100%" height="100%" name="yahoo" align="middle" play="true"loop="false" quality="high" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer"> </embed> </object> </body> </html>

Las variables que pasamos a un swf nos pueden servir para configurarlo o para instanciarlo, por ejemplo, si tenemos un reproductor de video flash player, podemos enviarle una variable para indicarle que vdeo debe reproducir, el reproductor se encargar ms delante de recuperar el video del servidor y reproducirlo

12.

Otras caractersticas de Adobe Flex SDK

12.1. Comunicacin con interfaces externas (javascript)


Un objeto shockwave/flash puede utilizar cdigo javascript del html que lo envuelve, e invocarlo desde su cdigo, pudiendo enviarle informacin y recuperarla de la misma forma a travs de su interfaz de comunicacin. 50

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Por ejemplo, podemos crear un mtodo javascript que abra un popup y detectar si el navegador lo ha bloqueado o no a travs del valor devuelto por el mtodo javascript, todo esto desde nuestro cdigo ActionScript. Este sera el cdigo javascript:
function abrirPopup( url ) { try { var opciones="toolbar=no, Location=no, directories=no, status=no, menubar=no, scrollbars=auto, resizable=yes, fullscreen=yes"; var popup = window.open( url, , opciones ); if ( popup == null ) return false;

if ( window.opera ) if (!popup.opera) return false; } catch(err) { return false; } return true; }

Recibe como parmetro la url a abrir y devuelve un valor verdadero o falso en funcin de si lo ha podido abrir o no. Vamos a probrarlo en nuestro proyecto yahoo. Aadimos a la imagen o al ttulo un evento clic y le asignamos un mtodo abrirPopup(). El cdigo del mtodo abrirPopup() es el siguiente:
private function abrirPopup():void { var url:String = "http://www.google.es"; var exito:Boolean = ExternalInterface.call("abrirPopup", url, "_self"); if (!exito) { Alert.show("Ventana emergente bloqueada, por favor habilite las ventanas emergementes para este sitio en su navegador", "Aviso" ); } }

La llamada ExternalInterface.call es la que se comunica con el cdigo javascript, el primer parmetro es el nombre del mtodo, y los siguientes los parmetros a recibir (tantos como sean necesarios, admitiendo tambin arrays de datos).

13.

SharedObjects

Los SharedObjects son objetos parecidos a las cookies, son pequeos archivos en los que se pueden almacenar datos en el equipo del cliente para luego recuperarlos en esa misma sesin o en otra.

51

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Su tamao est limitado a 100KB y slo son accesibles por la aplicacin que los creo, si bien, tienen ciertos inconvenientes: 1. Se guardan en una ruta fija, por lo que es fcil encontrarlos. 2. Los datos se guardan en claro, si bien siempre se pueden cifrar en la aplicacin antes de escribirlos. Vamos a crear un pequeo ejemplo extendiendo un poco la funcionalidad del chat que hemos creado anteriormente, utilizando un SharedObject que guarde los mensajes que el propio usuario ha ido enviando. Abrimos el proyecto chat1 y creamos un nuevo componente llamado Historico. El componente va a estar basado en un TitleWindow y va a contener un TextArea donde se mostrarn las conversaciones y al que asignaremos el identificador areaTexto.

Ilustracin 23: Vista de diseo del componente Historico.mxml

En el TitleWindow establecemos el atributo showCloseButton a true y aadimos y asignamos el evento close a un mtodo llamado cerrar(); esto nos servir para cerrar el componente una vez abierto. El cdigo resultante con el mtodo cerrar incluido es el siguiente:
<?xml version="1.0" encoding="utf-8"?> <mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" width="400" height="300" title="Histrico de conversaciones" showCloseButton="true" close="cerrar()"> <mx:TextArea width="100%" height="100%" id="areaTexto"/> <mx:Script> <![CDATA[ import mx.managers.PopUpManager;

52

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

public function setTexto(texto:String):void { areaTexto.text = texto; } private function cerrar():void { PopUpManager.removePopUp(this); } ]]> </mx:Script> </mx:TitleWindow>

Ahora nos vamos al componente chat1, debemos aadir un botn que lance un evento que nos permita ver el histrico, por lo que aadimos un botn justo al lado del de envo de mensajes, tal como muestra la siguiente imagen:

Ilustracin 24: Componente chat1.mxml modificado

Ahora editamos el mtodo send() del componente de forma que escriba en un SharedObject el mensaje enviado ms la fecha actual, de forma que tengamos algo parecido a lo mostrado a continuacin:
private function send():void{ var message:IMessage = new AsyncMessage(); message.body.chatMessage = msg.text; producer.send(message); var msgAux:String = msg.text; msg.text = ""; // Escribimos el mensaje en el historial var soHistorico:SharedObject = SharedObject.getLocal("historico"); if(soHistorico.data.conversaciones != null)

53

Adobe Flex SDK y Flex Builder 3


{

Universidad de Cdiz

soHistorico.data.conversaciones += msgAux + " enviado el " + (new Date()).toDateString() + "\n"; soHistorico.flush(); } else { soHistorico.data.conversaciones = msgAux + " enviado el " + (new Date()).toDateString() + "\n"; soHistorico.flush(); } }

Ahora nos vamos al nuevo botn del componente y le aadimos un evento click al que asignaremos un mtodo verConversaciones(), cuyo cdigo es el siguiente:
private function verConversaciones():void { var soHistorico:SharedObject = SharedObject.getLocal("historico"); var his:Historico = Historico(PopUpManager.createPopUp(this, Historico, false)); PopUpManager.centerPopUp(his); his.setTexto(soHistorico.data.conversaciones); }

El mtodo verConversaciones() lee del SharedObject en el que hemos escrito previamente, crea un objeto Historico mediante el gestor de popups, de forma que se muestre como una ventana emergente, y le asigna el contenido ledo. Podemos probar el chat modificado y comprobar cmo las conversaciones se guardan a pesar de haber el navegador o incluso despus de reiniciar el servidor.

14.

Adobe AIR

Adobe AIR es una extensin de Flex SDK que nos permite crear aplicaciones de escritorio. Funciona de forma similar a las aplicaciones flash para la web, pero en este caso se utiliza un reproductor diferente al flash player, el reproductor Adobe AIR, que puede descargarse de la siguiente pgina: http://get.adobe.com/es/air/ Las aplicaciones se construyen de forma similar a las aplicaciones Flex, pero con la particularidad de que podemos acceder al sistema de ficheros de nuestro ordenador, adems cada aplicacin Adobe AIR puede acceder a su base de datos SQLite. El principal problema que presenta Adobe AIR es su incapacidad para comunicarse directamente con otras aplicaciones del sistema, aunque actualmente se estn desarrollando soluciones para paliar esta deficiencia, no son especialmente sencillas ni eficientes.

14.1. Creando una aplicacin con Adobe AIR


Vamos a crear una sencilla aplicacin con Adobe AIR, un editor de texto que nos permita guardar y cargar nuestros ficheros de texto. Para ello vamos a crear un nuevo proyecto Adobe AIR. Hacemos clic en File\New\Flex Project y marcamos Desktop Application:

54

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Ilustracin 25: Ventana de creacin de proyecto Adobe AIR

Le damos como nombre Editor. En la casilla Application server type, debemos tener puesto none. Pulsamos Finish. Como un editor de texto consta de una interfaz muy simple, podemos aadir directamente los elementos en nuestro fichero Editor.mxml. Aadimos un componente VBox que ocupe todo el espacio (altura y anchura al 100%), y dentro un HBox y un TextArea, de forma que nos quede as:

55

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Aadimos tres botones al HBox, uno para guardar, otro para guardar como y otro para abrir:

56

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

A los botones les llamaremos: botonGuardar, botonGuardarComo y botonAbrir y al TextArea, areaTexto. De forma que el cdigo nos quede as:
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> <mx:VBox x="0" y="0" width="100%" height="100%"> <mx:HBox width="100%"> <mx:Button label="Abrir" id="botonAbir"/> <mx:Button label="Guardar" id="botonGuardar"/> <mx:Button label="Guardar como" id="botonGuardarComo"/> </mx:HBox> <mx:TextArea width="100%" height="100%" id="areaTexto"/> </mx:VBox> </mx:WindowedApplication>

Si arrancamos nuestra aplicacin y vemos el resultado hasta ahora. Vamos a crear una nueva clase ActionScript, denominada EntradaSalida, para gestionar la lectura y escritura de nuestros ficheros en el sistema. Pulsamos File\New\ActionScript class. Primero vamos a crear dos atributos en nuestra clase EntradaSalida, un atributo buffer de tipo String y un atributo fichero de tipo File y sus correspondientes get y set:

57

Adobe Flex SDK y Flex Builder 3


package { import flash.filesystem.File; public class EntradaSalida { private var buffer:String = null; private var fichero:File = null; public function EntradaSalida() { } public function getBuffer():String { return this.buffer; }

Universidad de Cdiz

public function setBuffer(buffer:String):void { this.buffer = buffer; } public function getFichero():File { return this.fichero; } public function setFichero(fichero:File):void { this.fichero = fichero; } } }

Ahora crearemos el mtodo para guardar como:


public function guardarComo(texto:String):void { var file:File = File.desktopDirectory; file.browseForSave("Guardar como:"); buffer = texto; file.addEventListener(Event.SELECT, manejadorGuardarComo); }

El mtodo guardarComo recibe como parmetro de entrada una cadena de texto y crea un objeto File que nos permite abrir el explorador del sistema para elegir la ubicacin donde guardar el fichero. Guardamos el texto en la variable auxiliar buffer de la clase y aadimos a nuestra variable file un listener (manejadorGuardarComo) que escucha cuando el usuario selecciona la ruta donde almacenar el fichero. Ahora debemos implementar el listener que se llamar manejadorGuardarComo y que recibe un evento como parmetro:
private function manejadorGuardarComo(event:Event):void { //Cogemos el nombre del fichero desde la ruta completa var tmpArr:Array = File(event.target).nativePath.split(File.separator); //Creamos un nuevo fichero con la extensin por defecto

58

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

fichero = new File("file:///" + tmpArr.join(File.separator)); //Guardamos var stream:FileStream = new FileStream(); stream.open(fichero, FileMode.WRITE); stream.writeUTFBytes(buffer); buffer = null; stream.close(); }

El mtodo manejadorGuardarComo crea un nuevo fichero (en una variable de la clase fichero), lo guarda y a continuacin escribe el contenido en el destino elegido. Vamos ahora a implementar el mtodo guardar:
public function guardar(texto:String):void { if(this.fichero == null) { guardarComo(texto); } else { //Guardamos var stream:FileStream = new FileStream(); stream.open(this.fichero, FileMode.WRITE); stream.writeUTFBytes(texto); buffer = null; stream.close(); } }

El mtodo guardar comprueba si existe un fichero asignado ya en nuestra clase, si lo hay guarda directamente y si no lo hay, llamar al mtodo guardarComo. Finalmente crearemos el mtodo abrir. El mtodo abrir recibir como parmetro un TextArea que es el rea de texto de nuestro editor, para poder cargar all el contenido el fichero abierto:
public function abrir(areaTexto:TextArea):void { // Almacenamos el rea de texto this.areaTexto = areaTexto; // Lanzamos el explorador var file:File = new File(); file.browseForOpen("Abrir"); file.addEventListener(Event.SELECT, manejadorAbrir); }

Debido a que necesitamos aadir un listener que escuche cuando el usuario pulse abrir en el explorador, tendremos que crear una variable auxiliar en la clase que almacene nuestra rea de texto entre ambas llamadas, ya que no se puede pasar parmetros entre un mtodo y su listener, lo que supone uno de los principales inconvenientes de los eventos.
private function manejadorAbrir(event:Event):void { //Cogemos la ruta del fichero y abrimos fichero = new File(File(event.target).nativePath); var stream:FileStream = new FileStream(); // Abrimos el fichero y cogemos su contenido stream.open(fichero, FileMode.READ); // Cargamos el texto ledo en el rea de texto

59

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

areaTexto.text = stream.readUTFBytes(fichero.size); }

Ya tenemos nuestra clase EntradaSalida terminada, ahora slo nos falta asociarla a la vista grfica de forma que cuando pulsemos los botones seamos capaces de abrir, editar y guardar nuestros ficheros. Abrimos el fichero Editor.mxml, y aadimos a cada botn un evento asociado al clic:
<mx:Button label="Abrir" id="botonAbir" click="abrir()"/> <mx:Button label="Guardar" id="botonGuardar" click="guardar()"/> <mx:Button label="Guardar como" id="botonGuardarComo" click="guardarComo()"/>

Ahora debemos implementar los mtodos asociados a los clic, primero aadimos las etiquetas de script que nos permiten aadir cdigo a nuestro mxml:
<mx:Script> <![CDATA[ ]]> </mx:Script>

Justo encima de la etiqueta </mx:WindowedApplication>. Dentro creamos una variable EntradaSalida y los tres mtodos:
<mx:Script> <![CDATA[ private var entradaSalida:EntradaSalida = new EntradaSalida(); private function abrir():void { } private function guardar():void { } private function guardarComo():void { } ]]> </mx:Script>

Aadimos el contenido a los mtodos invocando a nuestra variable entradaSalida, de forma que el cdigo completo nos quede de esta forma:
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> <mx:VBox x="0" y="0" width="100%" height="100%"> <mx:HBox width="100%"> <mx:Button label="Abrir" id="botonAbir" click="abrir()"/> <mx:Button label="Guardar" id="botonGuardar" click="guardar()"/> <mx:Button label="Guardar como" id="botonGuardarComo" click="guardarComo()"/> </mx:HBox> <mx:TextArea width="100%" height="100%" id="areaTexto"/> </mx:VBox> <mx:Script>

60

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

<![CDATA[ private var entradaSalida:EntradaSalida = new EntradaSalida(); private function abrir():void { this.areaTexto.text = entradaSalida.abrir(); } private function guardar():void { entradaSalida.guardar(this.areaTexto.text); } private function guardarComo():void { entradaSalida.guardarComo(this.areaTexto.text); } ]]> </mx:Script> </mx:WindowedApplication>

Ya tenemos nuestro editor multiplataforma implementado:

Ilustracin 26: Prueba del editor de texto

Ahora slo nos faltara crear un instalable que nos permita instalarlo en nuestros equipos y configurar las opciones de instalacin, como seran asociar una extensin de fichero determinados a nuestro programa, aadir un icono de instalacin, etc. Todo esto se puede configurar en el archivo Editor-app.xml que se ha creado automticamente en nuestro proyecto, para ms informacin sobre el fichero de configuracin consultar: http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS5b3ccc516d4fbf351e63e3d118666ade 46-7ff1.html 61

Adobe Flex SDK y Flex Builder 3

Universidad de Cdiz

Cuando hayamos aadido todas las caractersticas de instalacin que queramos, podemos crear un instalable pulsando en File\Export\Release Build, aunque slo nos permitir instalarlo en sistemas con Adobe AIR previamente instalado.

Anexo I: Instalacin de Adobe Flex SDK


Flex SDK es opensource, se puede descargar http://www.adobe.com/cfusion/entitlement/index.cfm?e=flex3sdk en la direccin

Lo descargamos y extraemos en una nueva carpeta, por ejemplo C:\Flex_HOME Lo primero es configurar Adobe Flex SDK, por lo que aadimos a las variables de entorno el directorio bin (Flex_HOME/bin) Existen dos comandos principales: compc y mxmlc mxmlc se utiliza para construir los ficheros .swf, que pueden ser reproducidos por Flash Player. Un ejemplo de compilacin podra ser >mxmlc Clase.as (Si se trata de una clase ActionScript) >mxmlc Clase.mxml (Si se trata de un mxml) Se generar un archivo .swf cada vez que compilemos y que podremos utilizar ya como cliente, ya que se reproducir con flash player. compc se utiliza para construir bibliotecas, obteniendo ficheros .swc

Con Adobe Flex SDK y el comando mxmlc podemos crear cualquiera de los ejemplos del manual, simplemente creando un directorio con los ficheros fuentes y compilando el fichero Main del proyecto.

Anexo II: Creando y compliando una aplicacin AIR con Adobe Flex SDK
Adobe AIR viene incluido en Adobe Flex SDK, las aplicaciones Adobe AIR se pueden crear utilizando Flex Builder, o creando directamente los proyectos en nuestro equipo y compilando los ficheros de la siguiente forma. Utilizando el comando amxmlc de Flex_HOME\bin podemos compilar nuestros proyectos AIR, por ejemplo: >amxmlc Editor.mxml Se generar un archivo Editor.swf, pero no podremos reproducirlo ya que se trata de un .swf para Adobe AIR. Para reproducirlo o para crear el instalador de la aplicacin debemos crear un archivo xml con la definicin de los parmetros de la aplicacin, en este caso se llamar Editorapp.xml:
<?xml version="1.0" encoding="UTF-8"?> <application xmlns="http://ns.adobe.com/air/application/1.5"> <id>Editor</id> <version>0.1</version> <filename>Editor</filename> <initialWindow> <content>Editor.swf</content> <visible>true</visible> <systemChrome>none</systemChrome> <transparent>true</transparent>

62

Adobe Flex SDK y Flex Builder 3


<width>400</width> <height>200</height> </initialWindow> </application>

Universidad de Cdiz

Este archivo bsicamente sirve para configurar la aplicacin y la instalacin de la misma, ya que las aplicaciones Adobe AIR pueden instalarse, es importante que el xml contenga correctamente la referencia al .swf generado. El xml puede configurar ms opciones, una descripcin se encuentra en: http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS5b3ccc516d4fbf351e63e3d118666ade 46-7ff1.html Para probar nuestra aplicacin debemos ejecutar el comando adl de Flex_HOME\bin, de la forma: >adl Editor-app.xml De esta forma se lanzar la aplicacin y podremos probarla. Para crear el instalador de nuestra aplicacin debemos hacer dos cosas utilizando el comando adt de Flex_HOME\bin: 1. Crear un certificado:
>adt -certificate -cn SelfSigned 1024-RSA sampleCert.pfx samplePassword

2. Crear el instalador:
>adt -package -storetype pkcs12 -keystore sampleCert.pfx Editor.air Editor-app.xml Editor.swf

63

Vous aimerez peut-être aussi