Can I access Stage from an AS3 Class with no DisplayObject?

Date October 8, 2008

I’m working on a project that requires creating and adding a Movie Clip to the Stage from a class file. Seemed like an easy task, however, referring to the Stage from my class turned out to be trickier than I thought.

I know that, although you can’t refer to Stage directly, it is a property of every DisplayObject named ’stage’ (lower case ’s’). For example, if my class extends Sprite, I can get the Stage width by referring to “stage.width”.

The problem arises when a class does not extend a DisplayObject and a DisplayObject is not passed to your class. The project I’m working on fell into this category. The purpose of my class is simply to create and manage instances of another class. The problem I ran into was that I could not refer to the Stage because my class had no reference to a DisplayObject.

I ended up working around the problem by passing a DisplayObject instance, but out of curiosity, I’d like to know if there is any way around this issue. Is there a way to refer to the Stage from a class file that has no DisplayObject instance?

-rG

5 Responses to “Can I access Stage from an AS3 Class with no DisplayObject?”

  1. SFBTom said:

    The easiest way is to set up a class with static references to the stage, that you then extend for all your document classes:


    package
    {
    import flash.display.MovieClip;
    import flash.display.Stage;
    public class GlobalStage extends MovieClip
    {
    public static var STAGE:Stage;
    public static var ROOT:MovieClip;

    public function GlobalStage()
    {
    STAGE = this.stage;
    ROOT = this.root;
    }
    }
    }

    Tom-

  2. Joshua Hart said:

    One thing to watch out for when using the method suggested by SFBTom: If you are dealing with the main SWF, this works because the Flash player wires up the “stage” reference before the constructor is called (but still triggers the ADDED_TO_STAGE event afterwards). However, if your SWF is a secondary load, you must wait for the ADDED_TO_STAGE event because stage will be null when your constructor is called.

    You can always architect it so that your secondary SWF depends on the initial SWF, but you will have problems if you want to test it independently because your code will behave differently.

    My general solution is to create a one-time ADDED_TO_STAGE event handler to the document class that does the work I would generally put into the constructor. The actual constructor just wires up the event handler and holds off adding any of its children. This way, we know that stage is available before any other objects have been created, even when the SWF is a secondary load. It won’t work if you are using CS3 and have items on the stage that might depend on it, but it will work if you keep your root timeline clean and do the initial setup in ActionScript.

  3. Paulius Uza said:

    Use my Global class. It allows you to have global storage without overriding or extending main classes.

    Download: http://www.uza.lt/codex/as3-global-object/

    Usage
    ———-
    Call this code from your main application class:

    private var global:Global = Global.init();
    ...
    global.stage = this.stage;

    And this code from any other class:

    private var global:Global = Global.init();
    ...
    trace(global.stage);

  4. rabidGadfly said:

    Thanks for all the suggestions! It’s interesting to see the different approaches. I’m a little surprised that there isn’t an ‘out of the box’ solution but it’s good to know that there are work-arounds available.

    @Paulius: Congratulations on the MTV Greece partnership!

    Glenn

  5. Scott Petrovic said:

    Thank you for this answer. I have been looking for a long time for this. It seems so obvious now. That is usually how it is.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>