Home > Component, Flex, code > Update to MenuItem class

Update to MenuItem class

February 24th, 2009 Gareth Leave a comment Go to comments

I have recently begun using my MenuItem and MenuItemWithChildren classes at my work, and have made a slight modification to the code to lessen some of the code writing required.

As I was using the menuItem class, I realized that when I selected the item, I was usually just calling some function based upon the label of that menu item. Using my updated MenuItem class, you can now pass in a function as one of the parameters.

My MenuItem class now looks like this:

package com.flexoop.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 _menuHandler:Function;
		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 menuHandler():Function {
			return this._menuHandler;
		}
 
		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 menuHandler( value:Function ):void {
			this._menuHandler = 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="", menuHandler:Function=null, 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.menuHandler = menuHandler;
			this.toggled = toggled;
			this.type = type;
		}
 
	}
}

And similarly for the MenuItemWithChildren class:

package com.flexoop.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="", menuHandler:Function=null, enabled:Boolean=true, type:String="normal", toggled:Boolean=true, groupName:String="", icon:Class=null ) {
			super( label, menuHandler, enabled, type, toggled, groupName, icon );
		}
 
	}
}

The 2nd parameter is now the menuHandler function. So in order to use this, you could set up something like this:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()" xmlns:flexoop="com.flexoop.utility.*">
	<mx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
 
			import mx.events.MenuEvent;
			import mx.controls.Alert;
 
			import com.flexoop.utility.MenuItemWithChildren;
			import com.flexoop.utility.MenuItem;
 
			[Bindable] private var menuData:ArrayCollection = new ArrayCollection;
 
			public function init():void {
				var menuItem:MenuItemWithChildren = new MenuItemWithChildren( "test 1", showMe );
				menuItem.children.push( new MenuItem( "test 4", showMe ) );
				menuItem.children.push( new MenuItem( "test 5", showMe ) );
				menuData.addItem( menuItem );
				menuData.addItem( new MenuItem( "test2", showMe ) );
				menuData.addItem( new MenuItem( "test3", showMe ) );
				mb.dataProvider = menuData;
 
			}
 
			private function menuItemHandler( event:MenuEvent ):void {
				( event.item as MenuItem ).menuHandler();
			}
 
			private function showMe():void {
				Alert.show( 'this was fired from my menuItem' );
			}
 
		]]>
	</mx:Script>
	<mx:VBox>
		<mx:ApplicationControlBar id="acb">
			<mx:MenuBar id="mb" dataProvider="{ menuData }" click="menuItemHandler( event )" />
		</mx:ApplicationControlBar>
	</mx:VBox>
</mx:Application>

(I didn’t get a chance to test the above example code so, if anyone finds that something doesn’t work correctly, feel free to ping me about it and I’ll try to get it working properly). It’s a somewhat basic example as all items point to the same function, but it would be very simple to alter this so each menuItem points to a separate method instead, or pass a certain value to the function to display.

  1. reiman
    October 29th, 2009 at 18:12 | #1

    Thanks for your post it is really informative, I wish had found it earlier, I ended up writing a MenuItem class as well after having been frustrated that the flex sdk didn’t come with something out of the box. One way to avoid having to create another class to hold MenuItems as children is to create the children property on the MenuItem and set it to “null”, the arrows will not appear. This way MenuItem can contain children with subclassing.

  2. Gareth
    October 30th, 2009 at 20:05 | #2

    @reiman,
    Ah, never tried null. I did try [] for an empty array, but that still gave the arrow for the child menus, but with no children. That would certainly make things simpler though…I guess I should’ve inspected what Flex was doing with the menu items I passed it.
    Thanks

  1. No trackbacks yet.