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

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.

Related

How to unload audio when a video is deleted

I've created a video player into which I dynamically load video from another component:
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()" >
<mx:Script>
<![CDATA[
[Bindable] public var videoAddress:String
private static const YOUTUBE_EMBED_URL:String = "http://www.youtube.com/v/";
[Bindable] public var videoUrl:String;
private function init():void {
videoUrl = YOUTUBE_EMBED_URL+videoAddress;
}
]]>
</mx:Script>
<mx:SWFLoader id="swfLoader" source="{videoUrl}" width="800" height="600" />
</mx:Canvas>
Here's how I load the video:
<?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[
private var videoPlayer:VideoPlayer;
protected function button1_clickHandler(event:MouseEvent):void{
if(this.videoPlayer != null){
this.videoPlayer.removeAllChildren();
}
videoPlayer = new VideoPlayer();
videoPlayer.videoAddress = "_OBlgSz8sSM";
this.addChild(videoPlayer);
}
protected function button2_clickHandler(event:MouseEvent):void{
if(this.videoPlayer != null){
this.videoPlayer.removeAllChildren();
}
videoPlayer = new VideoPlayer();
videoPlayer.videoAddress = "tvmIEP_BP9Q";
this.addChild(videoPlayer);
}
]]>
</mx:Script>
<mx:HBox top="600">
<mx:Button label="Button 1" click="button1_clickHandler(event)" />
<mx:Button label="Button 2" click="button2_clickHandler(event)" />
</mx:HBox>
</mx:Application>
The problem I'm experiencing is that when I load another video, the old video is removed and the new video loads, but the old audio keeps playing.
How can I remove the audio?
I read a post that discussed garbage collection
The solution for me was to add the following to the init() function:
SoundMixer.stopAll();

How to Access buttons and labels of one mxml file from another mxml file

I m completely fresher in Flex Programming,
I have a FileUploadPanel.mxml which contains functionality of uploading, deleting and viewing one file only.. Now i need to modify the application to accommodate multiple attachments facility, So i created another panel ie MultiFileUpload.mxml, which has the functionality to get all attachment in form of List of Objects , and for each object-id I need to call the previous File Upload Panel, Every Thing is Working fine, but when i am accessing buttons and Labels of FileUpload.mxml it is throwing error:
1009- cannot access property and method of null object reference.
code FileUploadPanel.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="492" height="46" >
<mx:Label x="0" y="4" text="File Attachment:"/>
<mx:Button x="93.5" y="2" label="Browse" id="btnBrowseView" click="__onBrowse();" enabled="true" width="67"/>
<mx:Text x="264.5" y="4" width="100%" id="lbUploadFile" height="18 " />
<mx:Button x="165" y="2" label="Upload" id="btnUpload" enabled="true" click="reserveAttachment();" width="67"/>
<mx:Text x="10" y="25" width="100%" height="18" id="__status__" fontWeight="bold" color="#023AF1"/>
<mx:Script>
<![CDATA[
public function SetAttachmentID(anAttachmentID: Number): void
{
this.AttachmentID = anAttachmentID;
lbUploadFile.text = ""; //here i am getting error
__status__.text = "";
if (AttachmentID != -1)
{
m_data = new DocumentsAdt();
m_data.ConnectionIndex = ConnectionIndex;
m_data.OnLoadData = this.OnDoxLoaded;
m_data.LoadFromWebService(AttachmentID);
btnBrowseView.label = "View";
btnUpload.label = "Delete";
btnUpload.enabled = true;
btnUpload.visible = true;
}
else
{
btnBrowseView.label = "Browse";
btnUpload.visible = false;
btnUpload.label = "Upload";
btnUpload.enabled = false;
Init();
}
}
</mx:Script>
</mx:Canvas>
Code MuliFileUpload.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="300" xmlns:BoycePanels="BoycePanels.*" xmlns:ns1="com.flextoolbox.controls.*" xmlns:ns2="com.adobe.flex.extras.controls.*" xmlns:ns3="BoycePanels.*">
<mx:Script>
<![CDATA[
import Adt.Attachments.DocumentsAdt;
import com.boycepensions.DocumentsService.DocumentsService;
import com.boycepensions.DocumentsService.GetDocumentsRecordResultEvent;
import mx.collections.ArrayCollection;
private var m_data: DocumentsAdt = null;
import mx.rpc.events.FaultEvent;
import BoycePanels.FileUploadPanel;
import mx.controls.Alert;
public var ConnectionIndex: int = new int(0);
public var AttachmentID: Number = new Number(-1);
public var acDocList:ArrayCollection=null;
public function Init():void
{
getDocs_Test();
}
public function getDocs_Test():void
{
blah..blah..blah..
}
public function OnGetDocumentsRecord(event:GetDocumentsRecordResultEvent): void
{
var acDocList:ArrayCollection=new ArrayCollection();
var m_data:DocumentsAdt=new DocumentsAdt();
if (!CheckResult(event.result))
return;
else
{
acDocList=m_data.LoadDocumentsFromXML(event.result);
for each(var obj:DocumentsAdt in acDocList)
{
var pnl:FileUploadPanel=new FileUploadPanel();
//pnl.OnReserveAttachmentDone=OnReserveAttachment;
pnl.Init();
pnl.SetAttachmentID(obj.Document_ID); //here it is throwing error
}
}
}
Please suggest, i have already spent days and hours on it..
You try to access lbUploadFile when it hasn't been initialized. So if you want the FileUploadPanel show on Stage, try add it to stage before call SetAttachmentID function, like this.
var pnl:FileUploadPanel=new FileUploadPanel();
this.addChild(pnl);//add it to where you want
If the pnl needn't show on stage, remove the lines where access the children.

Simple flex popup with dispatch event in child and listener in parent not working

Parent.mxml
This file is calling the popup class below when the button is clicked.
<?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.controls.Alert;
import mx.managers.PopUpManager;
var popup:pop = null ;
protected function clickHandler(event:MouseEvent):void
{
popup = PopUpManager.createPopUp(this,pop,true) as pop;
popup.ok.addEventListener(MouseEvent.CLICK, captureComments);
popup.close();
}
var str:String="";
private function captureComments():void{
Alert.show("Invoked Event Listener", "Alert");
str=popup.comments;
}
]]>
</fx:Script>
<mx:Button id="id1" label="Click" click="clickHandler(event)"/>
<s:Label id="lbl" height="18" width="282" text={str} />
</s:Application>
Child.mxml
This file is the popup reference, creating popup.
I have configured the close action and cancel buttons to work as needed, but unable to propagate the text entered in comment are back to the parent.
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
layout="vertical" width="524" height="322"
showCloseButton="true"
close="close()" chromeColor="#CCCCCC"
horizontalAlign="center" verticalAlign="middle" color="#000000">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.managers.PopUpManager;
import mx.rpc.events.ResultEvent;
[Bindable]public var comments:String;
public function close(): void{
PopUpManager.removePopUp(this);
}
private function save(): void{
if(comments == null){
comments = "";
}
dispatchEvent(new ResultEvent(comments));
}
]]>
</fx:Script>
<mx:HBox width="100%" height="70%">
<mx:VBox width="100%" height="100%">
<mx:TextArea id="comment" text="{comments}" width="100%" height="80%" change="comments = event.target.text">
</mx:TextArea>
<mx:HBox horizontalAlign="center" width="100%" height="20%">
<s:Button id="ok" label="OK" chromeColor="#CCCCCC" click="save()" fontWeight="bold"/>
<s:Button id="cancel" label="Cancel" chromeColor="#CCCCCC" click="close()" fontWeight="bold"/>
</mx:HBox>
</mx:VBox>
</mx:HBox>
</mx:TitleWindow>
You are dispatching a ResultEvent, like this:
dispatchEvent(new ResultEvent(comments));
However, the event type is the user entered input. Check out the ResultEvent constructor. The first argument is the event type. I have no idea how you'll be able to consistently listen for an event type that is unknown at compile time.
I think you are trying to pass your custom data back to your parent class. My preference would be to use a custom event for this; but if you wanted to use a ResultEvent you could pass your comments in the result property:
dispatchEvent(new ResultEvent(ResultEvent.RESULT,false,true,comments));
In your parent file, add an event listener like this:
popup.addEventListener(ResultEvent.RESULT, processResult);
You should be able to get at your comments value as a property on the event:
protected function processResult(event:ResultEvent):void{
str=event.result
}
Another thing I've done as well is in the Child Container Create a public variable to pass the function from the parent ie:
in parent:
protected function captureComments(comments:String):void{
str=comments;
}
in child :
declare a public var and add the function to the save() function
public var parentFunction:Function;
private function save(): void{
if(comments == null){
comments = "";
}
parentFunction(comments);
Then when Creating your popup container in the parent:
protected function clickHandler(event:MouseEvent):void
{
popup = PopUpManager.createPopUp(this,pop,true) as pop;
popup.parentFunction = captureComments;
popup.close();
}

UI component form Flex to Air

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.

Dynamically added FormItem doesn't show error text

I am dynamically creating a form on runtime of my application. The content of my form item (lets call it MyFormItemContent) looks like this (simplified):
<?xml version="1.0" encoding="utf-8"?>
<s:BorderContainer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
width="100%" borderAlpha="0.0">
<fx:Declarations>
<utils:DataItemValidator dataItem="{referenceToDataItem}"
source="{this}"/>
</fx:Declarations>
<s:HGroup width="100%">
<s:TextInput width="100%" text="#{bindingToText}"/>
<s:CheckBox width="14" selected="{refToBoolean}"/>
</s:HGroup>
</s:BorderContainer>
and the the code for the the validator we are using. It works fine other parts of the application and debuging shows that a message exists but is not shown.
/**
* This class effectively does *not* validate the given 'value', but just returns
* his 'dataItem's attached messages.
*/
public class DataItemValidator extends Validator {
private var _dataItem:StatefulDataItem;
public function get dataItem():StatefulDataItem {
return _dataItem;
}
public function set dataItem(dataItem:StatefulDataItem):void {
_dataItem = dataItem;
ChangeWatcher.watch(_dataItem, "messages", function():void {
validate();
}, false);
validate();
}
override protected function doValidation(value:Object):Array {
if (!isInitialized()) return [];
// Clear results Array.
var results:Array = [];
// If dataItem has error indicator append all messages to result array.
if (dataItem && dataItem.messages) {
for each (var message:ResultMessage in dataItem.messages) {
results.push(new ValidationResult(message.isErroneous(), null, "", message.text));
}
}
return results;
}
public function isErroneous():Boolean {
if (!dataItem) return false;
return dataItem.isErroneous();
}
private function isInitialized():Boolean {
return (dataItem != null);
}
}
The code that declares the form looks like this:
<s:Form id="myForm" width="100%" height="100%">
<s:layout>
<s:FormLayout gap="-7" paddingBottom="2" paddingLeft="2" paddingRight="2"
paddingTop="2"/>
</s:layout>
</s:Form>
And finally, the item is added to the form like this:
var formItem:FormItem = new FormItem();
formItem.label = "some text";
formItem.addElement(new MyFormItemContent());
myForm.addElement(formItem);
If the validation of MyValidator has errors a red frame apears around the BorderContainer as intended. But unfortunatly the error text that should apear right to the form item doesn't. I'm thinkin it's a layout problem because I define the validator inside the form item content before adding it to the form. I've already debugged this and read documentations a lot.
I thought it would help to know how a FormItem is added to a Form if you declare it in mxml but I couldn't find information on that either.
<?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" creationComplete="application2_creationCompleteHandler(event)" xmlns:local="*">
<fx:Script>
<![CDATA[
import mx.charts.series.ColumnSeries;
import mx.collections.ArrayCollection;
import mx.containers.FormItem;
import mx.events.FlexEvent;
protected function application2_creationCompleteHandler(event:FlexEvent):void
{
// TODO Auto-generated method stub
for(var i:int = 0; i < 4; i++)
{
var formItem:FormItem = new FormItem();
formItem.label = "some text";
formItem.addElement(new MyFormItemContent());
myForm.addElement(formItem);
}
}
]]>
</fx:Script>
<s:Form id="myForm" width="100%" height="100%">
<s:layout>
<s:FormLayout gap="-7" paddingBottom="2" paddingLeft="2" paddingRight="2"
paddingTop="2"/>
</s:layout>
</s:Form>
</s:Application>
form item mxml file
<?xml version="1.0" encoding="utf-8"?>
<s:BorderContainer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
width="100%" borderAlpha="0.0" xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="bordercontainer1_creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import mx.events.ValidationResultEvent;
[Bindable]
private var bindingToText:String;
[Bindable]
private var refToBoolean:Boolean;
protected function bordercontainer1_creationCompleteHandler(event:FlexEvent):void
{
// TODO Auto-generated method stub
}
protected function txt_focusOutHandler(event:FocusEvent):void
{
var obj:ValidationResultEvent = validator.validate(txt.text);
error.visible = !(obj.type == "valid");
}
]]>
</fx:Script>
<fx:Declarations>
<mx:PhoneNumberValidator id="validator"/>
</fx:Declarations>
<s:HGroup width="100%">
<s:TextInput id="txt" width="100%" text="#{bindingToText}" focusOut="txt_focusOutHandler(event)"/>
<s:CheckBox width="14" selected="{refToBoolean}"/>
<s:Label id="error" visible="false" backgroundColor="red" text="This Field Required"/>
</s:HGroup>
</s:BorderContainer>
I am posting this code for your interest.