Reputation: 109
I have the following two classes:
package
{
import flash.display.Sprite;
import flash.events.Event;
public class Main extends Sprite
{
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
var test:NewClass = new NewClass();
}
}
}
AND
package
{
import flash.display.Sprite;
public class NewClass extends Sprite
{
public function NewClass()
{
trace(stage.width);
}
}
}
I get the following error:
TypeError: Error #1009: Cannot access a property or method of a null object reference. at NewClass()[C:\Documents and Settings\Roma\poo\src\NewClass.as:10] at Main/init()[C:\Documents and Settings\Roma\poo\src\Main.as:23] at Main()[C:\Documents and Settings\Roma\poo\src\Main.as:15]
Why???
Upvotes: 1
Views: 3313
Reputation: 41054
As back2dos correctly says, only elements that are on the display list have a valid reference to the stage. As the instance of NewClass
is merely a temporary variable in the init
method of your Main
instance and you have yet to addChild
to put it on the display list the value of it's stage
property will be null. Note: only children of parents which are also on the display list will obtain a valid reference to the stage.
If you need a reference to the stage in a class that will not be added to the display list then you will need to pass the stage into an instance of that class. Unlike AS2 there is no globally accessible reference to the stage (i.e. _root
and _level0
are deprecated)
Upvotes: 0
Reputation: 15623
yeah, a flash develop user ... :D
uhm, the reason is: the stage is only available to objects, that are on the display list ...
modify your class as follows:
package {
import flash.display.Sprite;
import flash.events.Event;
public class NewClass extends Sprite {
public function NewClass():void {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
trace(stage.width);//you may want to use stage.stageWidth actually
}
}
}
and Main::init as follows:
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
var test:NewClass = new NewClass();
this.addChild(test);
}
oh, and you can change your Coding Style Type
from BraceAfterLine
to BraceOnLine
in Tools > Program Settings > FlashDevelop > Indenting
, just in case you are inclined ... ;)
edit:
if you want to access the stage, within the scope of a DisplayObject
, you need to be sure, the stage is available to it ... if you want to access the stage as soon as possible, then you will need the trick provided ... but if you access the stage within a click handler for example, this automatically implies the DisplayObject
is on the display list ... it couldn't be clicked otherwise ...
a little note though: i don't think, it's particularly clever to access the stage from everywhere ... when it comes to display, your app hierarchy should follow the display list hierarchy, i.e. access goes from the root down the branches, and not the other way round ... this is important to achieve reusability ...
greetz
back2dos
Upvotes: 8