Home > Component, Flex, code > MenuItem Class

MenuItem Class

November 28th, 2008 Gareth Leave a comment Go to comments

I am not completely sure why Adobe decided not to include this in their base classes when creating the Flex framework. They have, more or less, given all of the class structure in the definition of what a menuitem must contain…enabled, toggle, groupName, etc. I decided that there’s absolutely no point in rewriting the same thing over and over again, so why not create a MenuItem class.

package com.archfamily.utility {
 
	[Bindable]
	public class MenuItem {
 
		/***********************************
		 * properties
		 **********************************/
 
		private var _enabled:Boolean = true;
		private var _groupName:String = "";
		private var _icon:Class;
		private var _label:String = "";
		private var _toggled:Boolean = true;
		private var _type:String = "";
 
		/***********************************
		 * getters
		 **********************************/
 
		public function get enabled():Boolean {
			return this._enabled;
		}
 
		public function get groupName():String {
			return this._groupName;
		}
 
		public function get icon():Class {
			return this._icon;
		}
 
		public function get label():String {
			return this._label;
		}
 
		public function get toggled():Boolean {
			return this._toggled;
		}
 
		public function get type():String {
			return this._type;
		}
 
		/***********************************
		 * setters
		 **********************************/
 
		public function set enabled( value:Boolean ):void {
			this._enabled = value;
		}
 
		public function set groupName( value:String ):void {
			this._groupName = value;
		}
 
		public function set icon( value:Class ):void {
			this._icon = value;
		}
 
		public function set label( value:String ):void {
			this._label = value;
		}
 
		public function set toggled( value:Boolean ):void {
			this._toggled = value;
		}
 
		[Inspectable(enumeration=separator,check,radio,normal)]
		public function set type( value:String ):void {
			this._type = value;
		}
 
		public function MenuItem( label:String="", enabled:Boolean=true, type:String="normal", toggled:Boolean=true, groupName:String="", icon:Class=null ) {
			this.enabled = enabled;
			this.groupName = groupName;
			this.icon = icon;
			this.label = label;
			this.toggled = toggled;
			this.type = type;
		}
 
	}
}

I added the properties to the constructor so that the menu items could be created without have to first create a variable for them, but could rather just do something like “myArray.push( new MenuItem( “myLabel”, true ) )”. Initially I added the “children” as a property of this class, but then I found out that this will cause the menu items to show an arrow next to their name as if the MenuItem actually had children (even though the item is an empty array). In order to circumvent this problem, I decided to create a second class, MenuItemWithChildren, that extends MenuItem, but adds the property “children”:

package com.archfamily.utility {
 
	public class MenuItemWithChildren extends MenuItem {
 
		/***********************************
		 * properties
		 **********************************/
 
		private var _children:Array = [];
 
		/***********************************
		 * getters
		 **********************************/
 
		public function get children():Array {
			return this._children;
		}
 
		/***********************************
		 * setters
		 **********************************/
 
		public function set children( value:Array ):void {
			this._children = value;
		}
 
		public function MenuItemWithChildren(label:String="", enabled:Boolean=true, type:String="normal", toggled:Boolean=true, groupName:String="", icon:Class=null) {
			super(label, enabled, type, toggled, groupName, icon);
		}
 
	}
}

Now, whenever I want to create a menu item within one of my menu bars, all I have to do is create an array that holds all of my MenuItem or MenuItemWithChildren classes, and I have strongly typed class rather than a plain, old array of generic objects. The one other thing to note is that if the menu is not created in the property declarations, then you have to set the array to the dataProvider of the menu item, or it will not refresh the view and you will not be able to see your menu items. The implementation would look something like this:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()" xmlns:archfamily="com.archfamily.utility.*">
	<mx:Script>
		<![CDATA[
			import com.archfamily.utility.MenuItemWithChildren;
			import com.archfamily.utility.MenuItem;
 
			[Bindable] private var menuData:Array = [];
 
			public function init():void {
				var menuItem:MenuItemWithChildren = new MenuItemWithChildren( "test 1", true );
				menuItem.children.push( new MenuItem( "test 4", true ) );
				menuItem.children.push( new MenuItem( "test 5", false ) );
				menuData.push( menuItem );
				menuData.push( new MenuItem( "test2", true ) );
				menuData.push( new MenuItem( "test3", false ) );
				mb.dataProvider = menuData;
 
			}
 
		]]>
	</mx:Script>
	<mx:VBox>
		<mx:ApplicationControlBar id="acb">
			<mx:MenuBar id="mb" dataProvider="{ menuData }" />
		</mx:ApplicationControlBar>
	</mx:VBox>
</mx:Application>

I haven’t had to use the Menu class very often yet, but I’m sure this will come in handy to someone else. If nothing else, it saves typing in Flex Builder.

Enjoy!