I need to get all the properties of flex charts by using/calling the respective chart.
Example For Flex Area Chart we have xField,yField and minField.
Is there any way to get these properties from each chart through any methods.
There are no methods on the charts that will do this. If you want to find out the properties of the chart and their series, you will need to do this via reflection.
You can use the global describeType() method on any object for this. This will return you an XML object containing all properties of the object.
There is also an API on top of describeType that allows for easier access and introspection of objects: AS3Commons Reflect
Maybe this code will be useful, is an example for view all information of the ChartBase object:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" minWidth="955" minHeight="600" creationComplete="init()">
<mx:Script>
<![CDATA[
import mx.charts.chartClasses.ChartBase;
public function init():void{
getInfo(new ChartBase());
}
private function getInfo(obj:Object):void{
txt1.text = describeType(obj);
var myXML:XMLList = new XMLList(describeType(obj));
var info:String = "";
for each(var node:XML in myXML.children()){
switch(node.name().toString())
{
case "variable":
{
info = info + "var - " + node.#name + "\n"; //properties
break;
}
case "accessor":
{
info = info + "accessor - " + node.#name + "\n"; //getter-setter
break;
}
case "method":
{
info = info + "method - " + node.#name + "\n"; //methods
break;
}
}
txt2.text = info;
}
}
]]>
</mx:Script>
<mx:Label text="View Information of 'ChartBase' Object"/>
<mx:HBox width="100%">
<mx:HBox width="50%">
<mx:VBox width="100%" height="100%">
<mx:Label text="All Object Information"/>
<mx:TextArea id="txt1" width="800" height="800"/>
</mx:VBox>
</mx:HBox>
<mx:HBox width="50%">
<mx:VBox width="100%" height="100%">
<mx:Label text="Properties,Accessor and Methods from this Object"/>
<mx:TextArea id="txt2" width="800" height="800"/>
</mx:VBox>
</mx:HBox>
</mx:HBox>
</mx:Application>
Basically the method describeType returns a XML with the object information.
Adobe reference
Performing object introspection
Here you can run a SWF with this code LINK.
Related
So I have a requirement to display dynamically generated data in the view.
For this, my idea was to create a mxml file and then use it as an object. Fill the data in the ibject and then use addChild to display it. But even after adding all the data. The dynamically generated mxml file doesn't gets displayed.
Code
BuyTogetherGrid.MXML
<?xml version="1.0" encoding="utf-8"?>
<mx:Box xmlns:mx="http://www.adobe.com/2006/mxml" width="80" height="60" xmlns:image="org.commodity.detail.image.*">
<mx:HBox>
<image:ImageBox id="buyTogetherImg"></image:ImageBox>
<mx:VBox id="textInfo">
<mx:Box id="commonNameBox">
<mx:Label id="commonName">
</mx:Label>
</mx:Box>
<mx:Box id="commonPriceBox">
<mx:Label id="commonPrice">
</mx:Label>
</mx:Box>
</mx:VBox>
</mx:HBox>
<mx:Script>
<![CDATA[
public function createGrid():void{
this.buyTogetherImg = new ImageBox();
this.commonName = new Label();
this.commonPrice = new Label();
}
]]>
</mx:Script>
</mx:Box>
This is my MXMl File. My idea was to create an object of this mxml object. Add data to buyTogetherImg, CommonName, CommonPrice and then use addChild
Part where I set the data
<mx:HBox id="buyTogetherBox" width="100%" borderColor="black">
</mx:HBox>
The upper HBox is the container where I will keep all my generated object
var buyTogetherBox : BuyTogetherGrid = new BuyTogetherGrid();
buyTogetherBox.createGrid();
for each(var item:cmListItem in commod.items){
if(item.dataFormat == 2){
buyTogetherBox.buyTogetherImg.imgData = item.value as ImageData;
} else if(item.dataFormat == 0){
buyTogetherBox.commonName.text = item.value.toString();
} else if(item.dataFormat == 3){
buyTogetherBox.commonPrice.text = StringUtil.numToStrPrice(item.value as Number);
}
}
this.buyTogetherBox.addChild(buyTogetherBox);
}
The code check some conditions and add the data. However the buyTogetherBox is not visible. But if I try something like
this.buyTogetherBox.addChild(buyTogetherBox.buyTogetherImg);
then i can see the image in the H:Box.
I am pretty new to Flex. so may be I would have missed something
You are leaving the statically created instances of the label and image control unused and creating new instances instead. Basically, the entire createGrid() function is unnecessary. You already have the controls created in MXML. Just use them with creating new instances.
var grid:BuyTogetherGrid = new BuyTogetherGrid();
grid.addEventListener(FlexEvent.CREATION_COMPLETE, this.grid_creationCompleteHandler);
Elsewhere in the same class...
private function grid_creationCompleteHandler(event:FlexEvent):void
{
// Set your properties here
}
As Pranav said it takes some time to create MXML components and if you try to assess them immediately you will get a null pointer exception because they don't exist yet. A quick and dirty solution is to make public variables in your BuyTogetherGrid.MXML and then bind the text properties to these variables, like
<?xml version="1.0" encoding="utf-8"?>
<mx:Box xmlns:mx="http://www.adobe.com/2006/mxml" width="80" height="60" xmlns:image="org.commodity.detail.image.*">
<fx:Script>
<![CDATA[
[Bindable] public var imageData:ImageData;
[Bindable] public var name:String;
[Bindable] public var price:String;
]]>
</fx:Script>
<mx:HBox>
<image:ImageBox id="buyTogetherImg" imgData={imageData}/>
<mx:VBox id="textInfo">
<mx:Box id="commonNameBox">
<mx:Label id="commonName" text="{name}">
</mx:Label>
</mx:Box>
<mx:Box id="commonPriceBox">
<mx:Label id="commonPrice" text="{price}">
</mx:Label>
</mx:Box>
</mx:VBox>
and then you do
buyTogetherBox.imageData = yourImageData;
buyTogetherBox.name = "Your Name";
buyTogetherBox.imageData = "Your price";
and yes, remove the unnecessary createGrid() method
I have a spark list with custom Itemrenderer.
I use virtuallayout , because I'm binding it with about 500 elements.
I traced the datachange event of the item renderer and I've seen that about 120 items are binded to the list on the first load.
I need to show only 10 items on the stage, so I want to decrease the number of items fetched in the list, is there a property or a function to override to obtain this behaviour?
The code is so simple
<s:List id="thumbnailList" verticalScrollPolicy="off"
useVirtualLayout="true" itemRenderer="ThumbnailItemRenderer" >
<s:layout>
<s:HorizontalLayout gap="10" requestedColumnCount="10" />
</s:layout>
</s:List>
The item renderer
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
autoDrawBackground="false" >
<fx:Script>
override public function set data(value:Object):void{
super.data=value;
if(data !=null){
LoadImg();
}
}
protected function LoadImg():void{
trace(data.pagnum.toString());
var cacheDir:File=null;
cacheDir= Config.DirCache();
var folder:File = new File(cacheDir.nativePath + Config.CATALOG_FOLDER_NAME + Config.selected_catalog_id + "/");
var file:File = new File(folder.nativePath + "/" + data.pagnum.toString() + "_th.jpg");
trace(file.url);
thumbnail.source = file.url;
cacheDir=null;
folder=null;
file=null;
}
</fx:Script>
<s:Image id="thumbnail" top="0" left="0" right="0" bottom="0" scaleMode="letterbox" cacheAsBitmap="true" />
</s:ItemRenderer>
and the binding of the list
thumbnailList.dataProvider= {ArrayCollection with about 480 items}
How to ask user confirmation before highlighting/navigating to another panel/page?
I have few panels in my screen. Each panel has many controls. I would like to prompt a message box(or alert) with Ok and Cancel buttons, and take confirmation whenever user clicks on another panel.
If user clicks on "Ok" button then navigate to another panel/page.
If user clicks on "Cancel" button then remove the alert and focus to the same Panel.
Currently I have implemented this using panel's focus_out event(focusOutHandler(event:FocusEvent)). I click on the button which is in the another panel, now I got alert, but when i clicked on "OK" in the alert , nothing is happening(button click is event is not fired)
Thanks in advance
From the sounds of it you want to react depending on which button on the alert is clicked?
If that is the case, use the in-built close handler in the Alert class.
The Alert class has a static method show, with the following signature:
public static function show(text:String = "", title:String = "", flags:uint = 0x4, parent:Sprite = null, closeHandler:Function = null, iconClass:Class = null, defaultButtonFlag:uint = 0x4, moduleFactory:IFlexModuleFactory = null):Alert
By adding two flags with the pipe operator in the flags argument
Alert.OK || Alert.CANCEL and then adding your close handler in the closeHandler argument, you can inspect which button was clicked and react accordingly.
Something like this:
Alert:
Alert.show("Alert Title","Would you like to proceed?",Alert.OK || Alert.CANCEL,this,onClose)
onClose Function:
private function onClose(event:CloseEvent)
{
if (eventObj.detail==Alert.OK)
{
//proceed
}
else
{
//cancel operation
}
}
As per your comment on James post here i am posting sample, not sure if you are looking for the same: - Hope below code may give you some idea.
<?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:Declarations>
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.CloseEvent;
private var storeNextFocusID:String = "first";
private var storePreviousFocusID:String = "first";
private function firstFocus():void
{
first.setFocus();
storePreviousFocusID = first.name;
}
private function showFirstTimeAlert(event:MouseEvent):void
{
if(event.currentTarget.name != storePreviousFocusID)
{
Alert.show("Do you want to change Tab?","Alert",Alert.OK|Alert.CANCEL,null,closeHandler)
storeNextFocusID = event.currentTarget.name;
}
}
private function closeHandler(event:CloseEvent):void
{
if(event.detail == Alert.OK)
{
var focusCont:HGroup = mainContainer.getChildByName(storeNextFocusID) as HGroup;
focusCont.setFocus();
storePreviousFocusID = storeNextFocusID;
} else
{
}
}
]]>
</fx:Script>
<s:VGroup id="mainContainer" x="50" y="50" width="400" height="300" creationComplete="firstFocus()">
<s:HGroup id="first" name="first" width="100%" height="100%" click="showFirstTimeAlert(event)">
<mx:TabNavigator width="100%" height="100%">
<mx:VBox label="left">
<mx:Label text="labelPlacement = 'left'" />
</mx:VBox>
<mx:VBox label="right">
<mx:Label text="labelPlacement = 'right'" />
</mx:VBox>
</mx:TabNavigator>
<s:Panel width="100%" height="100%">
</s:Panel>
</s:HGroup>
<s:HGroup id="second" name="second" width="100%" height="100%" click="showFirstTimeAlert(event)">
<mx:TabNavigator width="100%" height="100%">
<mx:VBox label="top">
<mx:Label text="labelPlacement = 'top'" />
</mx:VBox>
<mx:VBox label="bottom">
<mx:Label text="labelPlacement = 'bottom'" />
</mx:VBox>
</mx:TabNavigator>
<s:Panel width="100%" height="100%">
</s:Panel>
</s:HGroup>
</s:VGroup>
</s:Application>
This is a basic security app and i just want to encrypt & decry-pt some data now my problem is after displaying the cyber text in text box and getting back that text then after converting it into a byte array and while decryption i am getting the error
Error: ECB mode cipher length must be a multiple of blocksize 16
at com.hurlant.crypto.symmetric::ECBMode/decrypt()
this is security.mxml
<?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:Declarations>
<fx:Script>
<![CDATA[
import com.hurlant.crypto.Crypto;
import com.hurlant.crypto.prng.Random;
import com.hurlant.crypto.symmetric.ICipher;
import com.hurlant.util.Base64;
import com.hurlant.util.Hex;
import com.security.AesKeyGen;
import com.security.EncryptionKeyGen;
import mx.utils.Base64Decoder;
public var mytest:String;
private var kdata:ByteArray = new ByteArray();
private var cleartextBytes:ByteArray = new ByteArray();
private function encryptedSave():void
{
//create or retrieve the current shared object
var so:SharedObject = SharedObject.getLocal("encryptedStore");
//generate a random key
var ec:EncryptionKeyGen = new EncryptionKeyGen();
kdata=//some plaine text converted to byte array or some byte array
trace(kdata);
//store our data to encrypt into a ByteArray
cleartextBytes.writeUTFBytes(plainText.text);
var aes:ICipher = Crypto.getCipher("aes-ecb", kdata, Crypto.getPad("pkcs5"));
aes.encrypt(cleartextBytes);
trace("after Encription-------------"+cleartextBytes.length+cleartextBytes);
}
private function encryptedLoad():void
{cleartextBytes=new ByteArray();
cleartextBytes.writeUTFBytes(cyperText.text);
trace(cleartextBytes +"-------------"+cleartextBytes.length);
var aes:ICipher = Crypto.getCipher("aes-ecb", kdata, Crypto.getPad("pkcs5"));
aes.decrypt(cleartextBytes);
}
]]>
</fx:Script>
<mx:Panel width="600" height="400" title="FlexEncryptionExample1">
<mx:Form width="100%">
<mx:FormHeading label="Stored WebService credentials"/>
<mx:FormItem label="User: " width="100%">
<mx:TextInput id="plainText" width="100%"/>
</mx:FormItem>
<mx:FormItem label="CyperText: " width="100%">
<mx:TextInput id="cyperText" width="100%"/>
</mx:FormItem>
<mx:FormItem label="plainText2: " width="100%">
<mx:TextInput id="plainText2" width="100%"/>
</mx:FormItem>
<s:Label text="" id="encryptedText" visible="false"/>
</mx:Form>
<mx:HBox width="100%" horizontalAlign="center" verticalAlign="bottom">
<mx:Button label="Save" click="encryptedSave()"/>
<mx:Button label="Load" click="encryptedLoad()"/>
</mx:HBox>
</mx:Panel>
</s:Application>
Anybody please can help me Thank you.....
After Aes Encryption while converting into string i added following code and finally all the things went correct.........
aes.encrypt(cleartextBytes);
trace("after Encription-------------"+cleartextBytes.length+cleartextBytes);
cleartextBytes.position=0;
var myEncoder:Base64Encoder = new Base64Encoder();
myEncoder.encodeBytes(cleartextBytes);
cyperText.text=myEncoder.toString();
trace("Encoded string length"+cyperText.text.length);
I am new in Flex. I want to display data in attached grid format. I found best way to display in DataGrid. But the CIs column has multiple entries so because of that other columns will duplicate. I want to avoid duplicate data in other columns. Attached screenshot is of excel, i want to achieve same format in Flex. I am using Flex 4.5
Best way I see to do what you want is to create a custom item renderer for the CLS column and have it render as a list control. That way, the CLS item in each row will only take up one row instead of multiple rows.
You can get some idea by following code... you can build logic using below concept for your implementation. Below example is sample not complete according to your requirement: -
<?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:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.core.UIComponent;
import mx.events.AdvancedDataGridEvent;
import mx.events.ListEvent;
[Bindable]
private var dpHierarchy:ArrayCollection= new ArrayCollection
([
{name:"Barbara Jennings", address: "Arizona", contact:999970, orders:["1"]},
{name:"Dana Binn", address: "Arizona", contact:9999130, orders:["2"]},
{name:"Joe Smith", address: "California", contact:9992929, orders:["3"]},
{name:"Alice Treu", address: "California", contact:9999230, orders:["4"]}
]);
private function addOrder():void
{
for(var i:int = 0 ; i < dpHierarchy.length; i++)
{
if(dropDownID.selectedItem.name == dpHierarchy[i].name)
{
var itemUpdated:Array = dpHierarchy[i].orders;
itemUpdated.push(orderNumber.text);
dpHierarchy[i].orders = itemUpdated;
dpHierarchy.itemUpdated(dpHierarchy[i]);
break;
}
}
}
]]>
</fx:Script>
<mx:VBox x="30" y="30" width="450" height="400">
<s:HGroup>
<s:Button label="Add Order" click="addOrder()"/>
<s:DropDownList id="dropDownID" dataProvider="{dpHierarchy}" labelField="name" selectedIndex="0"/>
<s:TextInput id="orderNumber" width="100"/>
</s:HGroup>
<mx:AdvancedDataGrid id="myADG"
dataProvider="{dpHierarchy}"
variableRowHeight="true" wordWrap="true">
<mx:columns>
<mx:AdvancedDataGridColumn dataField="name" headerText="Name"/>
<mx:AdvancedDataGridColumn dataField="address" headerText="Address"/>
<mx:AdvancedDataGridColumn dataField="contact" headerText="Contact"/>
<mx:AdvancedDataGridColumn dataField="orders" headerText="Orders" itemRenderer="OrderItemRenderer"/>
</mx:columns>
</mx:AdvancedDataGrid>
</mx:VBox>
</s:Application>
Item Reenderer Name: - OrderItemRenderer
<?xml version="1.0" encoding="utf-8"?>
<s:MXAdvancedDataGridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
focusEnabled="true" width="90%" height="90%">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
private var initDG:ArrayCollection = new ArrayCollection();
override public function set data(value:Object):void
{
super.data = value;
initDG = new ArrayCollection(value.orders)
}
]]>
</fx:Script>
<mx:DataGrid id="dataGrid" dataProvider="{initDG}" headerHeight="0" rowCount="{initDG.length}"/>
</s:MXAdvancedDataGridItemRenderer>