This blog post is related to My LFPUG Presentation about Mate blog post.
This is the seventh of a series of gradually more complex examples on how to use Mate. If you haven’t done it yet you should have a look first at our previous examples: #1, #2, #3, #4, #5, and #6.
In the previous example, we added a reset countdown which sets all the counters to 0 when the countdown is off. But it’s a bit of a pain this unstoppable countdown. It would be cool to add a start/stop button, wouldn’t it?
OK, let’s do it (source is available by right-clicking on the demo after launching it):
So we’ve first added this start/stop button (yeah, let’s have a toggle button this time):
Demo #7: src/views/MainView.mxml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | <?xml version="1.0" encoding="utf-8"?> <mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" width="860" height="600" title="{mainTitle}" layout="absolute" xmlns:views="views.*"> <mx:Script> <![CDATA[ import Events.CountdownEvent; import Events.CounterEvent; [Bindable] public var globalAmount : int = 0; [Bindable] public var isCountdownRunning : Boolean; [Bindable] private var numCounters : int = 0; [Bindable] private var mainTitle : String = "MainView"; protected function buttonIncrease_clickHandler( event : MouseEvent ) : void { dispatchEvent( new CounterEvent( CounterEvent.INCREASE_GLOBAL )); } protected function buttonDecrease_clickHandler( event : MouseEvent ) : void { dispatchEvent( new CounterEvent( CounterEvent.DECREASE_GLOBAL )); } protected function addCounterButton_clickHandler( event : MouseEvent ) : void { var counter : Counter = new Counter(); counter.counterTitle = "Counter " + ++numCounters; mainTile.addChild( counter ); } protected function deleteCounterButton_clickHandler( event : MouseEvent ) : void { mainTile.removeChildAt( mainTile.numChildren - 1 ); --numCounters; } public function updateTitle( event : CountdownEvent ) : void { mainTitle = "MainView (" + event.countdown + ")"; } protected function countdownButton_clickHandler( event : MouseEvent ) : void { if ( isCountdownRunning ) { countdownButton.label = "START COUNTDOWN"; dispatchEvent( new CountdownEvent( CountdownEvent.STOP_COUNTDOWN )); } else { countdownButton.label = "STOP COUNTDOWN"; dispatchEvent( new CountdownEvent( CountdownEvent.START_COUNTDOWN )); } } ]]> </mx:Script> <mx:Label text="Global Amount:" x="28" y="16"/> <mx:Label text="{globalAmount}" x="124" y="16"/> <mx:Tile id="mainTile" left="10" right="10" top="82" bottom="10"> </mx:Tile> <mx:Button id="buttonIncrease" x="68" y="34" label="+" click="buttonIncrease_clickHandler(event)"/> <mx:Button id="buttonDecrease" x="140" y="34" label="-" click="buttonDecrease_clickHandler(event)"/> <mx:Button id="addCounterButton" x="614" y="31" label="Add Counter" click="addCounterButton_clickHandler(event)"/> <mx:Button id="countdownButton" x="366" y="31" label="STOP COUNTDOWN" click="countdownButton_clickHandler(event)"/> <mx:Button id="deleteCounterButton" x="716" y="31" label="Delete Counter" enabled="{numCounters > 0}" click="deleteCounterButton_clickHandler(event)"/> </mx:Panel> |
Depending on isCountdownRunning (note that it is bindable…), the button’s label will change, and a click on the button will dispatch the new CountdownEvent.START_COUNTDOWN or CountdownEvent.STOP_COUNTDOWN.
Demo #7: src/Events/CountdownEvent.as
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package Events { import flash.events.Event; public class CountdownEvent extends Event { public static const COUNTDOWN : String = "countDown"; public static const START_COUNTDOWN : String = "startCountDown"; public static const STOP_COUNTDOWN : String = "stopCountDown"; public var countdown : int; public function CountdownEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false) { super(type, bubbles, cancelable); } } } |
We can see those two new types here. What about CountdownManager?
Demo #7: src/managers/CountdownManager.as
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | package managers { import Events.CountdownEvent; import Events.CounterEvent; import com.asfusion.mate.events.Dispatcher; import flash.events.Event; import flash.events.EventDispatcher; import flash.events.IEventDispatcher; import flash.events.TimerEvent; import flash.utils.Timer; public class CountdownManager extends EventDispatcher { private var timer : Timer; private var duration : int = 10; private var countdown : int; private var dispatcher : Dispatcher = new Dispatcher(); [Bindable] public var isCountdownRunning : Boolean = true; public function CountdownManager( target : IEventDispatcher = null ) { super( target ); init(); } private function init() : void { countdown = duration; timer = new Timer( 1000, 1 ); timer.addEventListener( TimerEvent.TIMER_COMPLETE, onTimerComplete ); timer.start(); } private function onTimerComplete( event : TimerEvent ) : void { timer.reset(); timer.start(); --countdown; var counterEvent : CountdownEvent = new CountdownEvent( CountdownEvent.COUNTDOWN ); counterEvent.countdown = this.countdown; dispatcher.dispatchEvent( counterEvent ); if ( countdown < 1 ) { dispatcher.dispatchEvent( new CounterEvent( CounterEvent.RESET )); countdown = duration; } } public function startCountdown() : void { timer.start(); isCountdownRunning = true; } public function stopCountdown() : void { timer.stop(); isCountdownRunning = false; } } } |
The same bindable isCountdownRunning here. And two dead simple methods: startCountdown() and stopCountdown().
Last, but not least: the now famous MainEventMap:
Demo #7: src/maps/MainEventMap.mxml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | <?xml version="1.0" encoding="utf-8"?> <mate:EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:mate="http://mate.asfusion.com/"> <mx:Script> <![CDATA[ import Events.CountdownEvent; import views.SubCounter; import managers.CountdownManager; import mx.events.FlexEvent; import views.Counter; import views.MainView; import managers.CounterManager; import Events.CounterEvent; ]]> </mx:Script> <mate:Debugger level="{Debugger.ALL}"/> <mate:EventHandlers type="{FlexEvent.APPLICATION_COMPLETE}"> <mate:ObjectBuilder generator="{CountdownManager}"/> </mate:EventHandlers> <mate:EventHandlers type="{CounterEvent.INCREASE_GLOBAL}"> <mate:MethodInvoker generator="{CounterManager}" method="increaseGlobal"/> </mate:EventHandlers> <mate:EventHandlers type="{CounterEvent.DECREASE_GLOBAL}"> <mate:MethodInvoker generator="{CounterManager}" method="decreaseGlobal"/> </mate:EventHandlers> <mate:EventHandlers type="{CounterEvent.RESET}"> <mate:MethodInvoker generator="{CounterManager}" method="reset"/> </mate:EventHandlers> <mate:EventHandlers type="{CountdownEvent.START_COUNTDOWN}"> <mate:MethodInvoker generator="{CountdownManager}" method="startCountdown"/> </mate:EventHandlers> <mate:EventHandlers type="{CountdownEvent.STOP_COUNTDOWN}"> <mate:MethodInvoker generator="{CountdownManager}" method="stopCountdown"/> </mate:EventHandlers> <mate:Injectors targets="{[Counter, MainView]}"> <mate:PropertyInjector source="{CounterManager}" sourceKey="globalAmount" targetKey="globalAmount"/> </mate:Injectors> <mate:Injectors targets="{[Counter, SubCounter]}"> <mate:ListenerInjector eventType="{CounterEvent.RESET}" method="reset"/> </mate:Injectors> <mate:Injectors target="{MainView}" debug="true"> <mate:PropertyInjector source="{CountdownManager}" sourceKey="isCountdownRunning" targetKey="isCountdownRunning"/> <mate:ListenerInjector eventType="{CountdownEvent.COUNTDOWN}" method="updateTitle"/> </mate:Injectors> </mate:EventMap> |
EventHandlers and ListenerInjectors catch events, then invoke methods, or inject properties, blah, blah, blah.
I bet you start to get it by now
Next: #8 Modules Example (pt 1)
Related posts:
- Mate examples: #6 Reset Countdown (pt 1) This blog post is related to My LFPUG Presentation...
- Mate examples: #8 Modules Example (pt 1) This is the eigth of a series of gradually more...
- Mate examples: #9 Modules Example (pt 2) This is the ninth of a series of gradually more...
- Mate examples: #5 LocalEventMap This is the fifth of a series of gradually more...
- Mate examples: #4 Counters created dynamically This is the fourth of a series of gradually more...
Related posts brought to you by Yet Another Related Posts Plugin.

Subscribe
/Mate_example7.png)


