Tree コンポーネントの各ノードの外観や昨日を変更するには
Tree コンポーネントの itemRenderer プロパティを用いる。
itemRenderer
itemRenderer は、Tree コンポーネントの全体ではなく
ノード1つ分、つまり1行分を設定するようなシステムである。
この、ノード1つ分を決めてやることで、各ノードにその設定が反映され
独自の Tree コンポーネントが出来上がる。
itemRenderer の作成
MXML で作成する手法
MXML エディタに上記のように打ち込むと、itemRenderer の作成サポートが表示される。
これを選択すると左のようなダイアログが表示される。
パッケージ は、参照からフォルダを辿ってもよいし、
自ら入力すればフォルダが存在しない場合はフォルダを自動生成してくれる。
終了 をクリックすれば、以下のような MXML ファイルが自動生成される。
プロジェクトフォルダ/src/hoge/moge/testRenderer.mxml
[mxml]
[/mxml]
これを見るとデフォルトの itemRenderer が分かる。
ステート
normal、hovered(マウスオーバー時)、selected(クリック時) の3つのステートがある。
itemEditor
itemRenderer に搭載される各コンポーネントのことを itemEditor という。
Tree コンポーネントの itemEditor は5つ(?)。
getChildAt(0):インデント用の Rect
getChildAt(1):disclosureIcon 用の Group
getChildAt(2):disclosureIcon 用の BitmapImage
getChildAt(3):icon 用の BitmapImage
getChildAt(4):Label
上記5つのうち、3 の icon 用の BitmapImage 以外は、確かめていないので怪しい。
いずれにせよ、ここに CheckBox なり RadioButton なり配置すれば、表示することができる。
データバインディング
また、バインドされているデータのところを見ると {treeListData.indent} のようになっている。
ここから見て、indent, icon, label は予め設定してあるようでこのまま使えるようだ。
Tree コンポーネントの iconField プロパティや lableField プロパティに XML データの属性を設定した結果、そのまま使えた。
しかしそれ以外の属性データを使いたい場合は
{treeListData.@hoge} ではなく {data.@hoge} としてやることで読み込んでくれた。
課題
ただ、残念ながら icon は上手くいかなかった。
固定アイコンは問題なかったのだが、@icon 属性に表示したい icon へのパスをセットし
source=”{treeListData.disclosureIcon}”
や
source=”@Embed source='{treeListData.disclosureIcon}'”
こんな風にしてみても反映されなかった。
AS で作成する手法
アシアルブログ:【Flex3】「Flex3の、こんなときどうするの??」
ここの6番。 6. ツリーに文字列以外のものを表示したい
これを参考にさせていただいた。
[mxml]
).node;
]]>
[/mxml]
TreeItemRenderer クラスを継承したクラスを新たに作成する。
[as3onfx4]package components
{
import mx.binding.utils.BindingUtils;
import mx.controls.CheckBox;
import mx.controls.treeClasses.TreeItemRenderer;
import mx.controls.treeClasses.TreeListData;
public class Hoge extends TreeItemRenderer
{
[Bindable]
public var checkBox:CheckBox;
public function Hoge()
{
super();
}
override public function set data(value:Object):void {
super.data = value;
}
override protected function createChildren():void{
super.createChildren();
checkBox = new CheckBox();
checkBox.setStyle(“verticalAlign”,”middle”);
BindingUtils.bindSetter(setSelected, checkBox, ‘selected’);
this.addChild(checkBox);
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
var treeListData:TreeListData = TreeListData(super.listData);
super.updateDisplayList(unscaledWidth,unscaledHeight);
if(super.data)
{
if (data.@selected.toString() == ‘true’)
{
checkBox.selected = true;
}
else
{
checkBox.selected = false;
}
checkBox.x = super.label.x;
checkBox.y = ( unscaledHeight – checkBox.height ) /2;
label.x = checkBox.x + checkBox.width + 20;
}
}
private function setSelected(selected:Boolean):void
{
if (data)
{
data.@selected = selected.toString();
}
}
}
}[/as3onfx4]
別途、こんな例も見つけた。
FXUG:Re: Treeのアイコンを動的に変更したい
[as3onfx4]
import flash.display.DisplayObject;
import mx.collections.*;
import mx.controls.Image;
import mx.controls.treeClasses.*;
public class TreeItemRendererEx extends TreeItemRenderer {
private var img:Image = new Image();
public function TreeItemRendererEx() {
super();
this.addChild(this.img as DisplayObject);
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
super.updateDisplayList(unscaledWidth, unscaledHeight);
if(data!=null) {
this.label.x += 5;
this.img.x = this.getChildAt(3).x;
this.img.y = this.getChildAt(3).y – 5;
this.img.width = 24;
this.img.height = 24;
this.img.source = data.iconPath;
this.getChildAt(3).visible = false;
}
}
}
[/as3onfx4]
この方法だと、上記 MXML による itemRenderer の実装時に問題となった
全ノード異なるアイコンを表示する という作業も上手くいった。
しかしこちらの方法だと Label を二段にする という作業は上手くできなかった。