Defining a Custom Control in the Test Application

Typically, the test application already contains custom controls, which were added during development of the application. If your test application already includes custom controls, you can proceed to Testing a Flex Custom Control Using Dynamic Invoke or to Testing a Custom Control Using Automation Support.

This procedure shows how a Flex application developer can create a spinner custom control in Flex. The spinner custom control that we create in this topic is used in several topics to illustrate the process of implementing and testing a custom control.

The spinner custom control includes two buttons and a textfield, as shown in the following graphic.

Flex custom control

The user can click Down to decrement the value that is displayed in the textfield and click Up to increment the value in the textfield.

The custom control offers a public "Value" property that can be set and retrieved.

  1. In the test application, define the layout of the control. For example, for the spinner control type:
    <?xml version="1.0" encoding="utf-8"?>
    <customcontrols:SpinnerClass xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:controls="mx.controls.*" xmlns:customcontrols="customcontrols.*">
    	<controls:Button id="downButton" label="Down" />		
    	<controls:TextInput id="text" enabled="false" />
    	<controls:Button id="upButton" label="Up"/>		
    </customcontrols:SpinnerClass>
    
  2. Define the implementation of the custom control. For example, for the spinner control type:
    package customcontrols
    {
    	import flash.events.MouseEvent;
    	
    	import mx.containers.HBox;
    	import mx.controls.Button;
    	import mx.controls.TextInput;
    	import mx.core.UIComponent;
    	import mx.events.FlexEvent;
    
    	[Event(name="increment", 	type="customcontrols.SpinnerEvent")]
    	[Event(name="decrement", 	type="customcontrols.SpinnerEvent")]
    	
    	public class SpinnerClass extends HBox
    	{
    		public var downButton : Button;
    		public var upButton : Button;
    		public var text : TextInput;
    		public var ssss: SpinnerAutomationDelegate;
    		private var _lowerBound : int = 0;
    		private var _upperBound : int = 5;
    		
    		private var _value : int = 0;
    		private var _stepSize : int = 1;
    		
    		
    		public function SpinnerClass() {
    			addEventListener(FlexEvent.CREATION_COMPLETE, creationCompleteHandler);
    		}
    		
    		private function creationCompleteHandler(event:FlexEvent) : void {
    			downButton.addEventListener(MouseEvent.CLICK, downButtonClickHandler);
    			upButton.addEventListener(MouseEvent.CLICK, upButtonClickHandler);
    			updateText();	
    		}
    		
    		private function downButtonClickHandler(event : MouseEvent) : void {
    			if(Value - stepSize >= lowerBound) {
    				Value = Value - stepSize;
    			}
    			else {
    				Value = upperBound - stepSize + Value - lowerBound + 1;
    			}
    
    			var spinnerEvent : SpinnerEvent = new SpinnerEvent(SpinnerEvent.DECREMENT);
    			spinnerEvent.steps = _stepSize;
    			dispatchEvent(spinnerEvent);
    		}
    		
    		private function upButtonClickHandler(event : MouseEvent) : void {
    			if(cValue <= upperBound - stepSize) {
    				Value = Value + stepSize;	
    			}
    			else {
    				Value = lowerBound + Value + stepSize - upperBound - 1;
    			}
    
    			var spinnerEvent : SpinnerEvent = new SpinnerEvent(SpinnerEvent.INCREMENT);
    			spinnerEvent.steps = _stepSize;
    			dispatchEvent(spinnerEvent);
    		}
    		
    		private function updateText() : void {
    			if(text != null) {
    				text.text = _value.toString();
    			}
    		}
    		
    		public function get Value() : int {
    			return _value;
    		}
    		
    		public function set Value(v : int) : void {
    			_value = v;
    			if(v < lowerBound) {
    				_value = lowerBound;
    			}
    			else if(v > upperBound) {
    				_value = upperBound;
    			}
    			updateText();
    			
    		}
    		
    		public function get stepSize() : int {
    			return _stepSize;
    		}
    		
    		public function set stepSize(v : int) : void {
    			_stepSize = v;
    		}
    		
    		public function get lowerBound() : int {
    			return _lowerBound;
    		}
    		
    		public function set lowerBound(v : int) : void {
    			_lowerBound = v;
    			if(Value < lowerBound) {
    				Value = lowerBound;
    			}
    		}
    		
    		public function get upperBound() : int {
    			return _upperBound;
    		}
    		
    		public function set upperBound(v : int) : void {
    			_upperBound = v;
    			if(Value > upperBound) {
    				Value = upperBound;
    			}
    		}		
    	}
    }
    
  3. Define the events that the control uses. For example, for the spinner control type:
    package customcontrols
    {
    	import flash.events.Event;
    	
    	public class SpinnerEvent extends Event
    	{
    		public static const INCREMENT : String = "increment";
    		public static const DECREMENT : String = "decrement";
    		
    		private var _steps : int;		
    		
    		public function SpinnerEvent(eventName : String) {
    			super(eventName);
    		}
    		
    		public function set steps(value:int) : void {
    			_steps = value;
    		}
    		
    		public function get steps() : int {
    			return _steps;
    		}
    
    	}
    }

The next step is to implement automation support for the test application.