Hola Facebook! Gana combinando Flex y Facebook

Asi es, el buen Edgar Parada de Riactive me informa de este concurso que Mentez Mexico esta organizando para crear aplicaciones para Facebook. La convocatoria esta abierta para cualquier tecnologia, pero Flex es perfecto para desarrollar aplicaciones para Facebook.  Ademas es una buena oportunidad para mostrar su experiencia con Flex.

 Para ver las bases y premios del concurso abran este enlace : Concurso Flex + Facebook

Independientemente del premio, creo que la plataforma Facebook para desarrolladores abre muchas posibilidades. En general, una aplicacion en corriendo en Facebook tiene acceso a cierta informacion de los miembros, y su distribucion viral es ilimitada. A su vez, este modelo esta siendo usado por muchas otras compañias que estan abriendo su plataforma a travez de APIs con desarrolladores. Asi que una vez teniendo experiencia con una, las demas son mas faciles de adoptar. La gran oportunidad que como desarrolladores tenemos es que tenemos la oportunidad de monetizar dichas aplicaciones, y las buenas noticias es que la demanda esta en crecimiento.

 Asi mismo les recuerdo del grupo de Flex en Español en Facebook que sigue creciendo en miembros cada dia, y en el que pueden comunicar ideas y contactar a otros Flex developers de habla hispana.

Sesiones sobre Flex y AIR en Adobe Online Developer week

Excelente manera de aprender mas sobre Flex y AIR.

Adobe - Online events : Event Details
http://www.adobe.com/cfusion/event/index.cfm?event=detail&id=1200007&...
Adobe provides end-to-end web development tool suites and solutions.
Join us to see what the buzz is all about in this one week long event
with 20 sessions covering AIR, Flex, Flash, Mobile, ColdFusion and
Dreamweaver technologies.

Mis recomendaciones:

Building Rich Internet Applications with Flex 3
Monday, March 24, 2008
4:00 PM US/Pacific

Introduction to Adobe Blaze DS
Tuesday, March 25, 2008
9:00 AM US/Pacific

Integrating Salesforce.com and Flex
Tuesday, March 25, 2008
11:00 AM US/Pacific

Adobe AIR Local Data Storage Options With Emphasis on Using Embedded
SQL Databases
Wednesday, March 26, 2008
9:00 AM US/Pacific

Flex and Java - Tying the Knot!
Wednesday, March 26, 2008
4:00 PM US/Pacific

Flex Data Services
Thursday, March 27, 2008
9:00 AM US/Pacific

Flex Visual Data & Charting
Thursday, March 27, 2008
4:00 PM US/Pacific

ILOG Elixir: Your Remedy for Vibrant Data Visualization
Friday, March 28, 2008
11:00 AM US/Pacific

AIR Native Drag and Drop
Friday, March 28, 2008
1:00 PM US/Pacific

Flex Architecture
Friday, March 28, 2008
4:00 PM US/Pacific

Hello Flex?

   En preparacion para una presentacion sobre Flex que hare para una consultoria en Boston, probablemente estare escribiendo algunas entradas en Ingles en las siguientes semanas, como apoyo a la audiencia de dicha platica. Esto no significa que el blog cambie de Español a Ingles. Eventualmente las entradas estaran tambien en Español, si tengo tiempo suficiente para traducirlas. Les adelanto que el topico sera sobre Flex 3 y Cairngorm 2.2.1, para los que esten manejando estas versiones.

  Por supuesto que aunque las entradas estaran en Ingles, estare recibiendo comentarios en Español, al mismo tiempo.

 Saludos desde Boston, donde Flex suporta Internationalization!

 

  

Grupo de Flex en Español en Facebook

Con la llegada de Flex 3 y su apertura a Open Source, hoy como nunca existe la posibilidad de explorar su uso para expresar nuestra creatividad. Ideas y planes nacen individualemte, tal vez en el rincon mas solitario de nuestra casa, oficina, o mientras caminanos solitariamente al trabajo.  Pero las mejoras ideas han sido consolidadas a traves de colaboracion con otros. Que mejor que tomar ventaja de una red social como Facebook para hacer la conexion entre los desarrolladores de habla hispana.

  Con esto en mente he creado un nuevo grupo en Facebook llamado "Adobe Flex en Español", para que los desarrolladores Flex nos conectemos ya sea localmente o globalmente. Asi pues les dejo aqui la direccion de este grupo ( necesitan cuenta de Facebook para verlo) para que se me unan y empezar conversaciones sobre ideas o proyectos en Flex.

                                       http://www.facebook.com/group.php?gid=2391727741

  Saludos desde Boston, donde las ideas nacen de la mano con Flex.

Flex Cookbook con nuevos ratings - mis entradas a la cabeza!

El Flex Team anuncia hoy una actualizacion a Flex Cookbook online, incluyendo el uso de Bayesian Rating. Para mi sorpresa, dos de mis entradas estan entre las diez mas populares del Flex Cookbook!

 Si ustedes nunca han usado el Flex Cookbook, es una fuente de conocimiento Flex, donde varios expertos contribuyen con ejemplos de cosas muy interesantes.

 Saludos desde Boston, donde yo siguo cocinando recetas escritas con Flex!

Usando fillFunction para rellenar un columSeries condicionalmente – Nuevo en Flex 3

Acabo de recibir mi licencia de Flex Builder 3, y para probar que todo su activacion, copie y corri un ejemplo del Charting, para probar que el watermark del trial hubiera desaparecido. Efectivamente asi fue, pero al mirar el ejemplo, me recordó de algo nuevo en Flex 3 , el uso de fillFunction, que simplifica una tarea algo complicada en Flex 2: el rellenado de columnas en un chart con colores específicos dependiendo de una condición en los datos.  En Flex 2, se podia hacer estaticamente, espeficando el fill en cada columna, sin embargo habría que hacer mas que eso, si por ejemplo se necesitaba seleccionar en tiempo de ejecución dependiendo de los datos. Yo encontré y publiqué una solución en el Flex Cookbook, la cual pueden leer en el Flex CookBook.

En esta hice uso de UpdateDisplayList para lograrlo, pero ahora con Flex 3 no hace falta más que usar el fillFunction para lograrlo. fillFunction se usa de igual forma que el labelFunction ( dataGridColumn) con el cual ya somos familiares. Pero en este caso recibe un chartItem (el elemento completo con datos de la columna) y un index (el índice de la columna)  y regresa un IFill

Por ejemplo:

private function myFillFunction ( item : ChartItem, index:Number ) : IFill

{

var curItem: ColumnSeriesItem = ColumnSeriesItem (item);

 

if(curItem.yNumber > 30) return(new SolidColor(0x123456, .75));

else

return(new SolidColor(0x563412, .75)); }   

Pueden experimentar al igual que yo con el ejemplo de la ayuda. El cual encontré aquí. Yo agregue la llamada a myfillFunction en el primer ColumnSeries asi (fillFunction="myFillFunction"), y podran observar como la columna que representa “Gold” se rellena según sus datos.
         

<mx:ColumnSeries xField="Country" yField="Gold" displayName="Gold" fill="{sc1}" stroke="{s1}"

fillFunction="myFillFunction"/> 

Y eso es todo, como verán mucho mas simplificado que en Flex 2. Algo que hay que hacer notar sin embargo, es que el Legend se estropea – Gold ya no se visualiza. Lo anterior es entendible, ya que la columna Gold ya no puede ser representada con un solo color. Para tal efecto tendrán que construir su propio Legend.

Nota : No se olviden de agregar estos imports al codigo, si utilizan myFillFunction


import mx.graphics.IFill;

import mx.charts.ChartItem;

import mx.charts.series.items.ColumnSeriesItem ;  

Saludos desde Boston, donde Flex 3 me hace la vida mas facil!

Como insertar un componente en el encabezado de un Panel

 Este pregunta fue la primera en el foro que cree la semana pasada, y es una excelente pregunta tanto para empezar tanto para empezar el foro y para demostrar el uso de componentes en Flex.La pregunta original cuestiona sobre como insertar un ApplicationControlBar en el encabezado del Panel, pero mi respuesta aquí explicara algo más genérico, como insertar cualquier componente en tal cabecera. 

 Para los que no son tan familiares con el Panel en Flex, este tiene un encabezado, el titleBar, el cual tiene propiedades para poner el titulo del panel (title) y su status (status). Pero hay ocaciones que queremeos agregar mas opciones a tal encabezado. Pero como hacerlo? Cual es la mejor manera de agregar tales elementos?

 Tenemos que resolver dos problemas en este caso, primero como insertar tales componentes en el encabezado y segundo, como hacer que el Panel responda a la interacción con esos componentes.  En este ejemplo, para demostrar el primer caso agregare un componente al encabezado el cual contiene un solo botón, el cual dispara un evento, y para el segundo agregare lógica en el panel para escuchar por tales eventos y modificar el Panel, en este caso maximizar y minimizar dicho Panel. Como veran el manejo de eventos en Flex es muy necesario para desarrollar componentes. Si necesitan un repaso, pueden ver la ayuda de Flex o esta entrada que al respecto escribi el otro dia.

 Primeramente enlistare los pasos que seguí:  

  •  
    1. Cree un componente – ActionBar.mxml - que contiene un botón y que dispara los eventos maximizarPanel y minimizarPanel.  Como verán en el código, este componente es completamente independiente y puede ser usado con cualquier propósito. Es más, el nombre de los eventos podría ser más genérico, pero he decidido dejarles los nombres que tienen por motivos didácticos. Puede ver que tiene una variable (maximizado) para mostrar ‘-‘ o ‘+’ como un indicativo visual de su propósito, es decir, maximizar (+) o minimzar (-) el Panel.

    2. Cree un componente que extiende el Panel -  PanelBar.mxml. Este componente es que el sobre todo nos interesa, ya que aquí esta el codigo que nos muestra primero como adicionar (ActionBar.mxml al titleBar del Panel ( usando createChildren y layoutChrome) , y segundo como responder a eventos disparados en ActionBar.mxml dentro de PanelBar.mxml ( usando addEventListener)

    3. Cree una aplicación solo para demostrar el ejemplo : PanelComponentApp.mxml

 Pero detengámonos un poco más en las funciones createChildren y layoutChrome usadas en este caso.  Si ya las han usado o están familiarizados con programación orientada a objetos los calificadores override protected no les serán extraños, pero si no es así, bueno piensen que lo que estan dicendole al Panel es algo como, “ hey Panel! Quiero que ejecutes esas funciones tal como ya sabes (lo cual indicamos llamando super.createChildren()), pero además quiero que ejecutes esto otro...”, es nuestro caso adicionar ActionBar.mxml al titleBar y posicionar ActionBar en layoutChrome. Como menciono en los comentarios, layoutChrome es llamado cada vez que se re-dibuja o actualiza el titleBar, lo cual lo hace el lugar perfecto para posicionar nuestro componente ActionBar. Podríamos haber usado UpdateDisplayList, sin embargo este es llamado cada vez que cualquier cosa cambia en el Panel, por ejemplo si adicionáramos contenido dinámicamente al Panel. Usando layoutChrome, el cual es solo usado para el titleBar y borders del Panel, nos ahorramos varias llamadas innecesarias.  Pero no olvidemos que esto ultimo es solo cierto para el Panel. Si están usando addChild en cualquier otro componente, seguramente tendrían que usar UpdateDisplayList para posicionarlo. Al mismo tiempo si el autoLayout del Panel es puesto a false o true, el layoutChrome es llamado en ambos casos. 

Asi pues es tiempo que les muestre el codigo o no? El propósito es meramente didáctico, y les queda de tarea tomar el concepto y crear sus propios componentes. Por ejemplo, en una versión completa, ActionBar seguramente puede usar customEvents para hacer el código mas genérico, y tal vez los botones puedes usar skins para mejorar su apariencia, y estos seguro que muchas mas.


Cuales ideas se les ocurren a ustedes?

 

--- ActionBar.mxml-----------------------------------------------------------------------

<?xml version="1.0" encoding="utf-8"?>

<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" width="55">

<mx:Script>

<![CDATA[

[Bindable(event="maximizarPanel")][Bindable(event="minimizarPanel")]

 

[Bindable] public var maximizado : Boolean = true;

 

public function resizePanel ( event : MouseEvent) : void

{

if( maximizado )

{

dispatchEvent(new Event("minimizarPanel"));maximizado = false;

}

else

{

maximizado = true;dispatchEvent(new Event("maximizarPanel"));

}

}

]]>

</mx:Script>

<mx:Button label="{maximizado?'-':'+'}" width="50" click="resizePanel(event)"/>

</mx:HBox>

 

--- PanelBar.mxml-----------------------------------------------------------------------

<?xml version="1.0" encoding="utf-8"?>

<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" width="400" height="300">

<mx:Script>

<![CDATA[

 

private var actionBar : ActionBar ;

 

// Usar createChildren para adicionar la barra con botones ( u otro componente)

override protected function createChildren ( ) : void

{

super.createChildren(); actionBar = new ActionBar();

// Los eventos que el ActionBar envia al panel

actionBar.addEventListener("maximizarPanel",cambiaPanel); actionBar.addEventListener("minimizarPanel",cambiaPanel);

// Finalmente adiciona el componente Action Bar al titleBar del Panel

titleBar.addChild(actionBar);

}

 

// Cuando el panel necesita actualizar borders o el titleBar lo hace a traves llamando layoutChrome

// Usamos ese evento para darle tamaño y posicionar nuestro componente ActionBar

override protected function layoutChrome ( unscaledWidth:Number, unscaledHeight:Number) : void

{

super.layoutChrome(unscaledWidth,unscaledHeight);

actionBar.height = actionBar.measuredHeight;

// Usar el posicionamiento de acuerdo al componente, en este caso solo centro verticalmente y

// lo pongo al lado del statusTextField del Panel

actionBar.move( statusTextField.x - actionBar.width, (titleBar.height - actionBar.height ) / 2);

}

 

// Un ejemplo simple de maximizar/minimizar el panel.

private function cambiaPanel ( event : Event ) : void

{

if ( event.type == "minimizarPanel" )

{

this.height = this.titleBar.height ;

}

else if ( event.type == "maximizarPanel" )

{

this.height = 300;

}

}

]]>

</mx:Script>

 

<mx:Text text=" Contenido del Panel"/></mx:Panel> --- PanelComponentApp.mxml-----------------------------------------------------------------------

<?xml version="1.0" encoding="utf-8"?>

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

<local:PanelBar width="300" height="300" title="Mi Panel" status="Normal"/>

</mx:Application>

Compilado usando Flex Builder 3

Como agregar columnas a un datagrid dinamicamente.

Este es un caso común cuando se quieren adicionar columnas dinamicamente a un datagrid. El caso de uso, puede que se tienen que agregar columnas a un datagrid de acuerdo a alguna selección del usuario. El código principal de cómo hacerlo este en la función agregarDataGridColumn de este ejemplo. Lo demás son componentes auxiliares para mostrar el ejemplo. En este caso, se presentan solo dos columnas por default en el datagrid de cinco disponibles. Las tres restantes pueden agregarse dinámicamente presionando un botón. Hasta donde puede llevarse este ejemplo? Bueno se me ocurren algunas ideas.

Por ejemplo:

- En vez de botones se pueden mostrar las columnas restantes en una lista. Y tal vez agregarlas con Drag&Drop?
- Validar que no se agregue la columna mas de dos veces.
- Adicionar itemRenderers dinámicamente.

Que otras ideas se les ocurren?

<?xml version="1.0" encoding="utf-8"?>

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

verticalAlign="middle">

 

<mx:Script>

<![CDATA[

import mx.controls.dataGridClasses.DataGridColumn;

private function agregarDataGridColumn(dataField:String):void {

var dgColumna:DataGridColumn = new DataGridColumn(dataField);var columnas:Array = dataGrid.columns;

columnas.push(dgColumna);

dataGrid.columns = columnas;

}

 

]]>

</mx:Script>

<!-- Los datos. En este caso un Array de objetos-->

<mx:ArrayCollection id="datosArrayColl">

<mx:source>

<mx:Array>

<mx:Object nombre="Ryan" apellido="Stewart" calle="adobe" pais="us" departamento="IT"/>

<mx:Object nombre="Steve" apellido="Jobs" calle="apple" pais="us" departamento="IT"/>

<mx:Object nombre="Bill" apellido="Gates" calle="microsoft" pais="us" departamento="IT"/>

<mx:Object nombre="Britney" apellido="Spears" calle="ninguna" pais="us" departamento="espectaculos"/>

<mx:Object nombre="Jessica" apellido="Simpsoms" calle="smith" pais="us" departamento="cine"/>

<mx:Object nombre="Barack" apellido="Obama" calle="president st." pais="us" departamento="politica"/>

</mx:Array>

</mx:source>

</mx:ArrayCollection>

 

 

<mx:DataGrid id="dataGrid"

dataProvider="{datosArrayColl}"width="

400" rowCount="6">

<mx:columns>

<mx:DataGridColumn dataField="nombre" />

<mx:DataGridColumn dataField="apellido" />

</mx:columns>

</mx:DataGrid>

 

<mx:VBox >

<mx:Button label="Agregar Calle" click="agregarDataGridColumn('calle')" />

<mx:Button label="Agregar Pais" click="agregarDataGridColumn('pais')" />

<mx:Button label="Agregar Departamento" click="agregarDataGridColumn('departamento')" />

</mx:VBox>

 

</mx:Application>

No Flash para el IPhone : Jobs dice ‘Es muy lento’

Me entero en este articulo que Steve Jobs CEO de Apple asevero que el iPhone no suportara Flash como algunos habían especulado. Esto sin duda causa desconsuelo entre los usuarios del iPhone, pero más a los desarrolladores de Flash/Flex/AIR que estábamos esperando en poder crear aplicaciones para el iPhone. Mi opinión personal es que esta no es solo una decisión política ( o de competencia) pero también técnica. Y como tal tiene solución si ambas empresas trabajan en conjunto. Sin embargo, Jobs ha hecho este anuncio unilateralmente, lo cual no ayuda a una pronta solución.

Este anuncio viene también en mal momento para Adobe que esta tratando de impulsar tecnologías como Flex y AIR contra las tecnologías de Microsoft como Silverlight. Microsoft solo esta semana cerro un trato con Nokia para que sus teléfonos soporten Silverlight 

No me sorprendería que este sea un parte aguas para que la adopción de Silverlight sea mas rapida que la de AIR o Flex, no porque ofrezcan la misma solución, pero si compiten en el mismo ámbito de desarrollo de aplicaciones RIA.

Será que tendremos que aprender Silverlight para poder llamarnos desarrollores RIA ?
 

Saludos desde Boston, donde el iPhone no entiende ActionScript

Declarando WebServices con ActionScript

 Como resultado de una pregunta que recibi, escribi este pequeño ejemplo de como llamar un WebService usando puro ActionScript.  Es un ejemplo basico, pero creo que cumple su cometido. Noten que el secreto, es que a diferencia del mxml tag, que maneja esto por nosotros, hay que cargar el WSDL antes de poder hacer llamadas a cualquiera de sus metodos.

  Espero que los comentarios tambien sean de utilidad:

<?xml version="1.0" encoding="utf-8"?>

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

creationComplete="loadWebService()">

<mx:Script>

<![CDATA[

import mx.rpc.Fault;

import mx.rpc.events.FaultEvent;

import mx.rpc.events.ResultEvent;

import mx.rpc.soap.LoadEvent;

import mx.rpc.soap.WebService;

 

private var webService : WebService = new WebService();

 

private function loadWebService ( ) : void

{

// Cargar el WSDL y agregar listeners para saber cuando este listo

webService.wsdl = "http://www.webservicex.net/WeatherForecast.asmx?WSDL";

webService.addEventListener(LoadEvent.LOAD, onWSDL);

webService.addEventListener(FaultEvent.FAULT, onWebServiceFault);

webService.loadWSDL( );

 

}

 

//listener que avisa cuando el WSDL se ha cargado

private function onWSDL ( event : LoadEvent ) : void

{

 

// Llamada a un metodo en el WebService, primero se crea otro listener para saber cuando

// el resultado esta listo.

webService.GetWeatherByZipCode.addEventListener(ResultEvent.RESULT, onGetWeatherByZipCode);

webService.GetWeatherByZipCode("02111");

}

 

private function onGetWeatherByZipCode ( event : ResultEvent ) : void

{

// Usar el resultado. Para mas detalles se puede inspecionar event.result en el debugger.

textArea.text += "La temperature maxima para hoy en " + event.result.PlaceName + " , "+ event.result.StateCode + " es : " + event.result.Details[0].MaxTemperatureC + "C";

}

 

// En caso de que el WebService no puede ser cargado.

private function onWebServiceFault(event:FaultEvent):void {

var fault: Fault = event.fault;

var message:String = "An error occurred. The details are as follows\ncode: " + fault.faultCode;

message += "\ndetail: " + fault.faultDetail;

trace("Web Service Error :" + message);

}

 

]]>

</mx:Script>

 

<mx:TextArea id="textArea" width="460" height="200" />

 

</mx:Application>