Question

I figured out how to create a static method that is available everywhere, for example:

UtilLib.as:

package
{   
     public final class UtilLib
     {  
          public static function getTimeStamp():uint
          {
               var now:Date = new Date();
               return now.getTime();
          }
     }
}

I can access this everywhere by doing UtilLib.getTimeStamp() - Now, I want to create a new staic method called log(msg:String). This should log a message to a multi-line inputfield.

The problem however is that this inputfield must be created somewhere and must be accessible and visible all the time, and I don't want to pass it through the function parameters all the time as this would cause a lot of trouble (I'd have to pass it through objects aswell..).

So, how do I make a "public textfield" so my static log method can write to it?

UPDATE: I now tried the following class, with a static constructor (I think). However, the textfield object is not showing. When I do an addChild(debugField) after creating it, it gives me error 1180.

Logger.as

package
{
    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.text.TextFieldType;

    public class Logger extends Sprite
    {
        public static var debugField:TextField;

        /* static block */
        {
            trace("Logger initializing.");
            debugField = new TextField();
            debugField.width = 500;
            debugField.height = 100;
            debugField.x = 100;
            debugField.y = 400;
            debugField.background = true;
            debugField.backgroundColor = 0xFFFFFF;
            debugField.defaultTextFormat = new CustomTextFormat();
            debugField.mouseWheelEnabled = true;
            debugField.multiline = true;
            debugField.type = TextFieldType.DYNAMIC;
        }

        public static function log(msg:String):void
        {
            if (debugField) debugField.appendText(msg);
        }

    }
}

I initialize it like this:

var test:Logger = new Logger();
addChild(test);

And I log a new message like this:

Logger.log("test");

Unfortunately, the textField is not showing.

Was it helpful?

Solution

Essentially you need:

  • somewhere to log a message which is globally accessible
  • the ability to update a text field whenever the log message changes

A simple solution using objects could look like this:

Example

package {
    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.events.Event;

    public class Example extends Sprite {
        private var messageLog:TextField;

        public function Example() {
            createTextField();
            MessageLogger.getInstance().addEventListener( MessageLogger.LOG, handleMessageLoggerUpdate );
            MessageLogger.getInstance().log( "Message!" );
        }

        private function handleMessageLoggerUpdate( event:Event ):void {
            messageLog.text = MessageLogger.getInstance().getLog();
        }

        private function createTextField():void {
            messageLog = new TextField();
            addChild( messageLog );
        }
    }
}

MessageLogger

package {
    import flash.events.EventDispatcher;
    import flash.events.Event;

    public class MessageLogger extends EventDispatcher {
        private static var instance:MessageLogger;
        public static function getInstance():MessageLogger {
            if ( !instance ) {
                instance = new MessageLogger( new InstanceKey() );
            }
            return instance;
        }

        public static var LOG:String = "MessageLoader#log";

        private var messageLog:String;

        public function MessageLogger(key:InstanceKey) {
            messageLog = "";
        }

        public function log( message:String ):void {
            messageLog += message;
            notify();
        }

        public function getLog():String {
            return messageLog;
        }

        private function notify():void {
            dispatchEvent( new Event( LOG ) );
        }
    }
}
class InstanceKey {}

The important thing here is that a message can be logged from anywhere using

MessageLogger.getInstance().log( "Your Message Here" );

and anything can be notified of when a message has been logged using

MessageLogger.getInstance().addEventListener( MessageLogger.LOG, listenerFunction );

at any point the current message log can be obtained using

MessageLogger.getInstance().getLog();

OTHER TIPS

Create a new Logging class and have that class have a static constructor. Add your logging method to this class. Make the static constructor save the logging field to a private variable. Now before you call the logging method just call your static constructor with the input field you'd like to use. This will create the class, set up the input field as the destination, and now you can simply just call the log function from anywhere.

Traditionally, the way you let static methods interact with private variables is to pass them in. Pass in a pointer to your textbox.

so instead of

public static function getTimeStamp():uint { ... }

you have

public static function writeTimeStamp(messageBox):uint { ... }

The syntax might be incorrect as I'm not an AS dev but, do you see what I mean? From there, that block of code can access messageBox as if it were a local variable. Well it is.

(I renamed the method name for clarity. You could even stop it returning a variable if it doesn't need to but you'll need to change the declaration further.)

In your updated post the debug text field needs to be added to the display list somewhere. Right now it looks like it is just created and used during that log method. You add display objects to the display list by calling addChild( displayObject:DisplayObject ):Boolean; on a DisplayObjectContainer that is already a child of stage.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top