1

I have a program where I created a singleton class for the stage so I can access it in my other classes.

I have a few other symbols which have text in them, so will need to have the text modified in the code.

My problem is that whenever I use TLF text instead of Classic Text, any of my classes that reference the singleton stage class get a "TypeError: Error #1009: Cannot access a property or method of a null object reference."

I have previous programs that work fine with TLF text but this is the first time I have used a singleton class for the stage so my guess is it involves that somehow.

I have tried a few solutions in other posts I've seen for related problems (such as publish settings) but so far nothing has worked.

Below is where the first error occurs:

// Constructor
    public function Zoom(object:MovieClip) {
        // Set the stage
        stage = StageManager.instance.stage;

        // Set the zoom object
        zoomObject = object;            

        // Add event listener for the mouse wheel
        stage.addEventListener(MouseEvent.MOUSE_WHEEL, mouseZoom); // ERROR OCCURS HERE

        if (Controls.instance.controls.zoomInBtn && Controls.instance.controls.zoomOutBtn) {
            Controls.instance.controls.zoomInBtn.addEventListener(MouseEvent.CLICK, zoomIn);
            Controls.instance.controls.zoomOutBtn.addEventListener(MouseEvent.CLICK, zoomOut);
        }
    }

Here is the singleton class:

package {
import flash.display.Stage;

// Singleton class so any other classes can access the stage.
public class StageManager {

    // Publicly accessible singleton instance
    public static var instance:StageManager = new StageManager();

    private var m_stage:Stage;

    // Getters and Setters
    public function set stage(stg:Stage):void {
        m_stage = stg;
    }

    public function get stage():Stage {
        return m_stage;
    }
}
}
Sean
  • 1,758
  • 3
  • 20
  • 34
  • It would help to share (the relevant part of) your code. – paddotk Jun 14 '12 at 12:54
  • I added the code, I am not sure if it would really help though. – Sean Jun 14 '12 at 13:04
  • I don't see any text-relevant code? If the TLF text is the problem, that's what we'd like to see. P.s. have you debugged to make sure the problem does really occur at the calling of the function? – paddotk Jun 14 '12 at 13:08
  • Currently there is no code for the TLF, it is just attached to a symbol. – Sean Jun 14 '12 at 13:30
  • Is the Zoom class a DisplayObject? – weltraumpirat Jun 14 '12 at 14:25
  • No the zoom class is sent a display object which can then be zoomed. However, to zoom properly, I needed to be able to access the stage, thus, the singleton. What doesn't make sense is that everything works fine unless I add a symbol with TFL text anywhere on the stage or in another class. – Sean Jun 14 '12 at 15:22

2 Answers2

0

First, really it is incorrect to use API method/properties names for your own class's property/method names. It makes a confusion.

Second if it throws null error then object (stage) that you are trying to access property of is null, now there can be a lot of reasons, e.g. this line of code is called before setting stage property or simpler the stage is not available to be assigned to stage (now you get why I've said about using the same names for own classes props?) Again, it can be that your code is executed before DisplayObject's stage property is available (content is not added to stage) and your class doens't check if it is not null.

The samples of code you've displayed are just poorly written, even "singleton" alike class is not proper singleton class.

Now the solution:

  • review your code design and change it read about design patterns (at least for a singleton)
  • trace out the stage values in StyleManager so you can see if and when the property is set, also trace out in the Zoom constructor
  • always use try catch block or at least test for existance of object that your code depends on

as follows:

if(stage) 
{
    stage.addEventListener(MouseEvent.MOUSE_WHEEL, mouseZoom);
}
else
{
    trace("[!] Expected stage but got null");
}

or

try
{
    stage.addEventListener(MouseEvent.MOUSE_WHEEL, mouseZoom);
}
catch(err:*)
{
    trace("[!] Expected stage but got null\n"+err);
}
  • Never use the same names used by ActionScript API in your own classes to avoid confusion and to make debugging easier:)
  • If you depend on the stage property to be not null use the following snippet:

this is exactly the same as FlashDevelop produces new Main class and it works very well:

if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init, false, int.MAX_VALUE, true);

and the init handler

protected function init(e:Event = null):void
{
    removeEventListener(Event.ADDED_TO_STAGE, init);
    //do here whatever is needed when stage proeprty is NOT null
}

best regards

Lukasz 'Severiaan' Grela
  • 6,078
  • 7
  • 43
  • 79
0

The question might be ancient, but I have had a similar problem recently, which was very perplexing due to my inexperience with TLF, which has been deprecated anyway, but I still need to use text fields that can flow into each other - simple enough unless you are using Flash. So I am happy to run with CS6 for this.

Anyway my solution was simply to remove the event listener from my constructor and place it in the timeline on the first frame; stage loaded and everything works - only my pride bruised for not understanding deeply enough to make it work properly.

I had always assumed that the constructor ran first - and have never had issues assigning events to the stage in there before, perhaps now I know better, but not by much.

Is this perhaps because loading the TLF component creates a lag in loading the stage? Surely the stage comes first and everything that is a child of it afterwards? Madness!