Flash CS3 ドキュメンテーション |
|||
| ActionScript 3.0 のプログラミング > 配列の操作 > Example: PlayList | |||
ここでは PlayList の例を使って、配列を操作する手法について、曲のリストを管理する音楽プレイリストアプリケーションのコンテキストで示します。それらの手法は、次のとおりです。
このサンプルのアプリケーションファイルを入手するには、www.adobe.com/go/learn_programmingAS3samples_flash_jp を参照してください。PlayList アプリケーションのファイルは、"Samples/PlayList" フォルダにあります。アプリケーションは、次のファイルで構成されています。
|
ファイル |
説明 |
|---|---|
|
PlayList.mxml または PlayList.fla |
Flash (FLA) または Flex (MXML) のメインアプリケーションファイル。 |
|
com/example/programmingas3/playlist/Song.as |
単一の曲に関する情報を表す値オブジェクト。PlayList クラスが管理する項目は Song インスタンスです。 |
|
com/example/programmingas3/playlist/SortProperty.as |
利用可能な値が Song クラスのプロパティを表し、このプロパティで Song オブジェクトのリストをソート可能な擬似列挙 |
PlayList クラスは Song オブジェクトセットを管理するクラスで、曲をプレイリストに追加するための addSong() メソッドや、リストの曲をソートするための sortList() メソッドなど、さまざまな機能のパブリックメソッドを備えています。このクラスには、読み取り専用アクセサプロパティの songList もあり、これによってプレイリストの実際の曲セットにアクセスできます。内部的には、PlayList クラスは、Array プライベート変数を使用して曲を追跡し続けます。
public class PlayList
{
private var _songs:Array;
private var _currentSort:SortProperty = null;
private var _needToSort:Boolean = false;
...
}
PlayList クラスが曲のリストを追跡し続けるために使用する _songs という Array 変数の他に、2 つのプライベート変数 (_needToSort と _currentSort) があり、前者はリストのソートが必要であるかどうかを、後者は指定の時刻にどのプロパティで曲のリストをソートするかを追跡し続けます。
すべてのオブジェクトの場合と同様に、Array インスタンスを宣言するだけでは Array の作成作業は完了しません。Array インスタンスのプロパティまたはメソッドにアクセスする前に、このインスタンスを PlayList クラスのコンストラクタでインスタンス化しておく必要があります。
public function PlayList()
{
this._songs = new Array();
// 最初のソートを設定する
this.sortList(SortProperty.TITLE);
}
コンストラクタの 1 行目は、_songs 変数をインスタンス化して使用できる状態にします。さらに、sortList() メソッドを呼び出し、最初のソート基準プロパティを設定します。
ユーザーが新しい曲をアプリケーションに登録すると、データ入力フォームのコードが PlayList クラスの addSong() メソッドを呼び出します。
/**
* 曲をプレイリストに追加する
*/
public function addSong(song:Song):void
{
this._songs.push(song);
this._needToSort = true;
}
addSong() 内では _songs 配列の push() メソッドが呼び出され、その配列の新しい要素として addSong() に渡された Song オブジェクトが追加されます。push() メソッドでは、以前に適用していたソートとは関係なく、新しい要素を配列の末尾に追加します。つまり、push() メソッドを呼び出した後では、曲のリストはソート順が正しくなっていない可能性が高いため、_needToSort 変数は true に設定されます。理論上は、sortList() メソッドをすぐに呼び出すため、指定の時刻にリストをソートするかどうかを追跡し続けることは不要になります。しかし、実際には、取得する直前まで曲のリストをソートする必要はありません。たとえば、取得前に何曲かリストに追加したときなど、ソート操作を遅らせると、アプリケーションは不要なソートを実行しなくなります。
プレイリストが管理する Song インスタンスは複雑なオブジェクトであるため、そのアプリケーションのユーザーは、曲のタイトルまたは発表の年など、さまざまなプロパティに従ってプレイリストをソートしたいと考えることがあります。PlayList アプリケーションにおいて、曲のリストをソートするタスクは、リストのソート基準としてのプロパティを見分けること、そのプロパティによるソート時に必要なソートオプションを指定すること、実際のソート操作を実行することの 3 つの部分から構成されます。
Song オブジェクトは、曲のタイトル、アーティスト、発表の年、ファイル名、およびユーザーの選曲ジャンル集など、いくつものプロパティを追跡し続けます。言うまでもなく、ソートに実用的なのは、例に挙げた最初の 3 つのプロパティのみです。開発者の便宜のため、例に含めた SortProperty クラスは、ソートに利用可能なプロパティを表す値を持つ列挙として機能します。
public static const TITLE:SortProperty = new SortProperty("title");
public static const ARTIST:SortProperty = new SortProperty("artist");
public static const YEAR:SortProperty = new SortProperty("year");
SortProperty クラスには、TITLE、ARTIST、および YEAR の 3 つの定数があり、各定数には、ソートに使用する関連 Song クラスプロパティの実際の名前を含むストリングが格納されます。コードの残り全体を通し、ソートプロパティが指定されると必ず列挙メンバーを使用して行われます。たとえば、PlayList コンストラクタでは、次のように、sortList() メソッドを呼び出してリストを最初にソートします。
// 最初のソートを設定する
this.sortList(SortProperty.TITLE);
ソートのプロパティは SortProperty.TITLE として指定されているため、曲はタイトルに従ってソートされます。
実際には曲のリストのソートは、次に示すように、PlayList クラスが sortList() メソッドで実行します。
/**
* 指定されたプロパティに従って曲のリストをソートする
*/
public function sortList(sortProperty:SortProperty):void
{
...
var sortOptions:uint;
switch (sortProperty)
{
case SortProperty.TITLE:
sortOptions = Array.CASEINSENSITIVE;
break;
case SortProperty.ARTIST:
sortOptions = Array.CASEINSENSITIVE;
break;
case SortProperty.YEAR:
sortOptions = Array.NUMERIC;
break;
}
// データの実際のソートを実行する
this._songs.sortOn(sortProperty.propertyName, sortOptions);
// 現在のソートプロパティを保存する
this._currentSort = sortProperty;
// リストがソートされたことを記録する
this._needToSort = false;
}
タイトルやアーティストによってソートする場合はアルファベット順にソートし、年によってソートする場合は数値順にソートします。switch ステートメントを使用して、sortProperty パラメータが指定する値に従った適切なソートオプション (変数 sortOptions に格納) を定義します。ここでも、プロパティの区別には、ハードコードされた値ではなく名前付き列挙メンバーを使用しています。
ソートプロパティおよびソートオプションの決定に続き、_songs 配列を sortOn() メソッドの呼び出しで実際にソートし、それらの 2 つの値をパラメータとして渡します。現在のソートプロパティが記録されますが、それは曲のリストが現時点でソートされたということです。
配列を使用して曲のリストを PlayList クラスで維持する以外に、この例では Song クラスでも配列を使用して、曲についてのジャンルリストを管理するのに役立てています。次に示す、Song クラスの定義からの抜粋で検討してみます。
private var _genres:String;
public function Song(title:String, artist:String, year:uint, filename:String, genres:Array)
{
...
// ジャンルは配列として渡されるが
// 格納時はセミコロンで区切られたストリングである
this._genres = genres.join(";");
}
新しい Song インスタンスの作成時に、曲のジャンルの指定に使用する genres パラメータが Array インスタンスとして定義されます。そのため、複数のジャンルを一緒のグループにまとめ、コンストラクタに渡せる 1 つの変数とするのに便利です。ただし、内部的には Song クラスは、セミコロンで区切られた String インスタンスとして _genres プライベート変数にジャンルを維持します。Array パラメータは、リテラルストリング値 ";" を区切り文字として指定して join() メソッドを呼び出すと、セミコロンで区切られたストリングに変換されます。
同じように、genres アクセサを使用して、ジャンルを配列として設定また取得できます。
public function get genres():Array
{
// ジャンルはセミコロンで区切られたストリングとして格納される
// そのため返すには配列に戻す変換が必要である
return this._genres.split(";");
}
public function set genres(value:Array):void
{
// ジャンルは配列として渡されるが、
// 格納時はセミコロンで区切られたストリングである
this._genres = value.join(";");
}
genres set アクセサの動作は、コンストラクタの動作とまったく同じです。配列を受け取って join() メソッドを呼び出し、セミコロン区切りのストリングに変換します。get アクセサは反対の操作を実行します。つまり、_genres 変数の split() メソッドが呼び出されると、指定された区切り文字 (リテラルストリング値 ";" など) を使用して、ストリングを値の配列に分割します。
このページに新しいコメントが追加された場合に、電子メールでの通知を希望する。 | コメントレポート
現在のページ: http://livedocs.adobe.com/flash/9.0_jp/main/00000094.html