Binding AS3 class functions to Flex menubar - apache-flex

New with Flex and mxml. How I can bind AS3 class' function to a menubar item? My menubar code is this:
<mx:MenuBar id="myMenubar" labelField="#label">
<fx:XMLList xmlns="">
<item label="File">
<item label="New" />
<item label="Open"/>
<item label="Save"/>
<item label="Save As"/>
<item label="Quit"/>
</item>
<item label="Edit">
<item label="Undo"/>
<item label="Redo"/>
<item label="Preferences"/>
</item>
<item label="Level">
<item label="New Room"/>
<item label="Properties"/>
</item>
<item label="Objects">
<item label="Clickable"/>
<item label="Character"/>
<item label="Door"/>
<item label="Treasure"/>
</item>
</fx:XMLList>
</mx:MenuBar>
I looked through few examples in Google but couldn't find definite explanation or example how to trigger AS3 class functions. I presume that I should somehow make click event listener for my subitems and make a call to my class. However, mxml syntax confuses me.

MXML is just a way to describe data and components declaratively, in the end it's compiled to pure ActionScript anyways, so you can simply subscribe an appropriate listener to myMenubar.
I think you are looking for the itemClick event:
myMenubar.addEventListener(MenuEvent.ITEM_CLICK, function(e:MenuEvent):void
{
trace(e.label + ' was clicked');
});
In order to be able to distinguish the items while being able to change the lablels, i'd recommend to assign IDs to them:
<mx:MenuBar id="myMenubar" labelField="#label">
<fx:XMLList xmlns="">
<item label="File">
<item id="abc" label="New" />
<item id="xyz" label="Open"/>
...
Then you could for example use a simple switch to handle the different items:
myMenubar.addEventListener(MenuEvent.ITEM_CLICK, function(e:MenuEvent):void
{
switch(e.item.#id)
{
case 'abc':
// do something
break;
case 'xyz':
// do something else
break;
}
});
Ofcourse you could also define which function to call using MXML:
<mx:MenuBar id="myMenubar" labelField="#label" itemClick="myMenuItemClickHandler(event)">
-
private function myMenuItemClickHandler(e:MenuEvent)
{
...
}
See also the example in the Adobe LiveDocs to get a grasp on how this all comes together:
<?xml version="1.0" encoding="utf-8"?>
<!-- Simple example to demonstrate the Halo MenuBar control. -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
initialize="initCollections();">
<fx:Script>
<![CDATA[
import mx.collections.*;
import mx.controls.Alert;
import mx.events.MenuEvent;
[Bindable]
public var menuBarCollection:XMLListCollection;
private var menubarXML:XMLList =
<>
<menuitem label="Menu1" data="top">
<menuitem label="MenuItem 1-A" data="1A"/>
<menuitem label="MenuItem 1-B" data="1B"/>
</menuitem>
<menuitem label="Menu2" data="top">
<menuitem label="MenuItem 2-A" type="check" data="2A"/>
<menuitem type="separator"/>
<menuitem label="MenuItem 2-B" >
<menuitem label="SubMenuItem 3-A" type="radio"
groupName="one" data="3A"/>
<menuitem label="SubMenuItem 3-B" type="radio"
groupName="one" data="3B"/>
</menuitem>
</menuitem>
</>;
// Event handler to initialize the MenuBar control.
private function initCollections():void {
menuBarCollection = new XMLListCollection(menubarXML);
}
// Event handler for the MenuBar control's itemClick event.
private function menuHandler(evt:MenuEvent):void {
// Don't open the Alert for a menu bar item that
// opens a popup submenu.
if (evt.item.#data != "top") {
Alert.show("Label: " + evt.item.#label + "\n" +
"Data: " + evt.item.#data, "Clicked menu item");
}
}
]]>
</fx:Script>
<s:Panel title="Halo MenuBar Control Example"
width="75%" height="75%"
horizontalCenter="0" verticalCenter="0">
<s:VGroup left="10" right="10" top="10" bottom="10">
<s:Label width="100%" color="blue" text="Select a menu item."/>
<mx:MenuBar labelField="#label" itemClick="menuHandler(event);"
dataProvider="{menuBarCollection}" />
</s:VGroup>
</s:Panel>
</s:Application>

Related

Stage scale mode error #1009

I'm trying to create a simple Air/Flex app which loads in user selected image and then resizes the window so that the selected image fits into it. If I have understood correctly, I need to set stage.scaleMode = StageScaleMode.NO_SCALE. However, when I call this I just get Error #1009 "Cannot access a property or method of a null object reference."
Below is my default application mxml:
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
initialize="init();"
applicationComplete="complete();"
xmlns:local="*">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<mx:MenuBar id="myMenubar" width="832" itemClick="menuHandler(event);" labelField="#label" depth="0">
<fx:XMLList xmlns="">
<item label="File">
<item label="New" id="new"/>
<item label="Open" id="open"/>
<item label="Save" id="save"/>
<item label="Save As" id="saveas"/>
<item label="Quit" id="quit"/>
</item>
<item label="Edit">
<item label="Undo" id="undo"/>
<item label="Redo" id="redo"/>
<item label="Preferences" id="preferences"/>
</item>
<item label="Level">
<item label="New Room" id="newroom"/>
<item label="Properties" id="properties"/>
</item>
<item label="Objects">
<item label="Clickable" id="clickable"/>
<item label="Character" id="character"/>
<item label="Door" id="door"/>
<item label="Treasure" id="treasure"/>
</item>
</fx:XMLList>
</mx:MenuBar>
<s:SpriteVisualElement id="flashpunk" depth="-2">
</s:SpriteVisualElement>
<fx:Script>
<![CDATA[
import mx.collections.*;
import mx.controls.Alert;
import mx.core.IUIComponent;
import mx.events.MenuEvent;
import flash.display.StageScaleMode;
public var Maini:Main = new Main;
private function init():void
{
flashpunk.addChild(Maini);
}
private function complete():void
{
stage.scaleMode = StageScaleMode.NO_SCALE;
}
private function menuHandler(evt:MenuEvent):void
{
// Don't open the Alert for a menu bar item that
// opens a popup submenu.
Alert.show("Label: " + evt.item.#label + "\n" +
"Data: " + evt.item.#data, "Clicked menu item");
Maini.foo();
}
]]>
</fx:Script>
</s:WindowedApplication>
What I'm doing wrong?
Also, after I have set scalemode, how exactly I can set the window size to a new size? My debug player doesn't seem to recognize even [SWF(width = "1200", height = "600")] or attempts to set stage width and height. I'm using Flash builder 4.6.
According to http://killerspaz.wordpress.com/2010/10/24/access-to-the-stage-in-flex/ - During component initialization, you can access the stage through this.systemManager reference.
systemManager.stage.scaleMode = StageScaleMode.NO_SCALE;

Flex: menu items not being displayed

This is my code, the expected menu would show grandparent > parent > child.
However, the 'parent' item is not being displayed, instead, it shows 'child' directly under 'grandparent'.
<mx:Script>
<![CDATA[
// Import the Menu control.
import mx.controls.Menu;
// Create and display the Menu control.
private function createAndShow():void {
var myMenu:Menu = Menu.createMenu(null, myMenuData, false);
myMenu.labelField="#label";
myMenu.show(10, 10);
}
]]>
</mx:Script>
<!-- Define the menu data. -->
<mx:XML format="e4x" id="myMenuData">
<root>
<menuitem label="grandparent">
<menuitem label="parent">
<menuitem label="child"/>
</menuitem>
</menuitem>
</root>
</mx:XML>
<mx:VBox>
<!-- Define a Button control to open the menu -->
<mx:Button id="myButton"
label="Open Menu"
click="createAndShow();"/>
</mx:VBox>
The funny thing is, when I add a second parent, it does show the menu correctly.
Can anyone explain what is going on here and how I can solve this?
I took your code, threw it in a project of my own and got the same results you did. I then added another parent to your XML and everything works fine. I am guessing that if you only have one parent node there really isnt a need need to show it so it skips to the child.
Added second parent below:
<root>
<menuitem label="grandparent">
<menuitem label="parent1">
<menuitem label="child"/>
</menuitem>
<menuitem label="parent2">
<menuitem label="child"/>
</menuitem>
</menuitem>
</root>
Try some thing like below: -
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<fx:XML id="myMenuData" >
<menuitem label="grandparent">
<menuitem label="Uparent">
<menuitem label="child"/>
</menuitem>
</menuitem>
</fx:XML>
</fx:Declarations>
<fx:Script>
<![CDATA[
// Import the Menu control.
import mx.controls.Menu;
// Create and display the Menu control.
private function createAndShow():void {
var myMenu:Menu = Menu.createMenu(null, myMenuData, true);
myMenu.labelField="#label";
myMenu.show(10, 10);
}
]]>
</fx:Script>
<!-- Define the menu data. -->
<mx:VBox>
<!-- Define a Button control to open the menu -->
<mx:Button id="myButton"
label="Open Menu"
click="createAndShow();"/>
</mx:VBox>
</s:Application>

How can I stop a FlexNativeMenu with keyEquivalents from stealing my keystrokes?

I have a native menu item with a shortcut for a simple letter like "F".
<s:menu>
<mx:FlexNativeMenu id="mainMenu"
dataProvider="{menuData}"
labelField="#label"
keyEquivalentField="#keyEquivalent"
showRoot="false" />
</s:menu>
<fx:Declarations>
<fx:XML format="e4x" id="menuData">
<root>
<menuitem label="Edit">
<menuitem label="Frame Selection" keyEquivalent="f"/>
</menuitem>
</root>
</fx:XML>
</fx:Declarations>
This works great, but when I try to type text in any textfield or textInput
anywhere in the app, I cant ever type f.
How can stop the menu from stealing my keyboard input ?
Perhaps a better pattern to menu accelerators would use the control key, such as CTRL+F in your example.
Your menuitem would therefore include controlKey="true"
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<s:menu>
<mx:FlexNativeMenu id="mainMenu"
dataProvider="{menuData}"
labelField="#label"
keyEquivalentField="#keyEquivalent"
showRoot="false" />
</s:menu>
<fx:Declarations>
<fx:XML format="e4x"
id="menuData">
<root>
<menuitem label="Edit">
<menuitem label="Frame Selection"
keyEquivalent="f"
controlKey="true" />
</menuitem>
</root>
</fx:XML>
</fx:Declarations>
<s:TextInput />
</s:WindowedApplication>

Charts (ColumnChart, BarChart, LineChart, AreaChart etc.) - Save as Image without ScrollBar

I have one problem related to charts.
I have Column chart with 1000+ columns on it with the scroll bar on it. Now I want to save it as Image to my Disktop or any location without scroll.
ScrollableAxisRenderer Class I have Downloaded from one of the link please find it below: -
http://www.connectedpixel.com/blog/scrollingcharts
Sample Column Chart Example: -
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="init();" xmlns:charts="com.connectedpixel.charts.*">
<fx:Declarations>
<fx:XML xmlns="" id="myData">
<items>
<item year="1960" rain="92" />
<item year="1961" rain="192" />
<item year="1962" rain="32" />
<item year="1963" rain="52" />
<item year="1964" rain="112" />
<item year="1965" rain="52" />
<item year="1966" rain="88" />
<item year="1967" rain="52" />
<item year="1968" rain="66" />
<item year="1969" rain="39" />
<item year="1970" rain="192" />
<item year="1971" rain="182" />
<item year="1972" rain="177" />
<item year="1973" rain="179" />
<item year="1974" rain="198" />
<item year="1975" rain="207" />
<item year="1976" rain="388" />
<item year="1977" rain="372" />
<item year="1978" rain="352" />
</items>
</fx:XML>
<s:XMLListCollection id="rainData" source="{myData.children()}" />
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.graphics.ImageSnapshot;
import mx.graphics.codec.PNGEncoder;
protected function initCreationComp():void
{
var image:ImageSnapshot = ImageSnapshot.captureImage(myChart,300,new PNGEncoder(),true);
var file:FileReference = new FileReference();
var chartName:String = "myChart"+count+".png";
file.save(image.data, chartName);
}
]]>
</fx:Script>
<mx:VBox width="100%" height="100%" x="50" y="50">
<s:Button label="Download Image" click="initCreationComp()"/>
<mx:ColumnChart id="myChart" name="myChart"
width="80%" height="80%"
dataProvider="{myData.children()}"
showDataTips="true" maxColumnWidth="35">
<mx:horizontalAxis>
<mx:CategoryAxis id="yearAxis" categoryField="#year" />
</mx:horizontalAxis>
<mx:series>
<mx:ColumnSeries xField="#year" yField="#rain" displayName="Rain" />
</mx:series>
<mx:horizontalAxisRenderers>
<charts:ScrollableAxisRenderer id="scrollAxisRenderer" axis="{yearAxis}" tickPlacement="none"
placement="bottom" labelGap="3" maxVisibleColumns="4"/>
</mx:horizontalAxisRenderers>
</mx:ColumnChart>
</mx:VBox>
</s:Application>
Thanks in advance....
Put the chart inside container which will show scrollbars instead of your chart:
<mx:VBox width="100%" height="100%" x="50" y="50">
<s:Button label="Download Image" click="initCreationComp()"/>
<mx:VBox width="80%" height="80%"
minWidth="100" minHeight="100">
<mx:ColumnChart id="myChart" name="myChart"
dataProvider="{myData.children()}"
showDataTips="true" maxColumnWidth="35">
<!-- etc -->
</mx:ColumnChart>
</mx:VBox>
</mx:VBox>

menu bar control in flex ,needed to handle separate method for individual menu item

i need to fire separate method for individual menu item clicked ,so that individual item can handle separate method.
and i need know what all the properties are available in menu item like type="radio".
<mx:MenuBar id="jj" labelField="#label" itemClick="MenuItemClick(event)" x="23" y="228">
<mx:XMLList>
<menuitem label="File">
<menuitem label="New" type="radio"/>
<menuitem label="Open" data="Openfile" type="Check" />
<menuitem label="Save" />
<menuitem label="Exist"/>
</menuitem>
</mx:XMLList>
</mx:MenuBar>
Can you give any link or example for menubar control?
Thanks
Example from Adobe Flex docs MenuBar
Only three types allowed: check, radio, or separator.
<?xml version="1.0"?>
<!-- Simple example to demonstrate the MenuBar control. -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initCollections();" >
<mx:Script>
<![CDATA[
import mx.events.MenuEvent;
import mx.controls.Alert;
import mx.collections.*;
[Bindable]
public var menuBarCollection:XMLListCollection;
private var menubarXML:XMLList =
<>
<menuitem label="Menu1" data="top">
<menuitem label="MenuItem 1-A" data="1A"/>
<menuitem label="MenuItem 1-B" data="1B"/>
</menuitem>
<menuitem label="Menu2" data="top">
<menuitem label="MenuItem 2-A" type="check" data="2A"/>
<menuitem type="separator"/>
<menuitem label="MenuItem 2-B" >
<menuitem label="SubMenuItem 3-A" type="radio"
groupName="one" data="3A"/>
<menuitem label="SubMenuItem 3-B" type="radio"
groupName="one" data="3B"/>
</menuitem>
</menuitem>
</>;
// Event handler to initialize the MenuBar control.
private function initCollections():void {
menuBarCollection = new XMLListCollection(menubarXML);
}
// Event handler for the MenuBar control's itemClick event.
private function menuHandler(event:MenuEvent):void {
// Don't open the Alert for a menu bar item that
// opens a popup submenu.
if (event.item.#data != "top") {
Alert.show("Label: " + event.item.#label + "\n" +
"Data: " + event.item.#data, "Clicked menu item");
}
}
]]>
</mx:Script>
<mx:Panel title="MenuBar Control Example" height="75%" width="75%"
paddingTop="10" paddingLeft="10">
<mx:Label width="100%" color="blue"
text="Select a menu item."/>
<mx:MenuBar labelField="#label" itemClick="menuHandler(event);"
dataProvider="{menuBarCollection}" />
</mx:Panel>
</mx:Application>
Also bookmark this page Language Reference.
Vineth,
You are unable to add individual event handlers for menu items unless you dynamically create the menu bar and the sub items. This is more pain than it's worth, so I would recommend using the itemCLick handler as stated above and use a switch to determine what methods to fire. For example:
switch( event.item.#data ){
case "3A":
doSomething();
break;
case "3A":
doSomethingElse();
break;
defualt:
doDefault();
break;
}
Note: this is building off of zdmytriv answer

Resources