Combobox Dataprovider - Only gets labelField from XML not the associated ID - apache-flex

Back again this time working with data providers.
Well i been doing a bit of training with Flex, and I've searched, and i managed to get a ComboBox being populated through XML data. Its works pretty well, he gets the LabelField for each item from XML, but the ID associated to each item he doesn't get then from the XML.
Code:
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="355" height="465" creationComplete="getPaises.send();"
xmlns:ns1="com.*" title="Perfil" fontWeight="normal">
<mx:HTTPService id="getPaises" url="com-handler/paises.php" result="paisesHandler()"/>
<mx:Script>
<![CDATA[
private function paisesHandler():void
{
pais.dataProvider = getPaises.lastResult.paises.pais;
pais.data = "id";
pais.labelField = "nome";
}
]]>
</mx:Script>
<mx:ComboBox x="121" y="328" width="200" id="pais">
</mx:ComboBox>
</mx:TitleWindow>
And now the ouput XML from PHP:
<?xml version="1.0" encoding="utf-8"?>
<paises>
<pais>
<id>1</id>
<nome>Portugal</nome>
</pais>
<pais>
<id>2</id>
<nome>Espanha</nome>
</pais>
</paises
Well this is what it happens, i does gets the Country names from the XML
(<nome></nome>) but he doesn't place the associated ID (<id</id>).
I now that because i placed a Label bindable to the ComboBox.selectedIndex
<mx:Label x="121" y="403" text="{pais.selectedIndex}"/>
And as you also see i used pais.data = "id"; that according to examples i saw in the web, it should include the ID from XML to each item NOME in the ComboBox.
I new to Flex, so probably didn't expressed things the right way.
Any help is appreciated. Thanks.

You don't need this line:
pais.data = "id";
change the label to
<mx:Label x="121" y="403" text="{pais.selectedItem.id}"/>
EDIT: The code can be simplified to
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
width="355" height="465" creationComplete="getPaises.send();"
xmlns:ns1="com.*" title="Perfil" fontWeight="normal">
<mx:HTTPService id="getPaises" url="com-handler/paises.php" resultFormat="e4x"/>
<mx:ComboBox x="121" y="328" width="200" id="pais" labelField="nome"
dataProvider="{XML(getPaises.lastResult).pais}"/>
</mx:TitleWindow>
Edited the data provider. Thanks

Related

mxml null reference

I have an example custom mxml component CustomRadio
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:RadioButton id="radio" />
<mx:Script>
public override function set label(value:String):void {
this.radio.label = value;
}
public override function get label():String {
return this.radio.label;
}
</mx:Script>
</mx:VBox>
and an application
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*">
<local:CustomRadio label="xxx" />
</mx:WindowedApplication>
And I get Null reference arror in set label saying this.radio is null. Why ?
The RadioButton tag needs to encompass the Script tag. The way you have it now, the script tag is part of the VBox only. Since you are using the 'this' pointer, it's referring to the VBox.

How to take screenshots of a Flex Spark VideoDisplay?

I want to build a component, where the user can play a video in a Flex Spark VideoDisplay. There will be a button and whenever the button is pressed, I want to save the current time of the VideoDisplay plus a screenshot. The screenshot needs to be someway saved, because I want to display all times and screenshots in a DataGrid (screenshots should appear when the user hovers a time in the DataGrid).
So, how can I take screenshots of the Spark VideoDisplay and save/display them?
You can take snapshots a few ways, this way just uses the ImageSnapshot class, but you could do it by manually drawing the bitmap of the video display if you'd like. Here's a sample:
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"
width="100" height="100" creationComplete="trace(data)">
<mx:Image source="{this.data}" width="100%" height="100%"/>
</s:ItemRenderer>
Sample App
<?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">
<fx:Script>
<![CDATA[
import mx.graphics.ImageSnapshot;
public function takeSnapshot():void
{
var snapshot:BitmapData = ImageSnapshot.captureBitmapData(videoDisplay);
var bitmap:Bitmap = new Bitmap(snapshot);
list.dataProvider.addItem(bitmap);
}
]]>
</fx:Script>
<s:layout>
<s:VerticalLayout horizontalAlign="center"/>
</s:layout>
<s:VideoDisplay id="videoDisplay"
source="video.mov"
width="400" height="300"/>
<s:Button id="button" click="takeSnapshot()"/>
<s:List id="list" horizontalCenter="0" width="100%" itemRenderer="SnapshotRenderer">
<s:dataProvider>
<mx:ArrayList/>
</s:dataProvider>
<s:layout>
<s:TileLayout/>
</s:layout>
</s:List>
</s:Application>
To accomplish exactly what you were describing (take snapshot and save snapshot), you could store those in an array in that takeSnapshot method, or you could loop through the list.dataProvider do get the bitmaps. Then you'd just need to pass them to a backend language (ruby, python, php...) to save.
Hope that helps,
Lance
use the JPEGEncoder in flex to convert it to bytearray, and then encode the byte array using the b64encoder as follow:
var jpg:JPEGEncoder = new JPEGEncoder();
var ba:ByteArray = jpg.encode(bitmapData);
var b64encoder:Base64Encoder = new Base64Encoder();
b64encoder.encodeBytes(ba);
var b64String:String = b64encoder.flush();
Now you can pass your b64String to your server via HTTP post method :)

Setting up content children for custom mxml component

I am trying to develop a custom component to act as a divider.
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Canvas id="left"/>
<mx:Canvas id="right"/>
</mx:HBox>
I would like to use this component to assign objects like this:
<Divider>
<left>
<mx:label text="Stuff I want to put in the left canvas"/>
<mx:label text="etc..."/>
<mx:label text="etc..."/>
</left>
<right>
<mx:label text="Stuff I want to put in the right canvas"/>
<mx:label text="etc..."/>
<mx:label text="etc..."/>
</right >
</Divider>
Unfortunately, this does not work. I get a compiler error saying :
In initializer for 'left': multiple initializer values for target type mx.containers.Canvas.
What am I missing ?
I ended up finding the solution reading the following from the Adobe website.
Using the technique described as template component, you can specify an array of a certain type of objects. I ended up rewriting my component as follow:
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" initialize="init()">
<mx:Script>
<![CDATA[
[ArrayElementType("mx.core.UIComponent")]
public var right:Array;
[ArrayElementType("mx.core.UIComponent")]
public var left:Array;
protected function init():void
{
var i:int;
for (i = 0; i < left.length; i++)
leftCanvas.addChild(left[i]);
for (i = 0; i < right.length; i++)
rightCanvas.addChild(right[i]);
}
]]>
</mx:Script>
<mx:Canvas id="rightCanvas"/>
<mx:Canvas id="leftCanvas"/>
</mx:HBox>
It now works as intended.

Image as Label with Checkbox in Flex

I want to use an image in my checkbox as label, anybody know how ?
When I tried doing the same thing with a RadioButton a while back, I ended up having to create my own component. This is what I did:
IconRadioButton.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.controls.RadioButtonGroup;
[Bindable]
public var imgLabel:Class;
[Bindable]
public var groupName:RadioButtonGroup;
[Bindable]
public var selected:Boolean;
[Bindable]
public var value:String;
]]>
</mx:Script>
<mx:RadioButton
id="radioBtn"
group="{groupName}"
groupName="{groupName}"
selected="{selected}"
label=""
value="{value}"
visible="{visible}"
includeInLayout="{includeInLayout}" />
<mx:Image source="{imgLabel}" click="{radioBtn.selected = true}" />
</mx:HBox>
Then you could use it like this:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:controls="com.example.controls.*">
<controls:IconRadioButton
groupName="{group}"
imgLabel="{AssetsFactory.getInstance().iconCCVisa}"
value="{CreditCardTypes.VISA}" />
...
Hope that maybe gets you started or gives you some ideas.
To use image as label, use the following code.
<mx:HBox width="100%">
<mx:RadioButton groupName="Yield"/>
<mx:Image source="#Embed('/scripts/btn_highest.png')"/>
</mx:HBox>

DataGrid itemrender

Hi i have added a control with the help itemrender in my datagrid. but there is a problem that
in time of execution it comes two times at init and creation complete event of that control
which i added in my datagrid column.
Thanks
Atul Yadav
<?xml version="1.0" encoding="utf-8"?>
<mx:DataGridColumn xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:ns1="Component.*" >
<mx:Script>
<![CDATA[
[Bindable]
public var columnID:String="";
[Bindable]
public var ColumnData:String="";
]]>
</mx:Script>
<mx:itemRenderer>
<mx:Component>
<ns1:test >
</ns1:test>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
and my control code:
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="300" xmlns:ns1="View.*" creationComplete="init(event)">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
private static var arr:Array;
private function init(e:Event):void{
if(!arr)
arr=new Array();
arr.push(this);
btn_apply.addEventListener(MouseEvent.CLICK,function(e:Event):void{Alert.show(arr.length.toString());});
}
]]>
</mx:Script>
<mx:Button label="Button" id="btn_apply"/>
</mx:VBox>
when i get arr length it gives me just double count.
If I understand correctly the second code snippet is your custom item renderer that is instantiated as <ns1:test> in the first snippet.
The DataGrid control will create instances of your renderer as and when it sees fit - you don't really have any control of how many instances will get created. So while you may have one row in the column the Data Grid is quite likely to have created more than one instance of the renderer component. The result, as you can see, is that creation complete is called more than once and you are getting more items in your static array than you are expecting. When developing item renderers you have to take into account that: you don't control their instantiation and that they are recycled by the framework. The best approach to take is to make them as stateless as possible.

Resources