Accediendo al stage antes de tiempo
En AS3 es una práctica habitual asociar eventos al stage para cogerlos globalmente. El caso más utilizado probablemente se dé con los del tipo MouseEvent. Por ejemplo, si tenemos varios objetos en pantalla, en vez de definir un evento click para cada uno de ellos, cogemos sólo el click en el escenario (global) y vemos sobre quién se está interactuando:
-
this.stage.addEventListener(MouseEvent.CLICK, click);
-
private function click(e:MouseEvent):void
-
{
-
trace("Click en", e.target);
-
}
Pero a veces, cuando intentamos añadir un evento al stage obtenemos el siguiente error:
TypeError: Error #1009: No se puede acceder a una propiedad o a un método de una referencia a un objeto nulo.
Vamos a reproducir el error.
Tenemos dos clases: Main, asociada al documentClass, y Circulo, que se encarga de dibujar un pequeño circulo y capta un evento click.
Clase Main
-
package {
-
import flash.display.Sprite;
-
import Circulo;
-
-
public class Main extends Sprite {
-
-
function Main() {
-
var c:Circulo = new Circulo();
-
addChild(c);
-
}
-
}
-
}
Clase Circulo
-
package {
-
import flash.display.Sprite;
-
import flash.events.*;
-
-
public class Circulo extends Sprite {
-
-
function Circulo() {
-
-
// Dibujar Circulo
-
this.graphics.beginFill(0xFF0000);
-
this.graphics.drawCircle(50, 50, 10);
-
this.graphics.endFill();
-
-
// Definir el evento click
-
this.stage.addEventListener(MouseEvent.CLICK, clic);
-
}
-
-
private function clic(e:MouseEvent):void
-
{
-
if (e.target == this) trace("Click sobre circulo")
-
else trace("No es circulo");
-
}
-
}
-
}
Si compilamos obtenemos:
TypeError: Error #1009: No se puede acceder a una propiedad o a un método de una referencia a un objeto nulo.
at Circulo()
at Main()
¿Por qué obtenemos este error?
Stage es el contenedor base de todos los objetos visuales y se encuentra en lo más alto de la displayList. Este contenedor no se puede acceder directamente, sino que se tiene que hacer mediante la propiedad stage, que se encuentra en cualquier objeto que extiende de DisplayObject.
Nuestro objeto Circulo extiende de Sprite y por tanto es un DisplayObject que soporta la propiedad stage, pero cuando intentamos acceder a dicha propiedad el objeto no se encuentra todavÃa en la displayList y por tanto la referencia es nula.
Solución
Para solucionar esto existen dos eventos muy útiles definidos en DisplayObjet: added y addedToStage. El primero se dispacha cuando un objeto se añade a la displayList y el segundo cuando se añade al escenario.
Asà pues, podemos suscribirnos a estos eventos antes de acceder al stage y asà garantizar que está disponible y que no genera error.
Finalmente nuestra clase Circulo quedarÃa:
-
package {
-
import flash.display.Sprite;
-
import flash.events.*;
-
-
public class Circulo extends Sprite {
-
-
function Circulo() {
-
-
// Dibujar Circulo
-
this.graphics.beginFill(0xFF0000);
-
this.graphics.drawCircle(50, 50, 10);
-
this.graphics.endFill();
-
-
// Escuchar el evento ADDED
-
this.addEventListener(Event.ADDED, init);
-
// o en este caso también ADDED_TO_STAGE
-
//this.addEventListener(Event.ADDED_TO_STAGE, init);
-
}
-
-
private function init(e:Event):void
-
{
-
// Definir el evento click
-
this.stage.addEventListener(MouseEvent.CLICK, clic);
-
}
-
-
private function clic(e:MouseEvent):void
-
{
-
if (e.target == this) trace("Click sobre circulo")
-
else trace("No es circulo");
-
}
-
}
-
}
Post publicado el 18 de February de 2008 a las 16:07 por llops
Categorias: Tips
Etiquetas: added, addedToStage, as3, Error #1009, stage
¿Quieres seguir los comentarios de esta entrada? RSS 2.0

6 comentarios
#1 Junio Vitorino
Hummm, i tried create another instance of the circle object and i add it to displaylist. After this the event workn't properly. The output show me both messages. Because?
Feb 18, 2008
#2 LLops
Ummm it's strange, for me this code works properly:
Are you trying with the correct code?
Feb 18, 2008
#3 EgoSum
Gracias por el tip, me ha solucionado ese runtime error que me salia cuando intentaba lanzar un swf hecho en flash que cargaba a partir de un SWFLoader en flex.
Apr 17, 2008
#4 Juan
Hola. Como les va?
Tengo la siguiente clase en un archivo .AS
package {
import mx.core.WindowedApplication;
import flash.events.*;
public class HW extends WindowedApplication
{
private var appWA:WindowedApplication;
public function HW(){
super();
}
}
}
Y cuando la quiero usar de la siguiente manera con el siguiente codigo de un archivo .MXML
public function ingresar():void {
var newWindow:HW = new HW();
newWindow.initialize();
newWindow.setVisible(true);
}
Obtengo el siguiente error:
TypeError: Error #1009: No se puede acceder a una propiedad o a un método de una referencia a un objeto nulo.
at mx.core::Application/initialize()
at HW/initialize()
at ingresar()
Para resolver el problema intente agregar el siguiente codigo:
override public function initialize():void{
super.initialize();
}
public function HW(){
this.addEventListener(Event.ADDED_TO_STAGE, initialize);
super();
}
Pero no he tenido éxito. AgradecerÃa me puedan indicar como lo soluciono.
Gracias.
May 15, 2008
#5 gonzalo geraldo
Muchas gracias Llops, este tema no lo podia resolver y no lo he visto documentado. Tengo el Essential Actionscript 3.0 y tampoco aparece (espero no pecar de no entender lo que leo). En el Help de Actionscript tampoco lo habia visto explicado asi.
Me ha servido mucho
saludos
Jun 2, 2008
#6 David E Sanchez
Hola!
Quisiera Agradecer la ayuda!!!! pues me proporciono informacion ademas de que encontre solucion al mismisimo problema que se presenta aqui; lo unico que puedo decir es gracias LLop!!! estare publicando mis trabajos para que me ayuden a mejorar pues soy Principiente en FLASH y empece con CS3
Salu2 a la comunidad!!!!
Jun 24, 2008
¡Deja un comentario!