UI component form Flex to Air - actionscript-3

In Flex application I have found a way to save target object to "string";
<?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:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.events.FlexEvent;
import mx.rpc.xml.SimpleXMLEncoder;
import mx.utils.ObjectUtil;
import mx.utils.XMLUtil;
protected function button1_clickHandler(event:MouseEvent):void
{
var fr:FileReference = new FileReference();
var ba:ByteArray = new ByteArray();
ba.writeObject(container);
fr.save(ba);
}
]]>
</fx:Script>
<s:BorderContainer id="container" x="68" y="64" width="341" height="257">
<s:Label x="69" y="83" width="257" height="124" text="Label"/>
</s:BorderContainer>
<s:Button x="68" y="329" label="SAVE" click="button1_clickHandler(event)"/>
Is there a way to read that file and show it as UIComponent in AIR?
This is my try:
<?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">
<fx:Script>
<![CDATA[
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.net.FileFilter;
import flash.net.FileReference;
import flash.utils.ByteArray;
import spark.components.BorderContainer;
private var fr:FileReference;
private function onLoadFileClick():void
{
fr = new FileReference();
fr.addEventListener(Event.SELECT, onFileSelect);
fr.addEventListener(Event.CANCEL,onCancel);
fr.browse();
}
private function onFileSelect(e:Event):void
{
fr.addEventListener(Event.COMPLETE, onLoadComplete);
fr.addEventListener(IOErrorEvent.IO_ERROR, onLoadError);
fr.load();
}
private function onCancel(e:Event):void
{
trace("File Browse Canceled");
fr = null;
}
private function onLoadComplete(e:Event):void
{
var data:ByteArray = fr.data;
//read the bytes of the file as a string and put it in the
//textarea
//outputField.text = data.readUTFBytes(data.bytesAvailable);
//var obj:BorderContainer = data.;
cc = data.readObject();
//clean up the FileReference instance
fr = null;
}
//called if an error occurs while loading the file contents
private function onLoadError(e:IOErrorEvent):void
{
trace("Error loading file : " + e.text);
}
]]>
</fx:Script>
<mx:Button label="Load Text File" right="10" bottom="10" click="onLoadFileClick()"/>
<mx:TextArea right="10" left="10" top="370" bottom="40" id="outputField"/>
<s:BorderContainer id="cc" x="130" y="99" width="200" height="200">
</s:BorderContainer>
</s:WindowedApplication>
And I'm getting this error:
TypeError: Error #1034: Type Coercion failed: cannot convert Object#6f2bc41 to spark.components.BorderContainer at primi/onLoadComplete()[C:\Users\user\Adobe Flash Builder 4.5\primi\src\primi.mxml:51]
Any solution would will be fine... as long it works :)

You need to register a class alias for BorderContainer before writing to the ByteArray. Otherwise the object's type cannot be preserved and the container is written as an ordinary Object to the ByteArray.
Check the documentation for registerClassAlias() to get detailed information about how to read/write (or with the more common terms: serialize/deserialize) strongly typed objects in ActionScript.
And when I'm right, you need to register the class alias in both applications the Web-based one and AIR.

Related

Main application can't capturing custom event Flex

I have a problem when despatching an custom event from my "ItemRendered" to "Main application",the function "avatarSelectedHandler()" is not called when I click in the "CheckBox" (ItemRendered) located in the "DataGrid", I followed the official doc adobe but unfortunately I have not led to a solution.
below my code :
Try.mxml(Main application)
<?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" creationComplete="initApps()">
<fx:Script>
<![CDATA[
import entity.Avatar;
import events.AvatarSelected;
import mx.collections.ArrayCollection;
import mx.controls.Alert;
[Bindable]
private var listAvatar:ArrayCollection=new ArrayCollection();
public function initApps():void{
getAvatar();
avatarColumn.addEventListener(AvatarSelected.SELECTED_AVATAR,avatarSelectedHandler);
//avatarGrid.addEventListener(AvatarSelected.SELECTED_AVATAR,avatarSelectedHandler);
if(avatarColumn.hasEventListener(AvatarSelected.SELECTED_AVATAR))
Alert.show("EventListener OK ");
}
public function avatarSelectedHandler(event:AvatarSelected):void
{
Alert.show("L'evenement est bien traité sur main");
}
public function getAvatar():void{
var date:Date=new Date();
var avatar1:Avatar=new Avatar();
avatar1.idAvatar=4562;
avatar1.pseudo="X";
var avatar2:Avatar=new Avatar();
avatar2.idAvatar=659;
avatar2.pseudo="Y";
listAvatar.addItem(avatar1);
listAvatar.addItem(avatar2);
}
]]>
</fx:Script>
<s:DataGrid x="158" y="177" width="649" height="194" fontFamily="Times New Roman" id="avatarGrid"
fontSize="15" requestedRowCount="4" textAlign="center" dataProvider="{listAvatar}">
<s:columns>
<s:ArrayList>
<s:GridColumn dataField="isAvatar" headerText="Id" ></s:GridColumn>
<s:GridColumn dataField="pseudo" headerText="Pseudo"></s:GridColumn>
<s:GridColumn headerText="Selectionner" width="100" itemRenderer="rendered.CheckRendered" id="avatarColumn"></s:GridColumn>
</s:ArrayList>
</s:columns>
</s:DataGrid>
</s:Application>
My ItemRendered "CheckRendered.mxml"
<?xml version="1.0" encoding="utf-8"?>
<s:GridItemRenderer 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="50" height="27" clipAndEnableScrolling="true">
<fx:Metadata>
[Event(name="avatarSelected", type="events.AvatarSelected")]
</fx:Metadata>
<fx:Script>
<![CDATA[
import entity.Avatar;
import events.AvatarSelected;
import mx.controls.Alert;
protected function cBox_clickHandler(event:MouseEvent):void
{
var eventAvatar:AvatarSelected=new AvatarSelected("avatarSelected",Avatar (data));
dispatchEvent(eventAvatar);
}
]]>
</fx:Script>
<s:CheckBox id="cBox" horizontalCenter="0" click="cBox_clickHandler(event)"/>
</s:GridItemRenderer>
My custom event "AvatarSelected.as"
package events
{
import entity.Avatar;
import flash.events.Event;
import mx.states.OverrideBase;
public class AvatarSelected extends Event
{
public static const SELECTED_AVATAR:String = "avatarSelected";
public var avatar:Avatar;
public function AvatarSelected(type:String, avatar:Avatar)
{
super(type);
this.avatar =avatar;
}
}
}
My VO "Avatar.as"
package entity
{
//[Bindable]
//[RemoteClass(alias="entity.Avatar")]
[Bindable]
public class Avatar
{
public var idAvatar:Number;
public var pseudo:String;
}
}
I opted for another way to capture the event, I created a class SkinDataGrid that extends GridColumn to accept the event as an argument, but it does not work yet!
DataGrid on the Main Application:
<s:DataGrid x="171" y="333" width="649" height="194" fontFamily="Times New Roman" id="avatarGridII"
fontSize="15" requestedRowCount="4" textAlign="center" dataProvider="{listAvatar}">
<s:columns>
<s:ArrayList>
<skin:SkinDataGrid dataField="isAvatar" headerText="Id" ></skin:SkinDataGrid>
<skin:SkinDataGrid dataField="pseudo" headerText="Pseudo"></skin:SkinDataGrid>
<skin:SkinDataGrid headerText="Selectionner" width="100" itemRenderer="rendered.CheckRendered" id="avatarColumnII" avatarSelected="avatarSelectedHandler(event)"></skin:SkinDataGrid>
</s:ArrayList>
</s:columns>
</s:DataGrid>
SkinDataGrid.as
package skin
{
import spark.components.DataGrid;
import spark.components.gridClasses.GridColumn;
[Event(name="avatarSelected", type="events.AvatarSelected")]
public class SkinDataGrid extends GridColumn
{
public function SkinDataGrid()
{
super();
}
}
}
any idea ?
Thank you in advance.
You don't specify what kind of problem do you have (type of error), but from looking at the code I find suspicious, that function avatarSelectedHandler has as argument of MouseEvent type, when you assign it as handler of AvatarSelected type.
You also can try to dispatch this event with bubbling enabled (by default it's set to false in the Event class constructor).
In your case, the AvatarSelected constructor can be changed to smth like that:
public function AvatarSelected(type:String, avatar:Avatar, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
this.avatar =avatar;
}
And event creating would be like this (attention on the third parameter in the AvatarSelected()):
var eventAvatar:AvatarSelected = new AvatarSelected("avatarSelected", Avatar (data), true);

Create Custom Dialog Box using dispatch events,states and titlewindow in flex/AS3.0

Since a month Iam working on creating a custom dialog box, having parameters like message,state and modal(true/false)
Eg:
showAlert("Hi, how are you doing","Goodmorning", true);
I have learned how to dispatch event. but unable to dispatch the alertevent/popupManager using States.
Below is the code, I am struggling with.
Main.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
public function onclick(event:MouseEvent):void
{
this.dispatchEvent("Hi, How are you?", "Morning", true);
}
public function dispatchEvent(arg1:String, arg2:String, arg3:Boolean):void
{
var str:*=null;
str.message = arg1;
str.stateName = arg2;
str.modal = arg3;
this.dispatchEvent(new ShowAlert(ShowAlert.SHOW, true));
}
]]>
</mx:Script>
<mx:Button id="click" click="onclick(event)"/>
</mx:Application>
ShowAlert.as
package
{
import flash.events.*;
public class ShowAlert extends Event
{
public var _stateName:String;
public var _closable:Boolean;
public var _message:String;
public var _isModal:Boolean;
public static const SHOW:String="show";
public function flash.events.(arg1:String, arg2:Boolean=false, arg3:Boolean=false)
{
super(arg1, arg2, arg3);
trace("arg1: "+arg1+"\t arg2: "+arg2+"\t arg3: "+arg3);
}
public function set message(arg1:String):void
{
this._message = arg1;
}
public function get message():String
{
return _message;
}
public function get modal():Boolean
{
return _isModal;
}
public function get stateName():String
{
return _stateName;
}
public function set stateName(arg1:String):void
{
this._stateName = arg1;
}
public function set modal(arg1:Boolean):void
{
this._isModal = arg1;
}
public override function clone():flash.events.Event
{
return new ShowAlert(type);
}
}
}
I was unable to write the custom titlewindow using states, so I dint post that.
Please let me know, how to make this happen.
Below is the Sample code, specifying my problem
main.mxml:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
public var info:IModuleInfo;
public var loadalert:DisplayObject;
import mx.modules.ModuleManager;
import mx.modules.IModuleInfo;
import mx.events.ModuleEvent;
public function init():void
{
Alert.show("This is forst alert.");
}
public function Loadalerrt():void
{
trace("loadalertmodule");
info = ModuleManager.getModule("../bin-debug/alerrtmod.swf");
info.addEventListener(ModuleEvent.READY, modEventHandler);
info.load();
}
public function modEventHandler(event:ModuleEvent):void
{
trace("modeventHandler");
loadalert=info.factory.create() as DisplayObject;
can1.addChild(loadalert);
}
]]>
</mx:Script>
<mx:Button label="Alert in Application" id="b1" click="init()" x="29" y="21"/>
<mx:Button label="Load Module" id="b2" click="Loadalerrt();" x="10" y="92"/>
<mx:Canvas id="can1" x="409" y="57" backgroundColor="cyan"/>
</mx:Application>
alerttmod.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="400" height="300">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
public function alertshow():void
{
Alert.show("This is second alert, You Can see it covers whole application, What I want is its scope should be limited to this specific module, not to whole application ");
}
]]>
</mx:Script>
<mx:Button label="Alert in Module" id="b1" click="alertshow()" x="163" y="100"/>
</mx:Module>
Now I see your problem. I think it is not possible to restrict the modal area of the Alert. I can suggest you to fake the modal behaviour by desabling the modules elements while your dialog is being shown.
May be it can help you...
Here are two components to demonstrate it:
//your module with another Alert
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="400" height="300">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.managers.PopUpManager;
public function alertshow():void
{
Alert.show("This is second alert...");
}
public function alertshow2():void
{
var customAlert:CustomAlert = new CustomAlert();
customAlert.addEventListener("CLOSED", onCustomAlertClosed);
this.enabled = false;
PopUpManager.addPopUp(customAlert, this, false);
PopUpManager.centerPopUp(customAlert);
}
private function onCustomAlertClosed(evt:Event):void
{
this.enabled = true;
}
]]>
</mx:Script>
<mx:Button label="Alert in Module" id="b1" click="alertshow()" x="163" y="100"/>
<mx:Button label="CustomAlert in Module" id="b2" click="alertshow2()" x="163" y="150"/>
<mx:Canvas width="100%" height="100%" backgroundColor="0xbbbbbb" alpha="0.8" visible="{!this.enabled}"/>
</mx:Module>
//simple CustomAlert as a Panel
<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="300" height="200">
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;
protected function button1_clickHandler(event:MouseEvent):void
{
PopUpManager.removePopUp(this);
this.dispatchEvent(new Event("CLOSED"));
}
]]>
</mx:Script>
<mx:Button x="112" y="128" label="Close" click="button1_clickHandler(event)"/>
</mx:Panel>

When using three ModuleLoaders my application sometimes fails with Error #1009

My problem occurs when I attempt to use more than 2 module loaders. My first problem was when I tried using more than 1. Below you can see my workaround. I'm still somewhat new to Modules so I wouldn't be surprised if I'm missing something obvious here. What kills me is how it sometimes works but other times doesn't?
Error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at ModuleInfo/completeHandler()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\modules\ModuleManager.as:717]
My Application:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" minWidth="955" minHeight="600">
<mx:Script>
<![CDATA[
import mx.core.Application;
import mx.events.ModuleEvent;
import mx.managers.PopUpManager;
import mx.modules.IModuleInfo;
import mx.modules.ModuleManager;
private var popUpManager:PopUpManager;
private var podXml:XML;
private var moduleIsReady:Boolean;
private function getSwf():String
{
return "location/SimpleModule.swf";
}
private function onModuleUnload(moduleEvent:ModuleEvent):void
{
// Had to release in order to get 2 to work, now it breaks on 3
var info:IModuleInfo = ModuleManager.getModule(getSwf());
info.release();
info = null;
trace("module unloaded");
}
private function onModuleReady(moduleEvent:ModuleEvent):void
{
// Module loaded
// moduleIsReady = true; //used as a flag for child to know when the module itself is ready
//var ichild:MyInterface = module.child as MyInterface
//if (module.child != null)
//{
// ichild.doStuff();
//}
}
]]>
</mx:Script>
<mx:Canvas>
<mx:ModuleLoader url="{getSwf()}" id="module" ready="onModuleReady(event)" unload="onModuleUnload(event)" x="50" y="50" width="100" height="100"/>
<mx:ModuleLoader url="{getSwf()}" id="module1" ready="onModuleReady(event)" unload="onModuleUnload(event)" x="50" y="250" width="100" height="100"/>
<mx:ModuleLoader url="{getSwf()}" id="module2" ready="onModuleReady(event)" unload="onModuleUnload(event)" x="50" y="450" width="100" height="100"/>
</mx:Canvas>
</mx:Application>
My Module:
<?xml version="1.0" encoding="utf-8"?>
<mx:Module layout="absolute" xmlns:mx="http://www.adobe.com/2006/mxml"
width="100%" height="100%"
backgroundColor="0xFF0000">
</mx:Module>
Thanks.

DataGrid.selectedIndex memory leak

I have noticed a memory leak in a DataGrid, in case I do not select an item, I am able to GC my dataGrid, if there was anything selected then dataGrid cause memory leak...
here is the simpliest example:
<?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:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.collections.ArrayList;
import spark.components.gridClasses.GridColumn;
[Bindable]
private var columns:ArrayList = new ArrayList;
[Bindable]
private var dataProvider:ArrayCollection = new ArrayCollection;
private function onCreationComplete():void
{
dataProvider.addItem({id:1});
var column:GridColumn = new GridColumn;
column.dataField = id;
columns.addItem(column);
container.selectedIndex = 0;
}
private function gotoOne():void
{
currentState = one;
}
private function gotoTwo():void
{
columns = null;
currentState = two;
}
]]>
</fx:Script>
<s:states>
<s:State name="one"/>
<s:State name="two"/>
</s:states>
<s:Button click="gotoOne()" label="one"/>
<s:Button click="gotoTwo()" label="two" left="150"/>
<s:DataGrid id="container" top="30" includeIn="one" itemDestructionPolicy="auto"
creationComplete="onCreationComplete()" columns="{columns}"
dataProvider="{dataProvider}"/>
</s:Application>
if you comment out line "container.selectedIndex = 0;" DataGrid gets GCed nicely.
Any ideas how to GC DataGrid with selected item?
I am using flex 4.6.0
It isn't a memory leak, it is cycle of a live item.
onCreationComplete is called when you finish render and display datagrid on the scene, you must add the item on click of the grid( selectedItem event).

connecting to remote webservice using SOAP and WSDL using flex or actionscript

The requirement is to get the method named getIncidentList() from web service using Soap and wsdl using Flex or Actionscript.
Can anyone help me i have a code which is not working:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:WebService id="DirectoryService"
wsdl="http://cmuicds.rutgers.edu/uicds/core/ws/services/DirectoryService.wsdl"
useProxy="false"
showBusyCursor="true"
result="onResult(event)"
fault="onFault(event)">
</mx:WebService>
<mx:ApplicationControlBar dock="true">
<mx:Button id="button"
label="get incidents from web service"
click="button_click()"/>
<mx:ComboBox id="cmb" dataProvider="{zipfls}" labelField="name" width="241" height="24"/>
</mx:ApplicationControlBar>
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
import mx.utils.ObjectUtil;
import mx.collections.ArrayCollection;
[Bindable] private var zipfls:ArrayCollection;
private var flag:Boolean;
private function button_click():void
{
//Alert.show("Hi");
//DirectoryService.GetIncidentList.send();
DirectoryService.GetIncidentList();
flag = DirectoryService.canLoadWSDL();
//flag = DirectoryService.hasOwnProperty();
//Alert.show("Testing....." + flag);
//Alert.show("Description " +DirectoryService.operations);
}
private function onResult(evt:ResultEvent):void
{
zipfls = new ArrayCollection();
//textArea.text = ObjectUtil.toString(evt.result);
zipfls = evt.result as ArrayCollection;
Alert.show("Is data comming in?" + zipfls.length);
}
private function onFault(evt:FaultEvent):void
{
Alert.show(evt.type);
}
]]>
</mx:Script>
</mx:Application>
I think you are not calling method properly
and event button_click should be
private function button_click():void
{
DirectoryService.GetIncidentList();
}
i.e. send should not be used.
also see Using WebService components
Hopes that helps