load symbol of flash in flex at runtime - apache-flex

Hey people, I've this huge problem loading a symbol from a swf file in the application at runtime. I want to load it and pass it as a argument to another class where it could be used further. The symbol name is passed on from the array collection from the "o" object. Can anybody please tell me what's the right way to go about it.. Thanks in advance..!!
Following is the code for reference..
public override function Show(o:ObjectProxy):void
{
var _this:Weather;
var _super:ContentItem;
var item:WeatherItem;
var items:ArrayCollection;
var widgetCount:Number;
var headlineFontSize:int;
var conditionsIconThemeLoader:Loader;
this.m_weatherWidgetContainer = new HBox();
super.Show(o);
_this = this;
_super = super;
(undefined == o["HeadlineFontSize"]) ? headlineFontSize = 20 : headlineFontSize = o["HeadlineFontSize"];
if (undefined != o["direction"])
this.m_textDirection = o["direction"];
if (o.LargeUrl.Forecast is ArrayCollection)
items = ArrayCollection(o.LargeUrl.Forecast);
else
items = new ArrayCollection([o.LargeUrl.Forecast]);
widgetCount = this.m_computeWidgetSpace(items.length);
conditionsIconThemeLoader = new Loader();
conditionsIconThemeLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void
{
for(var i:uint = 0; i < widgetCount; i++)
{
var symbolClass:Class = e.currentTarget.loader.contentLoaderInfo.applicationDomain.currentDomain.getDefinition(int(items[i].condition)) as Class;
var symbolInstance:Sprite = new symbolClass();
item = new WeatherItem();
item.Show(items[i], headlineFontSize, symbolInstance, widgetCount);
_this.m_weatherWidgetContainer.addChild(item);
}
});
conditionsIconThemeLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, function(e:IOErrorEvent):void
{
Alert.show("Failure loading " + WidgetStylesheet.instance.Weather_Widget_Theme + ".swf");
});
// Attempt to load theme weather icon file
conditionsIconThemeLoader.load(new URLRequest("assets/animation/" + WidgetStylesheet.instance.Weather_Widget_Theme + ".swf"));
super.media.addChild(this.m_weatherWidgetContainer);
}

Heres the answer
public override function Show(o:ObjectProxy):void
{
var _this:Weather;
var _super:ContentItem;
var conditionsIconThemeLoader:Loader;
var loaderContext:LoaderContext;
this.m_weatherWidgetContainer = new HBox();
this.m_weatherWidgetContainer.percentHeight = 100;
this.m_weatherWidgetContainer.percentWidth = 100;
super.Show(o);
_this = this;
(undefined == o["HeadlineFontSize"]) ? this.m_headlineFontSize = 20 : this.m_headlineFontSize = o["HeadlineFontSize"];
if (undefined != o["direction"])
this.m_textDirection = o["direction"];
if (o.LargeUrl.Forecast is ArrayCollection)
this.m_items = o.LargeUrl.Forecast;
else
this.m_items = new ArrayCollection([o.LargeUrl.Forecast]);
conditionsIconThemeLoader = new Loader();
loaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
conditionsIconThemeLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, this.m_loaderSuccess);
conditionsIconThemeLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, this.m_loaderFail);
// Attempt to load theme weather icon file
conditionsIconThemeLoader.load(new URLRequest("assets/animation/" + WidgetStylesheet.instance.Weather_Widget_Theme + ".swf"), loaderContext);
this.m_weatherWidgetContainer.addEventListener(FlexEvent.CREATION_COMPLETE, this.m_drawHorizontalLine);
super.media.addChild(this.m_weatherWidgetContainer);
}

Related

I am trying to programmatically add images to a list/array and access them in a for each loop to change their source image

I have been trying to add images to an array and then access their properties to change their source image in a loop.
Detailed: I create a grid with a layout for each for each grid element, in that layout there is a GridImage, who's source folder is set to "ClosedFolder.png", when I click one of the layouts it should change the clicked layouts folder to "OpenFolder.png".
for (int eachCount = 0; eachCount <= MaxRows / MaxCols; eachCount++)
{
Selectedrid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(80, GridUnitType.Absolute) });
for (int newCol = 0; newCol <= MaxCols; newCol++)
{
for (int newRow = 0; newRow <= MaxRows / MaxCols; newRow++)
{
if (folderIndex >= DirectoryArrayList.Count) { break; }
var folder = DirectoryArrayList[folderIndex];
var label = new Label()
{
Text = folder.Name,
FontSize = 12,
VerticalTextAlignment = TextAlignment.Center,
HorizontalTextAlignment = TextAlignment.Center
};
var GridImage = new Image() { Source = "ClosedFolder.png", StyleId = "Image" };
var GridTap = new TapGestureRecognizer();
var Layout = new StackLayout() { StyleId = "StackContent" };
var folderSelection = _mainFolder + "/" + folder.Name;
GridTap.Tapped += async(object sender, EventArgs e) =>
{
FileHandler.CreateTextFiles(folderSelection, "File_" + FileID + ".txt");
files = FolderOptions.AddFilesToList(folderSelection);
lst.ItemsSource = files;
//foreach (Image img in ImageList) I know this i incorrect, just an example of what I think!
//{
// img.Source = "ClosedFolder.png";
//}
GridImage.Source = "OpenFolder.png"; // clicked layout gets its openfolder.png
};
Layout.Children.Add(label);
Layout.Children.Add(GridImage);
Layout.GestureRecognizers.Add(GridTap);
Selectedrid.Children.Add(Layout, newCol, newRow);
folderIndex += 1;
FileID += 1;
}
}
}
Not sure on the declaration of the array and how to implement it.
I added the following into my BasicGrid method ...
var GridImage = new Image() { Source = "ClosedFolder.png", StyleId = "Image" };
var ImageList = new List<Image>{};
ImageList.Add( GridImage );
for (var i = 0; i < ImageList.Count; i++)
{
var img = ImageList[i];
img.Source = "ClosedFolder.png";
} GridImage.Source = "OpenFolder.png"
Just adding to say that Jason's information is the most likely direction I will go in, but as I am still learning it will take me time and I dint want to keep this open while I do that :-)

Flex: access dynamically added RicheEditableText in other function

When I click on a userlist, the function addTab is triggered:
private var counter:int = 0;
public function addTab():void {
var new vBox:VBox = new VBox();
var textBox:RichEditableText = new RichEditableText();
var nameEm:String = "dynamicTextBox" + counter;
textBox.id = nameEm;
counter++;
var textFlow:TextFlow = new TextFlow();
vbox.addChild(textFlow);
vbox.addChild(textBox);
tabNavigator.add(vBox);
}
In another function, I would like to add Rich Text to the newly created TextBox, but I can not access it.
I tried getChildByName(vbox) and vbox.getChildByName(textBox), but that doesn't seem to work.
To get childbyname assigned a name to richeditable text and if you want to get it by counter then give name to vbox also, as in the sample here:
private var counter:int = 0;
public function addTab():void {
var new vBox:VBox = new VBox();
var textBox:RichEditableText = new RichEditableText();
var nameEm:String = "dynamicTextBox" + counter;
textBox.id = nameEm;
vBox.name=nameEm;
textBox.name=nameEm;
counter++;
var textFlow:TextFlow = new TextFlow();
vbox.addChild(textFlow);
vbox.addChild(textBox);
tabNavigator.add(vBox);
}
If you know the index then
var vb:VBox = tabNavigator.getChildByName("dynamicTextBox"+index) as VBox;
var txt:RichEditableText=vb.getChildByName("dynamicTextBox"+index) as VBox;
So this will give you RichEditableText.
Or if you want to get access just after adding in to tab then return RichEditableText from the addtab function.
Elaborating on my comment, the idea is that you do something like this:
private var counter:int = 0;
public function addTab():void {
var new vBox:VBox = new VBox();
vBox.name = "dynVbox" + counter;
var textBox:RichEditableText = new RichEditableText();
textBox.name = "dynamicTextBox" + counter;
var textFlow:TextFlow = new TextFlow();
textFlow.name = "dynamicTextFlow" + counter;
vbox.addChild(textFlow);
vbox.addChild(textBox);
tabNavigator.add(vBox);
counter++;
}
Now, outside this function, you just need to know the counter number of the vBox you want. So for example:
var myBox = tabNavigator.getChildByName('dynVbox'+ 32).getChildByName('dynamicTextBox'+32)
Without seeing more of your code, I don't know if this is the best way to go about it, but if you want to mark your boxes with some dynamically generated name and look them up later, this will work
Example documentation

Remote Image with basic authentication?

I would like to load a an image from an external domain and I have the below so far:
private function get_coverArt(coverArtID:String):void
{
var requestString:String = "/rest/getCoverArt.view?v=1.5.0&c=AirSub&id=" + coverArtID;
var requestURL:String = subServerURL + requestString;
myCoverArtLoader = new URLLoader();
var myRequest:URLRequest = new URLRequest();
var authHeader:URLRequestHeader = new URLRequestHeader();
authHeader.name = 'Authorization';
authHeader.value = 'Basic ' + credentials;
myRequest.requestHeaders.push(authHeader);
myRequest.url = requestURL;
myRequest.method = URLRequestMethod.GET;
myCoverArtLoader.dataFormat = URLLoaderDataFormat.BINARY;
myCoverArtLoader.addEventListener(Event.COMPLETE, set_coverArt);
myCoverArtLoader.load(myRequest);
}
private function set_coverArt(evt:Event) : void {
coverArtImg = new Image();
var loader:Loader = new Loader();
loader.loadBytes(myCoverArtLoader.data);
coverArtImg.source = loader;
}
This does not seem to work - any help?
Thanks!
Try setting the source directly like so:
private function set_coverArt(evt:Event) : void {
coverArtImg = new Image();
coverArtImg.source = myCoverArtLoader.data;
}
Also, check your authentication, here's a question I answered regarding the auth :
Actionscript 3: Reading an RSS feed that requires authentication

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;

Dynamically Creating Variables In Actionscript 3.0?

i'm loading several sound files, and want to error check each load. however, instead programming each one with their own complete/error functions, i would like them to all use the same complete/error handler functions.
a successfully loaded sound should create a new sound channel variable, while an unsuccessfully loaded sound will produce a simple trace with the name of the sound that failed to load. however, in order to do this, i need to dynamically create variables, which i haven't yet figured out how to do.
here's my code for my complete and error functions:
function soundLoadedOK(e:Event):void
{
//EX: Sound named "explosion" will create Sound Channel named "explosionChannel"
var String(e.currentTarget.name + "Channel"):SoundChannel = new SoundChannel();
}
function soundLoadFailed(e:IOErrorEvent):void
{
trace("Failed To Load Sound:" + e.currentTarget.name);
}
-=-=-=-=-=-=-=-=-
UPDATED (RE: viatropos)
-=-=-=-=-=-=-=-=-
can not find the error.
TypeError: Error #1009: Cannot access a property or method of a null object reference. at lesson12_start_fla::MainTimeline/loadSounds() at lesson12_start_fla::MainTimeline/frame1():
//Sounds
var soundByName:Object = {};
var channelByName:Object = {};
var soundName:String;
var channelName:String;
loadSounds();
function loadSounds():void
{
var files:Array = ["robotArm.mp3", "click.mp3"];
var i:int = 0;
var n:int = files.length;
for (i; i < n; i++)
{
soundName = files[i];
soundByName[soundName] = new Sound();
soundByName[soundName].addEventListener(Event.COMPLETE, sound_completeHandler);
soundByName[soundName].addEventListener(IOErrorEvent.IO_ERROR, sound_ioErrorHandler);
soundByName[soundName].load(new URLRequest(soundName));
}
}
function sound_completeHandler(event:Event):void
{
channelName = event.currentTarget.id3.songName;
channelByName[channelName] = new SoundChannel();
}
function sound_ioErrorHandler(event:IOErrorEvent):void
{
trace("Failed To Load Sound:" + event.currentTarget.name);
}
You can do this a few ways:
Storing your SoundChannels in an Array. Good if you care about order or you don't care about getting them by name.
Storing SoundChannels by any name in an Object. Good if you want to easily be able to get the by name. Note, the Object class can only store keys ({key:value} or object[key] = value) that are Strings. If you need Objects as keys, use flash.utils.Dictionary, it's a glorified hash.
Here's an example demonstrating using an Array vs. an Object.
var channels:Array = [];
// instead of creating a ton of properties like
// propA propB propC
// just create one property and have it keep those values
var channelsByName:Object = {};
function loadSounds():void
{
var files:Array = ["soundA.mp3", "soundB.mp3", "soundC.mp3"];
var sound:Sound;
var soundChannel:SoundChannel;
var i:int = 0;
var n:int = files.length;
for (i; i < n; i++)
{
sound = new Sound();
sound.addEventListener(Event.COMPLETE, sound_completeHandler);
sound.addEventListener(IOErrorEvent.IO_ERROR, sound_ioErrorHandler);
sound.load(files[i]);
}
}
function sound_completeHandler(event:Event):void
{
// option A
var channelName:String = event.currentTarget.id3.songName;
// if you want to be able to get them by name
channelsByName[channelName] = new SoundChannel();
// optionB
// if you just need to keep track of all of them,
// and don't care about the name specifically
channels.push(new SoundChannel())
}
function sound_ioErrorHandler(event:IOErrorEvent):void
{
trace("Failed To Load Sound:" + event.currentTarget.name);
}
Let me know if that works out.
//Load Sounds
var soundDictionary:Dictionary = new Dictionary();
var soundByName:Object = new Object();
var channelByName:Object = new Object();
loadSounds();
function loadSounds():void
{
var files:Array = ["robotArm.mp3", "click.mp3"]; //etc.
for (var i:int = 0; i < files.length; i++)
{
var soundName:String = files[i];
var sound:Sound=new Sound();
soundDictionary[sound] = soundName;
soundByName[soundName] = sound;
sound.addEventListener(Event.COMPLETE, sound_completeHandler);
sound.addEventListener(IOErrorEvent.IO_ERROR, sound_ioErrorHandler);
sound.load(new URLRequest(soundName));
}
}
function sound_completeHandler(e:Event):void
{
var soundName:String=soundDictionary[e.currentTarget];
channelByName[soundName] = new SoundChannel();
}
function sound_ioErrorHandler(e:IOErrorEvent):void
{
trace("Failed To Load Sound:" + soundDictionary[e.currentTarget]);
}
//Play Sound
channelByName["robotArm.mp3"] = soundByName["robotArm.mp3"].play();
//Stop Sound
channelByName["robotArm.mp3"].stop();

Resources