How do you upload a photo in Flex 3? - actionscript-3

In Flex 3 how to upload a photo ssing Browse and Upload option?
In Flex 4 there is an option like:
<net:FileReference id="fileReference"
select="fileReference_select(event);"
complete="fileReference_complete(event);" />
But in Flex 3 there is no <net> tag.
EDIT:
This is my Button click handler code
protected function uploadProfileImage(event:MouseEvent):void
{
var fileRef:FileReference= new FileReference();
browseButton.addEventListener(MouseEvent.CLICK, onButtonClick);
function onButtonClick(e:MouseEvent):void {
fileRef.browse([new FileFilter("Images", "*.jpg;*.gif;*.png")]);
fileRef.addEventListener(Event.SELECT, onFileSelected);
Alert.show("0")
}
function onFileSelected(e:Event):void {
fileRef.addEventListener(Event.COMPLETE, onFileLoaded);
//fileRef.load();
Alert.show("1");
}
function onFileLoaded(e:Event):void {
var loader:Loader = new Loader();
loader.loadBytes(e.target.data);
//addChild(loader);
profileImage.data = loader.content;
profileImage.width = loader.width;
profileImage.height = loader.height;
this.height = profileImage.height;
this.width = profileImage.width;
this.visible = true;
Alert.show("2");
}

There's no <net> tag in Flex 4 either. The net part in <net:FileReference... is an xml namespace. There are a bunch defined at the top of your application's MXML file. Here's a sample from a Flash-based Flex 4 app:
<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">
The xmlns:s="library://ns.adobe.com/flex/spark" is just mapping all the Spark components to the s namespace which allows you to reference Spark components like Button in MXML like this:
<s:Button label="My Button"/>
In the case of Spark Adobe has provided a manifest file that maps the fully qualified Spark packages to the familiar MXML names (this question has an example of such a file). You can also map AS3 package names to an xml namespace.
FileReference is in the flash.net package. You can bind that package to the net namespace by adding the following to the root tag in your MXML file:
xmlns:net="flash.net.*"
Once you do that you can reference classes in the flash.net package in MXML by prefixing them with "net" ala <net:FileReference....
Of course, FileReference doesn't inherit UIComponent so you won't be able to add it directly to your application. So that's probably not what is happening in your case.
Without seeing more than what you've posted I suspect that the FileReference in your question is a custom component that has it's package bound to the net xmlns.
Can you post the complete MXML document that has the <net:FileReference... tag in it?
EDIT
Using the code you added, in your script block have this:
var fileRef:FileReference = new FileReference();
function onButtonClick(e:MouseEvent):void {
fileRef.browse([new FileFilter("Images", "*.jpg;*.gif;*.png")]);
fileRef.addEventListener(Event.SELECT, onFileSelected);
fileRef.addEventListener(Event.CANCEL, onFileCanceled);
}
function onFileSelected(e:Event):void {
fileRef.removeEventListener(Event.SELECT, onFileSelected);
fileRef.removeEventListener(Event.CANCEL, onFileCanceled);
fileRef.addEventListener(Event.COMPLETE, onFileLoaded);
fileRef.load();
}
function onFileCanceled(e:Event):void {
fileRef.removeEventListener(Event.SELECT, onFileSelected);
fileRef.removeEventListener(Event.CANCEL, onFileCanceled);
}
function onFileLoaded(e:Event):void {
fileRef.removeEventListener(Event.COMPLETE, onFileLoaded);
var loader:Loader = new Loader();
loader.loadBytes(e.target.data);
profileImage.data = loader.content;
profileImage.width = loader.width;
profileImage.height = loader.height;
profileImage.visible = true;
}
Then in your MXML have something like:
<mx:Button
label="Click to Load Profile Image"
click="onButtonClick(event)"/>
<mx:Image
id="profileImage"
visible="false"/>
EDIT 2
If you are having problems with calling load() on FileReference make sure you are targeting the correct Flash Player. This answer explains how to do that in Flash Builder. IIRC, Flex 3 projects target Flash Player 9 be default.

Related

Item Renderer not Working correctly in Spark List

I used flex sdk 4.5 for creating Adobe Air application. My application download files one by one. I show the currently downloading, pending and completed files in spark list. I used item Renderer that show the progress of the file and other states.
It works fine if selected files fit in current view. But as number of downloads increase, the Spark list shows vertical scroll. here I have the problem. Here file downloading functionality works fine, but if I try to scroll the list, File titles mix up or displayed out of order.
item renderer code:
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer 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="onInit()"
>
<fx:Script><![CDATA[
import com.streamingnetworks.hdvrwin.vo.DownloadInfo;
import mx.events.CloseEvent;
[Bindable]private var downloadInfo:DownloadInfo;
private var url:String = "";
private var fileName:String = "";
private function onInit():void
{
downloadInfo = data as DownloadInfo;
downloadInfo.addEventListener("Progress", onProgress);
downloadInfo.addEventListener("DownloadComplete", onComplete);
prog.label = "Downloading %3%%";
lblPath.text = " - " + downloadInfo.getPathIp();
trace("Downloading: " + downloadInfo.name);
}
private function onProgress(e:Event):void
{
prog.setProgress(downloadInfo.downloadedBytes, downloadInfo.totalBytes);
lblState.text = downloadInfo.getDownState();
}
private function onComplete(e:Event):void
{
prog.label = "Download Complete";
}
protected function onClose(event:CloseEvent):void
{
downloadInfo.state = "deleted"
}
]]></fx:Script>
<s:TitleWindow top="0" left="0" right="0" bottom="0" dropShadowVisible="false"
title="{'Downloading ' + downloadInfo.name}" close="onClose(event)">
<mx:ProgressBar id="prog" label="" mode="manual"
trackHeight="20" labelPlacement="center" width="100%"/>
<s:HGroup top="25">
<s:Label id="lblState" text="Downloading 0 Bytes of 0 Bytes."/>
<s:Label id="lblPath"/>
</s:HGroup>
</s:TitleWindow>
</s:ItemRenderer>
here the list control where I am using that renderer
<s:List id="lstControls" dataProvider="{urlArr}"
itemRenderer="ItemRenderer"
left="5" right="5" bottom="5" top="40"/>
urlArr is an arrayList that contains only url in string form.
How can I solve this problem? Any Help will be appreciated. Thanks
Your renderers are not updating correctly because you are setting your data when the renderer is created - but you should be overriding the set data method, eg:
override public function set data(value:Object):void
{
super.data = value;
downloadInfo = data as DownloadInfo;
downloadInfo.addEventListener("Progress", onProgress);
downloadInfo.addEventListener("DownloadComplete", onComplete);
prog.label = "Downloading %3%%";
lblPath.text = " - " + downloadInfo.getPathIp();
trace("Downloading: " + downloadInfo.name);
}
And remove the creationComplete listener.
As a better practice. Have all the data your progress bars will need all ready in the data provider and have them react ONLY to changes in the data. Adding and removing listeners and binding internally will only cause you grief. Renderers do not live forever and are re-used inside of list components. Manage everything through overriding set data().
In this example I would create a model object with a name like FileDownloadInfo and properties such as .downloadProgress .fileName and .ipAddress then have the renderer update on property change events of .downloadProgress

as3 / flex interface incompatibility when loading external swf

I have a main project, and i want to load another project's swf into it:
//loader code in Main class of main project
var url:URLRequest = new URLRequest("../src/components/TextTool.swf");
var ttWrapper:UIComponent = new UIComponent();
var ldr:SWFLoader = new SWFLoader();
var context:LoaderContext = new LoaderContext();
if (Security.sandboxType == Security.LOCAL_TRUSTED) {
context.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);
} ldr.source = "../src/components/TextTool.swf";
ldr.loaderContext = context;
ldr.addEventListener(Event.COMPLETE, onLoadComplete);
ldr.load();
can.addElement(ldr);
Here's the code of the Main class of the second project:
<?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:stark="stark.*" name="textModule" >
<stark:TextTool name="myTF" id="myTF"></stark:TextTool>
</s:Application>
Now both of the projects contain an interface file : IModule, with the same code, and an element of the second project (the one that's being loaded) which is an instance of my custom class "TextTool", which extends s:Group and implements IModule:
<s:Group 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="400"
xmlns:com="src"
height="130" creationComplete = "initText()" implements="IModule"></s:Group>
Now as soon as i've loaded the swf, i want to access that TextTool instance which has and id of "myTF" :
//Code in the main class of the main project
trace(getQualifiedClassName(mySwf.getChildByName('textModule')['myTF']));
trace(mySwf.getChildByName('textModule')['myTF'] is IModule);
//output:
//stark::TextTool
//false
As i've mentioned above, i have the interface in both projects, same code, it has the same path relative to main classes, and myTF does extend IModule. After the swf is loaded, i get the right element, but i still get false when verifying if it implements IModule.
Why?
You're testing Application for implementation
trace(mySwf.getChildByName('textModule') is IModule);
I think you forgot to add ['myTF']
trace(mySwf.getChildByName('textModule')['myTF'] is IModule);
You're loading both into different ApplicationDomains, so whichever loads first wins. Try loading them into the same ApplicationDomain.

flashvars not loading in Flex 4.5 application in Adobe Flash Builder

I am following this adobe flashvars example to try and get flashvars loading in my flex 4.5 application. However, the code is not working. I don't really understand what I'm doing wrong, or differently from the example. here is my index.template.html code (in the html-template folder) which uses swfobject to load the application:
function embedPlayer() {
var flashvars = {};
flashvars.userLoggedIn = true;
flashvars.test = "hello";
embedSWF(SWF_FILE, SWF_ID, SWF_WIDTH, SWF_HEIGHT, "9.0", "playerProductInstall.swf", flashvars);
}
And here is the simplified code from my flex application:
<?xml version="1.0" encoding="utf-8"?>
<s:Application
xmlns:d="http://ns.adobe.com/fxg/2008/dt"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:c="components.*"
initialize="mainInit()"
creationComplete="doCreationComplete()"
applicationComplete="_initializer.applicationComplete()"
xmlns:application="components.application.*"
xmlns:gui="com.gui.*" xmlns:main="com.gui.components.main.*" xmlns:photoTray="com.gui.components.main.photoTray.*">
<fx:Style source="/assets/all.css" />
<fx:Script>
<![CDATA[
import com.gui.components.main.Initializer;
import com.gui.components.main.LayoutsController;
import mx.core.FlexGlobals;
private var _initializer:Initializer;
private var _layoutsController:LayoutsController;
public var userLoggedIn:Boolean;
private function mainInit():void {
_initializer = new Initializer(this);
}
private function doCreationComplete():void {
_initializer.init();
var params:Object = FlexGlobals.topLevelApplication.parameters;
//userLoggedIn = params.userLoggedIn;
_layoutsController = new LayoutsController(this);
}
]]>
</fx:Script>
</s:Application>
I call FlexGlobals.topLevelApplication.parameters (after creationComplete) to try and access flashvars, which is what adobe says is the way to do it in flex 4.5. From my research using Application.application.parameters and root.loaderInfo.parameters are both deprecated.
Does anyone see what I am doing wrong? My application works fine in flash builder except for flashvars loading on creationComplete.
Thanks
This is how I do it in flex 3 not sure it applies to flex 4.5
Application.application.parameters.userLoggedIn
Also on this line
//userLoggedIn = params.userLoggedIn;
The value of any flash var is a string which you are trying to assign a Boolean.
So do this.
//userLoggedIn = Boolean(params.userLoggedIn);

How to use external actionscript classes in FlashBuilder (thought I knew)

I'm trying to implement CSVLib in an Air application and am getting an error that seems wholly illogical to me.
"1120: Access of undefined property csv."
and
"1120: Access of undefined property completeHandler."
The only thing I can think is it's not importing the csv class properly, or the class itself is broken somehow? I know my import path is correct because I typed it out directly based on automatic hinting. The code below is copied directly from the how-to wiki on the csv lib site.
Or is there something special you need to do to get external actionscript classes to work in flashbuilder?
<fx:Script>
<![CDATA[
import com.shortybmc.*;
import com.shortybmc.data.parser.CSV;
var csv:CSV = new CSV();
csv.addEventListener (Event.COMPLETE, completeHandler);
csv.load (new URLRequest('example-2.csv'));
function completeHandler (event: Event)
{
trace ( csv.data.join('\r') );
// do something ...
}
]]>
</fx:Script>
In this case, the problem is somewhere else. The fx:Script tag is within a MXML file, which represents a class definition.
Your error happens, because you have code within the class definition (i.e. outside of a method). You can write this instead for example:
<fx:Script>
<![CDATA[
import com.shortybmc.*;
import com.shortybmc.data.parser.CSV;
private var csv:CSV;
private function init ():void
{
csv = new CSV();
csv.addEventListener (Event.COMPLETE, completeHandler);
csv.load (new URLRequest('example-2.csv'));
}
private function completeHandler (event: Event):void
{
trace ( csv.data.join('\r') );
// do something ...
}
]]>
</fx:Script>
Then you need to make sure that the init method is actually called; you can do this in the complete handler of your MXML object.

How to run an external SWF inside a Flex Application?

EDIT: Due to the answer I change the code posted. I've added the Security.allowDomain("*") line and that line throws me an error. So, how can that be made?
I want to run an Action Script 3.0 Application into a Flex Application. To do this I've done the following:
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication windowComplete="loadSwfApplication()" xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
private function loadSwfApplication()
{
// The next line throws me an error.
Security.allowDomain("*");
var urlRequest:URLRequest = new URLRequest("path/to/the/application.swf");
swfLoader.addEventListener(Event.COMPLETE, loadComplete);
swfLoader.load(urlRequest);
}
private function loadComplete(completeEvent:Event)
{
var swfApplication:* = completeEvent.target.content;
swfApplication.init(); // this is a Function that I made it in the Root class of swfApplication
}
]]>
</mx:Script>
<mx:SWFLoader id="sfwLoader"/>
</mx:WindowedApplication>
The problem is that in the calling of swfApplication.init(); the AIR Player throws me an exception:
Security sandbox violation: caller file:///path/to/the/application.swf cannot access Stage owned by app:/SWFApplicationLoader.swf.
This is because somewhere in application.swf I use the stage like this:
if (root.stage != null)
root.stage.addEventListener(Event.REMOVED, someFunction);
root.stage.stageFocusRect = false;
How can I load this swf application and USE the stage without any problems?
You can try to load your SWF temporarily into a ByteArray and then load it with your SWFLoader.
Don't forget to set allowCodeImport to true since your SWF has as code inside.
Of course be sure that your loaded swf is secure enough for your application since it will have access at all your property.
private function loadSwfApplication():void {
// load the file with URLLoader into a bytearray
var loader:URLLoader=new URLLoader();
// binary format since it a SWF
loader.dataFormat=URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, onSWFLoaded);
//load the file
loader.load(new URLRequest("path/to/the/application.swf"));
}
private function onSWFLoaded(e:Event):void {
// remove the event
var loader:URLLoader=URLLoader(e.target);
loader.removeEventListener(Event.COMPLETE, onSWFLoaded);
// add an Application context and allow bytecode execution
var context:LoaderContext=new LoaderContext();
context.allowCodeImport=true;
// set the new context on SWFLoader
sfwLoader.loaderContext = context;
sfwLoader.addEventListener(Event.COMPLETE, loadComplete);
// load the data from the bytearray
sfwLoader.load(loader.data);
}
// your load complete function
private function loadComplete(completeEvent:Event):void {
var swfApplication:* = completeEvent.target.content;
swfApplication.init(); // this is a Function that I made it in the Root
// class of swfApplication
}
If they are being loaded from different domains you are going to have to add a security exception - http://livedocs.adobe.com/flex/3/html/help.html?content=05B_Security_08.html
if its being run locally youre probably going to have to add them to the list of trusted files or folders in the settings manager - http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html#117502
Assuming that the external SWF is also in the application directory, you could try loading it using the app:/ scheme:
var urlRequest:URLRequest = new URLRequest("app:/path/application.swf");
That may put it into the same security context as the main application.
One thing you may want to consider is that if you are trying to run a SWF from inside your application directory in AIR, AIR restricts execution of files. If you copy the file to a temp file and the run it (along with allowLoadBytesCodeExecution set to true) then it works.
var file:File = File.applicationDirectory.resolvePath("myFile.swf");
this.tmpFile = File.createTempDirectory().resolvePath("myFile.swf");
file.copyTo(this.tmpFile);
imagePreview.loaderContext = lc;
imagePreview.source = tmpFile.url;
it won't work for Flex Projectors.
Only we use SWFLoader and LocalConnection because they can communicate between external swf and main swf. Thanks for support!
Can you read my tutorial from Adobe's Forum
It is very better than MovieClip or Object-Callers
Thank for resolved solution :)
Best regards, Jens