windows vista telecharger acheter windows xp professional prix autocad 2006 telecharger adobe premiere pro francais preis microsoft office 2007 adobe flash cs4 preis achat windows 2000 günstig outlook 2007 prix cubase windows 7 preisvergleich heise office 2003 billig telecharger autocad lt 2010 preisvergleich dreamweaver sony vegas 9 preis cubase vollversion windows 2008 datacenter preis dreamweaver cs4 preis prix office 2008 preis windows 7 home premium preis office 2007 microsoft project kaufen windows vista ultimate preisvergleich preis acrobat professional autosketch kaufen preis windows 7 prof achat access 2003 microsoft access 2003 kaufen microsoft office download deutsch illustrator acheter achat photoshop cs solidworks 2009 prix autodesk inventor download deutsch autocad 2010 telecharger adobe indesign preisvergleich prix illustrator cs4 achat autocad 2004 office 2007 moins cher windows vista ultimate 64 bits achat 3ds max prix de windows 7 professionnel acheter archicad 12 dragon naturally speaking pas cher dreamweaver cs3 prix acheter photoshop 7.0 windows 7 home premium kaufen photoshop prix mac corel draw preisvergleich microsoft access prix mathcad 14 preis autocad 2010 preis pcanywhere prix prix pinnacle adobe illustrator cs4 vollversion outlook 2007 prix prix de microsoft project acheter microsoft outlook 2007 acheter windows 2000 pro microsoft word preis indesign cs4 download deutsch microsoft powerpoint preis windows 7 günstig downloaden preise photoshop cs4 prix adobe audition 3 prix de photoshop elements microsoft windows 7 prix acheter windows seven etudiant adobe illustrator cs3 download deutsch acheter vista basic acheter dreamweaver 8 acheter pinnacle studio 14 prix microsoft office professional 2007 prix autocad 2009 acheter photoshop cs3 occasion indesign cs4 français telecharger visual studio 2008 francais achat windows 7 meilleur prix preis windows 7 home premium upgrade corel draw x4 download deutsch acheter encarta 2009 windows 7 premium pas cher indesign achat windows xp professional preis achat microsoft visio acheter kaspersky internet security 2010 preis photoshop cs3 kaspersky internet security 2009 kaufen acheter windows 7 complet preise solidworks dreamweaver cs3 preis windows 7 home vollversion adobe cs5 francais lightroom preise windows 7 ultimate vollversion preise matlab prix cubase le 4 solidworks prix licence adobe fireworks kaufen acheter cubase 5 acheter adobe cs4 acheter lightroom 2 telecharger norton 360 francais preis vmware workstation 7 telecharger office 2010 francais adobe cs3 preis prix windows 7 64 bits adobe audition kaufen acheter windows 7 canada photoshop elements 8 prix acheter microsoft outlook 2003 preis word 2007 acheter autocad electrical preise cs4 acheter windows vista home basic telecharger cubase windows xp sp3 preisvergleich preis microsoft office 2007 solidworks kaufen preis nero 8 corel draw vollversion download office 2007 vollversion download prix omnipage sql server 2008 enterprise prix prix autocad inventor windows xp pro sp3 oem microsoft office 2007 kauf prix sony vegas illustrator cs5 kaufen dreamweaver acheter frontpage kaufen acheter pinnacle video capture for mac preisvergleich photoshop elements 8 windows xp kauf photoshop cs4 preise final cut express 4 kaufen windows 7 kaufen acheter adobe illustrator cs3 preis indesign cs3 illustrator günstig windows 7 home premium billiger nero 9 vollversion kaufen autocad 2010 preisliste autocad architecture 2009 kaufen telecharger windows seven french telecharger windows 7 francais dreamweaver cs5 prix windows vista home premium preise acheter corel draw x3 windows xp telechargementz acheter microsoft office 2010 matlab acheter photoshop elements 6 preis prix autocad architecture 2010 windows xp achat en ligne adobe cs5 vollversion windows 7 preis oem office 2010 preis inventor autodesk preis prix microsoft office 2007 standard acheter word 2007 adobe photoshop cs4 vollversion download preise autocad 2009 prix 3ds max 2010 microsoft powerpoint download deutsch prix kaspersky 2009 acheter windows 7 edition familiale indesign preise windows 7 ultimate kaufen windows 7 home premium preise 3ds max 2009 kaufen achat windows 7 starter adobe premiere pro cs4 download deutsch acheter adobe cs2 acheter microsoft money 2005 prix windows 7 etudiant microsoft office enterprise 2007 preis prix de illustrator telecharger windows vista 64 bits acheter after effect 7 microsoft windows 7 ultimate preis achat windows 7 pas cher windows 7 professional prix windows xp download deutsch word 2003 kaufen preis autocad lt adobe illustrator vollversion acheter windows 7 update photoshop elements 8 preisvergleich office 2007 etudiant prix acheter norton ghost 15 acheter autocad 2008 acheter office 2007 pro microsoft office 2003 kaufen excel 2003 kaufen cs3 prix prix autocad light prix guitar pro prix adobe flash cs4 windows 7 kauf download achat outlook seul microsoft outlook preis acheter adobe premiere elements adobe photoshop cs4 acheter microsoft office 2007 etudiant et famille microsoft office 2010 günstig windows 7 prix oem achat solidworks acheter windows 7 ultimate 64 windows vista preisvergleich cubase preise prix de windows xp visual studio preisvergleich windows 7 preisvergleich schweiz powerpoint vollversion telecharger windows 7 64 bits prix acrobat pro 9 acheter windows xp version boite windows xp pro acheter windows 7 preise versionen archicad 13 kaufen preis windows 7 family pack prix de photoshop achat windows 7 edition familiale premium adobe indesign cs5 preis windows 7 professional vollversion preis windows vista kaufpreis prix autocad 2009 adobe photoshop cs5 kaufpreis prix windows xp edition familiale adobe cs4 acheter prix solidworks 2010 seven windows prix telecharger dreamweaver cs4 after effects cs3 preis microsoft office 2010 download deutsch beta achat photoshop elements 7 prix de microsoft office 2009 preis windows 7 64 bit prix adobe creative suite 4 design premium acheter adobe photoshop acheter quarkxpress telecharger illustrator fr acheter vista pas cher acheter windows 7 aux usa telecharger adobe photoshop cs4 français windows 7 vollversion preis prix windows 7 suisse windows 7 ultimate prix telecharger windows 7 ultimate 32 bits autocad mechanical 2010 preis achat excel 2003 windows 7 vollversion oder upgrade telecharger adobe premiere pro cs3 norton ghost download deutsch pinnacle studio 14 preisvergleich télécharger autocad 2010 français windows 7 günstig kaufen nero preisvergleich windows 7 professionnel oem 32 bits adobe lightroom 2 prix acheter windows xp pro 64 bits acheter office 2007 en suisse windows 7 ultimate achat windows 7 prix microsoft office 2007 pme oem prix photoshop 7 acheter final cut express 4 acheter adobe flash cs3 dreamweaver vollversion download photoshop cs4 preis dragon naturally speaking preisvergleich windows 7 billiger.de microsoft visio download deutsch windows 7 ultimate billig acheter microsoft office pour windows 7 acheter indesign kaspersky internet security 2010 vollversion adobe indesign download deutsch acheter sql server 2008 achat adobe acrobat pro windows xp professional günstig kaufen acheter access 2003 adobe photoshop cs3 download deutsch prix acrobat standard acheter cubase 3 office 2003 prix acheter windows 7 premium acheter office 2003 telecharger word 2003 francais achat adobe photoshop cs5 telecharger photoshop filter windows 7 prix belgique acheter microsoft office en ligne windows 7 starter kaufen windows 7 professional kaufen windows 7 preis 2010 acheter windows vista home premium prix windows 7 acheter microsoft autoroute 2010 guitar pro 5 vollversion download windows 2003 preis maya preisig prix windows 7 integrale pcanywhere download deutsch outlook preis 3ds max 2010 preis achat powerpoint 2003 microsoft office 2003 preise autodesk maya kaufen sql server kaufen adobe premiere elements 8 kaufen acheter acrobat reader autocad electrical kaufen windows 7 pro download deutsch adobe photoshop cs3 preis preis omnipage prix de office 2007 microsoft works vollversion download prix premiere pro cs4 achat vmware workstation acheter sony vegas pro 9 acheter autodesk maya windows vista premium oem acheter adobe photoshop adobe premiere pro cs4 preis adobe after effect prix adobe captivate 3 download windows vista business kaufen sony vegas 9 download deutsch lightroom 2 preise adobe cs4 vollversion prix de frontpage acheter microsoft word 2009 microsoft money kaufen prix cs4 master collection telecharger kaspersky internet security 2010 fr prix windows 2008 r2 enterprise acheter windows 7 en ligne corel draw günstig acheter photoshop lightroom 2 acheter visual studio 2005 dreamweaver cs5 günstig microsoft outlook 2007 günstig acheter windows xp canada acheter adobe premiere pro cs5 adobe cs4 telecharger sql server 2008 enterprise preis prix cs4 photoshop quarkxpress preis prix windows vista prix powerpoint 2007 windows 7 kaufen student

Ejemplo Flex/JSP: Subir video usando la Media API de Brightcove

Este ejemplo muestra como cargar video a Brightcove usando la Media Write API en una aplicación Flex.

Incluye elementos del cliente y del servidor:

  • En el lado del cliente, VideoUploader.mxml es un aplicacion Flex que ofrece al usuario una interfaz (UI) para navegar hacia y seleccionar un archivo para subir, muestra el progreso del proceso de carga, y llama al script proxy en el servidor. A su vez, lee el video Id si la llamada a la Media API es correcta, o un mensaje de error en el caso que la carga falle.
  • En el lado del servidor, use un script proxy, en este caso una pagina JSP (Uploader.jsp) que recibe la multipart/form-data del cliente Flex, incluyendo el nombre del video, y un la descripción corta y larga, y si anuncios están permitidos o no. Este JSP desglosa la petición y es el que al final llama  create_video Media API.  Los resultados de la API, incluyendo el id del video recién cargado, se envían al cliente de Flex.

La aplicación Flex hace uso de las clase  FileReference para manejar todo lo relacionado a seleccionar el archivo de video, y pasarlo junto con los atributos del video a la pagina JSP.  Si no están familiarizados con esta clase, es posible que quieran leer primero la ayuda de Flex. Antes de usar este ejemplo, asegúrense de tener todos los componentes estén instalados. Todos los archivos que necesitan están incluidos en FlexVideoUploaderExample.zip:

  1. Flex app. Extraigan  VideoUploader.zip e importenlo en Flex Builder. Opción Import > Existing Project Into Workspace > Select archive file > VideoUploader.zipVideoUploader.mxml contiene la aplicación principal.
  2. UploaderVideo.jsp. Extraigan uploader.war y copienlo a un servidor web que soporte Java. En Tomcat por ejemplo, solo necesitan copiar el archivo war bajo el directorio  webapps y es automáticamente reconocido.  Despues de eso, deben tener un proyecto web llamado uploader. Revisen los archivos en el proyecto. La pagina JSP se llama  UploaderVideo.jsp. Este JSP usa ClientHTTPRequest para manipular el multipart/form-data enviado a la Media API. El JSP también necesita los JARs Apache Commons commons-iocommons-fileupload , también incluidos en el archivo war. No necesitan cambiar la utileria ClientHTTPRequest ,  a menos que quieran usar otra utileria HTTP que pueda manipular el envio multiparte. Tambien antes de ejecutar este ejemplo, asegurense de añadir su propio token de escritura de la Media API en UploaderVideo.jsp.  Busquen por la variable WRITE_API_TOKEN y asignen su token ahi. Si no cuentan con un token, por favor contacten al servicio al cliente de Brightcove ( en Ingles)

La aplicación Flex

Sin han usado FileReference antes, notaran que este ejemplo basicamente usa los tres pasos principales para cargar un archivo a un servidor:

  1. Navegar hacia y seleccionar un archivo.
  2. Llamar a un script en el servidor después de que el usuario ha seleccionado un archivo, y
  3. Manejar el resultado de la carga.

Navegando hacia el archivo

Esta acción es empezada cuando el usuario presiona el botón 'Upload' en la forma  uploadForm de la aplicación. La información acerca del video tiene que ser llenada. Noten que dado que solo queremos subir archivos de video, un filtro (FileFilter) con las extensiones comunes para video es usado. Este es también el lugar donde se ponen los metodos que procesan los eventos cuando el archivo es seleccionado (Event.SELECT) y cuando la carga se completa (DataEvent.UPLOAD_COMPLETE_DATA

 /**
   * Abre un mensaje de dialogo para que el usuario seleccione un archivo de vídeo
   * y agrega los métodos para procesar errores y cuando el video ha sido cargado al servidor
   */
    private function fileBrowse():void {
        fileRef = new FileReference();
        fileRef.addEventListener(Event.SELECT,selectHandler);
        fileRef.addEventListener(Event.COMPLETE,onComplete);
        // Procesar cuando el archivo de video ha sido cargado.
        fileRef.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA ,onUploadCompleteData);
        fileRef.addEventListener(IOErrorEvent.IO_ERROR,onError);            

        var videoFilter:FileFilter =
            new FileFilter ("Video (*.flv,*.mov,*.avi,*.mp4,*.wmv,*.mpeg)",
                                     "*.flv;*.mov;*.avi;*.mp4;*.wmv;*.mpeg");
        // Queremos subir solo archivos de video
        fileRef.browse([videoFilter]);
    }

Llamando al JSP despues de que el usuario ha seleccionado un archivo.

Usamos el método fileReference.upload() para llamar al JSP  y enviamos los meta datos del vídeo desde la forma (nombre, descripción, soporta anuncios , etc) como parametros. El JSP es donde en verdad se hace la llamada al metodo create_video de la Media API. Aqui seria donde agregarian mas meta datos como tags, cue points o ids de referencia.

private function selectHandler(event:Event): void {
 // Contruye una URL para llamar al script proxy en el servidor
 var request:URLRequest = new URLRequest(UPLOAD_VIDEO_URL);
 fileName.text = FileReference(event.target).name;

 // Enviar los atributos del video entrados por el usuario. La API de video
 // create_video soporta varios parametros. En este ejemplo son limitados a
 // shortDescription, longDescription, adEnabled, y name.
 // Cada atributo de 'createVideoParams'
 // debe pertenecer a uno de create_video
 // Para una lista completa de los atributos de create_video ver:
 // http://docs.brightcove.com/en/media/#Video_Write

 var createVideoParams:URLVariables = new URLVariables();
 createVideoParams.name=videoName.text;
 createVideoParams.shortDescription=shortDescription.text;
 createVideoParams.longDescription =longDescription.text;
 // Los videos que se cargan a Brightcove soportan anuncios de entrada
 // este ejemplo muestra como subir videos que no permitan anuncios, usando un
// parametro de create_video
 createVideoParams.adEnabled = adEnabledCheckBox.selected?"AD_SUPPORTED":"FREE";

 var parametersObject:Object = new Object();
 request.method = URLRequestMethod.POST;
 request.data = createVideoParams;
 fileRef.upload(request);
 fileUploadProgressBar.visible= true;
}

Procesando el resultado de la transferencia del archivo de vídeo

En onUploadCompleteData, verificamos que la llamada a  create_video en el JSP haya sido exitosa y el vídeo haya sido agregado. Si la llamada falla, un mensaje de error es regresado.  Si reciben un vídeo id, significa que el archivo ha sido agregado al sistema y esta siendo procesado. Pueden verificar el resultado de la transferencia usando la API  get_upload_status de la Media API o en el Media Module.

    /**
     * Se llama cuando UploadVideo.jsp termina de procesar la carga.
     * Si la llamada es exitosa, se puede leer el video id
     * de contenido de JSONResponse.result
     * Si falla, el mensaje de error con los detalles
     * puede leerse de JSONResponse.error.message
     */
    private function onUploadCompleteData(event:DataEvent):void {
     trace("onUploadCompleteData");
     var JSONResponse:Object = (JSON.decode(event.data));

        if(JSONResponse.error != null && JSONResponse.error != ""){
            videoResult.text = "Error : " + JSONResponse.error.message;
         }else {
            // Una llamada exitosa regresa el siguiente contenido JSON
            // {"result": 34414648001, "error";: null, "id": null}
            // Obtener el video id de la propiedad  'result'
            videoResult.text = " Video ID : " + JSONResponse.result;
        }
    }

El lado del Servidor

Entre el paso 2 y 3, la pagina JSP es llamada. El JSP analiza la información enviada por fileReference.upload() y prepara la llamada al método create_video. Este JSP es otra version del java servlet usado en un ejemplo previo "Java Example: Video Uploader", el cual usa HTML en vez de Flex. Una buena explicación del código puede encontrarse ahí. Una diferencia sin embargo, es la adición del parámetro 'anuncios' al subir los videos, para permitir o no anuncios de entrada, y es aqui donde se pueden agregar otros parametros que corresponden al video.  Así mismo, usando un script del lado del servidor protege su token de escritura para API.

Que sigue

Aunque este ejemplo demuestra la idea básica de usar Flex para subir vídeos a su cuenta en el sistema de Brightcove, puede ser expandido para incluir mas funcionalidad. Aquí un par de ideas que ustedes pueden implementar :

  • Agregar suporte para subir vídeos usando etiquetas para su clasificacion (tags).
  • Cambiar este ejemplo a una aplicación de Adobe AIR donde se pueda navegar al vídeo y verlo antes de subirlo.
  • Agregar suporte para cue points.
  • Obtener el estado de la carga del vídeo al sistema Brightcove. Tip: Llamar el método get_upload_status de la Media API

Espero escuchar pronto de lo que han desarrollado!

Slides and source code from my talk at Flex Camp Boston

It was great to see everyone at Flex Camp Boston last Friday! As promised, here are the slides and source code from my presentation about Building Mashups with Flex. You will need to get your own APi keys for the NYT, Google, Ribbit APIs before you try it out

Source Code Download

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>

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>

Experimentando con cacheAsBitmap

 Hace unos dias escuche de Todd Yard sobre como la propiedad cacheAsBitmap podria ser usada para conseguir algunos de los efectos que solo se logran si se usan embebed fonts, por ejemplo aplicar alpha a un texto.

 El uso de cacheAsBitmap en definicion no es complicado, ya que como programadores solo tenemos que ponerlo a true para indicarle al Flash Player que cree y conserve un bitmap de cualquier DisplayObject en memoria y use este para no re-dibujar tal DisplayObject. Con esto el Flash Player puede ofrecer mejor rendimiento. Regularmente cacheAsBitmap es usado en Display Objects que muestran contenido estático.

 Aunque aun sigo experimentando con esta propiedad, pude verla en acción al ver como aplicar alpha a un texto dentro de un Panel y al mismo titulo del panel sin usar embebed fonts. De acuerdo a mis pruebas no basta con poner la propiedad igual a true para forzar que una copia de un Text  sea guardado como bitmap en memoria por el Flash Player. De hecho parece ser ignorado. Sin embargo, esta propiedad es forzada a ser igual a true cuando se aplican filters al Text. Como en realidad no queremos afectar la apariencia del Text con un filtro, podermos  aplicar un filter ‘vacio’, por ejemplo un Blur(0,0), que no afecte al Display Object pero que pone el cacheAsBitmap=true.

   Pueden ver los resultados de mis pruebas aquí:

                   http://labs.holaflex.com/cacheasbitmap/PanelconAlpha.html       ( Pueden ver el codigo, mouse right click/ view source )

  Pueden ver como alpha del titulo del Panel cambia junto a la del panel mismo. Para este ejemplo cree un componente donde sobrescribí el metodo UpdateDisplayList para tener accesso al texto interno que representa el titulo del Panel. A su vez hay un texto dentro del Panel que también cambia a como se cambia el alpha del Panel, y un segundo que no cambia. Este ultimo para mostrar como se comportaría un texto sino se forzara el cacheAsBitmap a ser true.

   No he encontrado documentación que claramente especifique este uso, pero seguiré experimentando para ver mas se puede lograr. Por lo pronto les dejo el ejemplo para que pueden hacer sus propios hallazgos.

Del uso de mx_internal

 Como ya he discutido antes, los componentes en el Flex SDK tienen propiedades, métodos y eventos que nos permiten manipular su apariencia y comportamiento. Por ejemplo, el siguiente mxml declara un botón con una leyenda y que ejecuta cierta función al clic.

   <mx:Button id="miboton" label="Presiona me" click="ejecutaFuncion()"/>

 

  Cada uno de los componentes en el Flex SDK tiene propiedades y métodos, tanto públicos, privados y protegidos. Esto es por su naturaleza Orientada a Objetos. Teniendo esto en consideración es posible modificar propiedades y métodos predefinidos sobrescribiendo (overriding) su definición. Para saber el alcance ( public, private o protected) de cada propiedad o método, y si son propios o heredados, recurrimos a la documentación de Flex (http://livedocs.adobe.com/flex/2/langref/). Ahí podemos ver las propiedades y su alcance.

   A como los componentes son mas sofisticados, encontramos que sus propiedades pueden provenir de un antecesor o están de otros componentes que son usados como parte de ellos, por ejemplo un Label dentro un Button.  Aun así, regularmente encontramos como cambiar cierta propiedad mirando la ayuda. Pero que pasa cuando esas propiedades no están disponibles? Por ejemplo, tomemos el dateChooser, el cual muestra en esencia un calendario. 
 

 Internamente el dateChooser esta haciendo uso de otros componentes Flex, y regularmente podemos hacer referencia a ellos para cambiarlos.  Por ejemplo los meses que por default están en Ingles pueden ser cambiados a Español como ya mostré en otra entrada. Sin embargo, digamos que queremos desaparecer los botones de avance y regreso de los meses. Tal vez queremos mostrar un mes en específico a la vez, y no queremos que el usuario tenga la opción de avanzar o regresar en meses.
Bueno curiosamente no existe una función o propiedad pública, privada o protegida que nos permita hacer referencia a tales botones. 
 Pero es claro que estos son dos buttons y que fueron declarados en algún lugar. Donde?. Bueno tomando una mirada a la clase original (DateChooser.as) se puede ver que si están declarados ambos botones: backMonthButton y fwdMonthButton.

 /**

* @private

* The internal Button which, when clicked,

* makes the DateChooser display the next month.

*/

mx_internal var fwdMonthButton:Button;

 

/**

* @private

* The internal Button which, when clicked,

* makes the DateChooser display the previous month.

*/

mx_internal var backMonthButton:Button;  


Entonces si están como variables en DateChooser, pero no como public, private o protected, sino como mx_internal. Esta declaración, mx_internal, es diseñada para declarar variables de las cuales se pensó no son necesarias para el programador. Aunque en el caso del DateChooser y estos botones, yo diría que deberían estar disponibles y así pudiéramos hacerlos invisible con algo como:  

miDateChooser.backMonthButton.visible=false;

  Pero si hay una manera de accesarlos, usando el mismo mx_internal, podemos hacer referencia a dichas propiedades.

Esta seria una clase que extiende el DateChooser pero que esconde los botones de avance y regreso del mes usando mx_internal.

//DateChooserNoMonthButtons.as bajo fólder skins
package skins

{

import mx.controls.DateChooser;import mx.core.mx_internal;

// Paso 1: Usar decirle a ActionScript que use el namespace mx_internal

use namespace mx_internal; 

          public class DateChooserNoMonthButtons extends DateChooser

          {

                     override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{      

                                         super.updateDisplayList(unscaledWidth, unscaledHeight);

                     // Usar la sintaxis this.mx_internal:: para hacer referencia a propiedades bajo el namespace mx_internal

                                        this.mx_internal::fwdMonthButton.visible=false;                    

                                        this.mx_internal::backMonthButton.visible=false;

                 }

       }

}

Y se puede usar asi

 

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

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:calendario="skins.*">

       <calendario:DateChooserNoMonthButtons />

</mx:Application> 

 

Con un resultado como este:

 
 

Usando labelField, labelFunction con XML en un ComboBox

Por default cuando datos son asignados al dataProvider de un combo box, este busca por dos atributos dentro los elementos de datos: el label y data. Lo contenido en el atributo label es lo que finalmente es desplegado en la lista, y data es accesible via selectedItem.data. Sin embargo, la mayoría de las veces nuestras fuentes de datos no tienen la información etiquetada de esa forma. Digamos por ejemplo que queremos mostrar la lista de Mascotas contenidas en el siguiente XML:

private var misMascotas : XML = <WSResult>   <Resultado>       <Mascotas>          <Id>001</Id>                                               <Nombre>Gato</Nombre>   

      </Mascotas>

      <Mascotas> 

          <Id>002</Id> 

          <Nombre>Perro</Nombre> 

      </Mascotas>  

 </Resultado>    

</WSResult> 

En este caso se nos presentan tres cuestiones a solucionar, no tenemos label o data como parte de los atributos en nuestro XML y los datos en los que estamos interesados ( <Mascotas> ) esta en un subnivel en nuestro XML. Entonces como hacemos que el combo box despliegue los nombres de las mascotas en el combo box?  Bueno para eso que el combo box cuenta con dos opciones para que manipular que atributo o atributos usar para lo que se despliega en esta lista. Estas son labelField y labelFunction. El primero simplemente le indica al combo box cual el nombre del atributo a usar en vez de label. En este ejemplo ya que queremos mostrar el nombre de la mascota, el cual es el atributo Nombre en el XML, este seria labelField=”Nombre”.  Por supuesto esto es valido si usamos la notación punto para acceder al nivel de XML que nos interesa, en este caso <Mascotas>. En sintaxis de AS3 esto seria: misMascotas.Resultado.Mascotas

En otras instancias es necesario desplegar en el combo box una combinación o concatenación de varios de los atributos. Por ejemplo, tal vez queremos desplegar el Id y Nombre de nuestras mascotas concatenado. Para esto puede ser usada el atributo labelFunction, el cual permite ejecutar una función que puede acceder a los atributos de los datos en el dataProvider y regresar dicha concatenación o combinación.

Un ejemplo completo de todo lo anterior es la siguiente aplicación. La cual muestra como usar un subnivel del XML como dataProvider para el combo box y el uso de labelField y labelFuncion.

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

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

<mx:Script>

<![CDATA[

 

import mx.controls.Alert;import mx.events.ListEvent;

 

[Bindable]

private var misMascotas : XML =

<WSResult>

      <Resultado>

             <Mascotas>

                   <Id>001</Id>

                   <Nombre>Gato</Nombre>

           </Mascotas>

            <Mascotas>

                    <Id>002</Id>

                   <Nombre>Perro</Nombre>

            </Mascotas>

</Resultado>

</WSResult> ;

 

// Se llama cuando el usuario cambia de opcion en el combo box

private function getPetName ( event: ListEvent) : void

{

 

mx.controls.Alert.show("Hello I'm "+ myCombo.selectedItem.Id+" "+ myCombo.selectedItem.Nombre, "Mensaje");

}

 

// Funcion usada en labelFunction

// Concatena el Id y el Nombre para desplegar algo como : 001 Gato

private function getIDName(oItem : Object): String

{

return oItem.Id + " " + oItem.Nombre;

}

]]>

</mx:Script>

 

<mx:ComboBox id="myCombo" x="10" y="50" labelField="Nombre" dataProvider="{misMascotas.Resultado.Mascotas}"

change="getPetName(event)" />

 

<mx:ComboBox id="myCombo2" x="200" y="50" labelFunction="getIDName" dataProvider="{misMascotas.Resultado.Mascotas}"/>

 

</mx:Application>

Introduccion al manejo de Eventos en Flex

Como explique en una entrada anterior, el framework Flex es sinónimo de una colección de clases escritas enteramente en ActionScript, e incluye controles, contenedores, y gestores diseñados para la simplificar la construcción de aplicaciones sofisticadas para el Internet o RIA por su nombre en inglés ( Rich Internet Applications). A estos controles, contenedores o gestores, se les puede cambiar sus propiedades para obtener un comportamiento o apariencia especifica. De hecho en lo que probablemente mas se tarda alguien que esta aprendiendo Flex es en aprender la cantidad masiva de propiedades y métodos disponibles en todos los componentes y como usarlos. Por si solos los componentes Flex no crean una aplicación, es decir tienen que comunicarse unos con otros para responder a la interacción con el usuario y así representar una aplicación. El ingrediente que permite tal comunicación son los eventos o Events. Cada componente además de propiedades o métodos también tiene eventos predefinidos. Por ejemplo un botón (Button) tiene un evento click que se dispara cuando el usuario pulsa el botón en pantalla. A su vez, podemos crear nuestros propios eventos usando ActionScript, lo cual es común cuando queremos que dos o más componentes se comuniquen y necesitan intercambiar datos. El entendimiento de cómo funcionan y como usar eventos en Flex es una importante base para diseñar aplicaciones con una buena arquitectura. Principalmente para el re-uso de componentes. Aunque Flex permite hacer referencia a propiedades públicas de otros componentes dentro de otro componente, esta práctica no es buena por que este tipo de componentes no pueden ser extraídos para su uso en otra aplicación. A su vez entender como funcionan los eventos nos permite entender el comportamiento asíncrono de Flex con lo que a llamadas a data services se refiere (WebServices, Remote Object, http etc). Como todo en Flex, los eventos están basados en clases de ActionScript. En este caso, cada evento tiene un flujo con ciertos actores. Lo siguiente es una descripción simplificada de tales actores y su función:

  1. Dispatcher: El objeto que es manipulado por el usuario y que dispara el evento. No olvidemos de que además de que los eventos son disparados automáticamente como respuesta a una acción del usuario también podemos dispararlos manualmente con ActionScript. ( Ver el uso de dispatchEvent en el ejemplo)
  2. Event object : Este es un objeto creado de acuerdo al tipo de acción generada y es el elemento que toma información del dispatcher para compartirla con otros componentes. Por ejemplo, el clic de un botón dispara un evento cuyo tipo es MouseEvent, el cual tiene asociado un event object con información sobre tal evento, este podría contener un objeto con propiedades indicando las coordenadas X y Y donde el usuario hizo clic, así como una referencia al dispatcher.
  3. Listeners: Objetos que escuchan y responden a dichos eventos, es decir, son los objetos que están registrados para tomar una acción cuando cierto evento es disparado en algún otro objeto.

La secuencia es sencilla: a) un objeto dispara un evento, b) el cual es representado como un tipo de object event y que entonces esta disponible para los listeners de tal tipo de evento, c) los listeners ejecutan una acción como respuesta al evento, donde pueden o no usar datos enviados por el dispatcher.Nótese que pueden ser más de unos los objetos listeners que respondan a cierto evento.

Veamos un ejemplo en MXML de lo anterior, que es la manera mas usada de responder a un evento en el mismo componente:

 
<mx:Script>
        <![CDATA[
            import flash.events.MouseEvent;
        
            private function manejadorClick ( event:MouseEvent ):void
            {
                trace( "Hola Mundo!");
            }
        ]]>
    </mx:Script>      
   <mx:Button id="miBoton" label="Presioname!" click=" manejadorClick(event);" />
 

En este ejemplo, se define un manejador para el evento click de un botón.  Cuando el usuario hace clic en el, el manejador para el evento

despliega el mensaje ‘Hola Mundo!’ en la consola a través de la función trace.Como también ya he mencionado antes, MXML es una vía corta que nos salva de teclear mucho del código ActionScript. En este caso, aunque no lo veamos declarado en AS, el Listener es la aplicación o componente que contenga al botón, el botón es el dispatcher y el event object es del tipo MouseEvent. Internamente este MXML hace uso de las clases de ActionScript para declarar el event object,  disparar el evento y declarar el objeto que escuche por dicho evento. Para verlo mas claramente veamos el mismo ejemplo pero ahora usando ActionScript.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application 
    xmlns:mx="http://www.adobe.com/2006/mxml"      
    horizontalAlign="center" verticalAlign="middle" 
    width="300" height="200"
    creationComplete="manejadorCreationComplete (event);"> 
    <mx:Script>
        <![CDATA[
            import flash.events.MouseEvent;
            import mx.events.FlexEvent;
            private function manejadorCreationComplete (event:FlexEvent):void
            {
                // Escucha por el evento click event en el botón.
                miBoton.addEventListener (MouseEvent.CLICK, manejadorClick);
            }        
            private function manejadorClick ( event:Event ):void
            {
              miEtiqueta.text = "Hola Mundo!";
            }     
        ]]>
    </mx:Script>             

    <mx:Panel title="Mi aplicacion" horizontalAlign="center"
        paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10"    >
        <mx:Label id="miEtiqueta" width="180" fontWeight="bold" fontSize="24"/>
        <mx:Button id="miBoton" label="Presioname!" />
    </mx:Panel>
</mx:Application>

Esta vez hemos registrado el manejador para el evento usando la función addEventListener. Esto quiere decir que las siguientes dos líneas de código hacen lo mismo: miBoton.addEventListener (MouseEvent.CLICK, manejadorClick); Es lo mismo que click="manejadorClick(event);" dentro de

        <mx:Button id="miBoton" click="manejadorClick(event);" />         

El conocimiento del papel que juegan los Eventos en Flex es muy importante para el desarrollo de componentes. Lo presentado aquí es la idea

básica del manejo de eventos, pero aun hay más, como su propagación, sus fases, y su programación adecuada para el manejo de memoria. Pero eso lo dejaremos para más adelante.

Saludos desde Boston, una ciudad llena de Eventos!

Usando el comboBox en Flex, switch statement y mas

Este es un breve ejemplo de como usar el comboBox, detectar cuando se ha cambiado de seleccion y usar un switch statement para inicializar una variable de acuerdo al valor seleccionado. Tambien muestra como usar dataBinding para llenar el comboBox usando un ArrayCollection.

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

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

<mx:Script>

<![CDATA[

import mx.controls.Alert;

import mx.events.ListEvent;

import mx.collections.ArrayCollection;

 

[Bindable]private var myPets : ArrayCollection;

 

private function createDP() : void

{

myPets = new ArrayCollection();

 

// Addiciona dos elementos al ArrayCollection

var oItem : Object;

 

oItem = new Object();oItem.name = 'dog';

oItem.id =1;

myPets.addItem(oItem);

oItem = new Object();oItem.name = 'cat';

oItem.id =2;

myPets.addItem(oItem);

 

oItem = new Object();oItem.name = 'fish';

oItem.id =3;

myPets.addItem(oItem);

 

// Usar el arrayCollection como dataProvider en el comboBox

myCombo.dataProvider=myPets;

}

 

private function getPetName ( event: ListEvent) : void

{

var miSonido : String;

// Dependiendo de la seleccion asignamos un sonido.

switch ( myCombo.selectedItem.name )

{

case 'dog':

miSonido ="guau, guau!"

break; case 'cat':

miSonido ="meow, meow!"

break; case 'fish':

miSonido ="glup, glup!"

break;

}

 

mx.controls.Alert.show("Hello I'm a " + myCombo.selectedItem.name + " "+miSonido, "Mensaje");

}

]]>

</mx:Script>

<mx:ComboBox id="myCombo" creationComplete="createDP()" labelField="name" change="getPetName(event)"/>

</mx:Application>

google

google

asus