More than one titleWindow in a Flex Application - apache-flex

I'm a GIS Analyst that was moved to an Analyst Programmer position. This has been a hard transition for me as I don't have much of a programming background, but I was thrown into it.
I'm working on a Flex app inside a jsp page. Essentially it is a grid 3x2 that has images and text. What I am trying to do is have more than one titleWindow reference in this page, so that when an image is clicked a titleWindow is opened. (If anyone has a better idea, especially if it has to do with a hover I am very open to that!) Currently I have it working for one image. However, when I try to add a second function it errors on me. "Error 1021: Duplicate function definition" Below is the entire code for the main page that calls up the titleWindow. The code below is what gives the Error 1021.
<?xml version="1.0" encoding="utf-8"?>
<![CDATA[
import flash.geom.Point;
import mx.containers.TitleWindow;
import mx.core.IFlexDisplayObject;
import mx.managers.PopUpManager;
import windows.SimplePopupWindow;
private var point1:Point = new Point();
private function showWindow():void {
var login:SimpleTitleWindowExample=SimpleTitleWindowExample(PopUpManager.createPopUp( this, SimpleTitleWindowExample , true));
point1.x=131;
point1.y=119;
point1=roadStatus.localToGlobal(point1);
}
private var point2:Point = new Point();
private function showWindow():void {
var login:SimpleTitleWindowExampleFlood=SimpleTitleWindowExampleFlood(PopUpManager.createPopUp( this, SimpleTitleWindowExampleFlood , true));
point2.x=289;
point2.y=119;
point2=floodplain.localToGlobal(point2);
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:BorderContainer x="10" y="0" width="750" height="600" backgroundColor="#BBB082" backgroundAlpha="1.0" cornerRadius="20" borderColor="#E8DBA7">
<s:Panel x="10" y="10" width="728" height="578" cornerRadius="20" chromeColor="#983D3A" borderColor="#F1EFE7" backgroundColor="#BBB082">
<mx:Image x="131" y="119" width="150" height="115" source="file://GIS Map Portal/images/Map Images/SJCRoadStatus2_small.jpg" id="roadStatus" click="showWindow();"/>
<mx:Image x="289" y="119" width="150" height="115" source="file://GIS Map Portal/images/Map Images/SJCRoadStatus_small.jpg" id="floodplain" click="showWindow();"/>
<mx:Image x="447" y="119" width="150" height="115" source="file://GIS Map Portal/images/Map Images/SJCRoadStatus2_small.jpg"/>
<s:Label x="131" y="242" text="SJC Road Status"/>
<s:Label x="289" y="242" text="SJC Floodplain"/>
<s:Label x="447" y="242" text="Assessor's Parcels"/>
<mx:Image x="131" y="262" width="150" height="115" source="file://GIS Map Portal/images/Map Images/SJCRoadStatus_small.jpg"/>
<mx:Image x="289" y="262" width="149" height="115" source="file://GIS Map Portal/images/Map Images/SJCRoadStatus2_small.jpg"/>
<mx:Image x="446" y="262" width="151" height="115" source="file://GIS Map Portal/images/Map Images/SJCRoadStatus_small.jpg"/>
<s:Label x="131" y="385" text="Label"/>
<s:Label x="289" y="385" text="Label"/>
<s:Label x="446" y="385" text="Label"/>
<s:Label x="229" y="24" text="San Juan County Web Maps" fontFamily="Calvin and Hobbes" fontSize="25"/>
</s:Panel>
</s:BorderContainer>
Below is the titleWindow code. This code works so far!
<?xml version="1.0" encoding="utf-8"?>
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;
import mx.controls.Text;
// A reference to the TextInput control in which to put the result.
public var loginName:Text;
// Event handler for the OK button.
private function returnName():void {
//loginName.text="Name entered: " + userName.text;
PopUpManager.removePopUp(this);
}
]]>
</mx:Script>
<mx:HBox width="323" height="147" borderColor="#E8DBA7" dropShadowVisible="true">
<mx:Text text="The San Juan County GIS Department maintains aninteractive web map dedicated for researching county roads, but also includes city limits, lakes and rivers, and other geographic data.
" width="319" height="76" textAlign="center" color="#FFFFFF"/>
</mx:HBox>
<mx:HBox>
<mx:Button label="Go" click="navigateToURL(new URLRequest(''), 'quote')"/>
<mx:Button label="Back" click="PopUpManager.removePopUp(this);"/>
</mx:HBox>
Question: What code do I need to change above to be able to add more than one titleWindow (up to 6), or what code can I use for a hover to open a "window" or tool tip?
If anyone has any ideas or can direct me at all that would be great. I appreciate it!

Sounds like you just got thrown in the deep end. Generally speaking theres no limitation on the number of title windows you can have open, the PopUpManager class handles any UIComponent you tell it to open as a pop up and one of the arguments for the .createPopUp or addPopUp static methods on the manager will take a modal parameter which specifies if the user interaction should be blocked (indicated by blurring the application) or if the window should just be shown. It seems rather this error is stemming from your extension of the TitleWindow (the SimpleTitleWindowExample) can you post that code. Also as starting points on the topic check out the following documentation:
General Flex:
http://www.adobe.com/devnet/flex/videotraining.html
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/index.html
^ notice the runtimes and products selection options at the top of the screen, select according to SDK you're building with (or select SDK based on features)
PopUpManager:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/managers/PopUpManager.html#createPopUp()
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/managers/PopUpManager.html#addPopUp()
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/managers/PopUpManager.html#removePopUp()
Tooltips:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/managers/ToolTipManager.html#createToolTip()
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/managers/ToolTipManager.html#destroyToolTip()
If you're still having troubles definitely post the code for the custom TitleWindow, also what version of the SDK you're using so I can try to replicate.
EDIT:
Ah okay seeing the rest of your code clears it up... you can't have two functions that have the same exact name so in your code you have showWindow as a function that is declared two times (I'm not sure how this is getting past compilation, I would have imagined the compiler would be smart enough to see this error before run-time, but it is what it is). Change the other showWindow to be something like showOtherWindow or something along those lines. It also looks like you come from a procedural programming background (C or some other non-OOP language) Object Oriented programming takes a little while to get your head around but makes a whole lot more sense when it comes to solving real world problems once you understand it, basically you're setting up descriptions and sending messages between objects using method calls and when you define a class, via AS or MXML you're defining the methods (order of method/property definitions doesn't functionally matter, things are still procedural, like step by step within the methods but the order of method declaration or property declaration has no effect).
This may be helpful:
http://www.codeproject.com/KB/architecture/OOP_Concepts_and_manymore.aspx
I'm basically at the opposite end of the spectrum in terms of skills, I have a formal education from DePaul University in computer science but at my current position am doing a lot of google maps flash code so I'm finding myself more and more needing to understand Datums and other GIS specialty info (just thought it was sort of interesting to find someone at the same intersection but going the other way :).

Related

Access data in custom component in Flex

I am new to Flex so pardon me if my questions are quite basic. I have searched a lot before posting here, might be I was not looking in the right direction. Please redirect me to the path that leads to the solution of the problem. I really appreciate any help that I can get.
I'm following this video tutorial. (I was creating Mobile Project not a simple Flex project like in video)
http://www.gotoandlearn.com/play.php?id=100
All was going fine, until the tutor wanted to add custom component in the application. He added the HBox which I couldn't find in Flash Builder 4.6 so I added HGroup instead in my new component. Now when I want to use the data that was fetched in the parent component in custom component it gives me error. Here is the code and their file names.
File: SearchHomeView.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="Twitter Search">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<s:HTTPService result="onResult(event)" id="service" url="http://search.twitter.com/search.atom?q=adobe">
</s:HTTPService>
</fx:Declarations>
<fx:Script>
<![CDATA[
import flash.utils.flash_proxy;
import mx.collections.ArrayCollection;
import mx.rpc.events.ResultEvent;
[Bindable]
private var ac:ArrayCollection;
private function onResult(event:ResultEvent):void
{
ac = event.result.feed.entry as ArrayCollection;
trace(data);
trace(ac);
}
private function doSearch(event:MouseEvent):void
{
//service.url = "http://search.twitter.com/search.atom?q=" + tearch.text;
service.url = "http://search.twitter.com/search.atom?q=adobe";
service.send();
}
]]>
</fx:Script>
<s:TextInput x="25" y="26" width="146" id="tearch"/>
<s:Button x="224" y="26" height="33" label="Search" click="doSearch(event)" />
<s:List dataProvider="{ac}" itemRenderer="tweet" x="25" y="92" width="274" height="278"></s:List>
</s:View>
File: tweet.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:HGroup xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" width="400" height="300">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Image width="50" height="50" source="{parentDocument.data.link.getItemAt('1').href}">
</s:Image>
<s:TextBase width="100%" text="">
</s:TextBase>
</s:HGroup>
When I use source to be source="{parentDocument.data.link.getItemAt('1').href} ... it removes the error, but displays nothing on the resulting app.
When I use source to besource="{data.link[1].href} ... it gives the error,
Multiple markers at this line:
-1120: Access of undefined property data.
-parentDocument
What needs to be done to use the item renderer right in custom component ? Please tell me the solution to it... I'm stuck on it for quite a few time.
Your component Tweet.mxml should extend an ItemRenderer.
In Flex 3 many components could be used as item renderers, that old (Flex 3) HBox component you saw in the video works as an item renderer b/c it has a data property.
As part of Flex 4's "pay as you go" approach, the container classes (Group, HGroup, etc) do not support being used directly as item renderers. As a result HGroup doesn't have a data property.
Try making Tweet.mxml look something like this:
<?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" width="400" height="300">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:layout>
<s:HorizontalLayout />
</s:layout>
<!-- Typically, the dataProvider of your List is an array of objects of the same
type. So each item renderer that is on screen has it's data property populated
with one of these items. You can then craft an MXML document like this that
uses the properties of your array element. You're going to need to use the
right expression that finds the image source in the data item. If you really
want to be rendering the array data.link, pass that data w/an ArrayCollection
to the list instead ... it's hard to advise here w/out knowing what your data
looks like. -->
<s:Image width="50" height="50" source="{data.link.getItemAt('1').href}" />
<s:StyleableTextField width="100%" text="" />
</s:ItemRenderer>
The changes I'm making are:
extend ItemRenderer
replace HGroup's layout by using the HorizontalLayout in the renderer
using the data property of the renderer for the source of the image (use the data property to populate all of the dynamic parts of the renderer (like the text field)
using a StyleableTextField, optimized text for mobile
In your onResult event handler - be careful to check that you are in fact assigning all items into the arraycollection - If feed.entry is not explicitly an ArrayCollection you will need to iterate the list (assuming this an xmllist because it looks like an RSS feed)...
So instead:
protected function onResult(event:ResultEvent):void
{
if (!ac) ac = new ArrayCollection();
for each (var entry:XML in event.result.feed..entry)
{
ac.addItem(entry);
}
}
As for the ItemRenderer, you have a couple of different options...
ItemRenderer - as suggested by #Sunil, this is the 'base' class of renderers to use in spark based lists.
DataGroup - this is similar to a Group where you specify a layout, but it creates "renderers" - anything with a 'data' property using a dataprovider, the key to this one though is there is no virtualization it just creates all of them.
It gets more complicated than this when you switch to a DataGrid...

How to check the state of a Radio Button in Flex 3?

I'm working on a template for dynamic questionnaires in Flex. More detailed description in my previous thread HERE
To create the questionnaire, I use nested repeaters - one for the questions and one for the answers (as their amount may vary).
<mx:Repeater id="r" dataProvider="{questions}">
<mx:Label text="{r.currentItem.question}" width="200"/>
<mx:Repeater id="r2" dataProvider="{r.currentItem.answers}">
<mx:RadioButton label="{r2.currentItem.text}" width="200"
click="answerHandler(event, event.currentTarget.getRepeaterItem())"/>
</mx:Repeater>
</mx:Repeater>
To understand my data providers, it's probably best to check the answer for my previous thread - easier than if I try to explain it here.
The question here is... As you can see, I created click event handler for each radio button and my plan was to do playerScore++ every time the user chose correctly (which can be achieved by checking the Boolean property "correct" of sent RepeaterItem).
However, I see now that even if the button is selected already, I can still click on it more times, and even though it's not changing anything in the view, it increments the score every time.. I would also have to handle situation in which the user changes his mind (I could give + points for each good answer and - points for wrong, but this would mean, that if the user chose more wrong answers, my score will be negative and I don't want it).
So it would be way way easier to just have a Submit button and check the states of all my buttons and if they are correct only after the user clicks "submit". Is it possible?
I recommend you to refer to the following sample and add RadioButtonGroup to your repeater groups and listen to change events instead of click. You can listen change event right in RadioButtonGroup and check if (radioGroup.selectedValue.correct) for correctness of new selection. See corresponding documentation.
To have possibility to assign radiogroups unique name you have to extract inner repeater with answers into separate component. Breaking your application into smaller components can make your application more clear and readable. You can treat every MXML file as a class (as in OOP) but in declarative form. And to tell the true every MXML component is a class which inherited from root-node-class.
Lets look at the code.
First, our inner component which serves answers:
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Metadata>
[Event(name="rightAnswerEvent", type="AnswerEvent")]
</mx:Metadata>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
public var answers:ArrayCollection;
protected function answerGroup_changeHandler(event:Event):void
{
if (answerGroup.selectedValue.correct)
dispatchEvent(new AnswerEvent(AnswerEvent.RIGHT_ANSWER_EVENT));
}
]]>
</mx:Script>
<mx:RadioButtonGroup change="answerGroup_changeHandler(event)" id="answerGroup" />
<mx:Repeater dataProvider="{answers}" id="answersRepeater">
<mx:RadioButton group="{answerGroup}" label="{answersRepeater.currentItem.text}"
value="{answersRepeater.currentItem}" />
</mx:Repeater>
</mx:VBox>
It gets answers collection as input and fires our custom event to inform some components about right answer (see Metadata tag).
Our custom event is pretty simple an looks like the following:
package
{
import flash.events.Event;
public class AnswerEvent extends Event
{
public static const RIGHT_ANSWER_EVENT:String = "rightAnswerEvent";
public function AnswerEvent(type:String)
{
super(type);
}
}
}
So now our top level component:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application layout="vertical" xmlns:local="*"
xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
private var questions:ArrayCollection = new ArrayCollection();
[Bindable]
private var scoreCounter:int;
]]>
</mx:Script>
<mx:Label text="{'Score ' + scoreCounter}" />
<mx:Repeater dataProvider="{questions}" id="questionRepeater">
<mx:Label text="{questionRepeater.currentItem.question}" />
<local:AnswerGroup answers="{questionRepeater.currentItem.answers}" rightAnswerEvent="scoreCounter++" />
</mx:Repeater>
</mx:Application>
I omitted initialization code to populate our Question and Answer domain objects with data from XML (see previous thread).
So now we have compact modularized code where every part solves its own task.
Hope this helps!

How to Send Info From a Flex 3 Component?

I need some help with sending info from a component. I'm not sure how to proceed.
I'm using Alex Uhlmann's flip card class (Distortion Effects). I've got a card that has 3 faces. When the user clicks the button, it fires a change event, and in the main application, the change event calls a function, flipTo, that flips the card. The component is below:
<?xml version="1.0" encoding="utf-8"?>
<mx:Panel
xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
width="500"
height="400">
<mx:Metadata>
[Event("change", type="mx.events.Event")]
</mx:Metadata>
<mx:Script>
<![CDATA[
[Bindable]
public var backCaption:String;
]]>
</mx:Script>
<mx:Text id="myAnswer" htmlText="{backCaption}" width="100%" />
<mx:ControlBar height="40" width="100%" >
<mx:Button
x="20" y="400"
label="Flip"
click="dispatchEvent( new Event( Event.CHANGE ) );" />
</mx:ControlBar>
</mx:Panel>
The main application looks like:
<mx:Canvas id="homeStack" >
<mx:ViewStack id="flipViewStack2" x="200" y="150" >
<sides:FlipFace
id="frontFace2"
title="Newport"
change="flipTo(frontFace2, backFace2, DistortionConstants.LEFT, DistortionConstants.RIGHT);" />
<sides:FlipReverse
id="backFace2"
title="Newport: Answer"
change="flipTo(backFace2, anotherFace2, DistortionConstants.LEFT, DistortionConstants.LEFT);" />
<sides:FlipAnotherSide
id="anotherFace2"
title="Other Stuff"
change="flipTo(anotherFace2, frontFace2, DistortionConstants.RIGHT, DistortionConstants.LEFT);"/>
</mx:ViewStack>
</mx:Canvas>
<mx:Canvas id="OtherStack" >
(more code)
</mx:Canvas>
The flipTo function in the main application takes 4 parameters: the starting side, the ending side, and then two parameters that determine the direction of the flip.
Everything works great. If I hit the button, I can flip through all of the sides. But, I'd like to add a comboBox, so that the user can flip directly to the side that they want instead of having to cycle through all of the sides. (This is important as I plan to add more sides).
In the main application, please note that the sides have the number 2 in their ids. For example, frontFace2. I've got multiple sets of cards each with a different number, frontFace3, frontFace4, etc. The number determines which data is pulled from the database. (I've simplified the code for brevity).
How can I add a comboBox in the component that causes the card to flip to the selected side?
Do I need a custom event? (Unfortunately, I don't know anything about custom events). Is there a way to have the comboBox set a public variable and then somehow access that variable in the main application and call flipTo with the comboBox's chosen side? Other possibilities?
Any suggestions?
Thank you.
-Laxmidi
oh, yeah, you will need a custom event.
the custom event is your inheritance to the Event class which on it you can load more data, params, views and more.
in your case, things are a bit more simple but you will need to see what "face" the user selected and flip to it.
steps
1. create a custom event (inherit from event)
2. add a var to the event class that's called face
3. when the user selects the value from the combo, fill the face var with value and dispatch the event
4. listen to the event in the application level and then flipTo the relevant face.

Flex:: How do I prevent in drag and drop, dragging onto self

I have a Flex question. I was wondering, if I have two list boxes, and I want to drag and drop between both of them, how do I prevent the user from dragging onto the same list (thus duplicating the item? I cannot have a situation where that is the case. Thanks guys
Haven't tested it but I guess something like this should work:
Listen to dragStart event on both lists and set a source variable depending on event.target. Now listen to the dragDrop event on both lists and call event.preventDefault() if the source is same as the target.
Here are some simple functions I made while building a working application I used to wrap my head around flex drag and drop. I was looking for a way to have multiple lists with drag and drop functionality that would not interfere with each other. Also, I didn't want to deal with copying list data around.
private function onlyAllowMoveDragOverHandler(event:DragEvent):void {
event.preventDefault();
event.currentTarget.showDropFeedback(event);
DragManager.showFeedback(DragManager.MOVE);
}
private function allowDropOnlyIfInitiatorEqualsComponent(event:DragEvent, component:IUIComponent):void {
event.preventDefault();
if (event.dragInitiator == component) {
DragManager.acceptDragDrop(event.target as IUIComponent);
}
else {
DragManager.showFeedback(DragManager.NONE);
}
}
And I in use in my mxml:
<mx:List
x="10"
y="170"
id="availableLangsList"
dataProvider="{availableLangs}"
width="100"
height="200"
dragEnabled="true"
dragMoveEnabled="true"
dropEnabled="true"
dragOver="onlyAllowMoveDragOverHandler(event);"
dragEnter="allowDropOnlyIfInitiatorEqualsComponent(event, selectedLangsList);"
dragComplete="selectedLangs.refresh();"
/>
<mx:Label x="129" y="153" text="list 4"/>
<mx:List
x="129"
y="170"
id="selectedLangsList"
dataProvider="{selectedLangs}"
width="100"
height="200"
dragEnabled="true"
dragMoveEnabled="true"
dropEnabled="true"
dragOver="onlyAllowMoveDragOverHandler(event);"
dragEnter="allowDropOnlyIfInitiatorEqualsComponent(event, availableLangsList);"
dragComplete="availableLangs.refresh();"
/>
I found the solution, which im not sure would work for anyone else. I basically had in my two lists:
`
<mx:List id="srcList" dataProvider="{_source}"
allowMultipleSelection="true"
enabled="{enabled}"
labelField="{labelField}"
iconFunction="iconFunction"
dragEnabled="true"
dropEnabled="true"
dragDrop="doDragDrop(event);"
width="100%"
height="100%"
/>
</mx:VBox>
<mx:VBox paddingTop="50">
<mx:Button label="->" enabled="{enabled}" click="add()"/>
<mx:Button label="<-" enabled="{enabled}" click="rem()"/>
</mx:VBox>
<mx:VBox width="100%" height="100%">
<mx:Label text="{right_col_heading}" />
<mx:List id="dstList" dataProvider="{_destination}"
allowMultipleSelection="true"
enabled="{enabled}"
dragEnabled="true"
dropEnabled="true"
dragDrop="doDragDrop(event);"
width="100%"
height="100%"
labelField="{labelField}"
iconFunction="iconFunction"
verticalAlign="center"
/>`
I basically added a dragMoveEnabled = "true" to both lists and now basically not re-add to the same list an item of itself, but just move the order (which doesnt matter to me as its a soap send and the back-logic would put it in the correct order anyway).
In my case, I used a HashCollection (which extends ArrayCollection) [just google it, you'll find the component]. The dataprovider is bind to this has collection. You would add items to the collection with: dataprovider.put (key, object) instead of dataprovider.addItem(object).
The "hash" will ensure uniqueness in the collection. SO, even if the user drag-drop something that already exists in the hash, the original value would get replaced with the new object (but it wouldn't matter because it's the same value).
The "key", however, must be unique.... otherwise, the hash idea won't work.
Thanks Brice, Those functions were helpful.
For them to work in Spark Lists just update the first function as follows with createDropIndicator instead of showDropFeedback and stop passing the event.
private function onlyAllowMoveDragOverHandlerS(event:DragEvent):void {
event.preventDefault();
event.currentTarget.createDropIndicator();
DragManager.showFeedback(DragManager.MOVE);
}

Waiting for Flex Effects to Finish

I'm a Flex rookie tasked with enhancing an existing application. One of those enhancements is getting the field that currently shows the time to smoothly fade back and forth between showing the time and the date.
I know the proper way to do this is to embed the font file in the application so I can fade the label in and out directly. I'm trying to avoid that if I can, since I'd prefer to make my changes as unobtrusive as possible.
I came up with what I felt was a reasonable workaround: create a "privacy screen" that just so happens to be the exact size, shape, and color of the clock's background; initialize its alpha to 0; then when changing the time/date, fade-in the privacy screen, make the change, and fade the screen back out again.
The code looks something like this:
var targets:Array = new Array();
targets.push(this.privacyScreen);
this.effectFadeIn.play(targets);
this.mylabel.text = "I am a date and/or time";
this.effectFadeOut.play(targets);
... with the key components looking like this:
<mx:Label text="" id="mylabel" width="100%" height="100%" x="0" y="0" color="0xff0000"/>
<mx:Canvas id="privacyScreen" width="100%" height="100%" x="0" y="0" alpha="1" backgroundColor="{myConfiguration.backgroundColor}"/>
<mx:Fade id="effectFadeIn" alphaFrom="0.0" alphaTo="1.0" duration="250"/>
<mx:Fade id="effectFadeOut" alphaFrom="1.0" alphaTo="0.0" duration="250"/>
As I'm sure the experienced Flex designers already know, this code is made from delicious fresh-squeezed FAIL. The basic assumption that execution will wait for the fade-in effect to finish is wrong, and the fade-out effect is apparently ignored while the fade-in is still in progress.
So I guess I have two related questions:
Is it possible to get execution to pause while waiting for an effect to run to completion?
Is this approach even viable, or does it simply reek of Doing It Wrong from top to bottom?
My thanks in advance for any insight anyone can offer.
(And I admit in advance that the more I try to learn this by doing, the more I realize I need to avail myself of some of the online training resources out there.)
I just played a bit with your code, is this what you're looking for?
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
creationComplete="onComplete();">
<mx:Script>
<![CDATA[
private var targets:Array = new Array();
private function onComplete():void {
targets.push(canv);
effectFadeOut.play(targets);
}
private function onFadeInEnd():void {
effectFadeOut.play(targets);
}
private function onFadeOutEnd():void {
effectFadeIn.play(targets);
}
]]>
</mx:Script>
<mx:Label text="{(new Date()).toString()}" id="lbl" x="0" y="0" color="0xff0000"/>
<mx:Canvas id="canv" width="100%" height="{lbl.height+5}" x="0" y="0" backgroundColor="#000000"/>
<mx:Fade id="effectFadeIn" alphaFrom="0.0" alphaTo="1.0" duration="250"
effectEnd="onFadeInEnd();" />
<mx:Fade id="effectFadeOut" alphaFrom="1.0" alphaTo="0.0" duration="250"
effectEnd="onFadeOutEnd();" />
</mx:WindowedApplication>
Hope that helps :)
Your code is executed while the label fades. this.effectFadeIn.play () does not wait for it to finish. I would add a setTimeout call to the lines of code you need to call later, or better yet, put them in another function. Then, call the function again after a certain interval.
import flash.utils.*;
private function FadeIn () : void {
var targets:Array = new Array();
targets.push(this.privacyScreen);
this.effectFadeIn.play(targets);
this.mylabel.text = "I am a date and/or time";
setTimeout (function (): void {FadeOut (targets);}, effectFadeIn.duration); // Function and duration
}
private function FadeOut (targets : Array) : void {
this.effectFadeOut.play(targets);
setTimeout (FadeIn (), this.effectFadeOut.duration;
}
I'm pretty sure this should work...

Resources