2007年01月07日
Sprite のコンストラクタから stage を確実に取得する方法
Sprite を継承したクラスのコンストラクタから、stage プロパティを参照するときの注意点。
次のような Test.as を単体でコンパイルして SWF を生成すると問題なく動きます。
package{
import flash.display.Sprite;
public class Test extends Sprite
{
public function Test()
{
trace(stage.stageWidth);
}
}
}
ところが、Test.as を別のクラスから作成すると実行時エラーとなってしまいます。
function foo():void
{
// !!! Error !!!: stage is null
var test:Test = new Test();
}
理由は単純。別のクラスから test インスタンスが作成された段階では、test インスタンスはステージ上に存在しないため、stage プロパティは null が返されるのです。
stage プロパティが null でなくなるのは、test インスタンスが addChild されてステージ上に現れた後になります。
そこで、次のように addChild されたときに通知を受けられるよう、Test.as を書き換えれば、無事問題は解決します。
package{
import flash.display.Sprite;
import flash.events.Event;
public class Test extends Sprite
{
public function Test()
{
if(stage)
{
trace(stage.stageWidth);
}
else
{
addEventListener(Event.ADDED, addedHandler);
}
}
private function addedHandler(e:Event):void
{
removeEventListener(Event.ADDED, addedHandler);
trace(stage.stageWidth);
}
}
}
root や parent を取得する場合も、このテクニックが使えますね。
頻繁に追加・削除される表示オブジェクトの場合には、この Event.ADDED および Event.REMOVED のお世話になりそうです。
Flex の場合は、UIComponent の mx.events.FlexEvent.ADD イベントをハンドルしたほうがいいのかもしれません。 このへんはよく分かってないので、コメントいただければ幸い...
補足 (2007.06.09)
add で待機せずに stage を取得する方法があるようです。なるほど、確かにこれなら動きますね。