DataProvider の使用

DataProvider は、ComboBox、DataGrid、List、TileList コンポーネントにデータを供給するために使用できるデータソースです。 これらの各コンポーネントクラスには dataProvider プロパティがあり、それらのプロパティに DataProvider オブジェクトを割り当てて、コンポーネントのセルにデータを設定できます。通常、データプロバイダーは Array や XML オブジェクトなどのデータのコレクションです。

DataProvider の作成

ComboBox、List および TileList の各コンポーネントの場合は、オーサリング環境で dataProvider パラメーターを使用することによって、DataProvider を作成できます。DataGrid コンポーネントの場合、プロパティインスペクターに dataProvider パラメーターがありません。これは、DataGrid コンポーネントは複数の列を持つことができるので、データプロバイダーが複雑になるからです。 ActionScript を使用してこれらのコンポーネント、および DataGrid の DataProvider を作成することもできます。

dataProvider パラメーターの使用

プロパティインスペクターまたはコンポーネントインスペクターの「パラメーター」タブで dataProvider パラメーターをクリックして、ComboBox、List、TileList コンポーネントの簡単なデータプロバイダーを作成できます。

最初は空の配列を表示している「値」セルをダブルクリックすると、値ダイアログボックスが開きます。このダイアログボックスに複数のラベルおよびデータ値を入力し、データプロバイダーを作成できます。

dataProvider の値ダイアログボックス

プラス記号をクリックしてアイテムを dataProvider に追加します。 マイナス記号をクリックすると、アイテムが削除されます。 上矢印をクリックすると選択したアイテムがリストの上方に移動し、下矢印をクリックすると下方に移動します。 次の図は、子供の名前と誕生日のリストを作成する値ダイアログボックスを示します。

データを設定した値ダイアログボックス

ユーザーが作成する配列は、ラベルフィールドと値フィールドのペアで構成されています。 ラベルフィールドは label data であり、値フィールドは子供の名前と誕生日です。ラベルフィールドには、List に表示されるコンテンツを指定します。この場合は、子供の名前です。 ComboBox はこのように表示されます。

DataProvider でデータを設定した ComboBox

データの追加が終了したら、「OK」をクリックしてダイアログボックスを閉じます。 これで dataProvider パラメーターの配列にユーザーが作成したアイテムが設定されました。

データが設定された dataProvider パラメーター

ユーザーが作成したラベルとデータ値にアクセスするには、ActionScript を使用して、コンポーネントの dataProvider プロパティにアクセスします。

ActionScript を使用した DataProvider の作成

DataProvider は、Array または XML オブジェクトにデータを作成し、そのオブジェクトを value パラメーターとして DataProvider コンストラクターに指定することによって作成できます。

注意: ActionScript 3.0 では、Array または XML オブジェクトを dataProvider プロパティに直接割り当てることができません。これは、このプロパティが DataProvider オブジェクトとして定義されており、取得できるのが DataProvider 型のオブジェクトに限られるためです。

次の例では、単一列の行である List コンポーネントに数人の子供の名前と誕生日を設定します。 この例は、 items Array にリストを定義し、DataProvider インスタンスを作成するときにパラメーターとして指定し( new DataProvider(items) )、List コンポーネントの dataProvider プロパティに割り当てます。

import fl.controls.List; 
import fl.data.DataProvider; 
 
var aList:List = new List(); 
var items:Array = [ 
{label:"David", data:"11/19/1995"}, 
{label:"Colleen", data:"4/20/1993"}, 
{label:"Sharon", data:"9/06/1997"}, 
{label:"Ronnie", data:"7/6/1993"}, 
{label:"James", data:"2/15/1994"}, 
]; 
aList.dataProvider = new DataProvider(items); 
addChild(aList); 
aList.move(150,150);

Array は、ラベルフィールドと値フィールドのペアで構成されています。 ラベルフィールドは label data であり、値フィールドは子供の名前と誕生日です。ラベルフィールドには、List に表示されるコンテンツを指定します。この場合は、子供の名前です。 List は次のように表示されます。

DataProvider でデータを設定した List

データフィールドの値は、ユーザーがリスト内のアイテムをクリックして選択し、 change イベントが発生したときに利用可能になります。次の例は、TextArea( aTa )とイベントハンドラー( changeHandler )を前の例に追加し、ユーザーがリスト内の名前を選択したときに、その子供の誕生日を表示します。

import fl.controls.List; 
import fl.controls.TextArea; 
import flash.events.Event; 
import fl.data.DataProvider; 
 
var aList:List = new List(); 
var aTa:TextArea = new TextArea(); 
var items:Array = [ 
{label:"David", data:"1/19/1995"}, 
{label:"Colleen", data:"4/20/1993"}, 
{label:"Sharon", data:"9/06/1994"}, 
{label:"Ronnie", data:"7/6/1993"}, 
{label:"James", data:"2/15/1994"}, 
]; 
aList.dataProvider = new DataProvider(items); 
 
addChild(aList); 
addChild(aTa); 
 
aList.move(150,150); 
aTa.move(150, 260); 
 
aList.addEventListener(Event.CHANGE, changeHandler); 
 
function changeHandler(event:Event):void { 
    aTa.text = event.target.selectedItem.data; 
};

これで、ユーザーが List 内の子供の名前を選択したとき、次の図のように、その子供の誕生日が TextArea に表示されます。これは、 changeHandler() 関数が、TextArea の text プロパティ( aTa.text )を、選択されたアイテムのデータフィールドの値( event.target.selectedItem.data )に設定することによって実現します。 event.target プロパティは、イベントをトリガーしたオブジェクトであり、この場合は List です。

List の DataProvider からのデータフィールドの表示

DataProvider にはテキスト以外のデータも含めることができます。 次の例では、TileList にデータを供給する DataProvider に MovieClip が含まれています。 これは、色付きのボックスの MovieClip を作成した後に addItem() を呼び出して各アイテムを追加することによって DataProvider を構築します。

import fl.data.DataProvider; 
import flash.display.DisplayObject; 
 
var aBox:MovieClip = new MovieClip(); 
var i:uint = 0; 
var colors:Array = new Array(0x00000, 0xFF0000, 0x0000CC, 0x00CC00, 0xFFFF00); 
var colorNames:Array = new Array("Midnight", "Cranberry", "Sky", "Forest", "July"); 
var dp:DataProvider = new DataProvider(); 
for(i=0; i < colors.length; i++) { 
    drawBox(aBox, colors[i]);    // draw box w next color in array 
    dp.addItem( {label:colorNames[i], source:aBox} ); 
} 
aTl.dataProvider = dp; 
aTl.columnWidth = 110; 
aTl.rowHeight = 130; 
aTl.setSize(280,150); 
aTl.move(150, 150); 
aTl.setStyle("contentPadding", 5); 
 
function drawBox(box:MovieClip,color:uint):void { 
            box.graphics.beginFill(color, 1.0); 
            box.graphics.drawRect(0, 0, 100, 100); 
            box.graphics.endFill();        

XML データを (配列の代わりに) 使用して、DataProvider オブジェクトにデータを設定することもできます。 例えば、次のコードは、 employeesXML という名前の XML オブジェクトにデータを格納し、そのオブジェクトを DataProvider() コンストラクター関数の値パラメーターとして渡します。

import fl.controls.DataGrid; 
import fl.data.DataProvider; 
 
var aDg:DataGrid = new DataGrid(); 
addChild(aDg); 
 
var employeesXML:XML =  
    <employees> 
        <employee Name="Edna" ID="22" /> 
        <employee Name="Stu" ID="23" /> 
    </employees>; 
 
var myDP:DataProvider = new DataProvider(employeesXML); 
 
aDg.columns = ["Name", "ID"]; 
aDg.dataProvider = myDP;

前のコードのように、データを XML データの属性として指定すること、または次のコードのように XML データのプロパティとして指定することができます。

var employeesXML:XML =  
    <employees> 
        <employee> 
            <Name>Edna</Name> 
            <ID>22</ID> 
        </employee> 
        <employee> 
            <Name>Stu</Name> 
            <ID>23</ID> 
        </employee> 
    </employees>;

DataProvider にはメソッドとプロパティのセットもあり、ユーザーはそれを使用して DataProvider にアクセスし、操作できます。 DataProvider API を使用して、DataProvider のアイテムの追加、削除、置換、並べ替えおよび結合を行うことができます。

DataProvider の操作

addItem() メソッドと addItemAt() メソッドを使用して、DataProvider にアイテムを追加できます。次の例は、ユーザーが編集可能な ComboBox のテキストフィールドに入力するアイテムを追加します。 ComboBox をステージ上にドラッグし、 aCb というインスタンス名を指定するとします。

import fl.data.DataProvider; 
import fl.events.ComponentEvent; 
 
var items:Array = [ 
{label:"Roger"}, 
{label:"Carolyn"}, 
{label:"Darrell"}, 
{label:"Rebecca"}, 
{label:"Natalie"}, 
{label:"Mitchell"}, 
]; 
aCb.dataProvider = new DataProvider(items); 
     
aCb.addEventListener(ComponentEvent.ENTER, newItemHandler); 
 
function newItemHandler(event:ComponentEvent):void { 
    var newRow:int = event.target.length + 1; 
        event.target.addItemAt({label:event.target.selectedLabel}, 
        event.target.length); 
}

DataProvider を通じてコンポーネント内のアイテムを置換および削除することもできます。 次の例では、2 つの別々の List コンポーネント、 listA および listB を実装し、Sync というラベルの Button を指定します。この例では、ユーザーがこのボタンをクリックしたときに、 replaceItemAt() メソッドを使用して listB のアイテムを listA のアイテムに置換します。 listA listB より長い場合は、 addItem() メソッドを呼び出して、不足分のアイテムを listB に追加します。 listB listA より長い場合は、 removeItemAt() メソッドを呼び出して、 ListB の余分のアイテムを削除します。

// Requires the List and Button components to be in the library 
 
import fl.controls.List; 
import fl.controls.Button; 
import flash.events.Event; 
import fl.data.DataProvider; 
 
var listA:List = new List(); 
var listB:List = new List(); 
var syncButton:Button = new Button(); 
syncButton.label = "Sync"; 
 
var itemsA:Array = [ 
{label:"David"}, 
{label:"Colleen"}, 
{label:"Sharon"}, 
{label:"Ronnie"}, 
{label:"James"}, 
]; 
var itemsB:Array = [ 
{label:"Roger"}, 
{label:"Carolyn"}, 
{label:"Darrell"}, 
{label:"Rebecca"}, 
{label:"Natalie"}, 
{label:"Mitchell"}, 
]; 
listA.dataProvider = new DataProvider(itemsA); 
listB.dataProvider = new DataProvider(itemsB); 
 
addChild(listA); 
addChild(listB); 
addChild(syncButton); 
 
listA.move(100, 100); 
listB.move(250, 100); 
syncButton.move(175, 220); 
 
syncButton.addEventListener(MouseEvent.CLICK, syncHandler); 
 
function syncHandler(event:MouseEvent):void { 
    var i:uint = 0; 
    if(listA.length > listB.length) {     //if listA is longer, add items to B 
        while(i < listB.length) { 
            listB.dataProvider.replaceItemAt(listA.dataProvider.getItemAt(i), i); 
            ++i; 
        } 
        while(i < listA.length) { 
            listB.dataProvider.addItem(listA.dataProvider.getItemAt(i++)); 
        } 
    } else if(listA.length == listB.length) { //if listA and listB are equal length 
        while(i < listB.length) { 
            listB.dataProvider.replaceItemAt(listA.dataProvider.getItemAt(i), i); 
            ++i; 
        } 
    } else {                //if listB is longer, remove extra items from B 
        while(i < listA.length) { 
            listB.dataProvider.replaceItemAt(listA.dataProvider.getItemAt(i), i); 
            ++i; 
        } 
        while(i < listB.length) { 
            listB.dataProvider.removeItemAt(i++); 
        } 
    } 
}

merge() sort() および sortOn() の各メソッドを使用して、DataProvider の結合と並べ替えを行うこともできます。次の例では、2 つの DataGrid インスタンス( aDg bDg )に 2 つのソフトボールチームの名簿の一部を設定します。Merge というラベルのボタンを追加し、ユーザーがそのボタンをクリックしたときに、イベントハンドラー( mrgHandler )が bDg の名簿と aDg の名簿を結合し、得られた DataGrid を Name 列の内容で並べ替えます。

import fl.data.DataProvider; 
import fl.controls.DataGrid; 
import fl.controls.Button; 
 
var aDg:DataGrid = new DataGrid(); 
var bDg:DataGrid = new DataGrid(); 
var mrgButton:Button = new Button(); 
addChild(aDg); 
addChild(bDg); 
addChild(mrgButton); 
bldRosterGrid(aDg); 
bldRosterGrid(bDg); 
var aRoster:Array = new Array(); 
var bRoster:Array = new Array(); 
aRoster = [ 
        {Name:"Wilma Carter", Bats:"R", Throws:"R", Year:"So", Home: "Redlands, CA"},  
        {Name:"Sue Pennypacker", Bats:"L", Throws:"R", Year:"Fr", Home: "Athens, GA"}, 
        {Name:"Jill Smithfield", Bats:"R", Throws:"L", Year:"Sr", Home: "Spokane, WA"}, 
        {Name:"Shirley Goth", Bats:"R", Throws:"R", Year:"Sr", Home: "Carson, NV"} 
]; 
bRoster = [ 
        {Name:"Angelina Davis", Bats:"R", Throws:"R", Year:"So", Home: "Odessa, TX"}, 
        {Name:"Maria Santiago", Bats:"L", Throws:"L", Year:"Sr", Home: "Tacoma, WA"}, 
        {Name:"Debbie Ferguson", Bats:"R", Throws:"R", Year: "Jr", Home: "Bend, OR"} 
]; 
aDg.dataProvider = new DataProvider(aRoster); 
bDg.dataProvider = new DataProvider(bRoster); 
aDg.move(50,50); 
aDg.rowCount = aDg.length; 
bDg.move(50,200); 
bDg.rowCount = bDg.length; 
mrgButton.label = "Merge"; 
mrgButton.move(200, 315); 
mrgButton.addEventListener(MouseEvent.CLICK, mrgHandler); 
 
function bldRosterGrid(dg:DataGrid){ 
    dg.setSize(400, 300); 
    dg.columns = ["Name", "Bats", "Throws", "Year", "Home"]; 
    dg.columns[0].width = 120; 
    dg.columns[1].width = 50; 
    dg.columns[2].width = 50; 
    dg.columns[3].width = 40; 
    dg.columns[4].width = 120; 
}; 
 
function mrgHandler(event:MouseEvent):void { 
    aDg.dataProvider.merge(bDg.dataProvider); 
    aDg.dataProvider.sortOn("Name"); 
}

詳しくは、「 Adobe Flash Professional CS5 用 ActionScript 3.0 リファレンスガイド 」の DataProvider クラスを参照してください。