I’m probably not the first to blog on this, but some repetition is often valuable 🙂 Most examples illustrating integration of AS 3 with Flex show a function executed on the creationComplete event of the Application. It is helpful to understand the startup order of events in a Flex application.
If your attempts to access the stage in a Flex app. result in a null reference, try executing your script on the applicationComplete event, as shown in the following code segment (make sure the display object has been added to the display list). This particular segment is taken from a test driver that allows bones to be drawn interactively with mouse clicks, similar to 3ds max. I’ve removed much of the MXML and script that is not relevant to the topic.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="test()" width="600" height="500">
.
.
.
<mx:Script>
<![CDATA[
import Singularity.Rigs.Bone;
import Singularity.Rigs.Chain;
import Singularity.Numeric.Consts;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import mx.controls.sliderClasses.Slider;
import mx.core.UIComponent;
import mx.events.SliderEvent;
// bone (bn) namespace
public namespace bn;
bn var __move:Boolean = false;
bn var __count:uint = 0;
bn var __bone:Bone = null;
bn var __chain:Chain = new Chain();
bn var __hand:Chain = new Chain();
bn var __isTerminated:Boolean = false;
bn var __myReference:UIComponent = new UIComponent();
// user-interface (ui) namespace
public namespace ui;
ui var __stage:Stage = null; // Stage reference
public function test():void
{
addChild(bn::__myReference);
bn::__myReference.addChild(bn::__chain);
bn::__myReference.addChild(bn::__hand);
// notification of low-level bone interactivity
bn::__chain.setNotify(onBone);
// stage listeners
ui::__stage = bn::__chain.stage;
ui::__stage.addEventListener(MouseEvent.CLICK, onSelected, true);
ui::__stage.addEventListener(KeyboardEvent.KEY_DOWN, terminate);
// add the hand bone to the hand chain
bn::__hand.addBoneAt(30, 70, 30, 50, “hand”, 0, Bone.SQUARE);
bn::__hand.setNotify(onBone);
bn::__hand.enabled = true;
__status__.text = “Click anywhere to start drawing a bone. New clicks create new bones. Click SPACE BAR to end the chain”;
}
.
.
.
If the test() function was executed on the creationComplete event, the reference
ui::__stage = bn::__chain.stage;
would have been null. When executed on applicationComplete, everything works as expected. I hope this small observation helps you in a future application.
Great example!
I’ve started playing with your Singularity classes and have to say I’m very impressed. I do think it would be much easier for beginners to have examples without all the namespace overhead, but much in the way that Collin Moock codes, you are obviously way ahead of a lot of us and have clear reasoning behind such choices.
I was able to get as far as drawing my own 4 pt bezier, but it was mostly through de-engineering one of your sample projects. For us neophytes, definitely the simpler the better.
Please keep up the posts!
Ben – I got in the habit of using namespaces a long time ago when programming large-scale C++ applications, especially those using the Standard Template Library. I can work with the vector class in namespace std and still incorporate a vector class written by someone else by placing it in another namespace and have no naming conflicts in the application. I try to partition variables that belong to a particular class of functionality (user interface, splines, etc) into their own namespaces. Even in Flex applications, I often receive code segments from other developers and can quickly incorporate them into my code without worrying about duplicate variable names. The scope resolution operator in AS is the same as C++, so it’s a familiar way of coding to me. I try to code demos the same way I do in production.
good luck to you!
– jm arrmstrong
Thanks much! I was knocking my head against a wall figuring why stage was null. I thought ‘maybe flex doesn’t HAVE stage access for a while. Thanks!
Thank you so much, I have been fighting with this for a while. Finally after many searches your description and suggestion of using the “applicationComplete” event allowed me to disable the built-in context menu items that I so wanted **gone**.
Thanks again.
Just a small addition; you may notice that the aforementioned example works great, but that it does not exactly account for instances of components that need to reference the stage.
Components don’t have an “applicationComplete” event by default, and if you make a reference to the stage in a handler for the creationComplete event, you will notice that the reference is still null.
The easy way to work around this is to use the “addedToStage” event as opposed to “applicationComplete”, e.g.:
Cheers.
Duuuuuuude
Seriously, thank you so much, I spent the last hour trying to figure out how to get one lousy sprite to show up in this stupid old Flex app and get a mouse listener on the stage. I come here, and voila, everything works!
Thank you thank you thank you!
depending on what you need, you can access the stage prior to applicationComplete using “systemManager.stage”…
helped a lot.
thx
Thanks! Spent hours trying to figure this out!