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 を取得する方法があるようです。なるほど、確かにこれなら動きますね。