Flex4实现分组框GroupBox

文章来自:Iteye-jinxinhero

分组框(Group Box)是围绕在一组相关控件周围的带标签的矩形边框。它提供了一种通过视觉展示控件关系

的方法。如下图所示:

本文将通过以下几步来实现:

一、继承SkinnableContainer,创建组件类GroupBox。

二、声明外观部件titleDisplay用来显示组合框的标题。

三、增加title属性。

四、覆盖partAdded方法,使标题字符串能够作用于外观部件titleDisplay。

五、创建它的默认外观(皮肤)GroupBoxSkin。

六、为GroupBox增加必要样式。

---------------

一、继承SkinnableContainer,创建组件类GroupBox。

Actionscript 3.0代码

1 public class GroupBox extends SkinnableContainer  
2 {  
3  public function GroupBox()  
4  {  
5   super();  
6  }  
7 }  

二、声明外观部件titleDisplay用来显示组合框的标题。

Actionscript 3.0代码

1 [SkinPart(required="false")]  
2 public var titleDisplay:TextBase;  

三、增加title属性。

Actionscript 3.0代码
 1 private var _title:String = "";  
 2 [Bindable]  
 3 public function get title():String   
 4 {  
 5  return _title;  
 6 }  
 7 public function set title(value:String):void   
 8 {  
 9  _title = value;  
10    
11  if (titleDisplay)  
12   titleDisplay.text = title;  
13 }  

四、覆盖partAdded方法,使标题字符串能够作用于外观部件titleDisplay。

Actionscript 3.0代码
1 override protected function partAdded(partName:String, instance:Object):void  
2 {  
3  super.partAdded(partName, instance);  
4    
5  if (instance == titleDisplay)  
6  {  
7   titleDisplay.text = title;  
8  }  
9 }  

至此,GroupBox组件类基本创建完成,但是还不能显示。下面来创建它的默认外观(皮肤)GroupBoxSkin。
五、创建它的默认外观(皮肤)GroupBoxSkin。
第一步,创建组合框的边框。

Mxml代码

1 <!-- 边框 -->  
2 <s:Rect id="border" left="0" right="0" top="10" bottom="0"   
3   radiusX="4" radiusY="4">  
4  <s:stroke>  
5   <s:SolidColorStroke id="borderStroke" weight="1"/>  
6  </s:stroke>  
7 </s:Rect>  

第二步,创建外观部件titleDisplay。

Mxml代码
1 <!-- 标题 -->  
2 <s:Label id="titleDisplay"  
3    maxDisplayedLines="1"  
4    left="9" top="0"  
5    minHeight="20"  
6    verticalAlign="middle"   
7    textAlign="start"/>  

 

第三步,创建外观部件contentGroup,用于包含组合框的内容。

Mxml代码
1 <!-- 内容区域 -->  
2 <s:Group id="contentGroup"  
3    left="5" right="5" top="21" bottom="5">  
4  <s:layout>  
5   <s:VerticalLayout/>  
6  </s:layout>  
7 </s:Group>    

注意,此时边框是一个闭合的矩形。

图2 
从上图,可以看出现在组合框的标题文字与边框是重叠的,显然这不符合我们的要求。
为了解决这个问题,下面要为边框创建一个遮罩。

Mxml代码

 1 <!-- 边框遮罩 -->  
 2  <s:Group id="borderGroupMask" left="0" right="0" top="0" bottom="0">  
 3   <s:Rect left="0" width="7" top="0" bottom="0">  
 4    <s:fill>  
 5     <s:SolidColor color="#ff0000" alpha="1"/>  
 6    </s:fill>  
 7   </s:Rect>  
 8   <s:Rect left="7" width="{titleDisplay.width+4}" top="30" bottom="0">  
 9    <s:fill>  
10     <s:SolidColor color="#ff0000" alpha="1"/>  
11    </s:fill>  
12   </s:Rect>  
13   <s:Rect left="{titleDisplay.width+11}" width="100%" top="0" bottom="0">  
14    <s:fill>  
15     <s:SolidColor color="#ff0000" alpha="1"/>  
16    </s:fill>  
17   </s:Rect>  
18  </s:Group>  

为<s:Rect id="border"/>增加属性:mask="{borderGroupMask}"。
六、为GroupBox增加必要样式。
 第一步,在GroupBox类中增加以下样式声明,它们用来指定边框的颜色和圆角。
 增加borderColor样式。
 

Actionscript 3.0代码
1 [Style(name="borderColor", type="uint", format="Color", inherit="no", theme="spark")]  
2 [Style(name="cornerRadius", type="Number", format="Length", inherit="no", theme="spark")]  

第二步,在GroupBoxSkin中覆盖updateDisplayList,把样式应用于外观。

Actionscript 3.0代码
 1 override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void  
 2  {  
 3   var cr:Number = getStyle("cornerRadius");  
 4   if (cornerRadius != cr)  
 5   {  
 6    cornerRadius = cr; // 取变量  
 7    border.topLeftRadiusX = cornerRadius;  
 8    border.topRightRadiusX = cornerRadius;  
 9    border.bottomLeftRadiusX = cornerRadius;  
10    border.bottomRightRadiusX = cornerRadius;  
11   }  
12     
13   borderStroke.color = getStyle("borderColor");  
14   borderStroke.alpha = getStyle("borderAlpha");  
15   //  
16   super.updateDisplayList(unscaledWidth, unscaledHeight);  
17  }  

至此所有工作完成。效果如下:

图3
完整的文件如下:
1 GroupBox.as

Actionscript 3.0代码
  1 package jx.components  
  2 {  
  3     import spark.components.SkinnableContainer;  
  4     import spark.components.supportClasses.TextBase;  
  5     /**  
  6      *  The alpha of the border for this component.  
  7      *  
  8      *  @default 0.5  
  9      *   
 10      *  @langversion 3.0  
 11      *  @playerversion Flash 10  
 12      *  @playerversion AIR 1.5  
 13      *  @productversion Flex 4  
 14      */  
 15     [Style(name="borderAlpha", type="Number", inherit="no", theme="spark")]  
 16       
 17     /**  
 18      *  The color of the border for this component.  
 19      *  
 20      *  @default 0  
 21      *   
 22      *  @langversion 3.0  
 23      *  @playerversion Flash 10  
 24      *  @playerversion AIR 1.5  
 25      *  @productversion Flex 4  
 26      */  
 27     [Style(name="borderColor", type="uint", format="Color", inherit="no", theme="spark")]  
 28     /**  
 29      *  The radius of the corners for this component.  
 30      *  
 31      *  @default 5  
 32      *   
 33      *  @langversion 3.0  
 34      *  @playerversion Flash 10  
 35      *  @playerversion AIR 1.5  
 36      *  @productversion Flex 4  
 37      */  
 38     [Style(name="cornerRadius", type="Number", format="Length", inherit="no", theme="spark")]  
 39       
 40     public class GroupBox extends SkinnableContainer  
 41     {  
 42         public function GroupBox()  
 43         {  
 44             super();  
 45         }  
 46         //----------------------------------  
 47         //  titleField  
 48         //----------------------------------   
 49           
 50         [SkinPart(required="false")]  
 51           
 52         /**  
 53          *  定义容器中标题文本的外观的外观部件。  
 54          *  
 55          *  @see jx.skins.GroupBoxSkin  
 56          *    
 57          *  @langversion 3.0  
 58          *  @playerversion Flash 10  
 59          *  @playerversion AIR 1.5  
 60          *  @productversion Flex 4  
 61          */  
 62         public var titleDisplay:TextBase;  
 63           
 64           
 65         //----------------------------------  
 66         //  title  
 67         //----------------------------------  
 68           
 69         /**  
 70          *  @private  
 71          */  
 72         private var _title:String = "";  
 73           
 74         /**  
 75          *  @private  
 76          */  
 77         private var titleChanged:Boolean;  
 78           
 79         [Bindable]  
 80           
 81         /**  
 82          *  标题或者说明。  
 83          *  @default ""  
 84          *  @langversion 3.0  
 85          *  @playerversion Flash 10  
 86          *  @playerversion AIR 1.5  
 87          *  @productversion Flex 4  
 88          */  
 89         public function get title():String   
 90         {  
 91             return _title;  
 92         }  
 93           
 94         /**  
 95          *  @private  
 96          */  
 97         public function set title(value:String):void   
 98         {  
 99             _title = value;  
100               
101             if (titleDisplay)  
102                 titleDisplay.text = title;  
103         }  
104         override protected function partAdded(partName:String, instance:Object):void  
105         {  
106             super.partAdded(partName, instance);  
107               
108             if (instance == titleDisplay)  
109             {  
110                 titleDisplay.text = title;  
111             }  
112         }         
113     }  
114 }  

2 GroupBoxSkin.mxml

Mxml代码
 1 <?xml version="1.0" encoding="utf-8"?>  
 2 <s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009"   
 3         xmlns:mx="library://ns.adobe.com/flex/mx"   
 4         xmlns:s="library://ns.adobe.com/flex/spark"   
 5         xmlns:fb="http://ns.adobe.com/flashbuilder/2009"   
 6         alpha.disabled="0.5">  
 7     <fx:Metadata>  
 8         [HostComponent("jx.components.GroupBox")]  
 9     </fx:Metadata>   
10       
11     <fx:Script fb:purpose="styling">  
12         static private const exclusions:Array = ["titleDisplay", "contentGroup"];  
13           
14         /**  
15          * @private  
16          */    
17         override public function get colorizeExclusions():Array {  
18             return exclusions;  
19         }  
20           
21         /**  
22          * @private  
23          */  
24         override protected function initializationComplete():void  
25         {  
26             useChromeColor = true;  
27             super.initializationComplete();  
28         }  
29         private var cornerRadius:Number;          
30         /**  
31          * @private  
32          */  
33         override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void  
34         {  
35             var cr:Number = getStyle("cornerRadius");  
36             if (cornerRadius != cr)  
37             {  
38                 cornerRadius = cr;  // 取变量  
39                 border.topLeftRadiusX = cornerRadius;  
40                 border.topRightRadiusX = cornerRadius;  
41                 border.bottomLeftRadiusX = cornerRadius;  
42                 border.bottomRightRadiusX = cornerRadius;  
43             }  
44               
45             borderStroke.color = getStyle("borderColor");  
46             borderStroke.alpha = getStyle("borderAlpha");  
47             //  
48             super.updateDisplayList(unscaledWidth, unscaledHeight);  
49         }  
50     </fx:Script>  
51       
52     <s:states>  
53         <s:State name="normal" />  
54         <s:State name="disabled" />  
55     </s:states>  
56     <!-- 边框遮罩 -->  
57     <s:Group id="borderGroupMask" left="0" right="0" top="0" bottom="0">  
58         <s:Rect left="0" width="7" top="0" bottom="0">  
59             <s:fill>  
60                 <s:SolidColor color="#ff0000" alpha="1"/>  
61             </s:fill>  
62         </s:Rect>  
63         <s:Rect left="7" width="{titleDisplay.width+4}" top="30" bottom="0">  
64             <s:fill>  
65                 <s:SolidColor color="#ff0000" alpha="1"/>  
66             </s:fill>  
67         </s:Rect>  
68         <s:Rect left="{titleDisplay.width+11}" width="100%" top="0" bottom="0">  
69             <s:fill>  
70                 <s:SolidColor color="#ff0000" alpha="1"/>  
71             </s:fill>  
72         </s:Rect>  
73     </s:Group>  
74     <!-- 边框 -->  
75     <s:Rect id="border" left="0" right="0" top="10" bottom="0"   
76             radiusX="4" radiusY="4"  
77             mask="{borderGroupMask}"  
78             ><!--mask="{borderGroupMask}"-->  
79         <s:stroke>  
80             <s:SolidColorStroke id="borderStroke" weight="1"/>  
81         </s:stroke>  
82     </s:Rect>  
83     <!-- 标题 -->  
84     <s:Label id="titleDisplay"  
85              maxDisplayedLines="1"  
86              left="9" top="0"  
87              minHeight="20"  
88              verticalAlign="middle"   
89              textAlign="start"/>  
90     <!-- 内容区域 -->  
91     <s:Group id="contentGroup"  
92              left="5" right="5" top="21" bottom="5">  
93         <s:layout>  
94             <s:VerticalLayout/>  
95         </s:layout>  
96     </s:Group>          
97 </s:SparkSkin>  

3 GroupBoxExam.mxml 实例文件

Mxml代码
 1 <?xml version="1.0" encoding="utf-8"?>  
 2 <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"   
 3                xmlns:s="library://ns.adobe.com/flex/spark"   
 4                xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" xmlns:components="jx.components.*">  
 5     <s:layout>  
 6         <s:BasicLayout/>  
 7     </s:layout>  
 8     <fx:Declarations>  
 9     </fx:Declarations>  
10     <components:GroupBox skinClass="jx.skins.GroupBoxSkin" title="用户配置文件" cornerRadius="5">  
11         <components:layout>  
12             <s:HorizontalLayout/>  
13         </components:layout>  
14         <s:Button/>  
15         <s:Button/>  
16         <s:Button/>  
17     </components:GroupBox>  
18 </s:Application>  

4 css

可以通过css为GroupBox指定样式的默认值。

Css代码
1 @namespace components "jx.components.*";  
2 components|GroupBox {  
3     skinClass: ClassReference("jx.skins.GroupBoxSkin");  
4     cornerRadius: 5;  
5     borderColor: #104778;  
6     borderWeight: 1;  
7     dropShadowVisible: false;  
8 }  

5 代码方式指定组件的默认CSS样式

 Actionscript3.0代码

 1 private static const classConstructed:Boolean = classConstruct();  
 2   
 3         // 指定默认样式  
 4         private static function classConstruct():Boolean {  
 5             var styleManager:IStyleManager2 = FlexGlobals.topLevelApplication.styleManager;  
 6             if (!styleManager.getStyleDeclaration("jx.components.GroupBox")) {  
 7                 var css:CSSStyleDeclaration = new CSSStyleDeclaration(null, styleManager);  
 8                 css.defaultFactory = function():void {  
 9                     this.skinClass = GroupBoxSkin;  
10                     this.borderAlpha = 1;  
11                     this.borderColor = 0;           //
12 //                  this.borderColor = 0xD3D3D3;    // 灰  
13 //                  this.borderColor = 0x104778;    // 蓝  
14                     this.cornerRadius = 5;  
15 //                  this.dropShadowVisible = true;  
16 //                  this.borderWeight = 1;  
17                 }  
18                 styleManager.setStyleDeclaration("jx.components.GroupBox", css, true);  
19             }  
20             return true;  
21         }  

 

posted @ 2013-01-21 15:58  学海无涯1999  阅读(197)  评论(0编辑  收藏  举报