Flex的时间输入组件

        前几天因Flex项目中需要在DataGrid中输入时间,在网上搜寻到Plum中的一个TimeInput组件,试用了一下,发现单独使用没有问题,但在DataGrid中作为ItemEditor来调用,无法获得原来的值。经过调试研究,修改了几处代码,使得TimeInput可以传递字符串数据,可以在DataGrid中使用,时间值也从原来的时:分改成了时:分:秒。

代码如下:

package
{
    import flash.events.Event;
    import flash.events.FocusEvent;
    import flash.text.TextLineMetrics;
    import mx.core.UITextField;
    import mx.containers.HBox;
    import mx.controls.TextInput;
    import mx.controls.Button;
    import mx.events.FlexEvent;
    import mx.controls.Text;
    import mx.core.mx_internal;
    import mx.managers.IFocusManager;
    import mx.controls.NumericStepper;
    
    //import com.eshangrao.util.StringToolkit;
    
    use namespace mx_internal;
    
    /**
    * Dispatched when the time changes, which could be either the hour, minute.
    */    
    [Event(name="change",type="flash.events.Event")]
    /**
    * Dispatched when the hour changes.
    */    
    [Event(name="hoursChange",type="flash.events.Event")]
    /**
    * Dispatched when the minutes change.
    */    
    [Event(name="minutesChange",type="flash.events.Event")]
    /**
    * Dispatched when the seconds change.
    */    
    [Event(name="secondsChange",type="flash.events.Event")]

    public class TimeInputEx extends NumericStepper
    {
        public static function formatNumberWithChar(value:Number,length:int=2,pref:String="0"):String{
            var str:String=new String(value);
            var len:int=str.length;
            
            if(len>length)
                return str.substr(0,length);
            else{
                var n:int=length-len;
                for(var i:int=0;i
< n ; i++) {
                    str
=pref+str;
                
}
                return str;
            }
        }

        public function TimeInputEx()
        {
            super();
            this.maxChars
=2;
            
this.minimum =0;
            
this.maximum =23;
            
this.stepSize =1;
            
this.addEventListener(FlexEvent.VALUE_COMMIT,valueCommandHandler);
        }
        //--------------------------------------------------------------------------
        //
        //  Variables
        //
        //--------------------------------------------------------------------------
        
        /**
         *  @private
         */
        protected  var inputBox:HBox;
        
        /**
         *  @private
         */
        protected  var sText:Text;
        protected  var sText2:Text;
                
        /**
         *  @private
         */
        protected  var hoursInputField:TextInput;
        
        /**
         *  @private
         */
        protected  var minutesInputField:TextInput;
    
        /**
         *  @private
         */
        protected  var secondsInputField:TextInput;
    
        /**
         *  @private
         */
        protected var _hours:Number 
= 0;
        
/**
         *  @private
         */
        protected var _minutes:Number 
= 0;
        
/**
         *  @private
         */
        protected var _seconds:Number 
= 0;
        
/**
         *  @private
         */
        protected var _time:Date;
        /**
         *  @private
         */
        protected var _text:String;
         /**
         *  @private
         */
        private var _enabled:Boolean
=true;
        
        
override protected function createChildren():void
        {
            super.createChildren();
            if(!inputBox)
            {
                inputBox
=new  HBox();
                inputBox.setStyle("paddingLeft",0);
                inputBox.setStyle("paddingRight",0);
                inputBox.setStyle("paddingTop",0);
                inputBox.setStyle("paddingBottom",0);
                inputBox.setStyle("horizontalGap",0);
                inputBox.setStyle("borderStyle","solid");
                inputBox.setStyle("verticalAlign","middle");
                addChild(inputBox);
            }
            
            var widestNumber:Number
=61;
            
var lineMetrics:TextLineMetrics  = measureText(widestNumber.toString());
            
var textWidth:Number  = lineMetrics.width  + UITextField.TEXT_WIDTH_PADDING+4;
            if (!hoursInputField)
            {
                hoursInputField 
= new  TextInput();                
                hoursInputField.focusEnabled 
= false;
                
hoursInputField.styleName  = this;
                
hoursInputField.width =textWidth;
                
// restrict to numbers - dashes - commas - decimals
                hoursInputField.restrict 
= "0-9" ;
                hoursInputField.maxChars 
= 2;
                
hoursInputField.text  = formatNumberWithChar(_hours,2,"0");
                
//hoursInputField.parentDrawsFocus  = true;
                
hoursInputField.setStyle("textAlign","right");
                hoursInputField.setStyle("borderStyle","none");                
                hoursInputField.setStyle("paddingLeft",0);
                hoursInputField.setStyle("paddingRight",0);
                hoursInputField.setStyle("paddingTop",0);
                hoursInputField.setStyle("paddingBottom",0);
                hoursInputField.setStyle("horizontalGap",0);
                
                
                hoursInputField.addEventListener(FocusEvent.FOCUS_IN,inputField_focusInHandler);
                hoursInputField.addEventListener(FocusEvent.FOCUS_OUT, inputField_focusOutHandler);
                
                inputBox.addChild(hoursInputField);
            }
            inputField
=hoursInputField;
            
if(!sText){
                sText
=new  Text();
                sText.text
=":" ;
                sText.setStyle("textAlign","center");
                sText.setStyle("paddingLeft",0);
                sText.setStyle("paddingRight",0);
                sText.setStyle("paddingTop",0);
                sText.setStyle("paddingBottom",0);
                sText.setStyle("horizontalGap",0);
                inputBox.addChild(sText);
            }
            if (!minutesInputField)
            {
                minutesInputField 
= new  TextInput();            
                minutesInputField.focusEnabled 
= false;    
                
minutesInputField.styleName  = this;
                
minutesInputField.width =textWidth;
    
                
// restrict to numbers - dashes - commas - decimals
                minutesInputField.restrict 
= "0-9" ;
    
                minutesInputField.maxChars 
= 2;
                
minutesInputField.text  = formatNumberWithChar(_minutes,2,"0");
                
//minutesInputField.parentDrawsFocus  = true;
                
                
minutesInputField.setStyle("textAlign","left");
                minutesInputField.setStyle("borderStyle","none");        
                minutesInputField.setStyle("paddingLeft",0);
                minutesInputField.setStyle("paddingRight",0);
                minutesInputField.setStyle("paddingTop",0);
                minutesInputField.setStyle("paddingBottom",0);
                minutesInputField.setStyle("horizontalGap",0);
                minutesInputField.addEventListener(FocusEvent.FOCUS_IN,inputField_focusInHandler);
                minutesInputField.addEventListener(FocusEvent.FOCUS_OUT, inputField_focusOutHandler);
                
                inputBox.addChild(minutesInputField);
            }
            if(!sText2){
                sText2
=new  Text();
                sText2.text
=":" ;
                sText2.setStyle("textAlign","center");
                sText2.setStyle("paddingLeft",0);
                sText2.setStyle("paddingRight",0);
                sText2.setStyle("paddingTop",0);
                sText2.setStyle("paddingBottom",0);
                sText2.setStyle("horizontalGap",0);
                inputBox.addChild(sText2);
            }
            if (!secondsInputField)
            {
                secondsInputField 
= new  TextInput();            
                secondsInputField.focusEnabled 
= false;    
                
secondsInputField.styleName  = this;
                
secondsInputField.width =textWidth;
    
                
// restrict to numbers - dashes - commas - decimals
                secondsInputField.restrict 
= "0-9" ;
    
                secondsInputField.maxChars 
= 2;
                
secondsInputField.text  = formatNumberWithChar(_seconds,2,"0");
                
//secondsInputField.parentDrawsFocus  = true;
                
                
secondsInputField.setStyle("textAlign","left");
                secondsInputField.setStyle("borderStyle","none");        
                secondsInputField.setStyle("paddingLeft",0);
                secondsInputField.setStyle("paddingRight",0);
                secondsInputField.setStyle("paddingTop",0);
                secondsInputField.setStyle("paddingBottom",0);
                secondsInputField.setStyle("horizontalGap",0);
                secondsInputField.addEventListener(FocusEvent.FOCUS_IN,inputField_focusInHandler);
                secondsInputField.addEventListener(FocusEvent.FOCUS_OUT, inputField_focusOutHandler);
                
                inputBox.addChild(secondsInputField);
            }
        }
        
         /**
         *  @private
         *  Return the preferred sizes of the stepper.
         */
        override protected function measure():void
        {
            super.measure();
            var inputBoxHeight:Number 
= inputBox.getExplicitOrMeasuredHeight();
            
var buttonHeight:Number  = prevButton.getExplicitOrMeasuredHeight()  +
                                      nextButton.getExplicitOrMeasuredHeight();
    
            var h:Number 
= Math.max(inputBoxHeight,  buttonHeight);
            h 
= Math.max(DEFAULT_MEASURED_MIN_HEIGHT,  h);
    
            var inputBoxWidth:Number 
= inputBox.getExplicitOrMeasuredWidth();
            
var buttonWidth:Number  = Math.max(prevButton.getExplicitOrMeasuredWidth(),
                                              
nextButton.getExplicitOrMeasuredWidth());
    
            var w:Number 
= inputBoxWidth  + buttonWidth;
            w 
= Math.max(DEFAULT_MEASURED_MIN_WIDTH,  w);
    
            measuredMinWidth 
= DEFAULT_MEASURED_MIN_WIDTH;
            
measuredMinHeight  = DEFAULT_MEASURED_MIN_HEIGHT;
    
            
measuredWidth  = w;
            
measuredHeight  = h;
        
}
        /**
         *  @private
         *  Place the buttons to the right of the text field.
         */
        override protected function updateDisplayList(unscaledWidth:Number,
                                                      unscaledHeight:Number):void
        {
            super.updateDisplayList(unscaledWidth, unscaledHeight);
            
            var w:Number 
= nextButton.getExplicitOrMeasuredWidth();
            
var h:Number  = Math.round(unscaledHeight  / 2);
            var h2:Number 
= unscaledHeight  - h;
    
            nextButton.x 
= unscaledWidth  - w;
            nextButton.y 
= 0;
            
nextButton.setActualSize(w, h2);
           
            prevButton.x 
= unscaledWidth  - w;
            prevButton.y 
= unscaledHeight  - h;
            prevButton.setActualSize(w, h);
            var inputBoxHeight:Number 
= inputBox.getExplicitOrMeasuredHeight();
            
var inputBoxWidth:Number  = inputBox.getExplicitOrMeasuredWidth();
            
//inputBox.setActualSize(unscaledWidth - w, unscaledHeight);
            inputBox.setActualSize(inputBoxWidth,inputBoxHeight);    
        }
       
         /**
         *  @private
         */
        private function inputField_focusInHandler(event:FocusEvent):void
        {
            if (this.listData) {
                this.Caption 
= this.listData.label;
            
}
            inputField
=event.currentTarget  as TextInput;
            if(event.currentTarget as TextInput 
==  hoursInputField){
                this.value
=parseInt(inputField.text);
                
this.minimum =0;
                
this.maximum =23;
            
}else{
                this.value
=parseInt(inputField.text);
                
this.minimum =0;
                
this.maximum =59;
            
}
            
            focusInHandler(event);
            
            // Send out a new FocusEvent because the TextInput eats the event
            // Make sure that it does not bubble.
            dispatchEvent(new FocusEvent(event.type, false, false,
                                         event.relatedObject,
                                         event.shiftKey, event.keyCode));
        }
    
        /**
         *  @private
         */
        private function inputField_focusOutHandler(event:FocusEvent):void
        {
            if (this.listData) {
                this.listData.label 
= this.Caption;
            
}
            focusOutHandler(event);
            
            // Send out a new FocusEvent because the TextInput eats the event
            // Make sure that it does not bubble
            dispatchEvent(new FocusEvent(event.type, false, false,
                                         event.relatedObject,
                                         event.shiftKey,event.keyCode));
        }
        
        /**
         * @private
         * 
         * do for format number to string
         */
        private function valueCommandHandler(event:FlexEvent):void{
            //var v
=this.value;
            
inputField.text =formatNumberWithChar(value,2,"0");
            
if(inputField ==hoursInputField){
                
this.hours =value;
            
}
            else if(inputField
==minutesInputField){
                
this.minutes =value;
            
}
            else if(inputField
==secondsInputField){
                
this.seconds =value;
            
}
            this.Caption
=formatNumberWithChar(this.hours,2,"0")
                
+":"+formatNumberWithChar(this.minutes,2,"0")
                +":"+formatNumberWithChar(this.seconds,2,"0");
            
        }
        
         /**
         *  @private
         *  Remove the focus from the text field.
         */
        override protected function focusInHandler(event:FocusEvent):void
        {
            super.focusInHandler(event);
    
            var fm:IFocusManager 
= focusManager;
            
if (fm)
                fm.defaultButtonEnabled 
= false;
        
}
        [Bindable]
        /**
         * The hours (an integer from 0 to 23) of the day.  
         * 
         * @default 0
         */        
        public function get hours():Number
        {
            return _hours;
        }
        
        [Inspectable(defaultValue
=0,category="Time",name="Hours")]
        
public function set hours(val:Number):void
        {
            if (val 
> = 0 || val  < = 24 )
            {
                this._hours 
= val;
                
if(inputField){
                    if(inputField
==hoursInputField  && val! =value)
                        
value =val;
                    
else{
                        hoursInputField.text
=formatNumberWithChar(val,2,"0");
                    
}
                }
            }        
            
            dispatchEvent(new Event("hoursChange"));
            dispatchEvent(new Event("change"));
        }
        
        [Bindable]
        /**
         * The minutes (an integer from 0 to 59) passed in the hours.
         * 
         * @default 30
         */        
        public function get minutes():Number
        {
            return _minutes;
        }
        
        [Inspectable(defaultValue
=30,category="Time",name="Minutes")]
        
public function set minutes(val:Number):void
        {
            if (val 
> = 0 || val  < = 59 )
            {
                this._minutes 
= val;
                
if(inputField){
                    if(inputField
==minutesInputField  && val! =value)
                        
value =val;
                    
else{
                        minutesInputField.text
=formatNumberWithChar(val,2,"0");
                    
}
                }
            }
            
            dispatchEvent(new Event("minutesChange"));
            dispatchEvent(new Event("change"));
        }
        
        [Bindable]
        /**
         * The seconds (an integer from 0 to 59) passed in the hours.
         * 
         * @default 30
         */        
        public function get seconds():Number
        {
            return _seconds;
        }
        
        [Inspectable(defaultValue
=30,category="Time",name="Seconds")]
        
public function set seconds(val:Number):void
        {
            if (val 
> = 0 || val  < = 59 )
            {
                this._seconds 
= val;
                
if(inputField){
                    if(inputField
==secondsInputField  && val! =value)
                        
value =val;
                    
else{
                        secondsInputField.text
=formatNumberWithChar(val,2,"0");
                    
}
                }
            }
            
            dispatchEvent(new Event("secondsChange"));
            dispatchEvent(new Event("change"));
        }
        
        public function get Time():Date{
            var d:Date
=new  Date();
            d.hours
=_hours;
            
d.minutes =_minutes;
            
d.seconds =_seconds;
            
return d;
        }
        public function set Time(time:Date):void{
            this._time
=time;
            
this.hours =time.hours;
            
this.minutes =time.minutes;
            
this.seconds =time.seconds;
        
}
        
        [Bindable]
        public function get Caption():String{
            return _text;
        }
        [Inspectable(defaultValue
="00:00:00" ,category ="Caption" ,name ="Caption" )]
        public function set Caption(timestr:String):void{
            this._text
=timestr;
            
this.hours =Number(timestr.substring(0,2));
            
this.minutes =Number(timestr.substring(3,5));
            
this.seconds =Number(timestr.substring(6,8));
        
}
        
         /**
         *  @private
         */
        override public function set enabled(value:Boolean):void
        {
            _enabled 
= value;
            
if(hoursInputField){
                hoursInputField.enabled
=value;
                   
minutesInputField.enabled =value;      
                   
secondsInputField.enabled =value;      
                   
sText.enabled =value;
                   
sText2.enabled =value;
                   
nextButton.enabled =value;
                   
prevButton.enabled =value;
            
}
            
        }
        
    
        /**
         *  @private
         */
      
        override public function get enabled():Boolean
        {
            return _enabled;
        }
        
    }
}

将此代码保存为TimeInputEx.as文件,与你的工程文件放在同一目录下,即可调用。

完整的演示代码如下:

xml version="1.0" encoding="utf-8" ?>
< mx:Application  creationComplete ="init();"  xmlns:mx ="http://www.adobe.com/2006/mxml"  layout ="horizontal"  xmlns:ns1 ="*" >

< mx:Script >
    


        private function init():void{
            ac.addItem({starttime:"00:00:00", endtime:"01:00:00", program:""});
            ac.addItem({starttime:"01:00:00", endtime:"02:00:00", program:""});
        }

    
]]>

mx:Script >

 
    
< mx:DateFormatter  id ="timeFormatter"  formatString ="J:NN:SS A"   />
    
    
< mx:ArrayCollection  id ="ac" />

    
< mx:Panel  layout ="absolute"  paddingLeft ="5"  paddingRight ="5"  paddingTop ="5"  paddingBottom ="5"  title ="TimeInput"  width ="287"  height ="224" >
        
< ns1:TimeInputEx  hours ="3"  minutes ="45"  seconds ="30"  Caption ="03:45:30"  id ="timeInput"  left ="10"  right ="150"  top ="10" />
        
< mx:DataGrid  textAlign ="center"  id ="dg"  dataProvider ="{ac}"  sortableColumns ="false"  fontSize ="14"  editable ="true"  alternatingItemColors ="[#ffffff, #d1d1d1]"  headerColors ="[#ffffff, #d1d1d1]"  alpha ="0.6"   left ="10"  right ="10"  top ="51"  bottom ="29" >
            
< mx:columns >
                     
< mx:DataGridColumn  headerText ="start time"  dataField ="starttime"   textAlign ="center"   editable ="true"  minWidth ="125"  itemEditor ="TimeInputEx"  editorDataField ="Caption" />
               
< mx:DataGridColumn  headerText ="end time"  dataField ="endtime"   textAlign ="center"  editable ="true"  minWidth ="125"  itemEditor ="TimeInputEx"  editorDataField ="Caption" />
            
mx:columns >     
        
mx:DataGrid >
    
mx:Panel >
    
    
< mx:Panel  layout ="vertical"  paddingLeft ="5"  paddingRight ="5"  paddingTop ="5"  paddingBottom ="5"  title ="time now" >
        
< mx:Text  text ="hours:{TimeInputEx.hours}" />
        
< mx:Text  text ="minutes:{TimeInputEx.minutes}" />
        
< mx:Text  text ="seconds:{TimeInputEx.seconds}" />
        
< mx:Text  text ="caption:{TimeInputEx.Caption}" />
        
< mx:Button  label ="setTime to 8:10:03"  click ="TimeInputEx.Caption='08:10:03'"   />
        
< mx:Button  label ="switchEnable"  click ="if(TimeInputEx.enabled) TimeInputEx.enabled=false; else TimeInputEx.enabled=true;" />
    
mx:Panel >
mx:Application >

 

在此感谢feiy网友提供的TimeInput组件。请访问http://www.eshangrao.com/index.php/2007/08/08/427-timeinputflex获得TimeInput组件。

 

你可能感兴趣的:(Flex,flex,datagrid,string,date,application,encoding)