In Flex 4 you have the ability to use the mx components or the new spark components. I started a project the other day and wanted to use a ToggleButtonBar and noticed the only on available was the mx component. Spark does come with a toggle button but it is a single button. Also I wanted to be able to use the ToggleButtonBar as a vertical menu and the mx component, to my knowledge, only lays out horizontally, and extending that component to get it to layout vertical just seemed like to much of a pain.
After thinking about the issue for a moment I dove right in and here is the resulting code that I came up with.
package com.mswallace.components.menus { import flash.events.FocusEvent; import flash.events.KeyboardEvent; import flash.events.MouseEvent; import mx.collections.ArrayCollection; import mx.collections.ArrayList; import mx.events.FlexEvent; import spark.components.Group; import spark.components.ToggleButton; public class ToggleMenu extends Group { public function ToggleMenu() { super(); this.addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete); } private function onCreationComplete(event:FlexEvent):void { this.addEventListener(FocusEvent.FOCUS_IN, onFocusIn); } private function onFocusIn(event:FocusEvent):void { this.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown); } private function onKeyDown(event:KeyboardEvent):void { trace(event.keyCode); } private function createMenu():void { if(this.numChildren > 0) this.removeAllElements(); for (var i:String in toggleButtons) { var value:String = toggleButtons.getItemAt(int(i)) as String; var toggleButton:ToggleButton = new ToggleButton(); toggleButton.label = value; toggleButton.id = 'bn_' + value; toggleButton.addEventListener(MouseEvent.CLICK, onClick); this.addElement(toggleButton); } //this is optional code to select the first item } private function onClick(event:MouseEvent):void { if(event.currentTarget.selected == false) { event.currentTarget.selected = true; selectedIndex = this.getChildIndex(event.currentTarget as ToggleButton); } for(var i:int=0; i< this.numChildren; ++i ) { var button:ToggleButton = this.getElementAt(i) as ToggleButton; if(event.currentTarget != button) button.selected = false; } } ///////// vars \\\\\\\\\\\\ //array of string values that is passed in to create the buttons private var _toggleButtons : ArrayCollection; public function get toggleButtons():ArrayCollection { return _toggleButtons; } public function set toggleButtons( value : ArrayCollection ):void { _toggleButtons = value; if(value != null && value.length > 0) createMenu(); } //selected index private var _selectedIndex:int; public function get selectedIndex():int { return _selectedIndex; } public function set selectedIndex(value:int):void { _selectedIndex = value; } } }
Here is the component implemented in MXML after creating the Actionscript Class.
I only did this so that I could control the layout in mxml tags but you could also implement the layout in the Actionscript class if you like.
I only did this so that I could control the layout in mxml tags but you could also implement the layout in the Actionscript class if you like.
I tend to follow a “code behind” method when creating some of my components.
<?xml version="1.0" encoding="utf-8"?> <menus:ToggleMenu xmlns:menus="com.mswallace.components.menus.*" xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx"> <menus:layout> <s:VerticalLayout /> </menus:layout> <fx:Declarations> <!-- Place non-visual elements (e.g., services, value objects) here --> </fx:Declarations> </menus:ToggleMenu>


Groovymag