lunes, 29 de septiembre de 2008

Grandes Páginas de Flex


En estos últimos tres meses que me he adentrado en el mundo de flex, he visto que hay mucha mas documentación de la que pensaba, y no solo es simple documentacion, sino documentacion Open Source. Lamentablemente, al principio no conocia muchas de las mejores páginas lo que me llevo a desarrollar infinidad de componentes o aplicaciones que necesitaba, pero que en realidad ya otro las habia desarrollado (no saben lo frustrante que es saber que llevas 3 semanas haciendo algo que ya estaba hecho).

Por eso, he decidido recopilar lo que para mi, son páginas obligatorias a ojear antes de empezar a desarrollar algun componente o aplicación, probablemente lo que quieras hacer ya exista, y no solo existe, sino que ademas te la puedes bajar gratis y con una guia de como usarla!! que perfecto no?

Bueno aqui les dejo una lista de las mejores páginas que según mi humilde opinón les van a servir de mucho:

  • http://blog.flexexamples.com/ Una INCREIBE cantidad de ejemplos, probablemente tienen un ejemplo para todo lo que tu quieras hacer. Es la página que yo mas utilizo.
  • http://code.google.com/p/flexlib/ Una libreria de componentes para flex Open Source, tiene muchos componentes que pueden ser muy utiles y ha sido construida con la colaboracion de toda la comunidad desarrolladora de flex.
  • http://dougmccune.com/blog/ Uno de los gurus mas importantes de flex, publica ejemplos mas avanzados, pero no dejan de ser muy interesantes y uno nunca sabe cuando pueden ser utiles.
Espero que les sirvan estas páginas que para mi han sido de muchisima importancia.


Continuar leyendo...

Video Tutorial Eventos Flex


En este tutorial vamos a profundizar un poco mas en la utilización de los eventos con flex, la utilización de eventos en este framework es primordial para interactuar entre componentes o controles, por ejemplo, si queremos que un botón borre un campo de un formulario, debemos utilizar eventos (en este caso especifico el evento click).

Cada control en flex posee sus propios eventos definidos (los eventos que puede lanzar o disparar) y para saber cuales son solo debemos ir a la documentacion de su clase respectiva y ver de que eventos dispone.

En este tutorial vamos a estar trabajando especificamente con el control Button ya que es muy utilizado en las aplicaciones y me parecio apropiado, se va a utilizar especificamente 4 eventos, Mouse Over, Mouse Out, Creation Complete y Click (cabe destacar que practicamente todos los controles de flex poseen estos 4 eventos).
  1. Mouse Over: Ocurre cuando colocamos el mouse sobre el botón.
  2. Mouse Out: Ocurre cuando retiramos el mouse del botón.
  3. Click: cuando hacemos click en el botón.
  4. Creation Complete: cuando el botón termina de cargarse en la aplicación.
Estos eventos pueden ejecutar cualquier bloque de código (funcion) que nosotros definamos (esta función que se ejecuta es llamada Handler) dentro y fuera de la misma clase. Cabe destacar que la clase botón dispone de muchos otros eventos, y cada uno de ellos aporta una funcionalidad y oportunidad para realizar nuevas interaciones con el usuario.

Bueno les dejo un rar con el codigo fuente del ejemplo ademas del video y el ejemplo en funcionamiento en este post:



Código
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
public function limpiar() : void
{
LabelClick.text = "";
LabelMouseOver.text = "";
LabelMouseOut.text = "";
LabelCreationComplete.text = "";
}

public function clickHandler() : void
{
LabelClick.text = "Click";
}

public function mouseOverHandler() : void
{
LabelMouseOver.text = "Mouse Over";
}

public function mouseOutHandler() : void
{
LabelMouseOut.text = "Mouse Out";
}

public function creationCompleteHandler() : void
{
LabelCreationComplete.text = "Creation Complete";
}
]]>
</mx:Script>
<mx:Button x="190" y="103" label="Boton de prueba" click="clickHandler()" mouseOver="mouseOverHandler()" mouseOut="mouseOutHandler()" creationComplete="creationCompleteHandler()"/>
<mx:Label id="LabelClick" x="44" y="57" text="Label"/>
<mx:Label id="LabelMouseOver" x="125" y="57" text="Label"/>
<mx:Label id="LabelMouseOut" x="212" y="57" text="Label" />
<mx:Label id="LabelCreationComplete" x="299" y="57" text="Label" />
<mx:Button x="92" y="103" label="Limpiar" click="limpiar()"/>

</mx:Application>
Ejemplo



Continuar leyendo...

Video Tutorial Hola Mundo Flex


Este tutorial es para todas las sabias personas que han decidido empezar en el mundo de flex, es un video tutorial donde explico como crear la primera aplicacion en flex, con el típico "Hola Mundo".

Para empezar esta aplicacion debemos saber que flex es un lenguaje orientado a eventos, todos los controles (textBox, label, textArea, Botones, etc.) interactuan entre ellos disparando y escuchando eventos, por ejemplo:

Si queremos que cuando el usuario presione un botón se llene un label con un texto, entonces debemos decirle al botón que dispare un evento "click" y que cuando eso ocurra una funcion (tecnicamente llama "Handler") se encargue de realizar la accion de llenar el label con el texto deseado.



Un evento puede ser disparado por cualquier clase que implemente la interfaz IEventDispacher, todos los controles o componentes de flex la implementan, asi que pueden disparar eventos, la "Aplicacion principal" tambien puede disparar eventos, siendo uno de los mas populares y utilizados, el evento "creationComplete".

Un "Handler" puede llamarse por multiples eventos, como se muestra en este tutorial, el handler "init" se ejecuta en el evento "creationComplete" y en el evento "click", asi estos eventos sean disparados por controles diferentes.

Ya hablaremos un poco más de esto en los próximos tutoriales de eventos, asi que no debemos preocuparnos, es mucho mas fácil de lo que parece al principio, y ya van a ver que hasta le agarrarán el gusto a este estilo de programación.

Por ahora aqui les dejo el video tutorial y les coloco el descargable del código fuente de la aplicación, asi como el ejemplo funcionando:



Codigo
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
public function init() : void
{
label1.text = "Hola Mundo";
TextInput1.text = "Hola Mundo";
}

public function limpiar() : void
{
label1.text = "";
TextInput1.text = "";
}
]]>
</mx:Script>

<mx:Label id="label1" x="68" y="35" text="Label"/>
<mx:TextInput id="TextInput1" x="132" y="33"/>
<mx:Button id="Button1" x="215" y="63" label="Imprimir" click="init()"/>
<mx:Button id="Button0" x="130" y="63" label="Limpiar" click="limpiar()"/>

</mx:Application>
Ejemplo


Continuar leyendo...

domingo, 28 de septiembre de 2008

Video Tutorial Instalación Adobe Flex


Para los que han tomado la sabia decisión de iniciarse en este prometedor y apasionante mundo de Flex aqui les dejo un tutorial con video para aprender a instalarlo, es muy fácil y solo requiere de dos simples descargas fundamentalmente, espero que les guste ya que es mi primer tutorial, y empezaré a hacer muchos más con ejemplos de como llenar un datagrid, data Binding (enlace de datos), el típico primer "Hola Mundo", como crear un componente, etc.

Todos los ejemplos que agregue de ahora en adelante voy a procurar de publicarlos con un video acompañado que explico con mas detalle lo que se hace en el ejemplo, y se aceptan sugerencias de posibles ejemplos, estaré esperandolos y feliz de ayudarlos con mis humildes conocimientos. Sin mas que decir, les dejo el tutorial:







Lo primero que debemos hacer para empezar a desarrollar en flex es realizar las primeras dos descargas de la lista a continuación:
  1. Eclipse Classic 3.4.1
  2. El plugin para eclipse llamado Adobe Flex Builder
  3. El Adobe Flash player and debugger para Firefox o Internet Explorer segun nuestra preerencia.
El primero de la lista es el IDE para desarrollar, es el mismo que se utiliza con frecuencia para desarrollar aplicaciones con J2EE, C/C++, Java Standard Edition, etc.

El segundo de la lista le dice a eclipse como debe compilar y entender los codigos escritos en ActionScrip 3.0 (Que es el lenguaje para desarrollar en el framework Flex).

El tercero de la lista es opcional, y es el que nos permite realizar una prueba paso a paso de los codigos programados, aunque en el caso de flex, por ser un lenguaje asincrono y orientado a eventos, realizar estas pruebas paso a paso es un poco complejo cuando se involucran los eventos, yo me inclino por la utilización de la consola con la función "trace" en estos casos, pero ya hablaremos de estos temas mas adelante, espero que les guste y cualquier opinion o sugerencia por favor son bienvenidas, miren que es mi primer tutorial y no se que tan bien lo he hecho.


Continuar leyendo...

lunes, 1 de septiembre de 2008

DataGrid Expandilble - Componente Flex


Continuando con el desarrollo de los componentes de flex, les presento mi ultima creación. Lo hice puramente con fines esteticos, y porque hay veces que los formularios mostrados estan saturados de informacion y es mejor no mostrarla toda a menos que el usuario lo desee, para eso cree el Datagrid Expandible, que no es mas que un componente Datagrid que tiene dos propiedades nuevas: rowNumber que dice el numero de filas que se desean visualizar cuando el datagrid esta contraido (esto no quiere decir que no se puedan pasar las filas con el scrollBar, que es la diferencia con la propiedad rowCount que ya viene incluida dentro del datagrid del Framework de flex).

Otra cosa que le agregue fue la opcion de colocar un efecto visual a la hora de expandir y contraer, para volverlo mucho mas estetico y agradable para el usuario.

Bueno para no quitarles mas tiempo aqui les coloco el codigo fuente del componente:

Codigo

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()">
<mx:Script>
<![CDATA[

/**
* Componente DataGrid que permite especificar el numero de filas mostrar,
* colocando un scrollbara las demas filas para irlas pasando,
* tambien permite colocar un efecto de expansion y reduccion de las filas
* @version 1.0, 01/9/2008
* @author Alejandro Sánchez
*/

import mx.effects.Resize;
import mx.effects.Move;

import mx.collections.ArrayCollection;
import mx.collections.IList;
// Define the default property.
[DefaultProperty("columns")]

[Bindable]
public var _rowNumber : int = 0;

[Bindable]
private var _dataProvider : Object;

[Bindable]
private var _expanded : Boolean;

[Bindable]
private var _columns : Array;

[Bindable]
public var _effecto : Boolean = false;

private var _slow : Boolean = false;

private var timer : Timer;

/**
* Inicializa las variables por debecto y visializa el componenete
* por primera vez
*/

private function init() : void
{
if(_expanded) expand();
else collapse();
}

/**
* Permite setear la variable booleana que dice si el datagrid esta
* espandido o no
*/

public function set expanded(value : Boolean) : void
{
if(value!=_expanded)
{
_expanded = value;

invalidateSize();
invalidateProperties();
invalidateDisplayList();
}
}

public function get expanded() : Boolean
{
return _expanded;
}

/**
* La Default Property que recibe el datagrid para que se comporte como un
* datagrid comun y corriente
*/

public function set columns(value : Array) : void
{
if(value!=_columns)
_columns = value;


}

public function get columns() : Array
{
return _columns;
}

/**
* El datagrid debe cargarse de cualquier dataprovider que herede
* de la clase List
*/

public function set dataProvider(value : Object) : void
{
if(this._dataProvider!=value)
{
_dataProvider = value;

invalidateSize();
invalidateProperties();
invalidateDisplayList();
}
}

/**
* Determina el numero de filas a mostrar inicialmente
*/

public function set rowNumber(value : int) : void
{
if(_rowNumber!=value)
{
_rowNumber = value;

invalidateSize();
invalidateProperties();
invalidateDisplayList();
}
}

public function get rowNumber() : int
{
return _rowNumber;
}

public function get dataProvider() : Object
{
return _dataProvider;
}

/**
* Funcion que permite expandir el DataGrid
*/

public function expand() : void
{
_slow = true;
botonCollapse.visible = true;
boton.visible = false;

var cont : int = 0;
for each(var num : Object in _dataProvider)
cont++;

_rowNumber = cont;

invalidateSize();
invalidateProperties();
invalidateDisplayList();
}

/**
* Funcion que permite reducir el datagrid
*/

public function collapse() : void
{
_slow = true;
botonCollapse.visible = false;
boton.visible = true;

_rowNumber = 1;

invalidateSize();
invalidateProperties();
invalidateDisplayList();

}

/**
* Para realizar el binding con las principales propiedades
*/

override protected function commitProperties():void
{
super.commitProperties();

var cont : int = 0;
for each(var num : Object in _dataProvider)
cont++;

this.setChildIndex(boton, this.numChildren-1);
this.setChildIndex(botonCollapse, this.numChildren-1);

if(cont > 1)
{
boton.visible = true;
}
else
{
boton.visible = false;
}

}

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

if((_slow)&&(unscaledHeight!=dataGrid.height + boton.height))
{
var eff : Resize = new Resize(this);
eff.widthTo = dataGrid.width;
eff.heightTo = dataGrid.height + boton.height;
eff.duration = 400;

var eff2 : Move = new Move(boton);
eff2.yTo = dataGrid.height;
eff2.duration = 400;

var eff3 : Move = new Move(botonCollapse);
eff3.yTo = dataGrid.height;
eff3.duration = 400;

eff2.play();
eff3.play();
eff.play();

}
else
{
dataGrid.width = unscaledWidth;
this.height = dataGrid.height + boton.height;

boton.x = dataGrid.width - boton.width;
boton.y = dataGrid.height;
botonCollapse.x = dataGrid.width - boton.width;
botonCollapse.y = dataGrid.height;
}

}

]]>
</mx:Script>
<mx:Button id="boton" cornerRadius="0" width="18" height="18" click="expand()">
<mx:icon>@Embed(source='../../../assets/button_expand.PNG')</mx:icon>
</mx:Button>
<mx:Button id="botonCollapse" cornerRadius="0" width="18" height="18" click="collapse()">
<mx:icon>@Embed(source='../../../assets/button_collapse.PNG')</mx:icon>
</mx:Button>
<mx:DataGrid id="dataGrid" dataProvider="{_dataProvider}" rowCount="{_rowNumber}" columns="{_columns}">
</mx:DataGrid>
</mx:Canvas>
Ejemplo


Continuar leyendo...

Selector de Hora - Componente Flex


En los últimos dias he empezado a desarrollar mis primeros componentes, aprendiendo las fantásticas funciones como commitProperties, updateDisplayList, merge, etc. Que te permiten realizar un Binding de manera mas acoplada al framework de Flex y mejorar el rendimiento de los componentes.

Como primer componente (y en vista de mis necesidades para futuros componentes) he decidido desarrollar un componente que por extrañas razones no viene incluido en el framework de desarrollo de flex: Selector de Horas (Time Picker).

Trate de hacer el componente lo mas parametrizable posible, permite cambiar los saltos de minutos de 5minutos, 10minutos, 15 minutos, etc. Permite cambiar el color de fondo y texto del componente, puede trabajar tanto en hora militar como meridiano, etc.

Para descargar el codigo del componente en formato RAR debes hacer click aqui, y cualquier duda que tengan pueden preguntame a mi mail aalejo@gmail.com, espero que les guste y ¡ que le saquen dinero!

Sin mas, el codigo y ejemplo del componente, los parametros estan hechos para cargar desde el inicio, no para modificarlos en tiempo de ejecucion, asi que perdonen los errores si los cambian, prometo dar una version mejorada en los proximos dias que acepte cambios en tiempo de ejecucion sin errores:

Codigo

<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" initialize="initApp()" horizontalGap="0">
<mx:Metadata>
[Event(name="onChange", type="flash.events.Event")]
</mx:Metadata>

<mx:Script>
<![CDATA[

/**
* Componenete que permite seleccionar una hora del dia, representada
* en formato militar o meridiano, el componente tambien permite ajustar
* el salto en minutos que debe dar al aumentar o disminuir la hora,
* si se quiere saltar de dos horas en dos horas se debe colocar 120 minutos
* @version 1.0, 01/9/2008
* @author Alejandro Sánchez
*/

import mx.containers.VBox;
import mx.binding.utils.BindingUtils;


[Bindable]
public var textColor : uint = 0x000000;

[Bindable]
public var backGroundColor : uint = 0xffffff;

[Bindable]
public var _twelveHour : Boolean = true;

[Bindable]
private var _hour : Number = 1;

[Bindable]
private var _minutes : Number=0;

[Bindable]
private var _meridian : String = "AM";

[Bindable]
private var _minutesJump : Number = 1;

[Bindable]
private var _hoursJump : Number = 1;

[Bindable]
[Inspectable(type="Boolean")]
public var editable : Boolean = true;


private var focused : TextInput = null;

/**
* Inicializa las variables por debecto y visializa el componenete
* por primera vez
*/

private function initApp():void {
focused=tHour;
if(!_twelveHour) {
tMeridian.width=0;
}
tHour.text = _hour.toString();
tMinute.text = _minutes.toString();
tMeridian.text = _meridian.toString();

BindingUtils.bindSetter(changeHourType,this,"twelveHour");
BindingUtils.bindSetter(resetMinutes,this,"minutesJump");

validateHour();
validateMinutes();
}

/**
* Cambia la visualizacion del comoponente de militar a meridian
* o visceversa
* @param value Falso si se quiere pasar a hora militar
*/

public function changeHourType(value : Boolean) : void
{
if(!value)
{
tMeridian.width=0;
hBox.width = tHour.width + tMinute.width + TextDosPuntos.width + 5;
vBox.x = hBox.width;
}
else
{
tMeridian.width=20;
hBox.width = tHour.width + tMinute.width + TextDosPuntos.width + tMeridian.width + 5;
vBox.x = hBox.width;
}
}

[Inspectable(type="Boolean")]
public function set twelveHour(twHour:Boolean):void {
this._twelveHour = twHour;
}

/**
* Vuelve a empezar el conteo de minutos para evitar errores
*/

public function resetMinutes(value : int) : void
{
_minutes = 0;
}

/**
*
* @return true o false
*/

public function get twelveHour() : Boolean
{
return this._twelveHour;
}

public function set hour(hr:Number):void {
this._hour = hr;
this.tHour.text = hr > 9 ? ""+hr : "0"+hr;
}

public function set minutes(mn:Number):void {
this._minutes = mn;
this.tMinute.text = mn > 9 ? ""+mn : "0"+mn;
}

/**
*
* @return Los minutos actuales que marca el componente
*/

public function get minutes():Number {
return this._minutes;
}

/**
*
* @return La hora actual que marca el componente
*/

public function get hour():Number {
return this._hour;
}

/**
* El salto en minutos que se espera que haga
* @return El salto en minutos que se espera que haga.
*/

public function get minutesJump() : int {
return this._minutesJump;
}

/**
* Calcula el salto en horas y en minutos que se debe saltar
* @param value el salto en minutos que se quiere saltar (Ej. 120min)
*/
[Inspectable(defaultValue=5, enumeration="1,5,10,15,30,60,120,180,240,300,360,420,480,540,600", type="int")]
public function set minutesJump(value : int):void
{
if(value>=60)
{
_minutesJump= 0;
_hoursJump = Math.floor(value/60);
}
else
{
this._minutesJump = value;
}
}

/**
*
* @return AM o FM
*/

public function get meridian():String {
return this._meridian;
}

public function set meridian(ampm:String):void {
this._meridian = ampm;
}

/**
* Si el usuario presiona el boton para subir la hora (o minuto)
*/

private function arrowUp():void {
if(editable)
{
if(focused == tHour && _twelveHour) {
adjustHour12(true);
} else if (focused == tHour && !_twelveHour) {
adjustHour24(true);
} else if (focused == tMinute) {
if(_minutesJump>0) adjustMinute(true);
} else if (focused == tMeridian) {
switchAm();
} else {
return;
}
dispatchEvent(new Event("onChange",true));
}
}

/**
* Si el usuario presiona el boton para bajar la hora (o minuto)
*/

private function arrowDown():void {
if(editable)
{
if(focused == tHour && _twelveHour) {
adjustHour12(false);
} else if (focused == tHour && !_twelveHour) {
adjustHour24(false);
} else if (focused == tMinute) {
if(_minutesJump>0) adjustMinute(false);
} else if (focused == tMeridian) {
switchAm();
} else {
return;
}
dispatchEvent(new Event("onChange",true));
}
}

/**
* Si se esta trabajando en Meridian y se quiere subir o bajar una hora
* @param up Un booleano "verdadero" si se esta subiendo en la hora
*/

private function adjustHour12(up:Boolean):void {
var n:Number = new Number(tHour.text);
if ((n<=12) && ((n+_hoursJump) > 12) && up) {
n = (n+_hoursJump)%12;
} else if ((n>=1) && ((n-_hoursJump) < 1) && !up) {
n = 12 + (n-_hoursJump);
} else if (up) {
n+=_hoursJump;
} else if (!up) {
n-=_hoursJump;
}
_hour = n;
if (n<10) {
tHour.text = "0"+n.toString();
} else {
tHour.text = n.toString();
}
}

/**
* Actualiza los valores en minutos del componenete
* @param up Un booleano "verdadero" si se esta subiendo en la hora
*/

public function adjustMinute(up:Boolean):void {
var n:Number = new Number(tMinute.text);
if (n == (60-minutesJump) && up)
{
if(_twelveHour) adjustHour12(up);
else adjustHour24(up);
n = 0;
} else if (n == 0 && !up) {
if(_twelveHour) adjustHour12(up);
else adjustHour24(up);
n = 60 - minutesJump;
} else if (up) {
n+=minutesJump;
} else if (!up) {
n-=minutesJump;
}
if (n<10) {
tMinute.text = "0"+n.toString();
} else {
tMinute.text = n.toString();
}
_minutes = n;
}

/**
* Actualiza los valores en horas militares del componenete
* @param up Un booleano "verdadero" si se esta subiendo en la hora
*/

private function adjustHour24(up:Boolean):void {
var n:Number = new Number(tHour.text);
if ((n+_hoursJump) > 23 && up) {
n = (n+_hoursJump)%24;
} else if ((n-_hoursJump) <= 0 && !up) {
n = 24 + (n -_hoursJump);
} else if (up) {
n+=_hoursJump;
} else if (!up) {
n-=_hoursJump;
}
if (n<10) {
tHour.text = "0"+n.toString();
} else {
tHour.text = n.toString();
}
_hour = n;

}

/**
* Cambia de AM a FM o visceversa
*/

public function switchAm():void {
if (tMeridian.text == "AM") {
tMeridian.text = "PM";
} else {
tMeridian.text = "AM";
}
_meridian = tMeridian.text;
dispatchEvent(new Event("onChange",true));

}

/**
* Valida que los valores del campo para AM y PM sean coherentes (o AM o FM)
*/

public function validateAm():void {
if (tMeridian.text.toUpperCase() != "AM" && tMeridian.text.toUpperCase() != "PM") {
if (tMeridian.text.length > 0 && tMeridian.text.toUpperCase().charAt(0) == 'P') {
tMeridian.text="PM";
} else {
tMeridian.text="AM";
}
}
tMeridian.text = tMeridian.text.toUpperCase();
_meridian = tMeridian.text;
dispatchEvent(new Event("onChange",true));
}

/**
* Se encarga de llamar a las funciones que actualizan las horas segun
* el tipo de visualizacion
* @param up Un booleano "verdadero" si se esta subiendo en la hora
*/

public function validateHour():void {
if (_twelveHour) {
validateHour12();
} else {
validateHour24();
}
dispatchEvent(new Event("onChange",true));
}

public function validateHour12():void {
var n:Number = new Number(tHour.text);
if (n >12) {
n= n % 12;
} else if (n < 1) {
n = 12 + n;
}
if (n < 10) {
tHour.text = "0"+n.toString();
} else {
tHour.text = n.toString();
}
_hour = n;
}

public function validateHour24():void {
var n:Number = new Number(tHour.text);
if (n >23) {
n= n % 24;
} else if (n < 0) {
n = 24 + n;
}
if (n < 10) {
tHour.text = "0"+n.toString();
} else {
tHour.text = n.toString();
}
_hour = n;
}

public function validateMinutes():void {
var n:Number = new Number(tMinute.text);
if (n >59) {
n=0;
} else if (n < 0) {
n = 60 - _minutesJump;
}
if (n < 10) {
tMinute.text = "0"+n.toString();
} else {
tMinute.text = n.toString();
}
_minutes = n;
dispatchEvent(new Event("onChange",true));
}

public function changeFocus(focusBox : TextInput):void {
focused=focusBox;
}

]]>
</mx:Script>

<mx:HBox id="hBox" horizontalGap="0" borderStyle="inset" verticalAlign="middle" height="22" horizontalScrollPolicy="off" backgroundColor="{backGroundColor}">
<mx:TextInput color="{textColor}" maxChars="2" restrict="0-9" borderStyle="none" textAlign="right" id="tHour" width="17" focusIn="changeFocus(tHour)" focusOut="validateHour()" backgroundAlpha="0.0"/>
<mx:TextInput color="{textColor}" id="TextDosPuntos" borderStyle="none" textAlign="right" editable="false" text=":" width="7" focusEnabled="false" backgroundAlpha="0.0"/>
<mx:TextInput color="{textColor}" maxChars="2" restrict="0-9" borderStyle="none" textAlign="right" id="tMinute" width="17" focusIn="changeFocus(tMinute)" focusOut="validateMinutes()" backgroundAlpha="0.0"/>
<mx:TextInput color="{textColor}" visible="{_twelveHour}" maxChars="2" restrict="APM" borderStyle="none" textAlign="right" id="tMeridian" click="switchAm()" width="20" focusIn="changeFocus(tMeridian)" focusOut="validateAm()" backgroundAlpha="0.0"/>
</mx:HBox>

<mx:VBox id="vBox" verticalAlign="bottom" verticalGap="0" horizontalGap="0">
<mx:Button verticalGap="0" cornerRadius="0" icon="@Embed(source='assets//uparrow.png')" click="arrowUp()" width="16" height="10"/>
<mx:Button verticalGap="0" cornerRadius="0" icon="@Embed(source='assets//downarrow.png')" click="arrowDown()" width="16" height="11"/>
</mx:VBox>

</mx:HBox>
Ejemplo


Continuar leyendo...