导读:
Introduction
This tutorial aims to teach you in detail how to develop a Flex component using Actionscript classes. The object of the tutorial is to guide developers on the key steps necessary to generate a distributable Flex component in SWC format. The SWC format is Adobe's packaging mechanism where assets such as classes, codes, images, swf etc are bundled together into one zipped file for easy access. In reality, you can unpack all the contents of an SWC component using a zip application like WinRar but accessing the main swf after unpacking makes it unstable to use again. 本教程的目的是教读者如何使用AS3开发FLEX组件类。本教程的目标是帮助开发者开发SWC格式可以发布的组件的关键步骤。(SWC是ADOBE开发的一种压缩格式用来储藏CLASS资源等,实际上可以使用zip软件直接解压缩)So if you want to experiment, make a copy before doing that. We are developing a simple drag and drop component based on Flex's Panel class, it therefore extends the capabilities of the Panel class. It's called Adjustable and what it simply does is that it gives the user, the privilege of adjusting the width of a Panel from the right edge at runtime. It leaves the reader with the challenge to extend it to include height as well. 如果你想实验的话,那最好之前做个备份,我们要开发一个支持拖放的面版类,也就是说这个工程实际上是扩展了PANEL类,实现了在运行时候调整宽度的功能,而实现调整高度的工作则作为作业留给读者了
Requirements
1. Flex Builder 2.0 (You can get it here) OR Flash Develop (You can get it here)
2. Download Source Code with sample here
Tutorial
First, lets create the project in Flex Builder. Create a new project but this time, make it a Library Project. This ensures that the final output is an SWC file and not an swf. Name the project "Adjustable" and create a new folder for it anywhere you fell good about. If you are using Flash Develop, just create a new Project named "Adjustable" and select "Actionscript 2 - Flex 2 Project"from the installed Templates. Let the application create a new Folder and click Ok. 创建一个库工程,这样最后生成的就是SWC的文件了,而不是SWF了,将工程命名为...如果你是使用FLASH 开发那么直接创建一个AS2的FLEX工程Now we are ready! First create a new Folder named "Flexcubed", you can use any name you so choose, but it's advisable to structure your components in recognizable packages. This is the package name for the Adjustable Panel component I chose. Select the folder and Right Click to select New Actionscript Class from both applications. This will bring up a dialog for you to create a new AS class with the folder name as the package. Label this Class as Adjustable and in Flex Builder, select Panel as the base class. 首先创建一个名为FLEXCUBED的文件夹,或者随便取什么名字,这就是后来要识别的包的名字,右击此文件夹选择创建AS类,将此类命名为ADJUSTABLE并且选择PANEL作为基类This is our main Class file that defines what the component will do. In it we have这就是我们的主类文件 :packageFlexcubed{import mx.containers.Panel;publicclass Adjstable extendsPanel{publicfunction Adjstable(){
super();
}}}It's quite straightforward, the package is Flexcubed, the class is Adjustable and it extends the Panel Class as its base class. The import tells the compiler to import the Panel class from mx.containers. The function Adjustable() is the first function executed once the component runs so there we put the super() function. 导入了MX.CONTAINERS.PANLE类,构造函数Adjustable(0是创建一个对象时首先调用的,它首先调用了SUPER()即父类的构造函数It simply tells the component to run the main function of the base Panel class, thats all. Please run the sample to have a feel of what we are developing. From the sample, you will observe a Black Mouse pointer that's use in resizing when you mouse over the edge of the panel. That is not a system mouse icon so we are going to embed that as an image asset into our component. 也就是告诉基类去运行它的构造函数,做到这一步的时候你可以运行程序体会一下这个例子。当你试图改变PANEL的SIZE的时候你会发现鼠标呈黑色,由于那不是系统自带的图标因此我们必须将其作为资源嵌入到系统里面去,下面的代码完成了这个功能This line does it:[Embed(source="../assets/resizeLeft.gif")]
public var leftMouse:Class;The [Embed] is a meta information that tells the compiler where to locate the image and embed it into the swc for later use and we gave it a class name "leftMouse" so in our code, when we use that name, it refers to that asset. [Embed] 标签是一个元信息标签,它通知编译器到何处去定位这个资源并将其嵌入SWC库,这张图像我们在后面将会使用到并且给它命名为leftmouse的名字使用这个名字也即意味着使用这个资源 This could be a jpeg, png or gif image and can also be an swf file. We will discuss this later on. Next, let's declare our variables and imports. It's important you understand variable scoping. private means that the variable is accessible within that class while public means that it can be accessed from outside i.e after compilation, you can access it from mxml or even from actionscript outside the class. 图片可以是任意格式的如(jpg,png)等等下面我们应该申明我们的变量以及导入我们需要的包了,了解作用域机制很重要,PRIVATE意味着此变量在编译后不能被外部的变量和类访问Our variables here are private:import mx.containers.Panel;
import mx.events.FlexEvent;
import flash.events.*;
import flash.ui.Mouse;
import mx.managers.CursorManager;
import flash.display.Graphics;
import mx.core.UIComponent;private var edgeOffset:Number;
private var originalWidth:Number;
private var leftGrip:UIComponent;
private var lowestWidth:Number = 100;lowestWidth is the minimum width that our custom component can attain. leftGrip is a dummy UIcomponent, not visible that the user mouses over for us to know that he's on the edge of the Adjustable component. This UIcomponent is very important as we use it to listen and get mouse events to control the base panel.lowestWidth是我们的组件能够维持的最小的宽度,leftGrip是一个让人初级的UI组件不可视,但是由它来通知我们目前用户处在组件的框架上并准备调整组件的大小,这个初级的组件很重要,因为我们使用它来捕捉鼠标事件并进行相应的响应 Let's draw the leftGrip and place it in the panel. We do all our transactions in the createChildren() function. Please observe the code lines. The override protectedmeans it should override the base class's createChildern function, which is the function that creates all the assets and parts of the component. 让我们来绘制这个组件并将其放置在PANEL里,我们在createChildren函数里面完成所有的函数绘制,观察代码行,override protected意味着他将覆盖积累的此函数,通过这个函数组件完成UI界面的绘制It's a reserved function of all Actionscript UIComponents:super.createChildren();
leftGrip = new UIComponent();
leftGrip.width = 10;
leftGrip.height = height; ?
var g:Graphics = leftGrip.graphics;
g.clear();
g.beginFill(0xFFFFFF, 0);
g.drawRect(0, 0, 10, height);
g.endFill();
leftGrip.move(unscaledWidth-10, 0);
rawChildren.addChild(leftGrip);First thing is to call the super's (base panel class) createChildren() so the panel is formed normally! next we create an instance of the leftGrip UIComponent with the new() method, assign it a width of 10 pixels. Remember it's this object that helps us know when the user mouses over the edge of our Adjustable component so we give it a width of 10. Then draw a graphics on it so it has a content which is declared simply as "g". We draw on g and fill it with white color but leave it transparent (0xFFFFFF, 0) so the user doesnt see it.首先要调用基类的绘制函数这样PANEL组件就能很自然的呈现了,接下来我们首先NEW一个leftGrip对象,将其宽度设为10像素要记住这个对象帮助我们捕获用户拖动PANEL边缘的事件并完成事件的响应 ,我们将其填充为白色的但是设置为透明色To make it visible, enter a value from 0.1 to 1 instead of the zero after the color. Finally we positioned and added it to the leftGrip object so it can receive mouse events and report to us. Next, we need to add event listeners to the dummy object called leftGrip so we know when to adjust our component width, which is our aim. 如果要让它可视的话那么使用任意0-1的一个透明度代替第二个参数即可,接下来我们需要来捕获这个鼠标事件To do that, we have:leftGrip.addEventListener(MouseEvent.MOUSE_DOWN, resizeLeft);
leftGrip.addEventListener(MouseEvent.MOUSE_OVER,
function (event:MouseEvent):void{
CursorManager.setCursor(leftMouse);
});
leftGrip.addEventListener(MouseEvent.MOUSE_OUT,
function (event:MouseEvent):void{
CursorManager.removeCursor(CursorManager.currentCursorID);
});The first line adds an event listener called MOUSE_DOWN to our dummy leftGrip object so it executes the resizeLeft function whenever the user clicks and holds down the mouse over the dummy. We will refer to this resizeLeft function later on. Next is the mouse over listener which simply changes the mouse to our leftMouse image class we referred to earlier on. So when the user mouses over that area, the mouse changes to the black arrow image. We use a new AS3.0 class called CursorManager to do this. 第一行添加了一个捕获鼠标按下事件的监听器,因此当用户点击或者在此初级控件上按下鼠标的时候此事件将会被处理,同时处理的还有鼠标滑过的事件处理,同时我们使用一个鼠标管理器的类来更换我们的鼠标图像When the user moves the mouse out of that area, we change it to the default cursor by removing the current cursor which is the black arrow. Now let's consider the resizeLeft function that gets executed when the user mouses down on our dummy当鼠标滑出此区域的时候,我们将其换回原来的图标现在我们来考虑这resizeLeft函数:protected function resizeLeft(event:MouseEvent):void{
CursorManager.setCursor(leftMouse);
originalWidth = width;
edgeOffset = parent.mouseX;
systemManager.addEventListener(MouseEvent.MOUSE_MOVE, doLeft, true);
systemManager.addEventListener(MouseEvent.MOUSE_UP, stopResizing, true);
systemManager.stage.addEventListener(Event.MOUSE_LEAVE, stopResizing);
}First we ensure that the mouse is set to our black arrow using the CursorManager, then capture the current width of the component and store it in our variable "originalWidth" so all we do as the user moves the mouse is add or subtract from it to set the new width. we also capture the mouse's X position which is stored in edgeOffset. Note this position is taken with respect to the parent's coordinate. Now we simply add a new set of mouse event listeners using the systemManager. 首先我们确定光标管理器将我们的鼠标图像进行了替换,然后我们捕获此控件的原始宽度将其保存,因此我们的工作即对此宽度进行加加减减即可,然后我们捕获鼠标的X坐标,注意此坐标是相对于其父容器而言的,接下来我们添加了一系列全局的监听器This just ensures that only this mouse event is attended to because there's just one systemManager in a running flash application, same with stage. We have just one stage. Lets now consider how the adjustment is done when the user drags the mouse after clicking, which is the doLeft function.这么做只是为了保证只有此鼠标事件被管理,因为一个程序实例只有一个systemManager ,一个stage,下面考虑如何实现PANEL的宽度的更新protected function doLeft(event:MouseEvent):void{
if ((originalWidth + (parent.mouseX - edgeOffset)) >lowestWidth){
width = originalWidth + (parent.mouseX - edgeOffset);
leftGrip.move(unscaledWidth-10, 0);
}
}We check if the originalWidth plus or minus the new change is greater than the lowestWidth we want our component to attain. If not, then nothing is done but if it is still greater than that, then we adjust our component's width as follows: Add the originalWidth to the difference between the parent's new X position and the new one which is the actual drag difference that the user did. Simple logic! Then we reposition our leftGrip dummy to the edge of the panel again.我们确保跟新量加上或者减去原来的量不大于最小的宽度限制,那么我们更新宽度,否则什么也不做,注意的同时跟新我们的初级控件leftGrip 到PANELD的左边界protected function stopResizing(event:Event):void{
CursorManager.removeCursor(CursorManager.currentCursorID);
systemManager.removeEventListener(MouseEvent.MOUSE_MOVE, doLeft, true);
systemManager.removeEventListener(MouseEvent.MOUSE_UP, stopResizing, true);
systemManager.stage.removeEventListener(Event.MOUSE_LEAVE, stopResizing);
}The stopResizing removes all the systemManager listeners we registered earlier on and sets the mouse icon to the default by removing the current one, which is our black horizontal arrow. That is all, compile your application and FlexBuilder will generate an swc for you which will include your Adjustable component. Next, create a new Flex project and add the location of the new Adjustable swc file in the project's path. Go to the view and you'll see our new Adjustable panel as one of the components under the Custom folder in your components pane. Drag it and drop on the canvas and use it as you would a normal panel. Try and adjust it's width from the far right. stopResizing 撤销我们在systemManage上注册的监听器到原始的状态,现在编译此工程,你将得到一个SWC的工程,接下来的事情不过是创建一个工程验证一下你的这个组件是否可用
Conclusion
This component has been designed to add the width adjustment functionality to a base panel class found in Flex. Similar method can be used to extend other UI components or develop new ones. We leave it to the reader to extend this functionality further by adding the height adjustment to it as well.
Authors
本文转自
http://www.flexcubed.com/tutorials.php?id=b308c995ff752026f1beca89969b1360
Introduction
This tutorial aims to teach you in detail how to develop a Flex component using Actionscript classes. The object of the tutorial is to guide developers on the key steps necessary to generate a distributable Flex component in SWC format. The SWC format is Adobe's packaging mechanism where assets such as classes, codes, images, swf etc are bundled together into one zipped file for easy access. In reality, you can unpack all the contents of an SWC component using a zip application like WinRar but accessing the main swf after unpacking makes it unstable to use again. 本教程的目的是教读者如何使用AS3开发FLEX组件类。本教程的目标是帮助开发者开发SWC格式可以发布的组件的关键步骤。(SWC是ADOBE开发的一种压缩格式用来储藏CLASS资源等,实际上可以使用zip软件直接解压缩)So if you want to experiment, make a copy before doing that. We are developing a simple drag and drop component based on Flex's Panel class, it therefore extends the capabilities of the Panel class. It's called Adjustable and what it simply does is that it gives the user, the privilege of adjusting the width of a Panel from the right edge at runtime. It leaves the reader with the challenge to extend it to include height as well. 如果你想实验的话,那最好之前做个备份,我们要开发一个支持拖放的面版类,也就是说这个工程实际上是扩展了PANEL类,实现了在运行时候调整宽度的功能,而实现调整高度的工作则作为作业留给读者了
Requirements
1. Flex Builder 2.0 (You can get it here) OR Flash Develop (You can get it here)
2. Download Source Code with sample here
Tutorial
First, lets create the project in Flex Builder. Create a new project but this time, make it a Library Project. This ensures that the final output is an SWC file and not an swf. Name the project "Adjustable" and create a new folder for it anywhere you fell good about. If you are using Flash Develop, just create a new Project named "Adjustable" and select "Actionscript 2 - Flex 2 Project"from the installed Templates. Let the application create a new Folder and click Ok. 创建一个库工程,这样最后生成的就是SWC的文件了,而不是SWF了,将工程命名为...如果你是使用FLASH 开发那么直接创建一个AS2的FLEX工程Now we are ready! First create a new Folder named "Flexcubed", you can use any name you so choose, but it's advisable to structure your components in recognizable packages. This is the package name for the Adjustable Panel component I chose. Select the folder and Right Click to select New Actionscript Class from both applications. This will bring up a dialog for you to create a new AS class with the folder name as the package. Label this Class as Adjustable and in Flex Builder, select Panel as the base class. 首先创建一个名为FLEXCUBED的文件夹,或者随便取什么名字,这就是后来要识别的包的名字,右击此文件夹选择创建AS类,将此类命名为ADJUSTABLE并且选择PANEL作为基类This is our main Class file that defines what the component will do. In it we have这就是我们的主类文件 :packageFlexcubed{import mx.containers.Panel;publicclass Adjstable extendsPanel{publicfunction Adjstable(){
super();
}}}It's quite straightforward, the package is Flexcubed, the class is Adjustable and it extends the Panel Class as its base class. The import tells the compiler to import the Panel class from mx.containers. The function Adjustable() is the first function executed once the component runs so there we put the super() function. 导入了MX.CONTAINERS.PANLE类,构造函数Adjustable(0是创建一个对象时首先调用的,它首先调用了SUPER()即父类的构造函数It simply tells the component to run the main function of the base Panel class, thats all. Please run the sample to have a feel of what we are developing. From the sample, you will observe a Black Mouse pointer that's use in resizing when you mouse over the edge of the panel. That is not a system mouse icon so we are going to embed that as an image asset into our component. 也就是告诉基类去运行它的构造函数,做到这一步的时候你可以运行程序体会一下这个例子。当你试图改变PANEL的SIZE的时候你会发现鼠标呈黑色,由于那不是系统自带的图标因此我们必须将其作为资源嵌入到系统里面去,下面的代码完成了这个功能This line does it:[Embed(source="../assets/resizeLeft.gif")]
public var leftMouse:Class;The [Embed] is a meta information that tells the compiler where to locate the image and embed it into the swc for later use and we gave it a class name "leftMouse" so in our code, when we use that name, it refers to that asset. [Embed] 标签是一个元信息标签,它通知编译器到何处去定位这个资源并将其嵌入SWC库,这张图像我们在后面将会使用到并且给它命名为leftmouse的名字使用这个名字也即意味着使用这个资源 This could be a jpeg, png or gif image and can also be an swf file. We will discuss this later on. Next, let's declare our variables and imports. It's important you understand variable scoping. private means that the variable is accessible within that class while public means that it can be accessed from outside i.e after compilation, you can access it from mxml or even from actionscript outside the class. 图片可以是任意格式的如(jpg,png)等等下面我们应该申明我们的变量以及导入我们需要的包了,了解作用域机制很重要,PRIVATE意味着此变量在编译后不能被外部的变量和类访问Our variables here are private:import mx.containers.Panel;
import mx.events.FlexEvent;
import flash.events.*;
import flash.ui.Mouse;
import mx.managers.CursorManager;
import flash.display.Graphics;
import mx.core.UIComponent;private var edgeOffset:Number;
private var originalWidth:Number;
private var leftGrip:UIComponent;
private var lowestWidth:Number = 100;lowestWidth is the minimum width that our custom component can attain. leftGrip is a dummy UIcomponent, not visible that the user mouses over for us to know that he's on the edge of the Adjustable component. This UIcomponent is very important as we use it to listen and get mouse events to control the base panel.lowestWidth是我们的组件能够维持的最小的宽度,leftGrip是一个让人初级的UI组件不可视,但是由它来通知我们目前用户处在组件的框架上并准备调整组件的大小,这个初级的组件很重要,因为我们使用它来捕捉鼠标事件并进行相应的响应 Let's draw the leftGrip and place it in the panel. We do all our transactions in the createChildren() function. Please observe the code lines. The override protectedmeans it should override the base class's createChildern function, which is the function that creates all the assets and parts of the component. 让我们来绘制这个组件并将其放置在PANEL里,我们在createChildren函数里面完成所有的函数绘制,观察代码行,override protected意味着他将覆盖积累的此函数,通过这个函数组件完成UI界面的绘制It's a reserved function of all Actionscript UIComponents:super.createChildren();
leftGrip = new UIComponent();
leftGrip.width = 10;
leftGrip.height = height; ?
var g:Graphics = leftGrip.graphics;
g.clear();
g.beginFill(0xFFFFFF, 0);
g.drawRect(0, 0, 10, height);
g.endFill();
leftGrip.move(unscaledWidth-10, 0);
rawChildren.addChild(leftGrip);First thing is to call the super's (base panel class) createChildren() so the panel is formed normally! next we create an instance of the leftGrip UIComponent with the new() method, assign it a width of 10 pixels. Remember it's this object that helps us know when the user mouses over the edge of our Adjustable component so we give it a width of 10. Then draw a graphics on it so it has a content which is declared simply as "g". We draw on g and fill it with white color but leave it transparent (0xFFFFFF, 0) so the user doesnt see it.首先要调用基类的绘制函数这样PANEL组件就能很自然的呈现了,接下来我们首先NEW一个leftGrip对象,将其宽度设为10像素要记住这个对象帮助我们捕获用户拖动PANEL边缘的事件并完成事件的响应 ,我们将其填充为白色的但是设置为透明色To make it visible, enter a value from 0.1 to 1 instead of the zero after the color. Finally we positioned and added it to the leftGrip object so it can receive mouse events and report to us. Next, we need to add event listeners to the dummy object called leftGrip so we know when to adjust our component width, which is our aim. 如果要让它可视的话那么使用任意0-1的一个透明度代替第二个参数即可,接下来我们需要来捕获这个鼠标事件To do that, we have:leftGrip.addEventListener(MouseEvent.MOUSE_DOWN, resizeLeft);
leftGrip.addEventListener(MouseEvent.MOUSE_OVER,
function (event:MouseEvent):void{
CursorManager.setCursor(leftMouse);
});
leftGrip.addEventListener(MouseEvent.MOUSE_OUT,
function (event:MouseEvent):void{
CursorManager.removeCursor(CursorManager.currentCursorID);
});The first line adds an event listener called MOUSE_DOWN to our dummy leftGrip object so it executes the resizeLeft function whenever the user clicks and holds down the mouse over the dummy. We will refer to this resizeLeft function later on. Next is the mouse over listener which simply changes the mouse to our leftMouse image class we referred to earlier on. So when the user mouses over that area, the mouse changes to the black arrow image. We use a new AS3.0 class called CursorManager to do this. 第一行添加了一个捕获鼠标按下事件的监听器,因此当用户点击或者在此初级控件上按下鼠标的时候此事件将会被处理,同时处理的还有鼠标滑过的事件处理,同时我们使用一个鼠标管理器的类来更换我们的鼠标图像When the user moves the mouse out of that area, we change it to the default cursor by removing the current cursor which is the black arrow. Now let's consider the resizeLeft function that gets executed when the user mouses down on our dummy当鼠标滑出此区域的时候,我们将其换回原来的图标现在我们来考虑这resizeLeft函数:protected function resizeLeft(event:MouseEvent):void{
CursorManager.setCursor(leftMouse);
originalWidth = width;
edgeOffset = parent.mouseX;
systemManager.addEventListener(MouseEvent.MOUSE_MOVE, doLeft, true);
systemManager.addEventListener(MouseEvent.MOUSE_UP, stopResizing, true);
systemManager.stage.addEventListener(Event.MOUSE_LEAVE, stopResizing);
}First we ensure that the mouse is set to our black arrow using the CursorManager, then capture the current width of the component and store it in our variable "originalWidth" so all we do as the user moves the mouse is add or subtract from it to set the new width. we also capture the mouse's X position which is stored in edgeOffset. Note this position is taken with respect to the parent's coordinate. Now we simply add a new set of mouse event listeners using the systemManager. 首先我们确定光标管理器将我们的鼠标图像进行了替换,然后我们捕获此控件的原始宽度将其保存,因此我们的工作即对此宽度进行加加减减即可,然后我们捕获鼠标的X坐标,注意此坐标是相对于其父容器而言的,接下来我们添加了一系列全局的监听器This just ensures that only this mouse event is attended to because there's just one systemManager in a running flash application, same with stage. We have just one stage. Lets now consider how the adjustment is done when the user drags the mouse after clicking, which is the doLeft function.这么做只是为了保证只有此鼠标事件被管理,因为一个程序实例只有一个systemManager ,一个stage,下面考虑如何实现PANEL的宽度的更新protected function doLeft(event:MouseEvent):void{
if ((originalWidth + (parent.mouseX - edgeOffset)) >lowestWidth){
width = originalWidth + (parent.mouseX - edgeOffset);
leftGrip.move(unscaledWidth-10, 0);
}
}We check if the originalWidth plus or minus the new change is greater than the lowestWidth we want our component to attain. If not, then nothing is done but if it is still greater than that, then we adjust our component's width as follows: Add the originalWidth to the difference between the parent's new X position and the new one which is the actual drag difference that the user did. Simple logic! Then we reposition our leftGrip dummy to the edge of the panel again.我们确保跟新量加上或者减去原来的量不大于最小的宽度限制,那么我们更新宽度,否则什么也不做,注意的同时跟新我们的初级控件leftGrip 到PANELD的左边界protected function stopResizing(event:Event):void{
CursorManager.removeCursor(CursorManager.currentCursorID);
systemManager.removeEventListener(MouseEvent.MOUSE_MOVE, doLeft, true);
systemManager.removeEventListener(MouseEvent.MOUSE_UP, stopResizing, true);
systemManager.stage.removeEventListener(Event.MOUSE_LEAVE, stopResizing);
}The stopResizing removes all the systemManager listeners we registered earlier on and sets the mouse icon to the default by removing the current one, which is our black horizontal arrow. That is all, compile your application and FlexBuilder will generate an swc for you which will include your Adjustable component. Next, create a new Flex project and add the location of the new Adjustable swc file in the project's path. Go to the view and you'll see our new Adjustable panel as one of the components under the Custom folder in your components pane. Drag it and drop on the canvas and use it as you would a normal panel. Try and adjust it's width from the far right. stopResizing 撤销我们在systemManage上注册的监听器到原始的状态,现在编译此工程,你将得到一个SWC的工程,接下来的事情不过是创建一个工程验证一下你的这个组件是否可用
Conclusion
This component has been designed to add the width adjustment functionality to a base panel class found in Flex. Similar method can be used to extend other UI components or develop new ones. We leave it to the reader to extend this functionality further by adding the height adjustment to it as well.
Authors
本文转自
http://www.flexcubed.com/tutorials.php?id=b308c995ff752026f1beca89969b1360