Archive for 2009/6/19
flexで、SpriteオブジェクトをCanvasにaddChildしようとすると、
TypeError: Error #1034: Type Coercion failed: cannot convert flash.display::Sprite@59f3421 to mx.core.IUIComponent. at mx.core::Container/http://www.adobe.com/2006/flex/mx/internal::addingChild() at mx.core::Container/addChildAt() at mx.core::Container/addChild()
さて、ここでSpriteをaddChildする方法は、いろいろなblogで紹介されているようで結構多くの人が躓くポイントのようだ。
var uicomp:UIComponent = new UIComponent(); uicomp.addChild(sprite);
のようにすれば、いいわけだが、これを機にContainerのソースを見てみることにした。
確かに、マニュアルを見ると、
メモ:メソッドに対する child パラメータは DisplayObject 型として指定されますが、このパラメータがコンテナの子として追加されるためには、IUIComponent インターフェイスを実装する必要があります。 Flex コンポーネントはすべてこのインターフェイスを実装しています。
のように記述されている。
ここで、ContainerとUIComponentnのaddChildについてちょっと見てみることにした。
ContainerクラスのソースのaddChildを見てみると、UIComponentのaddChildから書き換えられている。
addingChildという部分でエラーが出ているので、その部分のContainerを見てみると、
/**
* @private
*/
override mx_internal function addingChild(child:DisplayObject):void
{
// Throw an RTE if child is not an IUIComponent.
var uiChild:IUIComponent = IUIComponent(child);
のように書かれているので、意図的にエラーにしているようだ。
直接は関係がないが、もうちょっとDeepに見ていくと、ContainerのaddChild(実際にはaddChildAt)では、
if (contentPane)
contentPane.addChildAt(child, index);
else
$addChildAt(child, _firstChildIndex + index);
のように、条件によりcontentPaneというFlexSpriteオブジェクトの下に追加されるようだ。
これが、さらにcontentPaneというオブジェクトを追っていくと、いろいろとやっている。
んー、Containerオブジェクトの子供はすべてcontentPaneで管理するのではなく、スクロールバーが表示されるときには、このオブジェクトで管理しているようだが、何か理由があるのであろうか・・・
ただ、Flexにはこのような、親のメソッドを書き換えている部分で引数の条件が変わってきてしまっているというものが結構ありそうな気がする。マニュアルを見ればルールはわかるが、オブジェクトの関係がわからないので、これからも、ソースとは仲良く付き合う必要がありそうだ・・・・

