Flex Android application suspends when using jpeg image - sqlite

I have a flex application in which I have to convert a jpeg picture taken by camera using base64 converter and then upload the result to sqlite database (as MEDIUMBLOB). The code looks like this:
MXML declarations of images:
<s:Group width="480" height="304">
<s:Label x="0" y="0" width="100%" height="34" backgroundColor="#4D4D4D"
color="#FFFFFF" fontSize="30" text=" Select photo" verticalAlign="middle"/>
<s:Image id="image" x="10" y="42" width="217" height="246" />
<s:Image id="image2" x="10" y="42" width="217" height="246" source = "#Embed(source='skins/PhotoNotAvailable.jpg')"/>
<s:Button x="235" y="42" width="235" height="84" label="Take a Picture"
click="captureImage(event)" enabled="{CameraUI.isSupported}" fontSize="30"/>
<s:Button x="235" y="150" width="235" height="70" label="Delete"
click="deletePhoto(event)" fontSize="30"/>
</s:Group>
Scripts for taking a picture and convertion:
//Taking the pictures
protected function application1_applicationCompleteHandler(event:FlexEvent):void {
image.setVisible(true);
image2.setVisible(false);
if (CameraUI.isSupported){
var mediaPromise:MediaPromise;
camera = new CameraUI();
camera.addEventListener(MediaEvent.COMPLETE, onComplete);
camera.addEventListener(ErrorEvent.ERROR, onError);
} else {
}
}
protected function view1_activateHandler(event:Event):void
{
conn = data as SQLConnection;
}
private function captureImage(event:MouseEvent):void {
camera.launch(MediaType.IMAGE);
}
private function onError(event:ErrorEvent):void {
trace("error has occurred");
}
private function onComplete(event:MediaEvent):void {
var mediaPromise:MediaPromise = event.data;
image.source = mediaPromise.file.url;
pictureTaken = true;
}
//Convertion and uploading to database
protected function AddHandler(event:MouseEvent):void
//irrelevant code skipped
insertStmt = new SQLStatement();
insertStmt.sqlConnection = conn;
var insertSQL:String = ("INSERT INTO RecipeDB (RecipeID, Name, Category, Origin, Recipe, Favorite, Image)" + "VALUES (:RecipeID, :Name, :Category, :Origin, :Recipe, :Favorite, :Image)");
insertStmt.text = insertSQL;
if(pictureTaken)
{
var jencoder:JPEGEncoder = new JPEGEncoder(75);
var imageByteArray:ByteArray = jencoder.encode(image.bitmapData);
var baseEncoder:Base64Encoder = new Base64Encoder();
baseEncoder.encodeBytes(imageByteArray);
encodedBytes = baseEncoder.toString();
}
else
{
var jencoder:JPEGEncoder = new JPEGEncoder(75);
var imageByteArray:ByteArray = jencoder.encode(image2.bitmapData);
var baseEncoder:Base64Encoder = new Base64Encoder();
baseEncoder.encodeBytes(imageByteArray);
encodedBytes = baseEncoder.toString();
}
insertStmt.parameters[":RecipeID"] = ID as int;
insertStmt.parameters[":Name"] = NameArea.text;
insertStmt.parameters[":Category"] = TypeArea.text;
insertStmt.parameters[":Origin"] = OriginArea.text;
insertStmt.parameters[":Recipe"] = RecipeArea.text;
insertStmt.parameters[":Favorite"] = 0 as int;
insertStmt.parameters[":Image"] = encodedBytes;
insertStmt.execute();
}
//Deleting photo
protected function deletePhoto(event:MouseEvent):void
{
pictureTaken = false;
image.setVisible(false);
image2.setVisible(true);
}
Now, if no picture was taken, the program uploads skins/PhotoNotAvailable.jpg to the DB correctly, but if the picture was taken or taken and deleted, the program hangs (android asks if to close it or wait). I have checked the size of taken pictures and it does not exceed MEDIUMBLOB`s size (picture has ca. 2 MBytes). What could be wrong?

My first thought from your description of what happens is "a breakpoint." The only time my phone gives me that message is when I'm debugging and it's stopped on a break point for too long.
You might cast your event.data as MediaPromise
private function onComplete(event:MediaEvent):void {
var mediaPromise:MediaPromise = event.data as MediaPromise;
image.source = mediaPromise.file.url;
pictureTaken = true;
}
Though that may just be a copying error.
So far as I can tell you don't need to base64 encode the image data. It's already encoded and ready to be inserted into a database. Perhaps "double-encoding" is somehow creating a problem. ???
I would change
if(pictureTaken)
{
var jencoder:JPEGEncoder = new JPEGEncoder(75);
var imageByteArray:ByteArray = jencoder.encode(image.bitmapData);
var baseEncoder:Base64Encoder = new Base64Encoder();
baseEncoder.encodeBytes(imageByteArray);
encodedBytes = baseEncoder.toString();
}
else
{
var jencoder:JPEGEncoder = new JPEGEncoder(75);
var imageByteArray:ByteArray = jencoder.encode(image2.bitmapData);
var baseEncoder:Base64Encoder = new Base64Encoder();
baseEncoder.encodeBytes(imageByteArray);
encodedBytes = baseEncoder.toString();
}
insertStmt.parameters[":RecipeID"] = ID as int;
insertStmt.parameters[":Name"] = NameArea.text;
insertStmt.parameters[":Category"] = TypeArea.text;
insertStmt.parameters[":Origin"] = OriginArea.text;
insertStmt.parameters[":Recipe"] = RecipeArea.text;
insertStmt.parameters[":Favorite"] = 0 as int;
insertStmt.parameters[":Image"] = encodedBytes;
insertStmt.execute();
to
var jencoder:JPEGEncoder = new JPEGEncoder(75);
var imageByteArray:ByteArray;
if(pictureTaken)
{
imageByteArray = jencoder.encode(image.bitmapData);
}
else
{
imageByteArray = jencoder.encode(image2.bitmapData);
}
insertStmt.parameters[":RecipeID"] = ID as int;
insertStmt.parameters[":Name"] = NameArea.text;
insertStmt.parameters[":Category"] = TypeArea.text;
insertStmt.parameters[":Origin"] = OriginArea.text;
insertStmt.parameters[":Recipe"] = RecipeArea.text;
insertStmt.parameters[":Favorite"] = 0 as int;
insertStmt.parameters[":Image"] = imageByteArray;
insertStmt.execute();
If for some reason you still want the base64 encoding and it's not creating the problem, I would still suggest refactoring the code like this to save duplication since the only thing that varies between the two if branches is the source of the bitmap data.
var jencoder:JPEGEncoder = new JPEGEncoder(75);
var imageByteArray:ByteArray;
if(pictureTaken)
{
imageByteArray = jencoder.encode(image.bitmapData);
}
else
{
imageByteArray = jencoder.encode(image2.bitmapData);
}
var baseEncoder:Base64Encoder = new Base64Encoder();
baseEncoder.encodeBytes(imageByteArray);
encodedBytes = baseEncoder.toString();
However, this is just a first stab at it. It would be useful to see the code all together. I'm assuming that encodedBytes is a String available to the whole class? I can't see how/when AddHandler is invoked, so I also can't tell variable states when it is called (which could be related to the problem). It would also be useful to know what's happening after the AddHandler is completed. Perhaps it's an error occurring after the insert statement that is hanging up?
Did you debug it and get any errors to share?
I know the post is a month old, so maybe you already figured it out. Maybe you could share it so others don't make the same mistake. Either way, I hope this can help someone.

Related

newbie: flex netstream how to get my code stream and receive netstreams correctly?

I have problems getting my flex code to work, below is my code I try to netstream a webcam and receive it and use 2 functions for that. Any flex guru can help me fix these functions?
function onNetConnectionPublish():void {
StatusMessage("onNetConnectionPublish called");
ncNetStream = new NetStream(nc, NetStream.DIRECT_CONNECTIONS);
ncNetStream.addEventListener(NetStatusEvent.NET_STATUS, sendNetStreamHandler);
ncNetStream.publish("media");
ncNetStream.attachAudio(Microphone.getMicrophone());
ncNetStream.attachCamera(Camera.getCamera());
}
and:
function connectToRemote(remoteId:String) {
StatusMessage("connectToRemote(" + remoteId + ")");
ncNetStream = new NetStream(nc, remoteId);
ncNetStream.addEventListener(NetStatusEvent.NET_STATUS, receiveNetStreamHandler);
ncNetStream.play("media");
}
display video:
The Publisher Application:
private function Publisher():void{
var camera1:Camera = Camera.getCamera();
var video:Video = new Video(285, 254);
if (camera1)
{
video.attachCamera(camera1);
VideoDisplay1.addChild(video);
camera1.addEventListener(ActivityEvent.ACTIVITY, camera_activity);
camera1.addEventListener(StatusEvent.STATUS, camera_status);
}
var nc:NetConnection = new NetConnection();
nc.connect("rtmp://your/stream/url");
nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
function netStatusHandler(event:NetStatusEvent):void {
switch (event.info.code) {
case "NetConnection.Connect.Success":
var ns:NetStream = new NetStream(nc,NetStream.CONNECT_TO_FMS);
ns.attachCamera(camera1);
ns.publish("videofeed", "live");
break;
case "NetStream.Play.StreamNotFound":
trace("Unable to locate video: ");
break;
}
}
}
The Reciever Application :
import mx.utils.ObjectUtil;
private var nc:NetConnection;
private var ns:NetStream;
private var video:Video;
private var meta:Object;
private function init():void {
var nsClient:Object = {};
nsClient.onMetaData = ns_onMetaData;
nsClient.onCuePoint = ns_onCuePoint;
nc = new NetConnection();
nc.connect(null);
ns = new NetStream(nc);
ns.play("http://www.helpexamples.com/flash/video/cuepoints.flv");
ns.client = nsClient;
video = new Video();
video.attachNetStream(ns);
uic.addChild(video);
}
private function ns_onMetaData(item:Object):void {
trace("meta");
meta = item;
// Resize Video object to same size as meta data.
video.width = item.width;
video.height = item.height;
// Resize UIComponent to same size as Video object.
uic.width = video.width;
uic.height = video.height;
panel.title = "framerate: " + item.framerate;
panel.visible = true;
trace(ObjectUtil.toString(item));
}
private function ns_onCuePoint(item:Object):void {
trace("cue");
}
Reciever mxml code :
<mx:Panel id="panel" visible="false">
<mx:UIComponent id="uic" />
<mx:ControlBar>
<mx:Button label="Play/Pause" click="ns.togglePause();" />
<mx:Button label="Rewind" click="ns.seek(0); ns.pause();" />
</mx:ControlBar>
</mx:Panel>

Flex 3: Setting one arrayCollection to another is stalling the application

I'll just go ahead and C/P the entire function to ensure you guys see everything going on:
public function directorsPrepsToShow():void
{
var tempDPrepsAC:ArrayCollection = new ArrayCollection;
var dprepSD:Date = new Date;
var dprepED:Date = new Date;
var viewSD:Date = rightDate(startViewDate.getMonth(), startViewDate.getDate(), startViewDate.getFullYear());
var viewED:Date = rightDate(viewSD.getMonth(), viewSD.getDate() + 14, viewSD.getFullYear());
var newACIDs:String = new String;
var useACIDs:String = new String;
for each (var item:Object in dPrepAC)
{
dprepSD = textToDate(item[2]);
dprepED = rightDate(dprepSD.getMonth(), Number(dprepSD.getDate() + (item[3] - 1)), dprepSD.getFullYear());
if (dateCollider(dprepSD, dprepED, viewSD, viewED))
tempDPrepsAC.addItem(item as Array);
}
if (tempDPrepsAC.length != usePrepAC.length)
{
usePrepAC = new ArrayCollection();
usePrepAC = tempDPrepsAC;
Alert.show("HI");
}
}
This function is in a separate file, that's called from the main mxml via the following:
<mx:Script source="functions/dprep.as" />
The line that's causing the app to stall is "usePrepAC = tempDPrepAC;". usePrepAC is declared in the main mxml like this:
[Bindable] public var usePrepAC:ArrayCollection = new ArrayCollection;
Dose anybody see why this one line would cause the application to stall? If I comment out that line, the application loads fine (loads everything except for the information that this AC should contain). I've been looking at this now for about an hour, trying different ways to get the contents of tempDPrepsAC into usePrepAC - but nothing is working. I tried googling it, but found nothing :(
Thanks,
Brds
EDIT
dprep AC is declared in the main mxml like this:
[Bindable] public var dPrepAC:ArrayCollection = new ArrayCollection;
And the function that populates it is as follows:
public function createDirectorsPrepCollection(e:ResultEvent):void
{
var xmlList:XMLList = XML(e.result).directorsprep;
var dupString:String = "|";
var tempArray:Array = new Array;
for (var i:int = 0; i < xmlList.length(); i++)
{
if (dupString.indexOf(String("|" + xmlList[i].name.#id) + "|") == -1)
{
tempArray = new Array;
tempArray[0] = xmlList[i].prepDBID;
tempArray[1] = xmlList[i].projectDBID;
tempArray[2] = xmlList[i].startdate;
tempArray[3] = xmlList[i].numdays;
tempArray[4] = xmlList[i].positions;
dPrepAC.addItem(tempArray);
dupString += "|" + xmlList[i].prepDBID + "|";
}
}
directorsPrepsToShow();
}
This function is called by this:
<mx:HTTPService id="dprepHttp" url="{dprepXML}" resultFormat="e4x" makeObjectsBindable="true" result="createDirectorsPrepCollection(event)" />
dPrepAC is populating fine btw... I check it in a for each loop.
Try using following code:
usePrepAC.source = tempDPrepsAC.source;

How to read the Dynamic form Child data in Flex?

i created a form dynamically by adding each component in action script,
now i want to get back the text/data entered in to that each component dynamically?
private function loadAllComponents():void
{
var formItemArray:Array = new Array();
for(var i:int=0; i< Application.application.designList.length; i++)//which had the colonName, colComponet to be dispalyed,
{
var fm:FormItem = new FormItem();
fm.label = Application.application.designList.getItemAt(i).colName;
var comp:String = Application.application.designList.getItemAt(i).component;
switch(comp)
{
case "TextBox":
var ti:TextInput = new TextInput();
ti.id = Application.application.designList.getItemAt(i).component;
fm.addChild(ti);
break;
case "TextArea":
var ta:TextArea = new TextArea();
ta.id = Application.application.designList.getItemAt(i).colName;
fm.addChild(ta);
break;
case "ComboBox":
var mycb:myComboBox = new myComboBox();
mycb.getAllMasterCBData(Application.application.selectedgridItem, Application.application.designList.getItemAt(i).colName);
fm.addChild(mycb);
break;
case "DateField":
var df:DateField = new DateField();
df.id = Application.application.designList.getItemAt(i).component;
fm.addChild(df);
break;
}
myform.addChild(fm);
}
}
private function saveToDb():void // Here i wan to read all the formdata
{
var formItems:Array = myform.getChildren();
for each (var item:UIComponent in formItems)
{
if (item is TextInput)
{
var text:String = Object(item).text;
Alert.show("came here");
}
else if (item is DateField)
{
var date:Date = DateField(item).selectedDate;
}
}
}
]]>
</mx:Script>
<mx:Form id="myform" cornerRadius="5" borderColor="#B7BABC" borderStyle="solid" width="100%" height="100%" />
<mx:HBox width="100%" height="100%" >
<mx:Spacer width="120"/>
<mx:Button label=" Save " id="saveBtn" click="saveToDb()" />
</mx:HBox>
You're creating the input components in ActionScript, but based on this code you are not creating them dynamically; you're just hard coding them. With your given sample, you'll know the components you are creating at compile time.
You'll need to store a reference to the form items you create; make them public variables instead of 'var' local variables. Kind of like this:
protected var ti:TextInput ;
protected var ta:TextArea ;
protected var df:DateField;
Then in your creation method, do something like this:
ti = new TextInput();
ti.id = Application.application.designList.getItemAt(i).component;
fm.addChild(ti);
ta = new TextArea();
ta.id = Application.application.designList.getItemAt(i).colName;
fm.addChild(ta);
df = new DateField();
df.id = Application.application.designList.getItemAt(i).component;
fm.addChild(df);
myform.addChild(fm);
Then when you need to access them, just do something like this:
private function getMyformData()
{
ti.text;
ta.text;
}
If you're generating the form components at run time based on data, then store then form elements in an array of some sort.
You could also work something out by looping over all children of your container, although that wouldn't be my first approach.
Since poster posted more complete code; here are some additions. I added the protected array of all form items and in each 'switch' block; the new input element is pushed onto the array.
<mx:Script>
protected var itemsArray : Array = new Array();
private function loadAllComponents():void
{
var formItemArray:Array = new Array();
for(var i:int=0; i< Application.application.designList.length; i++)//which had the colonName, colComponet to be dispalyed,
{
var fm:FormItem = new FormItem();
fm.label = Application.application.designList.getItemAt(i).colName;
var comp:String = Application.application.designList.getItemAt(i).component;
switch(comp)
{
case "TextBox":
var ti:TextInput = new TextInput();
ti.id = Application.application.designList.getItemAt(i).component;
fm.addChild(ti);
itemsArray.push(ti)
break;
case "TextArea":
var ta:TextArea = new TextArea();
ta.id = Application.application.designList.getItemAt(i).colName;
fm.addChild(ta);
itemsArray.push(ta)
break;
case "ComboBox":
var mycb:myComboBox = new myComboBox();
mycb.getAllMasterCBData(Application.application.selectedgridItem, Application.application.designList.getItemAt(i).colName);
fm.addChild(mycb);
itemsArray.push(mycb)
break;
case "DateField":
var df:DateField = new DateField();
df.id = Application.application.designList.getItemAt(i).component;
fm.addChild(df);
itemsArray.push(df)
break;
}
myform.addChild(fm);
}
}
The sateToDb method will change to be something like this:
private function saveToDb():void // Here i wan to read all the formdata
{
var formItems:Array = myform.getChildren();
for each (var item:UIComponent in itemsArray )
{
if (item is TextInput)
{
var text:String = Object(item).text;
Alert.show("came here");
}
else if (item is DateField)
{
var date:Date = DateField(item).selectedDate;
}
}
}
]]>
</mx:Script>
Edited Response:
OK, I think I see the issue.
You're adding your data controls to FormItems and adding those to the Form. But then you're iterating over the Form's children and as if they were the data controls and not FormItems.
Without commenting on the rest of the code, have a look at what this updated function is doing to retrieve the data controls:
private function saveToDb():void
{
var formItems:Array = myform.getChildren();
for each (var item:FormItem in formItems)
{
var itemChildren:Array = item.getChildren();
for each (var control:UIComponent in itemChildren)
{
if (control is TextInput)
{
var text:String = Object(item).text;
Alert.show("TextInput");
}
else if (control is DateField)
{
var date:Date = DateField(item).selectedDate;
Alert.show("Date");
}
}
}
You can delete the formItemArray variable too, it's not needed since we're getting the list of children from the Form and FormItems.
Original response:
If you keep a reference to each of the dynamic form items in an Array you can iterate over each of them in your getMyFormData() function.
e.g.
protected var formItems:Array = new Array();
// Other class stuff here...
var ti:TextInput = new TextInput();
ti.id = Application.application.designList.getItemAt(i).component;
formItems.push(ti); // Add item to array.
fm.addChild(ti);
var ta:TextArea = new TextArea();
ta.id = Application.application.designList.getItemAt(i).colName;
formItems.push(ta); // Add item to array.
fm.addChild(ta);
var df:DateField = new DateField();
df.id = Application.application.designList.getItemAt(i).component;
formItems.push(df); // Add item to array.
fm.addChild(df);
myform.addChild(fm);
<mx:button click="getMyformData()"/>
private function getMyformData()
{
//How to get the myform Data dynamically here after validations... ? &
for each (var item:UIComponent in formItems)
{
if (item is TextInput || item is TextArea)
{
// Cast to Object to access the 'text' property without the compiler complaining.
var text:String = Object(item).text;
// Do something with the text...
}
else if (item is DateField)
{
var date:Date = DateField(item).selectedDate;
// Do something with the date...
}
// Insert additional type checks as needed.
}
}
You'll have to work out what to do with the data on your own though :)
If you are using a separate list make sure you clear out the formItems array when you're done with it so you don't have references to the items keeping them in memory unnecessarily.
Instead of keeping a separate array of form items you could also iterate over the children in the fm container. You might have to make some assumptions about the children you'd be accessing but it looks like you have control over all of the children being added so that's no problem.
I hope that helps...
:)

moving between states I get an error in Flex

ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
so i have a function that runs in state1 and has a
while(myCanvas.rawChildren.numChildren > 0){
myCanvas.rawChildren.removeChildAt(0);
}
//this code is definitely the problem....
I can move to state2, but when I move back to state1 i get the error.
why? the function that has the while loop only runs when something is searched in state1, so why is it running when coming back from state2?
edit...
so i did i test for a function that runs at app initialization:
private function init():void{
trace(g);
if(g == true){
while(myCanvas.rawChildren.numChildren > 0){
myCanvas.rawChildren.removeChildAt(0);
}
g = false;
}
trace(g);
}
It shouldnt run one it comes back to state1, but i still get the error. So basically as long as that while loop runs once while in state1 I can never get back to state1
<mx:states>
<mx:State name="contactform">
<mx:AddChild position="lastChild">
<mx:Canvas id="msgCanvas" backgroundColor="0xEEEEEE" height="121" y="158" width="800" fontWeight="normal" fontSize="12" backgroundAlpha="0.02" x="0">
</mx:Canvas>
</mx:AddChild>
<mx:AddChild position="lastChild">
<custom:email_cmp x="150" y="287" height="213"/>
</mx:AddChild>
</mx:State>
<mx:State name="main">
<mx:AddChild position="lastChild">
<mx:Canvas id="myCanvas" backgroundColor="0xEEEEEE" height="342" y="158" width="800" fontWeight="normal" fontSize="12" backgroundAlpha="0.02" x="0">
</mx:Canvas>
</mx:AddChild>
</mx:State>
</mx:states>
public function mainFunction():void{
origArray = [];
var cache:int = 0;
if(myCanvas.rawChildren.numChildren > 0){
myCanvas.rawChildren.removeChildAt(0);
}
//text format for links
var hFormat:TextFormat = new TextFormat();
hFormat.font = "Verdana";
hFormat.color = 0x000000;
hFormat.size = 15;
//text format end
var sprite1:Sprite = new Sprite();
var textQ:TextField = new TextField();
textQ.mouseEnabled = false;
if(amt_cnt.count == 1){
amt_cnt.end = amt_cnt.endCache;
amt_cnt.start = amt_cnt.startCache;
//set the text
textQ.defaultTextFormat = hFormat;
textQ.text = "Still can't find your answer? Need more help?";
textQ.x = 270;
textQ.y = 300;
textQ.width = textQ.textWidth +20;
textQ.selectable = false;
sprite1.addChild(textQ);
sprite1.buttonMode = true;
myCanvas.rawChildren.addChild(sprite1);
sprite1.addEventListener(MouseEvent.CLICK, moreHelp);
}else{
amt_cnt.end = amt_cnt.endCache;
amt_cnt.start = amt_cnt.startCache;
textQ.defaultTextFormat = hFormat;
textQ.text = "More Questions...";
textQ.x = 275;
textQ.y = 300;
textQ.width = textQ.textWidth +20;
textQ.selectable = false;
sprite1.addChild(textQ);
sprite1.buttonMode = true;
myCanvas.rawChildren.addChild(sprite1);
sprite1.addEventListener(MouseEvent.CLICK, moreQuestions);
}
var fontSize:int = 12;
//text formatting for the displayed question list Begin
var qFormat:TextFormat = new TextFormat();
qFormat.font = "Verdana";
qFormat.color = 0x000000;
qFormat.size = fontSize;
//ending text format
for(var t:uint = amt_cnt.start; t<amt_cnt.end; t++){
/*if(t == 0){
var topQ:TextField = new TextField();
topQ.text = full_array[t][1];
mainQsprite.addChild(topQ);
}*/
var qSprite:Sprite = new Sprite();
var txt:TextField = new TextField();
txt.defaultTextFormat = qFormat;
txt.text = full_array[t][0];
txt.selectable = false;
txt.mouseEnabled = false;
txt.border = false;
txt.width = 500; // how wide you want the text to go.
var numLines:Number = Math.floor(txt.textWidth/txt.width)+1; //calculates number of lines of the textfield.
txt.height = ((fontSize+8)*numLines);
txt.wordWrap = true;
qSprite.x = 30;
qSprite.y = 350;
qSprite.alpha = 0;
var temp_a:Number = cache; //20 is the padding between questions displayed
if(t != amt_cnt.end-1){
Tweener.addTween(qSprite, {y:temp_a, alpha:1, time:1, delay:t*0.1, transition:"easeoutexpo"}); //tweener INNNNN!
}else{
Tweener.addTween(qSprite, {y:temp_a, alpha:1, time:1, delay:t*0.1, transition:"easeoutexpo", onComplete:runTop}); //tweener INNNNN!
}
cache = txt.height + temp_a;
qSprite.buttonMode = true;
origArray[t] = new Array(qSprite.x,temp_a, qSprite);
mainDict[qSprite] = new Object();
mainDict[qSprite].question = full_array[t][0];
mainDict[qSprite].answer = full_array[t][1];
mainDict[qSprite].count = full_array[t][2];
mainDict[qSprite].top = full_array[t][3];
mainDict[qSprite].origX = qSprite.x;
mainDict[qSprite].origY = temp_a;
mainDict[qSprite].id = t;
mainDict[qSprite].height = txt.height;
amt_cnt[t] = new Object();
amt_cnt[t].hit = false;
qSprite.addChild(txt);
qSprite.addEventListener(MouseEvent.CLICK, clicked);
qSprite.addEventListener(MouseEvent.MOUSE_OVER, over);
qSprite.addEventListener(MouseEvent.MOUSE_OUT, out);
myCanvas.rawChildren.addChild(qSprite);
if(full_array[t][3] == true){
var thereIsTop:Boolean = true;
}
}
amt_cnt.array = origArray;
/*if(thereIsTop == true){
topAnswer(); //makes the top answer open first
thereIsTop = false;
}*/
}
So this the mainfunction. The top part has the states. main state is loaded first and has the myCanvas canvas. Everything in mainfunction adds to myCanvas.
This is my first time working with flex, so tell me if there is a better way of doing this.Thanks?
I really need to get this solved. I've been stressing over this for weeks.
I understand why you might not use mx:RemoveChild in your state (if you're managing your states in the easier-to-love mxml states property), but it looks like your code is trying to do what removeAllChildren() already does. Can you use removeAllChildren instead? Though, it would be nice to have more code to see what you're trying to accomplish.
Maybe you're handling an enterState event with this code ?

Flex AdvancedDataGrid - ColumnOrder With Formatter and ItemRenderer Question For Experts

I have a advanceddatagrid that has around 15 columns. Some are string,
some are numbers. I have shown 4 columns below.
The number columns have formatting done for zero precision and 2
digits precision. The itemRenderer is just to show Blue Color if the
number is +ve and Red Color if the number is -ve.
It looks something like below
<mx:columns>
<mx:AdvancedDataGridColumn dataField="Name" textAlign"left"/>
<mx:AdvancedDataGridColumn dataField="Time" textAlign="right"/>
<mx:AdvancedDataGridColumn dataField="Score" textAlign="right" formatter="{zeroPrecisionFormatter}" sortable="true" itemRenderer="ColorRenderer" />
<mx:AdvancedDataGridColumn dataField="Average" textAlign="right" headerWordWrap="true" formatter="{twoPrecisionFormatter}" itemRenderer="ColorRenderer" />
...
I am trying to save the users setting of column order when he closes
the application and reload with the same order when the user opens the
applications. I am using SharedObjects and below is the code.
for(var i:int=0; i< adgrid.columns.length;i++){
var columnObject:Object = new Object();
columnObject.columnDataField = adgrid.columns[i].dataField as String;
columnObject.columnHeader =adgrid.columns[i].headerText as String;
columnObject.width = adgrid.columns[i].width;
columnArray.push(columnObject);
}
and then I save the columnArray to SharedObject.
I retrive them using the below code
for(var i:int=0;i<columnArray.length;i++){
adgrid.columns[i].dataField =columnArray[i].columnDataField;
adgrid.columns[i].headerText =columnArray[i].columnHeader;
adgrid.columns[i].width = columnArray[i].width;
}
How can I save and reload the Formatter and ItemRenderer data .
I am having trouble saving the formatter and itemrenderer and
reloading it again.
I would really appreciate if you can shown the code.
How can I reshuffle the columns but can preserve all the properties of it to though sharedobject and recover it again.
private function loadLayout(name:String="custom"):void {
var storedLayoutData:SharedObject;
storedLayoutData = SharedObject.getLocal("layouts");
if (storedLayoutData.data["pocketBankDG_"+name]) {
var columns:Array = new Array();
var index:int = 0;
for each (var column:Object in storedLayoutData.data["pocketBankDG_"+name]["columns"]) {
for ( var key:String in column) {
var propClass:Class = getDefinitionByName(column[key].propClassName) as Class;
adgOperations.columns[index][key] = column[key].propValue as propClass;
}
index++
}
} else {
saveLayout("default");
openSettingsWindow();
}
}
private function saveLayout(name:String="custom"):void {
var storedLayoutData:SharedObject;
storedLayoutData = SharedObject.getLocal("layouts");
if (!storedLayoutData.data["pocketBankDG"]) storedLayoutData.data["pocketBankDG_"+name] = new Object();
var columns:Array = new Array();
for each(var column:AdvancedDataGridColumn in adgOperations.columns) {
var describeType:XML = flash.utils.describeType(column);
var accessoriesList:XMLList = describeType..accessor;
var data:Object = new Object;
for each(var accessor:XML in accessoriesList) {
if (accessor.#access=="readwrite") {
var propClassName:String = getQualifiedClassName(column[accessor.#name]);
var propValue:* = column[accessor.#name];
if (propClassName=="String" || propClassName=="int" || propClassName=="Boolean" ||
propClassName=="Number" || propClassName=="uint") {
data[accessor.#name] = {}
data[accessor.#name].propClassName = propClassName;
data[accessor.#name].propValue = propValue;
}
}
}
columns.push(data);
}
storedLayoutData.data["pocketBankDG_"+name]["columns"] = columns;
storedLayoutData.flush();
}

Resources