How to access stage in a class that is not a Displ

2019-07-24 15:17发布

问题:

How do I access the stage in Actionscript 3 in a class which is not my main class and not a displayobject?

回答1:

the easiest way is to use a global object

http://github.com/inruntime/AS3-Global-Object

this page has examples of how to set and retrieve objects from any class.



回答2:

The easy way, you can keep it in a static var for example:

public class MyMain extends Sprite {
 public static var STAGE:Stage;

 public function MyMain() {
  if (stage)
   init();
  else
   addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
  }
 }

 private function init(e:Event=null):void{
  removeEventListener(Event.ADDED_TO_STAGE, init);
  // store stage reference when stage ready  
  STAGE=stage;
 }
}

and in your other class import the class that is holding the static var, of course the var have to be initialized before accessing it.

import MyMain;

public class Other {
 public function useStage():void {
   MyMain.STAGE...
 }
}


回答3:

Adobe failed to provide static access to the stage, leaving you no option but to implement it yourself.

This is an epic fail, since it's impossible to access the stage before your main document class instance constructor runs to stash the stage instance in some arbitrary static variable.

Since you'll have to initialize that arbitrary static variable every time you want static access to the stage, it's best to ensure you only have to do it once.

To ensure you'll only have to initialize it once, you'll have to make sure that EVERY STATIC METHOD you ever write points to that variable and doesn't try to access it before it's initialized.

Given all that... the most logical steps are: 1. File a Feature Request with Adobe NOW. 2. Create a "Global" or "Document" base class that initializes a static stage variable for you, and have all your document classes inherit from it. Extending MovieClip gives you the most flexibility:

package
{
    import flash.display.Stage;
    import flash.display.MovieClip;
    import flash.events.Event;
    public class Document extends MovieClip
    {
        public static var _stage:Stage = null;

        public static function get sstage():Stage //added an extra s for "static" to differentiate the static property name from the instance property name "stage"; call it what you want
        {
            return _stage;
        }

        public function Document()
        {
            super();
            if (stage != null)
               initStage( null ); //explicitly pass null to indicate no listener was attached
            else
                addEventListener( Event.ADDED_TO_STAGE, initStage, false, 0, true ); //prefer weak references
        }

        private function initStage( e:Event ):void
        {
            _stage = stage;
            if (e != null) //event listener will be non-null iff listener was added
                removeEventListener( Event.ADDED_TO_STAGE, initStage, false );           
        }
    }
}

You will not have to write this class more than once, as long as all your document classes extend the above defined "Document" class (and calls "super" in its constructor right away). By doing that, your document's constructor code and the rest of your project from that point forward will have static access to the stage via "Document.sstage". There is no way for a static context to have access to the stage before this initialization occurs in the main document class.

I suggest you adopt this kind of consistency very early on, because it will make it easier to fix if Adobe ever adds static access to Stage. It will simply be a matter of replacing "Document.sstage" with whatever Adobe provides.



回答4:

You could use accessor and mutator class to set and retrieve the stage instance?