2009-01-09

Flex金额转大写函数

  从一个VFP函数转过来的,调用:transformAmount(231010045.31) 。 代码如下:

private function transformAmount(amount:Number):String
{
var result:String = "";
var number:Number = 0;
var i:int = 0;
if (isNaN(amount) == true)
return result;
result = (amount < 0, "负", "");
number = Math.round(amount * 100);
for (i = number.toString().length - 1; i >= 0; i--)
{
result = result +
"零壹贰叁肆伍陆柒捌玖".substr(Math.floor(number / Math.pow(10, i)), 1) +
"分角元拾佰仟万拾佰仟亿拾佰仟万".substr(i, 1);
number = number % (Math.pow(10, i));
}
result = STRTRAN(STRTRAN(STRTRAN(STRTRAN(STRTRAN(result, "零仟", "零"), "零佰", "零"),
"零拾", "零"), "零角", "零"), "零分", "整");
result = STRTRAN(STRTRAN(STRTRAN(STRTRAN(STRTRAN(result, "零零", "零"), "零零", "零"),
"零亿", "亿"), "零万", "万"), "零元", "元");
result = (result == "整" ? "零元整" : STRTRAN(STRTRAN(result, "亿万", "亿"), "零整", "整"));
return result;
}

private function STRTRAN(strSearched:String, strExpressionSought:String,
strReplacement:String):String
{
var result:String = null;
var i:int = 0;
if (strSearched == null)
return result;
result = "";
for (i = 0; i < strSearched.length; i++)
if (strSearched.substr(i, strExpressionSought.length) == strExpressionSought)
{
result = result + strReplacement;
i = i + strExpressionSought.length - 1;
}
else
{
result = result + strSearched.substr(i, 1);
}
return result;
}

2009-01-05

合影

  元旦前给妹妹买的W960与女朋友的M600的合影:

日期输入控件

  我是在MXML里写的,代码如下:

import code.Global;
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.text.TextFieldType;
import mx.controls.DateField;
import mx.utils.StringUtil;

private var _date:Date = null;
private var _maxYear:int = 2100;
private var _minYear:int = 1900;
private var _formatString:String = null;
private var _labelFunction:Function = null;
private var _parseFunction:Function = null;
private var _overrideEditable:Boolean = false;

private var dateIndex:int = 0;
private var inputIndex:int = 0;
private var setValueFlag:Boolean = false;
private var datePositionArray:Array = new Array();

public function get date():Date
{
return _date;
}

public function set date(value:Date):void
{
_date = value;
setValueFlag = true;
if (formatString == null)
formatString = null;
if (labelFunction != null)
this.text = _labelFunction(_date, formatString);
else
this.text = DateField.dateToString(_date, formatString);
setValueFlag = false;
}

public function get maxYear():int
{
return _maxYear;
}

public function set maxYear(value:int):void
{
_maxYear = value;
}

public function get minYear():int
{
return _minYear;
}

public function set minYear(value:int):void
{
_minYear = value;
}

public function get formatString():String
{
return _formatString;
}

public function set formatString(value:String):void
{
value = (value == null ?
this.resourceManager.getString("SharedResources", "dateFormat") :
value);
_formatString = StringUtil.trim(value);
refreshDatePositionArray();
}

public function get labelFunction():Function
{
return _labelFunction;
}

public function set labelFunction(value:Function):void
{
_labelFunction = value;
}

public function get parseFunction():Function
{
return _parseFunction;
}

public function set parseFunction(value:Function):void
{
_parseFunction = value;
}

public function get overrideEditable():Boolean
{
return _overrideEditable;
}

public function set overrideEditable(value:Boolean):void
{
_overrideEditable = value;
}

override public function set text(value:String):void
{
super.text = value;
if (setValueFlag == true)
return;
if (formatString == null)
formatString = null;
if (_parseFunction != null)
date = _parseFunction(value, formatString);
else
date = DateField.stringToDate(value, formatString);
}

override protected function commitProperties():void
{
super.commitProperties();
this.textField.type = TextFieldType.DYNAMIC;
}

private function init():void
{
this.addEventListener(FocusEvent.FOCUS_IN, onFocusIn);
this.addEventListener(FocusEvent.FOCUS_OUT, onFocusOut);
this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
this.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
this.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
this.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
}

private function onFocusIn(event:FocusEvent):void
{
if (this.text.length > 0)
selectDatePart(1);
inputIndex = 0;
}

private function onFocusOut(event:FocusEvent):void
{
saveDate();
}

private function onMouseDown(event:MouseEvent):void
{
var beginIndex:int = this.selectionBeginIndex;
var flags:String = "";
var index:int = 0;
var i:int = 0;
var flag:String = "";
event.preventDefault();
this.focusManager.setFocus(this);
if (this.text.length > 0)
{
for (i = 0; i < datePositionArray.length; i++)
{
flag = datePositionArray[i].flag;
if ("YMD".indexOf(flag) >= 0)
{
if (flags.indexOf(flag) < 0)
{
flags = flags + flag;
index = flags.indexOf(flag) + 1;
}
}
if (beginIndex >= datePositionArray[i].startIndex &&
beginIndex <= datePositionArray[i].endIndex)
break;
}
selectDatePart(index);
}
}

private function onMouseUp(event:MouseEvent):void
{
if (this.focusManager.getFocus() == this)
onMouseDown(event);
}

private function onMouseMove(event:MouseEvent):void
{
if (this.focusManager.getFocus() == this)
onMouseDown(event);
}

private function onKeyDown(event:KeyboardEvent):void
{
var keyCode:int = event.keyCode;
if (this.editable == false && _overrideEditable == false)
return;
switch (keyCode)
{
case 37: // Left Arrow
event.preventDefault();
if (dateIndex == 1 || dateIndex == 2 || dateIndex == 3)
selectDatePart(dateIndex > 1 ? dateIndex - 1 : 3);
saveDate();
inputIndex = 0;
break;
case 39: // Right Arrow
event.preventDefault();
if (dateIndex == 1 || dateIndex == 2 || dateIndex == 3)
selectDatePart(dateIndex < 3 ? dateIndex + 1 : 1);
saveDate();
inputIndex = 0;
break;
case 38: // Up Arrow
event.preventDefault();
changeDateValue("UP");
break;
case 40: // Down Arrow
event.preventDefault();
changeDateValue("DOWN");
break;
case 36: // Home
event.preventDefault();
changeDateValue("HOME");
break;
case 35: // End
event.preventDefault();
changeDateValue("END");
break;
case 46: // Delete
event.preventDefault();
deleteDateValue();
break;
case 8: // Backspace
event.preventDefault();
deleteDateValue();
break;
}
if (keyCode >= 48 && keyCode <= 57) // 数字键
{
event.preventDefault();
changeDateValue2(keyCode - 48);
}
}

private function getDayCount(year:int, month:int):int
{
var dayCount:int = 0;
if (month == 1 || month == 3 || month == 5 || month == 7 ||
month == 8 || month == 10 || month == 12 || month == 0)
dayCount = 31;
else
if (month == 4 || month == 6 || month == 9 || month == 11)
dayCount = 30;
else
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
dayCount = 29;
else
dayCount = 28;
return dayCount;
}

private function refreshDatePositionArray():void
{
var testDate:Date = new Date(4567, 9, 23);
var testDateString:String = "";
var dateFormatString:String = "";
var i:int = 0;
var char:String = "";
var dateFlags:String = "";
var lastFlag:String = "";
var lastIndex:int = 0;
var flag:String = "";
var object:Object = null;
datePositionArray = new Array();
try
{
if (_labelFunction != null)
testDateString = _labelFunction(testDate, formatString);
else
testDateString = DateField.dateToString(testDate, formatString);
}
catch (error:*)
{
}
for (i = 0; i < testDateString.length; i++)
{
char = testDateString.charAt(i);
if ("4567".indexOf(char) >= 0)
char = "Y";
else
if ("01".indexOf(char) >= 0)
char = "M";
else
if ("23".indexOf(char) >= 0)
char = "D";
dateFormatString = dateFormatString + char;
}
for (i = 0; i < dateFormatString.length; i++)
{
char = dateFormatString.charAt(i);
flag = ("YMD".indexOf(char) >= 0 ? char : "-");
if (flag != lastFlag)
{
lastFlag = flag;
if ((flag != "-" && dateFlags.substr(dateFlags.length - 1, 1) != flag) ||
flag == "-")
{
if (datePositionArray.length > 0)
{
object = datePositionArray[datePositionArray.length - 1];
object.endIndex = i - 1;
object.length = object.endIndex - object.startIndex + 1;
}
datePositionArray.push(new Object());
object = datePositionArray[datePositionArray.length - 1];
object.flag = flag;
object.text = "";
object.startIndex = i;
object.endIndex = -1;
object.length = 0;
}
else
{
object = null;
}
}
if (object != null)
object.text = object.text + char;
}
object = (datePositionArray.length == 0 ? null :
datePositionArray[datePositionArray.length - 1]);
if (object != null && object.endIndex == -1)
{
object.endIndex = dateFormatString.length - 1;
object.length = object.endIndex - object.startIndex + 1;
}
}

private function getDatePositionObjectByIndex(index:int):Object
{
var object:Object = null;
var flags:String = "";
var i:int = 0;
for (i = 0; i < datePositionArray.length; i++)
{
if ("YMD".indexOf(datePositionArray[i].flag) >= 0)
{
if (flags.indexOf(datePositionArray[i].flag) < 0)
{
flags = flags + datePositionArray[i].flag;
if (flags.length == index)
{
object = datePositionArray[i];
break;
}
}
}
}
return object;
}

private function getDatePositionObjectByFlag(flag:String):Object
{
var object:Object = null;
var i:int = 0;
for (i = 0; i < datePositionArray.length; i++)
{
if (datePositionArray[i].flag == flag)
{
object = datePositionArray[i];
break;
}
}
return object;
}

private function getDateTextByFlag(flag:String):String
{
var dateText:String = "";
var object:Object = getDatePositionObjectByFlag(flag);
if (object != null)
dateText = Global.trim(this.text).substr(object.startIndex,
object.length);
return dateText;
}

private function getDateValueByFlag(flag:String):int
{
var dateValue:int = 0;
var object:Object = getDatePositionObjectByFlag(flag);
if (object != null)
dateValue = parseInt(Global.trim(this.text).substr(object.startIndex,
object.length), 10);
return dateValue;
}

private function getDateIndexByFlag(flag:String):int
{
var flags:String = "";
var i:int = 0;
for (i = 0; i < datePositionArray.length; i++)
{
if ("YMD".indexOf(datePositionArray[i].flag) >= 0 &&
flags.indexOf(datePositionArray[i].flag) < 0)
{
flags = flags + datePositionArray[i].flag;
if (datePositionArray[i].flag == flag)
break;
}
}
return flags.length;
}

private function selectDatePart(index:int):void
{
var defaultDate:Date = null;
var dateString:String = "";
var object:Object = null;
var i:int = 0;
if (this.editable == false && _overrideEditable == false)
return;
if (this.text.length == 0)
{
defaultDate = new Date();
if (defaultDate.fullYear < minYear || defaultDate.fullYear > maxYear)
defaultDate = new Date(minYear, 0, 1);
try
{
if (_labelFunction != null)
dateString = _labelFunction(defaultDate, formatString);
else
dateString = DateField.dateToString(defaultDate, formatString);
}
catch (error:*)
{
}
this.text = dateString;
}
if (index != 1 && index != 2 && index != 3)
index = 1;
object = getDatePositionObjectByIndex(index);
if (object != null)
this.setSelection(object.startIndex, object.endIndex + 1);
dateIndex = index;
}

private function deleteDateValue():void
{
this.text = "";
dateIndex = 0;
}

private function changeDateValue(action:String):void
{
var object:Object = null;
var currentValue:int = 0;
var minValue:int = 0;
var maxValue:int = 0;
var yearValue:int = 0;
var monthValue:int = 0;
var dayValue:int = 0;
var dayIndex:int = 0;
if (Global.trim(this.text).length == 0)
{
selectDatePart(dateIndex);
return;
}
selectDatePart(dateIndex);
object = getDatePositionObjectByIndex(dateIndex);
if (object == null)
return;
currentValue = getDateValueByFlag(object.flag);
switch (object.flag)
{
case ("Y"):
minValue = minYear;
maxValue = maxYear;
break;
case ("M"):
minValue = 1;
maxValue = 12;
break;
case ("D"):
minValue = 1;
yearValue = getDateValueByFlag("Y");
monthValue = getDateValueByFlag("M");
if (yearValue != 0 && monthValue != 0)
maxValue = getDayCount(yearValue, monthValue);
break;
default:
break;
}
if (minValue == 0 || maxValue == 0)
return;
switch (action)
{
case ("UP"):
currentValue = currentValue + 1;
if (currentValue > maxValue)
currentValue = minValue;
break;
case ("DOWN"):
currentValue = currentValue - 1;
if (currentValue < minValue)
currentValue = maxValue;
break;
case ("HOME"):
currentValue = minValue;
break;
case ("END"):
currentValue = maxValue;
break;
default:
break;
}
setDateValue(dateIndex, currentValue);
object = getDatePositionObjectByFlag("D");
yearValue = getDateValueByFlag("Y");
monthValue = getDateValueByFlag("M");
dayValue = getDateValueByFlag("D");
dayIndex = getDateIndexByFlag("D");
if (object != null && yearValue != 0 && monthValue != 0 && dayValue != 0)
if (dayValue > getDayCount(yearValue, monthValue))
setDateValue(dayIndex, getDayCount(yearValue, monthValue));
}

private function changeDateValue2(value:int):void
{
var oldInputIndex:int = 0;
var object:Object = null;
var dateValue:int = 0;
var dateText:String = "";
var setFlag:Boolean = true;
var dayIndex:int = 0;
var dayValue:int = 0;
var dayCount:int = 0;
if (Global.trim(this.text).length == 0)
{
selectDatePart(dateIndex);
return;
}
selectDatePart(dateIndex);
oldInputIndex = inputIndex;
object = getDatePositionObjectByIndex(dateIndex);
if (object == null)
return;
inputIndex = inputIndex + 1;
if (inputIndex > object.length)
inputIndex = 1;
dateText = getDateTextByFlag(object.flag);
dateText = dateText.substr(dateText.length - inputIndex + 1,
inputIndex - 1) + value;
dateValue = parseInt(dateText, 10);
if (inputIndex > 1)
{
switch (object.flag)
{
case ("M"):
if (dateValue < 1 || dateValue > 12)
setFlag = false;
break;
case ("D"):
if (dateValue < 1 || dateValue > getDayCount(
getDateValueByFlag("Y"), getDateValueByFlag("M")))
setFlag = false;
break;
}
}
if (setFlag == false)
{
inputIndex = oldInputIndex;
return;
}
setDateValue(dateIndex, dateValue);
if (object.flag != "D")
{
dayIndex = getDateIndexByFlag("D");
dayValue = getDateValueByFlag("D");
dayCount = getDayCount(getDateValueByFlag("Y"), getDateValueByFlag("M"));
dayValue = Math.max(Math.min(dayValue, dayCount), 1);
if (dayIndex > 0)
setDateValue(dayIndex, dayValue);
}
}

private function setDateValue(index:int, value:int):void
{
var dateValue:String = Global.trim(value.toString());
var dateText:String = Global.trim(this.text);
var object:Object = getDatePositionObjectByIndex(index);
var i:int = 0;
if (object == null)
return;
for (i = dateValue.length + 1; i <= object.length; i++)
dateValue = "0" + dateValue;
dateText = dateText.substring(0, object.startIndex) + dateValue +
dateText.substr(object.endIndex + 1, dateText.length);
setValueFlag = true;
this.text = dateText;
setValueFlag = false;
selectDatePart(dateIndex);
}

public function saveDate():void
{
var yearValue:int = 0;
var monthValue:int = 0;
var dayValue:int = 0;
if (Global.trim(this.text).length == 0)
return;
yearValue = getDateValueByFlag("Y");
yearValue = Math.min(Math.max(yearValue, minYear), maxYear);
if (getDateIndexByFlag("Y") > 0)
setDateValue(getDateIndexByFlag("Y"), yearValue);
yearValue = getDateValueByFlag("Y");
monthValue = getDateValueByFlag("M");
monthValue = Math.min(Math.max(monthValue, 1), 12);
if (getDateIndexByFlag("M") > 0)
setDateValue(getDateIndexByFlag("M"), monthValue);
monthValue = getDateValueByFlag("M");
dayValue = getDateValueByFlag("D");
dayValue = Math.max(dayValue, 1);
dayValue = Math.min(dayValue, getDayCount(yearValue, monthValue));
if (getDateIndexByFlag("D") > 0)
setDateValue(getDateIndexByFlag("D"), dayValue);
this.text = this.text;
if (dateIndex > 0)
selectDatePart(dateIndex);
}

基于TextInput,MXML中需要加上这行代码:creationComplete="init()"。感觉还比较好用,不过如果formatString设置的过于变态的话(比如5位的年份、1位的月份等),应该会出问题,没做这方面的测试。下一步准备把这个控件加入到自定义的DateField里,替换掉它原有的那个TextInput。

2009-01-04

Flex的BUG?

  在Flex项目下新建一个应用,代码如下:

然后保存并在DEBUG方式下运行,控制台会打印出下面的文本:
  3
  bug0.panel.btn001
  bug0.panel.btn002
  bug0.panel.btn003
这显示显然不对,把ControlBar给漏掉了。
  把代码中的注释去掉,再运行一下,控制台打印的文本就是正确的了:
  5
  bug0.panel.btn001
  bug0.panel.btn002
  bug0.panel.btn003
  bug0.panel.ControlBar12
  bug0.panel.Spacer16
但是显示出的界面似乎有些问题:

  我用的Flex版本是3.1。