Seven Yu @ 03/26/2008 (4:07 am)

让你的自定义组件拥有自己的图标

通常, 我们使用自定义组件时, 列表中显示的是默认的一个很丑陋的图标(见右图).

今天在看一官方文档(Creating and Extending Adobe Flex 3 Components)时发现一个专门用来定义组件图标的元标签 [IconFile], 使用方法也非常简单:

PLAIN TEXT >> ACTIONSCRIPT:
  1. [IconFile("path/to/your/icon/filename.ext")]
  2. // 支持 png, gif 和 jpg 文件
  3. // 文件尺寸 18*18 px
  4. class YourClass{}

这样, 我们的自定义组件也有了自己的图标了, 够酷吧 ;)

Seven Yu @ 03/26/2008 (3:25 am)

IP 输入组件

一个 IP 输入组件, 跟 windows 的 IP 设置框功能类似, 只是没有实现方向键控制输入框跳转, 但可以用 tab 和 shift + tab 移动焦点, 具体用法和实现功能如下:

  • 读/写 值使用 IpInputBox.value 属性(支持绑定);
  • 输入满3位或按<.>键(全键盘和数组小键盘的都可以)跳入下一输入框;
  • 输入大于 255 的数值自动格式化成 255
  • 可以使用 Backspace 键删除字符, 本输入框内容清空后自动跳入前一输入框

IpInputBox.as

PLAIN TEXT >> ACTIONSCRIPT:
  1. package org.phpz.controls
  2. {
  3.     import flash.events.Event;
  4.     import flash.events.KeyboardEvent;
  5.     import flash.ui.Keyboard;
  6.    
  7.     import mx.containers.HBox;
  8.     import mx.controls.Label;
  9.     import mx.controls.TextInput;
  10.  
  11.     [IconFile("icons/IpInputBox.png")]
  12.  
  13.     public class IpInputBox extends HBox
  14.     {
  15.         private const DOT1:uint = 110;
  16.         private const DOT2:uint = 190;
  17.         private const STR_NULL:String = '';
  18.        
  19.         private var nullNow:Boolean = false;
  20.        
  21.         private var ips:Array;
  22.         private var txt:Array;
  23.        
  24.         public function IpInputBox()
  25.         {
  26.             super();
  27.             ips = new Array('','','','');
  28.             txt = new Array();
  29.         }
  30.        
  31.         override protected function createChildren():void
  32.         {
  33.             super.createChildren();
  34.             setStyle('horizontalGap', 0);
  35.             for (var i:uint = 0; i <4; i++)
  36.             {
  37.                 if (i> 0)
  38.                 {
  39.                     var newLabel:Label = new Label();
  40.                     newLabel.text = '.';
  41.                     newLabel.width = 7;
  42.                     addChild(newLabel);
  43.                 }
  44.                 var newInput:TextInput = new TextInput();
  45.                 newInput.maxChars = 3;
  46.                 newInput.percentWidth = 100;
  47.                 newInput.restrict = '0-9';
  48.                 newInput.setStyle("textAlign", "center");
  49.                 newInput.addEventListener(Event.CHANGE, changeHandler);
  50.                 newInput.addEventListener(KeyboardEvent.KEY_UP, keyDownInTextHandler);
  51.                 txt.push(newInput);
  52.                 addChild(newInput);
  53.             }
  54.         }
  55.        
  56.         //////////////////////////////
  57.         // getter & setter
  58.         //////////////////////////////
  59.        
  60.         /**
  61.          * IP 值
  62.          * */
  63.         [Bindable]
  64.         public function set value(v:String):void
  65.         {
  66.             ips = v.split('.', 4);
  67.             for (var i:uint = 0; i <txt.length; i++)
  68.             {
  69.                 txt[i].text = ips[i] = formatIpPart(ips[i]);
  70.             }
  71.         }
  72.         public function get value():String
  73.         {
  74.             for (var i:uint = 0; i <txt.length; i++)
  75.             {
  76.                 txt[i].text = ips[i] = padIpPart(ips[i]);
  77.             }
  78.             return ips.join('.');
  79.         }
  80.        
  81.         //////////////////////////////
  82.         // private functions
  83.         //////////////////////////////
  84.        
  85.         /**
  86.          * 填补空位
  87.          * */
  88.         private function padIpPart(part:String):String
  89.         {
  90.             if (STR_NULL == part)
  91.             {
  92.                 part = "0";
  93.             }
  94.             return part;
  95.         }
  96.        
  97.         /**
  98.          * 格式化
  99.          * */
  100.         private function formatIpPart(part:String):String
  101.         {
  102.             if (null == part || STR_NULL == part)
  103.             {
  104.                 part = '0';
  105.             }
  106.             else
  107.             {
  108.                 part = part.replace(/[^0-9]/g, STR_NULL);
  109.             }
  110.             if (uint(part)> 255)
  111.             {
  112.                 part = "255";
  113.             }
  114.             return part;
  115.         }
  116.        
  117.         /**
  118.          * 使前一个输入框获得焦点
  119.          * */
  120.         private function setFocusToPrevText(target:TextInput):TextInput
  121.         {
  122.             var index:int = txt.indexOf(target);
  123.             if (index> 0)
  124.             {
  125.                 txt[index - 1].setFocus();
  126.                 txt[index - 1].selectionBeginIndex = txt[index - 1].selectionEndIndex = txt[index - 1].length;
  127.                 return txt[index - 1];
  128.             }
  129.             return target;
  130.         }
  131.        
  132.         /**
  133.          * 使后一个输入框获得焦点
  134.          * */
  135.         private function setFocusToNextText(target:TextInput):TextInput
  136.         {
  137.             var index:int = txt.indexOf(target);
  138.             if (index <3)
  139.             {
  140.                 txt[index + 1].setFocus();
  141.                 return txt[index + 1];
  142.             }
  143.             return target;
  144.         }
  145.  
  146.        
  147.         ////////////////////////////
  148.         // handler
  149.         ////////////////////////////
  150.    
  151.         private function keyDownInTextHandler(event:KeyboardEvent):void
  152.         {
  153.             var thisText:TextInput = event.currentTarget as TextInput;
  154.             if (DOT1 == event.keyCode || DOT2 == event.keyCode)
  155.             {
  156.                 STR_NULL != thisText.text && setFocusToNextText(thisText);
  157.             }
  158.             if (!nullNow && Keyboard.BACKSPACE == event.keyCode && 0 == thisText.selectionBeginIndex)
  159.             {
  160.                 var curText:TextInput = setFocusToPrevText(thisText);
  161.                 curText.text = curText.text.substr(0, curText.length - 1);
  162.             }
  163.             nullNow = false;
  164.         }
  165.        
  166.         private function changeHandler(event:Event):void
  167.         {
  168.             var thisText:TextInput = event.currentTarget as TextInput;
  169.             var index:int = txt.indexOf(thisText);
  170.             thisText.text = ips[index] = formatIpPart(thisText.text);
  171.             if (thisText.length == 3)
  172.             {
  173.                 // 焦点到下一输入框
  174.                 setFocusToNextText(thisText);
  175.             }
  176.             if (STR_NULL == thisText.text)
  177.             {
  178.                 nullNow = true;
  179.             }
  180.         }
  181.     } // end class
  182. } // end package

IpInputBox_test.mxml

PLAIN TEXT >> XML:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
  3.     xmlns:ns1="*" xmlns:controls="org.phpz.controls.*">
  4.     <mx:Form>
  5.         <mx:FormItem label="IP">
  6.             <controls:IpInputBox id="ip" value="{ipBind.text}" />
  7.         </mx:FormItem>
  8.         <mx:FormItem label="Bind Test">
  9.             <mx:TextInput id="ipBind" />
  10.         </mx:FormItem>
  11.         <mx:FormItem label="ip.value" direction="horizontal">
  12.             <mx:TextInput id="ipInput" />
  13.             <mx:Button label="set" click="ip.value = ipInput.text;" />
  14.             <mx:Button label="get" click="ipInput.text = ip.value;" />
  15.         </mx:FormItem>
  16.     </mx:Form>
  17. </mx:Application>

下载 IpInputBox.swc

Seven Yu @ 03/25/2008 (7:15 am)

在 Panel 的 Title 上添加组件

Tags: , , ::

原文: http://blog.olivermerk.ca/index.cfm/2007/6/17/Flex-Adding-Icons-to-the-P...

我的实验: NewPanel.mxml

PLAIN TEXT >> XML:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx :P anel xmlns:mx="http://www.adobe.com/2006/mxml">
  3.     <mx:Script>
  4.         <![CDATA[
  5.             import mx.controls.ComboBox;
  6.             import mx.containers.Panel;
  7.  
  8.             public var myComboBox:ComboBox;
  9.            
  10.             override protected function createChildren() : void{
  11.                 super.createChildren();
  12.                 myComboBox = new ComboBox;
  13.                
  14.                 titleBar.addChild(myComboBox);
  15.             }
  16.            
  17.              override protected function updateDisplayList (unscaledWidth:Number, unscaledHeight:Number):void{
  18.                 super.updateDisplayList(unscaledWidth, unscaledHeight);
  19.                
  20.                 // Do this or the HBox won't appear!
  21.                 myComboBox.setActualSize( myComboBox.getExplicitOrMeasuredWidth(),
  22.                 myComboBox.getExplicitOrMeasuredHeight() );
  23.                
  24.                 // Position the HBox
  25.                 var y:int = 4;
  26.                 var x:int = this.width - myComboBox.width - 12;
  27.                 myComboBox.move(x, y);
  28.              }
  29.         ]]>
  30.     </mx:Script>
  31. </mx :P anel>

test.mxml

PLAIN TEXT >> XML:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" xmlns:ns1="*" creationComplete="initApp();">
  3.     <mx:Script>
  4.         <![CDATA[
  5. ...
  6.             private function initApp():void{
  7.                 var arrData:Array = new Array(1,2,3,4,5);
  8.                 newPanel.myComboBox.dataProvider = arrData;
  9.                 newPanel.myComboBox.addEventListener(ListEvent.CHANGE, onChange);
  10.             }
  11.             private function onChange(event:ListEvent):void{
  12.                 trace((event.target as ComboBox).value);
  13.             }
  14.         ]]>
  15.     </mx:Script>
  16. ...
  17.     <ns1:NewPanel id="newPanel" width="100%" height="200">
  18.     </ns1:NewPanel>

Seven Yu @ 03/25/2008 (1:29 am)

Flex3 Component Explorer

Tags: , , ::

http://examples.adobe.com/flex3/componentexplorer/explorer.html

这是官方的在线版, 如果安装了 Flex Builder 3 可以在安装目录的 \sdks\3.0.0\samples\explorer 中找到.

第一次运行下 build.bat 就行了, 以后用 explorer.html 观看.