Flex: menu items not being displayed - apache-flex

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>

Related

Flex AIR compile error access of undefined property

Working through a series of Adobe AIR examples I have encountered a compilation error with one of them that I have distilled into the following demo application file
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication
xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.events.MenuEvent;
private static const MENU_DEMO:String = "Demo...";
private function onMenuItemClick(evt:MenuEvent):void
{
switch(evt.label)
{
case MENU_DEMO:
break;
}
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%" paddingBottom="5">
<mx:MenuBar id="menuBar"
width="100%"
labelField="#label"
itemClick="onMenuItemClick(event);">
<mx:XMLList>
<menuitem label="Error">
<menuitem label="{MENU_DEMO}" />
</menuitem>
</mx:XMLList>
</mx:MenuBar>
</mx:VBox>
</mx:WindowedApplication>
for which the descriptor file is
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://ns.adobe.com/air/application/1.0.M6">
<id>ErrorDemo</id>
<filename>ErrorDemo</filename>
<name>Error Demo</name>
<version>v0.1</version>
<description>Demo undefined property error</description>
<copyright></copyright>
<initialWindow>
<title>Error Demo</title>
<content>ErrorDemo.swf</content>
<systemChrome>standard</systemChrome>
<transparent>false</transparent>
<visible>true</visible>
</initialWindow>
</application>
Compilation produces the following output
C:\Projects\AIR\ErrorDemo>amxmlc ErrorDemo.mxml
Loading configuration file C:\Projects\flex_sdk_4.6\frameworks\air-config.xml
C:\Projects\AIR\ErrorDemo\ErrorDemo.mxml(28): Error: Access of undefined property _ErrorDemo_XMLList1.
<menuitem label="{MENU_DEMO}" />
The problem seems to be down to the use of the static const {MENU_DEMO} bound to the menuitem tag's label attribute because substituting it with text leads to no compilation error. Adobe's Using Flex 4.6 documentation states that static constants can be used as data binding sources, but maybe not in the way they're used here. Does anyone know what the problem is with using them in this way?
To clarify: replacing the bound constant reference {MENU_DEMO} with the string literal Demo... produces the following expected output. But using a string literal in place of the bound constant reference defeats the purpose of using a bound constant. Which is what seems to generate the error, and is the point of this post.
try adding [Bindable] before private static const MENU_DEMO:String = "Demo...";
it becomes:
[Bindable]
private static const MENU_DEMO:String = "Demo...";
I don't use Flex but from some research about your problem I noticed...
(1)
Your code has:
<menuitem label="{MENU_DEMO}" />
Try setting that as:
<menuitem label text="{MENU_DEMO}" />
(2)
Also since you say itemClick="onMenuItemClick(event);" shouldn't that be backed up by:
import mx.events.ItemClickEvent;
(3)
What is the expected result if your code compiled correctly?
I can't (or won't) test any Flex code so let me know if this works or errors...
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication
xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.events.MenuEvent;
import mx.events.ItemClickEvent; //add this
[Bindable]
public var MENU_DEMO:String = "Demo...";
public function onMenuItemClick(evt:MenuEvent):void //or try... (evt:MenuEvent = null):void
{
if (evt.label.text == MENU_DEMO) //untested
{
//do something here
evt.label.text = "Changed...";
}
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%" paddingBottom="5">
<mx:MenuBar id="menuBar"
width="100%"
labelField="#label"
itemClick="onMenuItemClick(event);">
<mx:XMLList xmlns="">
<menuitem label="Error" />
<menuitem label text="{MENU_DEMO}" />
</menuitem>
</mx:XMLList>
</mx:MenuBar>
</mx:VBox>
</mx:WindowedApplication>
For anyone interested in what a Flex 4 version of the mxml code looks like, here is what I came up with, following #ProgrammerDancuk's suggestion, who really should receive credit
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Script>
<![CDATA[
import mx.events.MenuEvent;
private static const MENU_DEMO:String = "Demo...";
private function onMenuItemClick(evt:MenuEvent):void
{
switch(evt.label)
{
case MENU_DEMO:
break;
}
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<fx:XMLList id="demoMenu">
<menuitem label="Error">
<menuitem label="{MENU_DEMO}" />
</menuitem>
</fx:XMLList>
</fx:Declarations>
<mx:VBox width="100%" height="100%" paddingBottom="5">
<mx:MenuBar id="menuBar"
width="100%"
labelField="#label"
itemClick="onMenuItemClick(event);">
<mx:dataProvider>
{demoMenu}
</mx:dataProvider>
</mx:MenuBar>
</mx:VBox>
</s:WindowedApplication>

Random Picking an XMLList menuitem

i have this XMLList:
<fx:XMLList id="Generic List" xmlns="">
<menuitem label="First entry" url="www.aaa.com"/>
<menuitem label="Second entry" url="www.bbb.com"/>
<menuitem label="Third Entry" url="www.ccc.com"/>
</fx:XMLList>
I want to randomly select in my combobox (code not displayed) one of these menu item picked randomly.
I'm using Flex Builder 4,6.
Thanks for your help.
Try this:
<?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>
<fx:XMLList id="genericList" xmlns="">
<menuitem label="First entry" url="www.aaa.com"/>
<menuitem label="Second entry" url="www.bbb.com"/>
<menuitem label="Third Entry" url="www.ccc.com"/>
</fx:XMLList>
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.XMLListCollection;
]]>
</fx:Script>
<s:ComboBox
id="cbEntry"
dataProvider="{new XMLListCollection(genericList)}"
labelField="#label"
creationComplete="{cbEntry.selectedIndex = Math.floor(cbEntry.dataProvider.length * Math.random());}"/>
</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>

how to develop 2 level horizontal menu in flex3?

How can I develop a 2 level horizontal menu in flex 3? I want a sub menu to appear when you mouse over the 1st level.
The Menu control has this functionality built in. Here's Adobe's online documentation with some examples for you to check out.
Example:
<?xml version="1.0"?>
<!-- menus/SimpleMenuControl.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" >
<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="MenuItem A" >
<menuitem label="SubMenuItem A-1" enabled="false"/>
<menuitem label="SubMenuItem A-2"/>
</menuitem>
<menuitem label="MenuItem B" type="check" toggled="true"/>
<menuitem label="MenuItem C" type="check" toggled="false"/>
<menuitem type="separator"/>
<menuitem label="MenuItem D" >
<menuitem label="SubMenuItem D-1" type="radio"
groupName="one"/>
<menuitem label="SubMenuItem D-2" type="radio"
groupName="one" toggled="true"/>
<menuitem label="SubMenuItem D-3" type="radio"
groupName="one"/>
</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>
</mx:Application>

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