Flash CS3 でゼロからはじめよう
AIR アプリケーション作成講座 Vol.3

つい先頃、Adobe AIR のベータ版第三弾となる AIR Beta 3 がリリースされました。Flash Player 9 の新バージョンで大きく話題になっている H.264 および AAC コーデックが、AIR Beta 3 でも同様にサポートされました。また今回のバージョンで API の仕様が完成し、いよいよ大勢の方が開発を着手するフェーズに突入します。今月の AIR アプリケーション制作講座 第3回目では今まで作ってきた Web ブラウザを AIR Beta 3 に準拠しながら、別ウィンドウの表示、ローカルデータベースのレコードの編集や削除、デスクトップからのドラッグ&ドロップといった、より高度なデスクトップアプリケーションに成長させていく課程に向けて挑戦してみたいと思います。

Adobe AIR update Beta 3 for Flash CS3 Professional のインストール

Beta 2 の公開から2ヶ月を経て、Adoobe Labs にて AIR Beta 3 が公開されました。着々と機能追加が行われていく AIR ですが、今回は 外部HTML内にある Flashコンテンツの再生をサポートした HTMLLoader (旧 HTMLControl )や H.264 や AAC のサポートなどの新たな機能が追加されています。また、これまでの Beta 期間中に追加や変更が行われてきた API も、今回を最後に正式版リリースを迎える予定です。今後はドキュメントの充実やローカライズ作業など、AIR 開発環境周りの整備が行われていく段階になります。それでは早速、以下のリンクからアクセスしてダウンロードを行ってください。

Adobe AIR Beta 3 Installer

次に AIR Beta 3 用の Flash CS3 アップデータが必要になりますが、今回も Flash CS3 用のアップデータは日本語版用のものを使用する必要があります。以下のリンクからダウンロードしてください。

Adobe AIR update beta 3 for Flash CS3 Professional (Japanese)

既に AIR Beta 2 用のアップデータをインストールされている場合は、先に Beta 2 のアンインストール作業を行ってからそれぞれインストールすることをお奨めします。前回の記事では AIR Beta 2 のアンインストール手順をご紹介しましたが、AIR Beta3に関しても同じ手順で行えますのでそちらを参考にして行ってください。なお、今回はこれらに併せて Flash Player のアップデートも必要になります。以下のサイトよりダウンロードしてアップデートを行うか、Flash CS3 の「ヘルプ」メニューにある「アップデート」から Adobe Update を起動してアップデートを行ってください。

Adobe Flash Player Update for Flash CS3 Professional (9.0.2)

なお、AIR Beta 3 をインストールした場合、Beta 2 までの環境で作成された AIR アプリケーションは Web サイトからの直接インストール (install badge) が行えなくなります。これは Beta 2 までのインストールの方法が Beta 3 で変更になったためのもので、アプリケーションそのものの互換性の問題ではありません。右クリックするなどしてインストーラをデスクトップに保存してから実行してください。Beta 2 でコンパイルされたAIR アプリケーションは Beta 3 の環境でも同様に実行することが可能です。

AIR Beta 3 でのコードの変更点

これまでの記事では AIR アプリケーション内の外部 HTML の表示ローカルデータベースの作成に挑戦してきましたが、Beta 3 で引き続きアプリケーションの作成を行うためにはいくつかコードを変更する必要があります。これまでの記事で使用していたHTMLControlHTMLLoaderに変更されました。また、SQLのエラー表示に使用していたSQL.Error.codeがなくなりました。前回の記事内では内部的なエラー内容を返す目的に使っていたのでコードから削除しても問題ありませんし、代わりにSQL.Error.errorIDを使用するなどしてください。前回記事で作成したファイルをお持ちの方は EdgeBrowser.fla を Adobe Flash CS3 で開き、タイムラインの第1フレームに記述されている ActionScript を以下のように変更してください。

//HTMLControlの読み込み処理
var html:HTMLLoader = new HTMLLoader();
html.width = contentWidth;
html.height = contentHeight;
html.load(urlReq);

(中略)

//データベースエラーハンドラ
function errorHandler(event:SQLErrorEvent):void {
	trace("Error code:", event.error.errorID);
	trace("Details:", event.error.message);
}

前回までの記事で作成したコードの修正点はこれだけですが、Beta 3 ではこのほかにも数多くの API が変更されています。詳細につきましてはリリースノートを参照して下さい。

Adobe AIR release notes

また、Beta 3 の公開に合わせてリファレンスも改訂されています。現在のところ英語版のみとなりますが、こちらも併せて参照されることをお奨めします。

ActionScript 3.0 Language Reference for Adobe AIR

レコード編集用の画面を準備する

それでは今回の本題に入りましょう。前回まではローカルデータベースの作成とホームページのURLを追加するところまでを解説しました。しかし、次第にレコードの数が増えてくると、それを編集したり、削除したくなるものです。今回は追加されたレコードの編集画面の作成から始めましょう。

Flash CS3 の 「挿入」メニューの「新規シンボル」をクリックし、タイプを「ムービークリップ」、インスタンス名を「DBEdit_mc」として設定を確定します。

新規シンボル作成のダイアログ

作成した編集画面になりましたら、前回作成したウィンドウの背景用のムービークリップをライブラリからドロップして利用しても良いですし、新たに矩形ツールでステージ上にウィンドウの背景にあたる部分を描画してムービークリップにすることもできます。この背景のムービークリップはインスタンス名を「DBEdit_BG」としてください。その背景の上にテキストツールでレコード編集用のテキスト入力フィールドを2つ作成し、それぞれインスタンス名をつけます。上から「pageTitle_txt」、「urlStr_txt」と設定しましょう。

また、ボタンを横並びに3つ作成して配置し、それぞれインスタンス名を左から、「UPDATE_btn」「CANCEL_btn」「DELETE_btn」とします。

データベース編集用の画面をムービークリップで作成
レコード編集画面をムービークリップとして作成

ムービークリップを動的に表示するためにクラスファイルを作成

ここで Flash に関する話になりますが、ライブラリに登録されているムービークリップを ActionScript を使って動的に呼び出す場合、ActionScript 3.0 からは「クラス」を使用するようになりました。「クラス」の概念は ActionScript 3.0 への移行するうえで躊躇してしまう部分ではありますが、この機会にぜひ挑戦してみてください。具体的には以下のような手順です。

リンケージの設定

  1. 保存されているFLAファイルと同階層にテキストエディタなどで空白のASファイル DBEdit_mc.as を作成します。このファイル名はそのままクラスの名前として使用されますので半角英数字を使用し、ActionScriptの予約語とぶつからないような名前にします。
  2. Flah CS3 の「ライブラリ」パネルを開き、先ほど作成したムービークリップをライブラリパネル上で右クリックするなどして「リンケージプロパティ」のダイアログ画面を表示させます。
  3. 「ActionScriptに書き出し」と「最初のフレームに書き出し」にチェックを入れます。「クラス」の項を先ほど作成したASファイルと 同じ名前 DBEdit_mc とし、「基本クラス」の項をflash.display.Spriteとします。
  4. 「クラス」の項の右側にある緑色のチェックマークをクリックし、Flash からクラスファイルが参照できるかどうか確認します。
  5. 問題ないようであればさらに右側のエンピツマークのアイコンをクリックしコードの編集が行えるようであれば準備完了です。

余談になりますが、ActionScript 3.0 ではこれまでのムービークリップの概念が変わり、ムービークリップもテキストフィールドやシェイプと同様、DisplayObject の1つとして扱われるようになりました。今回のようにタイムラインを使わないような場合、ムービークリップを「スプライト」とすることでメモリ効率や処理速度の点で有利になります。

それでは、先ほど作成したクラスファイル DBEdit_mc.as に以下のようなコードを記述してください。。


package {
	//ムービークリップやテキストフィールド、ボタンを表示するために必要な外部クラス
	import flash.display.*;
	import flash.text.*;
	import flash.events.MouseEvent;
	import flash.events.Event;

    //リンケージプロパティで設定した基本クラスSpriteを継承
	public class DBEdit_mc extends Sprite {
	
		//コンストラクタ
		public function DBEdit_mc() {
			this.x=0;
			this.y=0;
			this.edit_PageTitle_txt.text = "HTMLのタイトル";
			this.edit_UrlStr_txt.text = "HTMLのURLアドレス";

		}
	
	}
}

クラスはこのようにpackageではじめて中括弧で閉じた構造の中に記述を行います。先頭でクラス内で使用する外部クラスを読み込み、強調表示したクラス名と関数名はすべて同じにする必要があります。ここで設定する関数はNEW 演算子で呼び出されるのと同時に実行される関数で戻り値を持たないという特性があります。一般的にはコンストラクタ関数とも呼ばれます。ここではこれ以上クラスファイルの構造については解説しませんが、ActionScript 3.0 で作成するアプリケーションのクラスファイルは同様の構造で作成することが可能です。詳細はアプリケーションのヘルプや各リファレンスなどをご参照ください。

アプリケーションから新しくウィンドウを開く

せっかく AIR のアプリケーション作成に挑戦しているので、同じウィンドウの中にムービークリップを配置させるのではなく、新たに別のウィンドウを開いて、その中にムービークリップを表示させてみましょう。

AIR のアプリケーションウィンドウは flash.display クラスに属する NativeWindow クラスを使用することで動的に作成することが可能です。先ほど作成したクラス内にコードに追加すると以下のようになります。

package {
	import flash.display.*;
	import flash.text.*;
	import flash.events.MouseEvent;
	import flash.events.Event;

	public class DBEdit_mc extends Sprite {
		public var EditWindow:NativeWindow
		//コンストラクタ
		public function DBEdit_mc() {
			this.x=0;
			this.y=0;
			this.edit_PageTitle_txt.text = "HTMLのタイトル";
			this.edit_UrlStr_txt.text = "HTMLのURLアドレス";

			//ウィンドウの種類を設定
			var winOption:NativeWindowInitOptions = new NativeWindowInitOptions();
			winOption.type = NativeWindowType.LIGHTWEIGHT;
			winOption.systemChrome = NativeWindowSystemChrome.NONE;
			winOption.transparent=true;

			//ウィンドウの表示設定
			EditWindow= new NativeWindow(winOption);
			EditWindow.width = 700;
			EditWindow.height = 400;
			EditWindow.stage.align = StageAlign.TOP_LEFT;
			EditWindow.stage.scaleMode = StageScaleMode.NO_SCALE;
			EditWindow.title = "Bookmark編集画面";
			EditWindow.x=300;
			EditWindow.y=200;
		}	
	}
}

まず最初に、クラス全体で使用できる外部からアクセス可能な変数を EditWindow として設定しています。データ型は NativeWindow です。これはこのクラスが生成するインスタンスの「プロパティ」とも言えます。

次にコンストラクタ関数の中で、winOptionという名前の NativeWindowInitOptions のインスタンスを作成し、表示するウィンドウタイプの設定を行っています。ここでは、メニューのない透明なウィンドウを設定しています。

次に、ここで行ったウィンドウタイプの設定が格納されたインスタンスを使用して、あらためてEditWindowのインスタンスを生成しています。その後に続く設定はこのウィンドウ自体の表示内容を設定しています。ウィンドウのサイズやステージの配置方法、表示するウィンドウのタイトル(メニューが非表示の場合は表示されません)になります。このほかにも設定可能な値はありますが、詳細はリファレンス等を参照して下さい。

さて、ここまでで編集用のウィンドウの準備が出来ました。次に、このムービークリップが行う一連の処理の関数を準備しましょう。これはこのクラスが生成するインスタンスのメソッドを作成しているとも言えます。

このムービークリップに必要なものとして考えられる処理としては、大元の Flash ムービーからからウィンドウを開くように要求された場合の処理、ムービークリップ上にある各ボタンの処理、ムービークリップ上の背景をドラッグした際にウィンドウを移動させる処理が考えられます。これらのことをふまえて一連のウィンドウ表示設定の後に続けて以下のコードを追加します。

			//各ボタンにマウスがクリックされた時のイベントハンドラを登録
			this.UPDATE_btn.addEventListener(MouseEvent.CLICK, updateButtonHandler);
			this.CANCEL_btn.addEventListener(MouseEvent.CLICK, cancelButtonHandler);
			this.DELETE_btn.addEventListener(MouseEvent.CLICK, deleteButtonHandler);

			//背景用のムービークリップがマウスでドラッグされたときのイベントハンドラを登録
			this.DBEdit_BG.addEventListener(MouseEvent.MOUSE_DOWN, windowMove);

		}
        
        //このムービークリップをウィンドウに貼り付け、表示を有効化
		public function open() {
			EditWindow.stage.addChild(this);
			EditWindow.activate();
		}
        
        //ウィンドウを移動させる処理
		private function windowMove(e:MouseEvent):void {
			EditWindow.startMove();
		}

        
		// UPDATEボタンのイベント処理
		private function updateButtonHandler(e:MouseEvent) {
			EditWindow.close();
		}
		// CANCELボタンのイベント処理
		private function cancelButtonHandler(e:MouseEvent) {
			EditWindow.close();
		}
		// DELETEボタンのイベント処理
		private function deleteButtonHandler(e:MouseEvent) {
			EditWindow.close();
		}

まずムービークリップ上にある各オブジェクトに対して、EventListenerを追加してイベントを検知できるように設定し、次に各イベントに対する処理をメソッドとして登録しています。ボタンついては外部から制御される必要がないのでprivateのメソッドとし、表示させる処理には大元のタイムラインから呼び出せるように publicとしています。

なお、NativeWindowで作成したウィンドウはインスタンスを生成しただけでは実際の表示は行われません。このようにNativeWindow.activate()を使用して表示を有効化する必要がありますのでご注意ください。

データグリッドの値を別ウィンドウに表示する

さて、ここまでで表示する別ウィンドウ側の準備は整いました。今度は大元のタイムライン上のオブジェクトからこのウィンドウを呼び出すようにしましょう。今回はデータグリッドのリスト項目をダブルクリックするとレコード編集用のウィンドウが開いて、そのデータが表示されるという形にしたいと思います。

前回の記事の最後に以下のようなコードを記述します。リスト項目の ID を基準に SQL を発行し、取得したデータベースの内容を格納してムービークリップのインスタンスに対して先ほど作成した open のメソッドを使ってパラメータとして渡します。AIR における SQLite の解説については 前回の内容と重複するのでここでは割愛させていただきます。

//データグリッドの項目をダブルクリックしてIDをパラメータとして渡し、レコード編集用のウィンドウを表示
dg.addEventListener(ListEvent.ITEM_DOUBLE_CLICK, sendDBEdit_ID);

function sendDBEdit_ID(e:Event):void {
	var ID:Number = e.target.selectedItem.linkId;
	var selectState:SQLStatement= new SQLStatement();
	selectState.sqlConnection = dbCon;
	
    var selectSql:String =
	"SELECT * FROM EdgeBookmarks " + 
	"WHERE linkId = @ID";

	selectState.parameters["@ID"] =ID;

	selectState.text = selectSql;
	selectState.addEventListener(SQLEvent.RESULT, selectEditData);
	selectState.addEventListener(SQLErrorEvent.ERROR, errorHandler);

	selectState.execute();

	function selectEditData(event:SQLEvent) {
		var selectData:SQLResult = selectState.getResult();

		var subwin:DBEdit_mc = new DBEdit_mc;
		subwin.open(selectData);
	}
ここで一点追加する処理が必要になります。今回のように新たにウィンドウを開くアプリケーションを作成する場合、大元のウィンドウが閉じられた際に新しく開かれたウィンドウは自身の手で閉じる必要があります。開発環境上ではインスタンスが消失するのと同時に新しく開かれたウィンドウも自動的に閉じられますが、コンパイルしたアプリケーションでは開かれたままになります。これは大元のアプリケーションをNativeApplication.exit のメソッドで終了させた場合でも同様です。ウィンドウが開いたままの状態でさらにウィンドウを開こうとすると、アプリケーションが反応しなくなったように見えたり IllegalOperationError エラーになったりします。このような事態を避けるために、以下のようにして元のウィンドウが閉じられると新たに作成したウィンドウも一緒に閉じられるようにしておきましょう。
//親のウィンドウを監視し閉じられたら子のウィンドウを閉じる
stage.nativeWindow.addEventListener(Event.CLOSE, onClose);

function onClose(evt:Event) {
	subwin.EditWindow.close();
}

最後にムービークリップの方にこのデータベースの結果からデータを取り出して表示する処理を追加します。再度 DBEDit_mc.as を開いて、openメソッドの箇所を以下のように変更します。

	public function open(selectData) {
			edit_PageTitle_txt.text=selectData.data[0].pageTitle;
			edit_UrlStr_txt.text=selectData.data[0].urlStr;
			EditWindow.stage.addChild(this);
			EditWindow.activate();
		}

データベースからSQLを発行して取得した結果は配列として格納されれます。pageTitleurlStrはデータベースフィールドの名前です。上記のようにして各フィールド名を指定して実データを取り出し、ムービークリップ上のテキストフィールドに渡します。

さて、ここまでで実際に表示が行えるかどうかを試してみましょう。うまくいかない方も以下のリンクからソースファイルをダウンロードし、実際に動作させたりコード内容を自分なりに変更するなどして色々と試してみてください。

 

AIRアプリケーションで別ウィンドウを開いた状態

 

今回は Flash CS 3 を使って AIR アプリケーション特有のウィンドウ処理に挑戦してみましたが、次回はデスクトップへのドラッグ&ドロップのような OS との連携機能の作成に挑戦してみたいと思います。

関連記事

Flash CS3 でゼロからはじめよう AIRアプリケーション作成講座
Vol.1 AIRとFlash CS3で簡単にデスクトップアプリケーションを作成しよう
Vol.2 AIRで作るedgeBrowser ─ データベースを利用したブックマーク機能

Developer Center
HTMLベースのAIRアプリケーション開発環境のセットアップ