Flex 4 - Embedding Multiple MP3's - actionscript-3

I have an mp3 embedded in a Flex application with a start and stop button. Using this code...
<fx:Script>
<![CDATA[
import mx.core.SoundAsset;
import flash.media.*;
[Embed(source="assets/pie-yan-knee.mp3")]
[Bindable]
public var Song:Class;
public var mySong:SoundAsset = new Song() as SoundAsset;
public var channel:SoundChannel;
public function playSound():void
{
stopSound();
channel = mySong.play();
}
public function stopSound():void
{
if ( channel != null ) channel.stop();
}
]]>
</fx:Script>
<s:HGroup>
<s:Button label="play" click="playSound();"/> <s:Button label="stop"
click="stopSound();"/>
</s:HGroup>
I want to have multiple instances with different sounds though.
How can I do this?

Just make a separate class reference for each:
[Embed(source="assets/song1.mp3")]
[Bindable]
public var Song1:Class;
[Embed(source="assets/song2.mp3")]
[Bindable]
public var Song2:Class;
[Embed(source="assets/song3.mp3")]
[Bindable]
public var Song3:Class;

Related

Tabbing does not work in mx:TileList component

I am using mx:Tilelist component to display set of textfields on screen, but when i try to traverse the fields through TAB foucs move out of the list. Please provide solution for this problem. Following is the code i am using
<mx:TileList id="tileList"
dataProvider="{collection}"
change="setCurrentIndex(tileList.selectedIndex);"
dataChange="setCurrentIndex(tileList.selectedIndex);"
columnCount="1"
columnWidth="345"
itemRenderer="components.InputParamIR"
rowHeight="30"
verticalScrollPolicy="auto"
horizontalScrollPolicy="auto"
backgroundColor="#EEEEEE"
dragEnabled="false"
dragMoveEnabled="true"
dropEnabled="true"
width="100%" height="100%"
itemClick="chartTileClick(event);"
/>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.containers.Panel;
[Bindable]
public var index:uint;
[Bindable]
public var collection:ArrayCollection = new ArrayCollection();
[Bindable]
public var isVisible:Boolean ;
public function initEventsLocal(event:Event):void
{
this.initEvents(event);
collection = new ArrayCollection();
isVisible = false;
}
private function chartTileClick(event:ListEvent):void
{
event.currentTarget.tabFocusEnabled=true;
event.currentTarget.tabEnabled=true;
}
]]>
</fx:Script>
In Flex List Itemrenderer may not get the focus since it is non editable and it will not implement the focus manager interface, you need to implement IFocusManagerComponent in your item renderer components.InputParamIR also you have to override your TileList class to enable tab for childrens.
package
{
import mx.controls.TileList;
public class MyTileList extends TileList
{
override protected function createChildren():void {
super.createChildren();
this.listContent.tabChildren = this.tabChildren
this.listContent.tabEnabled = this.tabEnabled
}
}
}
Have a look in to these
Tile list item renderer text focus solved
Issues with keyboard navigation on list with custom renderer
i hope this will help you
happy coding...

Can't display video coming in from NetStream properly

I am basically starting work with Flex and netstream for video calls. So I was able to read a bit about Netstreams and streaming and I wrote this code to get my camera and publish my stream in a video display below in the view but even though I pass through all the methods without any error, the display is not showing so I don't really know what's going on. Here is what I did.
<?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" applicationDPI="160" creationComplete="start();">
<fx:Script>
import flash.media.Camera;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.ObjectEncoding;
import flash.events.AsyncErrorEvent;
import flash.events.NetStatusEvent;
import flash.net.NetStream;
import mx.graphics.ImageSnapshot;
import mx.graphics.codec.JPEGEncoder;
public var camera:Camera;
var video:Video;
public var myVideo:Video;
private var nc:NetConnection;
private var rtmpf:String="rtmfp://p2p.rtmfp.net/61c33c80be7022350a0dea3d-960194f988ba/";
private const DEVKEY:String = "61c33c80be7022350a0dea3d-960194f988ba";
public var in_ns:NetStream;
public var out_ns:NetStream;
public function start():void{
trace("Started the start function");
nc=new NetConnection();
nc.objectEncoding = ObjectEncoding.AMF0;
nc.client=this;
nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
nc.connect(rtmpf);
}
public function netStatusHandler(event:NetStatusEvent):void{
switch(event.info.code){
case "NetConnection.Connect.Success":
trace("Received the status");
initStart();
default:
trace( event.info.code);
}
}
public function initStart():void{
trace("Started the initstart function");
initNetStream();
initMyVideo();
publish();
playIt();
}
public function initNetStream():void{
trace("Started the initNetstream start function");
out_ns=new NetStream(nc);
out_ns.client=this;
in_ns=new NetStream(nc);
in_ns.client=this;
}
public function publish():void{
trace("Started the publish function");
camera=Camera.getCamera();
out_ns.attachCamera(camera);
out_ns.publish("Me", "live");
}
public function startCamera(muteCam:Boolean=false):void{
if(!video)
video = new Video();
trace("Started the startCamera function");
camera=Camera.getCamera();
if(muteCam){
video.attachCamera(camera);
//out_ns.attachCamera(camera);
//out_ns.publish("Me", "live");
vidHolder.addChild(video);
}else{
video.attachCamera(null);
if(contains(video))
vidHolder.removeChild(video);
//camera=null;
}
}
public function initMyVideo():void
{
trace("Started the initmyvideo function");
myVideo = new Video(230,160);
myVideo.x = 10;
myVideo.width = 230;
myVideo.height = 160;
myVideo.y = 30;
// myVid.addChild(myVideo);
}
public function playIt():void{
trace("Started the play it function");
myVideo.attachNetStream(in_ns);
in_ns.play("Me");
myVid.addChild(myVideo);
}
public function stopCamera():void{
vidHolder.removeChild(video);
}
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Button x="116" y="28" label="Start" click="startCamera(true)"/>
<s:VideoDisplay id="vidHolder" x="31" y="87" width="200" height="100"
/>
<s:VideoDisplay id="myVid" x="31" y="250"/>
<s:Button id="stop" x="208" y="28" label="Stop" click="startCamera(false)"/>
</s:Application>
These are some reasons that is stopping from displaying the stream.
Are you testing it on the same browser using your same webcam device
driver ?
Possibility is that you were not able to see it maybe since the driver is being used.
Get a virtual webcam driver from a website ManyCam and test it out. Your application will work.

How avoid focus on a control in Flex?

I have a Custom Component the parent is Group with Horizontal layout, in that i have two controls one is TextInput and other is datefield. When use this custom component in ant place i provide tabindex to that control as a whole.
I want just that if user tab(keyborad) then when focus on the Textinput the focus does't on dateField.
How i achieve this.
Here is my Code.
<?xml version="1.0" encoding="utf-8"?>
<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="100%" height="20"
xmlns:components="com.zigron.controls.extended.components.*"
creationComplete="creComp()">
<!--
Author : Tahir Alvi
Date : 11/06/2012
Place : Zigron Inc
-->
<fx:Declarations>
<mx:DateFormatter id="formatter" formatString="MM/DD/YYYY" />
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.controls.TextInput;
import mx.events.CalendarLayoutChangeEvent;
import spark.events.TextOperationEvent;
private var _selectedDate:Date;
private var _text:String='';
private var _propmt:String='DOB';
//---- creation Complete ----------
private function creComp():void
{
id_dob.tabIndex = tabIndex;
}
//--At the initlize of datefield hide the Textinput ---
protected function init():void
{
var tf:TextInput = df.mx_internal::getTextInput();
tf.visible = false;
tf.includeInLayout = false;
}
//-- date change handler ---
protected function df_changeHandler(event:CalendarLayoutChangeEvent):void
{
id_dob.text = formatter.format(df.selectedDate.toString());
text = id_dob.text;
selectedDate = df.selectedDate;
}
// -- Text Input Change handler and apply masking on it -------
protected function id_txt_changeHandler(event:TextOperationEvent):void
{
var s:String = id_dob.text.replace(/[^0-9]/g,"");
id_dob.text = s.substring(0,2) + (s.length>2?"/"+s.substring(2,4) + (s.length>4?"/"+s.substring(4,8):""):"");
id_dob.selectRange(id_dob.text.length, id_dob.text.length);
text = id_dob.text;
if(text.length)
{
selectedDate = null;
}
else
{
text = '';
}
}
[Bindable]
public function get selectedDate():Date
{
return _selectedDate;
}
public function set selectedDate(value:Date):void
{
_selectedDate = value;
}
[Bindable]
public function get text():String
{
return _text;
}
public function set text(value:String):void
{
_text = value;
if(_text.length)
id_dob.text = _text;
}
[Bindable]
public function get propmt():String
{
return _propmt;
}
public function set propmt(value:String):void
{
_propmt = value;
}
]]>
</fx:Script>
<s:layout>
<s:HorizontalLayout horizontalAlign="left" verticalAlign="top" gap="2"/>
</s:layout>
<components:LabelTextInput id="id_dob"
width="100%" prompt="{propmt}" change="id_txt_changeHandler(event)"/>
<mx:DateField id="df"
initialize="init()" width="20" change="df_changeHandler(event)" selectableRange="{{rangeEnd:new Date()}}"
toolTip="Select Date of Birth" yearNavigationEnabled="true" textInputStyleName="mandatoryDateSkin"
maxYear="{new Date().getFullYear()}" minYear="1901"/>
</s:Group>
i had a similar problem with a custom component with a textinput inside him. My solution was create a public var, something like this:
//This is my component MyComponent...
[Bindable] public var fTabIndex:int = -1;
<mx:TextInput id="field" tabIndex="{fTabIndex}"/>
(Other component...)
//Other component
<mx:TextInput tabindex="1"/>
<control:MyComponent fTabIndex="2"/>
I hope it will be helpful.
set enabled = "false";
and change it in code when required.

In label, value is not displaying which is used in module

I am trying to call a function (having two parameters) of module and assign values to it.
I can see the value being assigned in trace, but the same value is not displaying when it is assigned to label.
If I directly assign the value to label. It says:
Error:1009: Null object Reference
If I use [Bindable] meta tag to that label, it won't show any runtime error but the value is also not displayed. I have searched the internet and found that the [Bindable] meta tag works as try and catch blog.
How to get value display assign to label?
Main.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:custom="com.custom.*" xmlns:local="*" creationComplete="onload()">
<mx:Script>
<![CDATA[
import modules.AModule;
import mx.events.ModuleEvent;
import mx.containers.VBox;
import mx.containers.TitleWindow;
import mx.controls.TextInput;
import mx.controls.Button;
import mx.containers.HBox;
import mx.controls.Label;
import mx.events.CloseEvent;
import mx.controls.Text;
import com.custom.CustomAlert;
import mx.controls.Alert;
import mx.containers.Canvas;
import mx.events.ItemClickEvent;
import mx.core.UIComponent;
import mx.modules.ModuleManager;
import mx.modules.IModuleInfo;
import mx.containers.Box;
import mx.controls.ProgressBar;
//private var can:Canvas;
public var titlewin:TitleWindow = new TitleWindow();
public var usern:TextInput = new TextInput();
public var passw:TextInput = new TextInput();
public var vb:VBox = new VBox();
public var hb1:HBox = new HBox();
public var hb2:HBox = new HBox();
public var hb3:HBox = new HBox();
public var nc:NetConnection;
public var bt1:Button = new Button();
private var pb:ProgressBar;
private var progressContainer:Box;
private var info:IModuleInfo;
private var module:UIComponent = null;
public var can:Canvas= new Canvas();
public function onload():void
{
var label1:Label= new Label();
var label2:Label= new Label();
label1.text="Username";
label2.text="Password ";
hb1.addChild(label1);
hb1.addChild(usern);
hb2.addChild(label2);
hb2.addChild(passw);
vb.addChild(hb1);
vb.addChild(hb2);
bt1.label="Sign In";
hb3.addChild(vb);
hb3.addChild(bt1);
titlewin.addChild(hb3);
//Title Window creation starts here
titlewin.title="Login";
titlewin.setStyle("paddingLeft",20);
titlewin.setStyle("paddingRight",20);
titlewin.setStyle("paddingTop",20);
titlewin.setStyle("paddingBottom",20);
titlewin.setStyle("borderThicknessBottom",0);
titlewin.setStyle("borderThicknessLeft",0);
titlewin.setStyle("borderThicknessRight",0);
titlewin.setStyle("borderThicknessTop",0);
titlewin.setStyle("cornerRadius",0);
titlewin.setStyle("borderColor","#D20101");
this.addChild(titlewin);
viewStack.enabled=false;
ctbb.enabled=false;
bt1.addEventListener(MouseEvent.CLICK, netconn);
}
private function onclick():void
{
if(usern.text!="")
{
this.removeChild(titlewin);
viewStack.enabled=true;
ctbb.enabled=true;
username.text=usern.text;
}
else
{
Alert.show("Please enter Username");
}
}
private function netconn(event:MouseEvent):void
{
nc = new NetConnection();
nc.connect("rtmp://localhost/loginhere",usern.text);
nc.addEventListener(NetStatusEvent.NET_STATUS, onstatushandler);
}
private function onstatushandler(event:NetStatusEvent):void
{
if(event.info.code=="NetConnection.Connect.Success")
{
status.text="Connected";
onclick();
}
if(event.info.code=="NetConnection.Connect.Rejected")
{
status.text="Rejected";
}
if(event.info.code=="NetConnection.Connect.Failed")
{
status.text="Failed";
}
}
private function JoinClick(event:MouseEvent):void{
if(viewStack.numChildren==3)
{
Alert.show("You Cant Add More Button","Alert");
}
if(viewStack.numChildren<3)
{
if(viewStack.numChildren<2)
{
can.label="Button2";
var button1:CustomButton= new CustomButton();
button1.label="Leave Table";
button1.x=300;
button1.y=200;
var txt:Text = new Text();
txt.text=can.label;
txt.x=50;
txt.y=50;
button1.addEventListener(MouseEvent.CLICK,remove2);
can.addChild(button1);
can.addChild(txt);
loadmodule();
}
else
{
can.label="Button3";
var button2:CustomButton= new CustomButton();
button2.label="Leave Table";
button2.x=300;
button2.y=200;
button2.addEventListener(MouseEvent.CLICK,remove3);
can.addChild(button2);
var txt1:Text = new Text();
txt1.text=can.label;
txt1.x=50;
txt1.y=50;
can.addChild(txt1);
}
can.setStyle("backgroundColor","0x5EA5BA");
viewStack.addChild(can);
if(viewStack.numChildren>2)
{
viewStack.selectedIndex=2;
}
else
{
viewStack.selectedIndex=1;
}
}
}
private function remove2(event:MouseEvent):void{
Alert.show("Do you want to Leave Table?","Confirmation",Alert.YES|Alert.NO,this,closeAlert2);
}
private function closeAlert2(event:CloseEvent):void{
if(event.detail==Alert.YES)
{
viewStack.removeChildAt(1);
}
}
private function remove3(event:MouseEvent):void{
if(viewStack.numChildren>2)
{
Alert.show("Do You want to leave Table?","Confirmation",Alert.YES|Alert.NO,this,closeAlert3);
}
else
{
Alert.show("Do you want to Leave Table?","Confirmation",Alert.YES|Alert.NO,this,closeAlert1);
}
}
private function closeAlert1(event:CloseEvent):void{
if(event.detail==Alert.YES)
{
viewStack.removeChildAt(1);
}
}
private function closeAlert3(event:CloseEvent):void{
if(event.detail==Alert.YES)
{
viewStack.removeChildAt(2);
}
}
private function loadmodule():void
{
pb = new ProgressBar();
pb.labelPlacement = "center";
pb.label = "Loading %3 %";
progressContainer = new Box();
progressContainer.percentWidth = 100;
progressContainer.percentHeight = 100;
progressContainer.setStyle("horizontalAlign", "center");
progressContainer.setStyle("verticalAlign", "middle");
progressContainer.addChild(pb);
can.addChild(progressContainer);
var moduleUrl:String="../bin-debug/modules/useModule.swf";
info=ModuleManager.getModule(moduleUrl);
if(info!=null)
{
info.addEventListener(ModuleEvent.READY, modEventHandler);
info.addEventListener(ModuleEvent.ERROR,modErrorHandler);
info.load();
}
}
private function modEventHandler(e:ModuleEvent):void
{
info.removeEventListener(ModuleEvent.READY, modEventHandler);
info.removeEventListener(ModuleEvent.ERROR, modErrorHandler);
can.removeAllChildren();
if(module==null)
{
module = info.factory.create() as UIComponent;
if(module!=null)
{
module.x=0;
module.y=0;
module.percentWidth=100;
module.percentHeight=100;
can.addChild(module);
if(module is AModule)
{
}
}
}
}
private function modErrorHandler(event:ModuleEvent):void {
//cleanup and display an error alert
info.removeEventListener(ModuleEvent.READY, modEventHandler);
info.removeEventListener(ModuleEvent.ERROR, modErrorHandler);
info = null;
Alert.show(event.toString(), "Error Loading Module");
unloadModule();
}
private function unloadModule():void
{
can.removeAllChildren();
if (module != null && info != null) {
info.addEventListener(ModuleEvent.UNLOAD, unloadEventHandler);
info.unload();
}
}
private function unloadEventHandler(e:ModuleEvent):void
{
info.removeEventListener(ModuleEvent.UNLOAD, unloadEventHandler);
module = null;
info = null;
}
]]>
</mx:Script>
<mx:Canvas width="700" height="400" x="166" y="32">
<mx:ViewStack id="viewStack" width="100%" height="100%">
<mx:Canvas label="Button1" backgroundColor="#5EA5BA" visible="true" id="can1" >
<local:CustomButton label="Join" click="JoinClick(event)" x="536" y="222"/>
<mx:Label x="304" y="120" text="Label" id="username"/>
<mx:Label x="304" y="55" text="Label" id="status"/>
</mx:Canvas>
</mx:ViewStack>
</mx:Canvas>
<custom:CustomControlBar x="166" y="423" id="ctbb">
<custom:CustomToggleButtonBar dataProvider="viewStack"/>
</custom:CustomControlBar>
</mx:Application>
useModule.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="508" height="218" implements="modules.AModule" backgroundColor="#F00F0F" creationComplete="addlabel();">
<mx:Script>
<![CDATA[
import mx.core.Application;
public var logsin:loginhere = new loginhere();
public function addlabel():void
{
lb1.text=logsin.username.text;
txt3.text=logsin.username.text;
trace(txt3.text);
trace(lb1.text);
}
]]>
</mx:Script>
<mx:TextInput id="txt3" x="30.5" y="10" width="79"/>
<mx:Label id="lb1" x="31.5" y="40" width="78" text="Will it Change?"/>
</mx:Module>
AModule.as (Its an interface)
package modules
{
import flash.events.IEventDispatcher;
public interface AModule extends IEventDispatcher
{
function addlabel():void;
}
}
I haven't looked through the entire code, but one thing I noticed is that you should pass the values on as parameters to the child components and use data binding to dynamically update parameters.
So in AModule.as:
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="508" height="218" implements="modules.AModule" backgroundColor="#F00F0F" creationComplete="addlabel();">
<mx:Script>
<![CDATA[
import mx.core.Application;
public var logsin:loginhere = new loginhere();
[Bindable]
public var username:String = "";
]]>
</mx:Script>
<mx:TextInput id="txt3" text="{username}" x="30.5" y="10" width="79"/>
<mx:Label id="lb1" text="{username}" x="31.5" y="40" width="78" text="Will it Change?"/>
</mx:Module>
In the method where you create the module you can then:
module.username = //var that holds username;
The point I missed was, I dint create a instance for interface in main.mxml
The var should be created in modEventHandler function In that function the below lines should be added
ichild=module as AModule;
ichild.addlabel(tt.text);
so the module gets called and the value is displayed in the label field.
Please let me know, if its wrong way of working. Thank You

Send data from popup to main application.

I'm not getting the answer I'm looking for.
I want to send the request data i get to the main application.
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" remove="titlewindow1_removeHandler(event)"
width="400" height="220" layout="absolute" title="USER LOGIN">
<mx:Metadata>
[Event(name="commEvent", type="flash.events.Event")]
</mx:Metadata>
<mx:Script>
<![CDATA[
import data.Data;
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
[Bindable]
public var userID:String;
private function loginUser():void{
trace("btn");
var req:URLRequest = new URLRequest('http://localhost/CCN/userProcess.php');
var loader:URLLoader = new URLLoader();
req.method="POST";
var variables:URLVariables = new URLVariables();
variables.email= username.text;
variables.password= password.text;
variables.action= "login_user";
req.data=variables;
loader.addEventListener(Event.COMPLETE,onDataLoaded);
loader.load(req);
}
protected function loginButton_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
loginUser();
}
private function onDataLoaded(e:Event):void{
var xml:XML= new XML(e.target.data);
if(xml.status=="success"){
//SEND DATA TO MAIN APPLICATION ????
PopUpManager.removePopUp(this);
}else{
fail.visible=true;
username.text="";
password.text="";
username.setFocus();
}
}
protected function loginButton_keyDownHandler(ee:KeyboardEvent):void
{
// TODO Auto-generated method stub
if(ee.keyCode==13){
loginUser();
}
}
protected function titlewindow1_removeHandler(event:FlexEvent):void
{
// TODO Auto-generated method stub
}
]]>
</mx:Script>
<mx:TextInput id="username" x="141" y="31" width="199" text=""/>
<mx:TextInput keyDown="loginButton_keyDownHandler(event)" text="000" id="" x="141" y="84" width="199" displayAsPassword="true"/>
<mx:Button id="loginButton" x="275" y="133" label="LOGIN" click="loginButton_clickHandler(event)"/>
<mx:Label x="22" y="33" text="Email"/>
<mx:Label x="22" y="86" text="Password"/>
<mx:Label x="22" visible="false" y="135" id="fail" color="#FF0000" text="LOGIN FAILED"/>
</mx:TitleWindow>
here is the main application code
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
minWidth="955" minHeight="600" backgroundColor="#FFFFFF"
creationComplete="application1_creationCompleteHandler(event)" layout="absolute">
<mx:Script>
<![CDATA[
import mx.containers.TitleWindow;
import mx.core.IFlexDisplayObject;
import mx.events.CloseEvent;
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
//private var loginWindow:TitleWindow;
public var user:String;
private var login:Login
private function application1_creationCompleteHandler(event:FlexEvent):void
{
// TODO Auto-generated method stub
login = Login(
PopUpManager.createPopUp(this, Login, true));
PopUpManager.centerPopUp(login);
//login['loginButton'].addEventListener(MouseEvent.CLICK,onClose);
login.addEventListener(CloseEvent.CLOSE,oncc)
}
private function onClose(e:Event):void{
trace("Trace : "+login.userID);
}
private function
]]>
</mx:Script>
</mx:Application>
I would recommend solving this by adding a custom event, as your tag implies you may understand.
If not, here are the steps you would follow.
1) Create a new Event type (extend the Event class in actionscript - be sure to override clone())
2) Add an event listener for your new Event type in the parent application on the popup
3) cause the popup to dispatch your new Event type before it closes
4) Handle whatever it is you're looking for (userID?) in the event handler.
I would recommend attaching the userID to the actual event, so that the parent is not directly addressing login.userID. From a loose coupling standpoint, it's more correct. That said, if you don't wish to, you can simplify the solution by NOT attaching the userID. Loose coupling is a great goal, but if you only plan to use this relationship once, it's not incredibly necessary.
If you choose to go the tighter coupling route, then you only have to dispatch an event with a custom "type" instead of an extended Event.
If you need a lower level example (less description, more code) let me know, and I can help with that as well.
The example provided below is the slightly more complex version, where you extend an event to contain the data.
Event class::
package mycomponents
{
import flash.events.Event;
public class CustomEvent extends Event
{
public static const EVENT_TYPE_NAME:String = "myEventType"
public var mUserID:String = "";
public var mSuccess:Boolean = false;
public function CustomEvent(aType:String, aUserID:String, aSuccess:Boolean)
{
super(aType)
mUserID = aUserID;
mSuccess = aSuccess;
}
override public function clone():Event
{
var lEvent:CustomEvent = new CustomEvent(mUserID, mSuccess);
return lEvent;
}
}
}
In Popup::
private var loginSuccessful:Boolean = false;
private function onDataLoaded(e:Event):void{
var xml:XML= new XML(e.target.data);
if(xml.status=="success"){
userID = username.text;
loginSuccessful = true;
//SEND DATA TO MAIN APPLICATION
dispatchEvent(new CustomEvent(CustomEvent.EVENT_TYPE_NAME, userID, loginSuccessful );
PopUpManager.removePopUp(this);
}else{
fail.visible=true;
username.text="";
password.text="";
username.setFocus();
}
}
protected function titlewindow1_removeHandler(event:FlexEvent):void
{
if (!loginSuccessful)
dispatchEvent(new CustomEvent(CustomEvent.EVENT_TYPE_NAME," userID, loginSuccessful ));
}
And in the Main Application::
import mycomponents.CustomEvent;
private function application1_creationCompleteHandler(event:FlexEvent):void
{
//...your code
login.addEventListener(CustomEvent.EVENT_TYPE_NAME, handleLoginEvent);
}
private function handleLoginEvent(aEvent:CustomEvent)
{
//My example code dispatches an event with mSuccess = false if the login prompt closes
//without a successful login
//
//now do whatever you want with the information from the popup
//aEvent.mUserID gets you ID
//aEvent.mSuccess gets you success
}
Tossed that together in the middle of a break at work, so no promises will compile as-is.