Event

1.在FlashPlayer创建完一个组件时,它会分派一个creationComplete事件。DisplayObject 类是 EventDispatcher 类的子类,这意味者每一个 DisplayObject 都可以注册事件监听器,并在事件发生的时候进行相应的处理。

 

2.用户自定义的类可以业务逻辑中分派事件。

 

3.EnterFrame事件由AVM触发,并以程序中帧的刷新速率进行触发。

   addEventListener(Event.ENTERFRAME, onEnteringFrame);

 

4.可以分派自定义事件。

 

 

JAVA中的事件监听者是对象,AS3中事件监听者只是Function。如果要在自定义的AS3类里分派事件,这个类必须是EventDispatcher的子类,或实现了IEventDispathcer接口。

 

 

JAVA中,将产生某个事件的对象称为这个事件的source。但在Flex中,可以说所有的事件都是FlashPlayer产生的。FlashPlayer9对事件模型的实现是建立在W3C的DOM事件模型上的,一个事件的生命周期有三个阶段:捕获、target、bubbling。

 

capture:在这一阶段,Flashplayer从display list的根开始检查,一直到目标组件,来看看有没有任何父组件对这一事件感兴趣。默认情况下,目标组件的父组件会忽略这一事件。

 

target:在这一阶段,事件对象的属性将会设置至目标组件中,并且所有注册的对这一事件的监听器将会获得这一事件对象。

 

bubbling:最后,事件流将会从目标对象沿原路返回到根层组件,并通知在capture阶段确定的对这事件感兴趣的对象。

 

但是用户自定义的事件并不会经历上述的三个阶段,不过AS3开发者可以建立自定义的事件分派者来实现这三个阶段。

 

 

例如下面的代码:

<?xml version=”1.0” encoding=”utf-8”?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” >
  <mx:Panel x=”17.5” y=”20” width=”209” height=”142”  layout=”absolute”
      click=”trace(‘click event in the Panel’)” title=”Just a Panel”>
  <mx:Button label=”ClickMe” x=”60.5” y=”38”
      click=”trace(‘click event in the Button’)”/>
  </mx:Panel>
 
</mx:Application>

 

将会在控制台输出:

click event in the Button
click event in the Panel

 

 

默认情况下,在capture阶段是不会执行事件的监听器的,但是可以通过设置来让监听器在capture阶段就被执行:myPanel.addEventListener(MouseEvent.CLICK, panelClickHandler, true);这里第三个参数就是指明要在capture阶段执行监听器。如果注册两遍,一遍带参数true,一遍不带,那么在capture阶段和bubbling阶段都会执行监听器。

 

我们还可以阻止事件的分派:

private function panelClickHandler(event:MouseEvent) :void{
             var badNews: Boolean = true; // a flag to emulate a bad situation
             if (event.eventPhase == EventPhase.CAPTURING_PHASE){
               trace (“Capturing phase: click event in the Panel”);              
               if (badNews){
                  trace (“Capturing phase: Bad news. Will not propagate click to  Button”);
                  event.stopPropagation();
               }
             }else {
               trace (“click event in the Panel”);
             }
            }

 

 

需要强调的是,一个组件并不是将事件发送到任何其他的组件。它仅仅是将这个“令人激动的新闻”广播到事件分派器。如果有任何组件对处理这个事件有兴趣的话,它必须为这个事件注册一个监听器。

 

在MXML中使用自定义事件时,要使用元数据标签:

<?xml version=”1.0” encoding=”utf-8”?>
<mx:Button xmlns:mx=”http://www.adobe.com/2006/mxml”
  width=”104” height=”28” cornerRadius=”10” fillColors=”[#00ff00, #00B000]”
  label=”Add Item” fontSize=”12” click=”greenClickEventHandler()”>
 
  <mx:Metadata>
    [Event(name=”addItemEvent”, type=”flash.events.Event”)]
  </mx:Metadata>
 
  <mx:Script>
    <![CDATA[
        private function greenClickEventHandler():void{
              trace(“Ouch! I got clicked! Let me tell this to the world.”);
              dispatchEvent(new Event(“addItemEvent”, true));// bubble to parent
        }
    ]]>
  </mx:Script>
</mx:Button>

在上面的代码中,当点击这个button时,这个组件会将自定义的addItemEvent事件分派到“外面的世界”,它不用知道其他的事情。下面一段代码注册了一个监听器来监听这个事件。

<mx:TextArea xmlns:mx="http://www.adobe.com/2006/mxml"  backgroundColor="#ff0000"  creationComplete="init()">
 <mx:Script>
    <![CDATA[
        private function init():void{
         parent.addEventListener("addItemEvent",addItemToCartEventHandler);
        }
 
       private function addItemToCartEventHandler(event:Event):void{
         this.text+="Yes! Someone has put some item inside me, but I do not know what it is. /n";
       }
    ]]>
  </mx:Script>
</mx:TextArea>

然后在application中这样写:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:ctrl="controls.*" layout="vertical">
 <ctrl:CustomEvent_LargeGreenButton addItemEvent="greenButtonHandler(event)"/>
 <ctrl:CustomEvent_BlindShoppingCart width="350" height="150" fontSize="14"/>
 <mx:Script>
      <![CDATA[
        private function greenButtonHandler(event:Event):void{
         trace("Someone clicked on the Large Green Button!");
        }
        ]]>
    </mx:Script>
</mx:Application>

如果在JAVA中,这样的代码要写成:

LargeGreenButton.addClickEventListener(

    new XXXListener(){

        public void action() {

              这里往ShoppingCart中添加物品;

        }

    });

这样就把LargeGreenButton和ShoppingCart粘合起来了,FLEX里就去掉了这种粘合。

 

========================================================================

 

Flex中的事件机制 <script></script> ofengofeng | 更新时间:2008-07-11 08:49:25 | 点击数:685

 

一. 事件简介
事件可以由外设触发, 比如:键盘,鼠标, 也可能是外部输入, 比如:web service的返回.
事件还能由组件的外观和生命周期发生变化时触发, 比如:组件的创建或者改变大小.
所有用户与应用交互都会产生事件.用户没有直接与应用交互也可能产生事件, 比如:数据装载完毕.
你可以在程序中使用事件监听器监听这些事件. 事件监听器是函数方法用于响应指定的事件. 有时也称之为事件处理器.
Flex的事件模型基于DOM3事件模型.
组件产生派发事件并消费(监听)其他事件.如果一个对象想要了解其他对象事件的信息, 可以注册一个监听器.
当事件发生时,对象派发此事件到所有注册过的监听器中.
组件有Flex提供的内建事件. 也可以使用派发-监听模型定义自己的事件监听器, 并指定监听器监听何种事件.
二. 事件流简介
当一个事件被派发出来时, 事件对象从根节点开始自上而下开始扫描display list, 一直到目标对象, 检查每个节点是否有相应的监听器.
目标对象指的是display list中产生事件的对象. 比如:
<mx:Panel>
<mx:HBox>
<mx:VBox>
<mx:Button />
</mx:VBox>
</mx:HBox>
</mx:Panel>
如何此时 resize了VBox, 则会从根(Application)开始, 下来检查Panel, HBox, 直到目标对象-产生resize事件的VBox为止.

三. 事件的派发
Flex中可以通过dispatchEvent()方法手工派发事件, 所有UIComponent的子类都可以调用此方法.
语法:
objectInstance.dispatchEvent(new Event("event_type"):Boolean
参数event_type是Event对象的type属性. 函数的返回值总是True.
可以使用此方法派发任意事件, 而不仅仅是用户自定义事件, 比如: 可以派发一个Button的Click事件.
var result:Boolean = buttonInstance.dispatchEvent(new Event(MouseEvent.CLICK));

在Flex应用中不是必须对新派发的事件进行处理, 如果触发了一个事件, 而没有对应的Listener时,Flex忽略此事件.
如果想给Event对象添加新属性, 就必须继承Event类,然后定义新属性

四.事件的传播:
事件触发后, Flex有3个检测事件监听器的阶段, 3个阶段的发生的顺序如下:
1. 捕获
2. 目标
3. 上浮
在任意一个阶段, 节点们都有机会操作事件. 比如: 用户点击了一个在VBox中的Button,
在捕获阶段, Flex检查Application对象(根节点)和VBox是否有监听器处理此事件. Flex然后在目标阶段触发按钮的监听器.
在上浮阶段, VBox和应用以与捕获阶段相反的顺序再次获得机会处理事件.
在Actionscript3.0中,你可以在任意目标节点上注册事件监听器. 但是部分事件会被直接传给目标节点,比如Socket类.
捕获阶段的节点顺序是从父节点到子节点的, 而上浮阶段刚好相反.
捕获事件缺省是关闭的,也就是说如果要捕获事件, 必须显式指定在捕获阶段进行处理.
每一个Event都有target和currentTarget属性, 帮助跟踪事件传播的过程.

捕获阶段:
在捕获阶段,Flex在显示列表中检查事件的祖先是否注册了事件的监听器. Flex从根节点开始顺序而下.
大多数情况中, 根节点是Application对象. 同时, Flex改变事件的currentTarget值.
缺省情况下, 在此阶段,没有容器监听事件. use_capture参数的值是False,在此阶段添加监听的唯一方法是在调用add_listener时,
传入一个为True值的use_capture参数, 比如:
myAccordion.addEventListener(MouseEvent.MOUSE_DOWN, customLogEvent, true);
如果是在Mxml中添加监听, Flex设置此参数为False, 没有办法进行修改.
如果设置了use_capture为True, 那么事件将不会上浮. 如果既想捕获又想上浮就必须调用 addEventListener两次.
一次use_capture参数为true, 一次为false;
捕获很少使用, 上浮的使用更为普遍.

目标阶段:
在目标阶段, Flex激发事件的监听程序, 不检查其他的节点.

上浮阶段:
事件只在bubbles属性为True时才进行上浮. 可以上浮的事件包括: change, click, doubleClick, keyDown, keyUp, mouseDown, mouseUp.
在上浮阶段, Flex改变事件的currentTarget属性, 而target属性是初始派发事件的对象.

查询事件阶段:
使用事件的eventPhase可以获得事件当前的阶段,
1: CAPTURE_PHASE
2: AT_TARGET
3: BUBBLING_PHASE
示例: private function determineState(event:MouseEvent):Void { Debug.trace(event.eventPhase + ":" + event.currentTarget.id); }

停止传播:
使用下面两个函数停止事件的传播:
stopPropagation()
stopImmediatePropagation()

 
件是一个非常有用的功能,通常用于信息传递交互大大提高程序编写的灵活性。在高级语言中都会集成这方面特性;Flex也不例外几乎所有控件中都集成了大量的事件,如果Button的Click事件等。但实际应用中控件自有的事件是不能满真实需要的,特别在自己编写自定义控件时,自定义控件内部信息的改变如何及时通知所在的容器变得很更要;这个时候自定义事件就起到它的作用。

       在Flex中定义事件有两中情况,分别是ActionScript和MXML中定义。

       在ActionScript中定义:

 
CODE:
[Event(name="myEnableEvent", type="flash.events.Event")]

public class MyComponent extends UIComponent

{

           ...

}

在MXML中定义:

 

CODE:
<mx:Metadata>

    [Event(name="DataChange", type="DataChangeEvent")]

</mx:Metadata>

DataChangeEvent事件参数的定义:

 

CODE:
import flash.events.Event;

public class DataChangeEvent extends flash.events.Event

{

       public function DataChangeEvent()

       {

              super("DataChange");

       }

       public var Data:Object;

}

 

在自定义控件中定义和触发事件:

 

CODE:
<?xml version="1.0" encoding="utf-8"?>

<mx:Form xmlns:mx="http://www.adobe.com/2006/mxml" width="212" height="56">

<mx:Metadata>

        [Event(name="DataChange", type="DataChangeEvent")]

    </mx:Metadata>

<mx:Button label="Button" click="Change()"/>

       <mx:Script>

              <![CDATA[

                     function Change():void

                     {

                            this.dispatchEvent(new DataChangeEvent());

                     }

              ]]>

       </mx:Script>

</mx:Form>

容器接收相关自定义控件事件:

 

CODE:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:ns1="*">

      

       <ns1:EmployeeCombo x="146" y="132" DataChange="onChange(event)" >

       </ns1:EmployeeCombo>

       <mx:Script>

              <![CDATA[

                     import mx.controls.Alert;

                     function onChange(e:DataChangeEvent)

                     {

                           

                     }

              ]]>

       </mx:Script>

</mx:Application>

其实自定义事件的现实也很简单,但起着非常重要的作用;正是因为有了事件的机制,使得大部分重复的功能抽取到自定义控件中,从而达到一个很高的代码重用性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章