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

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>

Related

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>

Binding AS3 class functions to Flex menubar

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>

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>

Flex DropDownList ItemRenderer probably a bug

I am trying to make a simple change on look of Flex 4.5 Spark DropDownLis trough extending it's item renderer, anyway even a just shiny new item renderer bring me as result a items which labels is blanks.
If i remove the renderer everything is fine, but with it - the items is blank white.
<s:DropDownList id="cbX" x="140" y="281" width="276" itemRenderer="comboItemRenderer" labelField="#text">
<mx:XMLListCollection>
<fx:XMLList>
<node text="1" />
<node text="2" />
<node text="3" />
</fx:XMLList>
</mx:XMLListCollection>
</s:DropDownList>
item renderer :
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true">
<s:Label text="{data}"/>
</s:ItemRenderer>
Is it a bug, or i am doing it wrong ?
Try to use:
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true">
<s:Label text="{label}"/>
</s:ItemRenderer>
The data for the renderer is still the data. But if you use labelField you rely on List's label calculation routine. So just display it.

Flex Combobox: how to get the value of the selected item?

I am using a combobox for the us states, link. The label is set to the full name of the state, while the value attribute holds the abbreviation. What I want to do is to get the selected item's value. So I tried combo.selectedItem.value and combo.selectedItem.#value, but neither of them worked. Can someone shed a light on this please?
Here's a simple example that might be helpful.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:ComboBox id="comboBox" dataProvider="{[{label:'California', value:'CA'}, {label:'New York', value:'NY'}]}" />
<mx:Label text="{comboBox.selectedItem.value}" />
</mx:Application>
Here's another example. In this one we use XML as dataProvider.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:XML id="xml" xmlns="">
<states>
<state label="Alabama" value="AL" country="US" />
<state label="Alaska" value="AK" country="US" />
<state label="Arkansas" value="AR" country="US" />
</states>
</mx:XML>
<mx:ComboBox id="comboBox" dataProvider="{xml.state}" labelField="#label" />
<mx:Label text="{comboBox.selectedItem.#value}" />
</mx:Application>
You can populate an array with the values you want to get and retrieve the index of the selected item on the combo box (which should be the same as in the array).
Or in your component ... just look for the index (selected item) child on statesUS

Resources