本記事中のサンプルを表示するには最新のFlashPlayer9が必要です(本稿執筆時点では【9,0,28,0】が最新)。こちらから最新のFlashPlayer9をインストールしてください。また,インストール後はブラウザの再起動が必要です。インストールされているFlash Playerのバージョンを確認するにはこちら

 これまで3回かけて,Flexが備えるコンポーネントの説明をしてきました。今回と次回はちょっと趣向を変えて,これまで解説したコンポーネントを使って,簡単なサンプル・アプリケーションを作ってみることにします。

 サンプル・アプリケーションを作るに当たって,以下のお題を考えました。
・第6回までに紹介したコンポーネントを使用する
・シンプルな“業務アプリケーション的”なサンプル
・サーバーサイドとの連携は無し
もっとも,これまでの連載の解説内容だけでは厳しいので,初めて紹介するコンポーネントやTipsも使用しているます。

 著者はFlex2でアプリケーションを開発するときにActionScriptを使用しないことは無いと思っています。しかし,今回は今までの解説のおさらい的なサンプルですので,ActionScriptをあまり知らなくてもソースを読めるような構成にしてみました。それだけに今回のお題はかなりタフでした。

ブラウザのバックで戻っても状態を保持している

 では,実際に作成した「ウィザード形式に顧客情報を入力する」サンプルを見てみましょう(図1)。

図1●「ウィザード形式に顧客情報を入力する」サンプル・アプリケーション
図1●「ウィザード形式に顧客情報を入力する」サンプル・アプリケーション(クリックすると別ウィンドウでアプリケーションを表示します。ソースはこちら)
[画像のクリックで拡大表示]

 このサンプルは,インターネット・サービスのユーザー登録やネット通販の決済手続きにおいて常套手段とも言うべき「ウィザード形式」を題材にしてみました。ステップごとに画面が変わり,一画面における入力内容も気持ち的に耐えられる範囲になっていると思います(ただ,今回のサンプルでは必須入力チェックなどは省かせていただきました)。「次へ」をクリックすると次ステップの画面を表示し,「戻る」をクリックすると前ステップの画面を表示します。

 図1をクリックしてアプリケーションを起動し,「次へ」ボタンを5回クリックしてみてください。お気づきになった方もおられるかもしれませんが,ブラウザの「戻る」ボタンが有効(クリックできる状態)になっています。では,ここでブラウザの「戻る」ボタンをクリックしてみてください。

 どうでしょうか?ブラウザの「戻る」ボタンも5回クリックでき,ステップ画面も逆順に戻ったと思います。これがFlashPlayer9で新たに追加された「履歴管理」機能です*1

 ただし,この機能はHTMLページの「戻る」という動作とは大きく異なりますので混同しないように注意してください。FlashPlayer9での「履歴管理」はページを戻るのでもなく,操作をやり直すのでもなく,“特定の”コンポーネントの表示していた“状態”を記憶・追跡する機能です。

 ここで,特定のコンポーネントとは,「Accordion」*2,「TabNavigator」*3,「ViewStack」*4の三つです。これらのコンポーネントは,「ナビゲータ」というカテゴリに分類されるものです。複数の子オブジェクトをレイヤー階層的に保持し,ユーザーが指定した子オブジェクトだけを表示するという制御を自動的にしてくれます。

 状態というのは,表示した子オブジェクトのことです。サンプルでは表示したステップ画面が子オブジェクトです。試しに,ステップ2の画面に移動し「生年月日」を変更してからブラウザの「戻る」ボタンをクリック。さらに,ステップ1画面の「次へ」ボタンをクリックしてステップ2の画面を表示してください。いかがでしょうか?生年月日は変更されたままですね(「Debug Child Model」ボタンと「確定」ボタンについては後編にて詳しく解説しますので,今回は省略させていただきます)。

MXMLコンポーネントを利用する

 このサンプルのソース・ファイルの構成は図2のようになっています。

図2●アプリとコンポーネントのファイルの構成の概略図
図2●アプリとコンポーネントのファイルの構成の概略図

 「main.mxml」のViewStackコンポーネント内にある「TopMessage.mxml」「BasicInfo.mxml」「OfficeInfo.mxml」「FamilyInfo.mxml」「OtherInfo.mxml」「NoteInfo.mxml」は,拡張子がMXMLですが,MXMLアプリケーションではありません。MXMLコンポーネント*5になります。

図3●MXMLファイルのアイコン
図3●MXMLファイルのアイコン

 MXMLアプリケーションとMXMLコンポーネントの違いは名前の通り,コンパイルされSWFファイルとなるアプリケーションなのか,そのアプリケーションに内包されたUIコンポーネント(=カスタムクラス)なのかの違いです*6図3のようにアイコンも違います。図3のmain.mxmlの左上に付いている再生マークのような緑色の三角印がMXMLアプリケーションであることを意味し,右下の球体マークがデフォルト・アプリケーションを意味します。

 MXMLコンポーネントを作成するには,ツールバーの新規作成ボタンから図4のように「MXMLコンポーネント」をクリックし,図5の画面が起動したら「ファイル名」とベースとなるUIコンポーネントを選択します。

図4●「MXMLコンポーネント」新規作成メニュー
図4●「MXMLコンポーネント」新規作成メニュー

図5●「MXMLコンポーネント」作成画面
図5●「MXMLコンポーネント」作成画面

 それでは各MXMLコンポーネントの中身を見ていきます。図1のアプリケーションを起動して,画面を見ながら読み進めてください。

ステップ1

 「TopMessage.mxml」はステップ1,すなわちSWFファイルをロードしたときに最初に表示されるウィザードのトップ画面です。ベースコンポーネントはVBox*7というContainerを拡張したBoxコンポーネントをさらに拡張したコンポーネントです。

 基本的な動きは子オブジェクトを自動的に縦列に配置してくれるレイアウト制御コンポーネントです。その子オブジェクトにはダミーの「Model」*8とメッセージを表示するTextコンポーネント*9のみです。ここでは2行で表示したかったので,1行しか表示できないLabelでは無く,Textを使用しています。また,「text」属性を中括弧で囲むことでその中身をActionScript的に表現できるようにしています。そうすることで文字列を「+(プラス)」で結合できたり,「\n」で改行を表現することができます。

ステップ2

 「BasicInfo.mxml」はステップ2の画面コンポーネントで,個人の基本情報を入力する画面です。前項と同様にVBoxを拡張しています。最初のLabelコンポーネント*10の「toolTip」属性にこの画面の説明をセットしていますが,この「toolTip」というのは実はコンポーネントレベルの機能ではなく,FlexFramework2レベルの機能です。「mx.managers.ToolTipManager」*11というクラスがToolTipを制御しています*12

 次にHBoxコンポーネント*13があります。これはお気づきの通りVBoxと対を成すコンポーネントでVBoxが縦配置なのに対してHBoxは横配置用のレイアウト制御コンポーネントです。頭文字の「V」と「H」はそれぞれ英語の「Vertical(垂直の)」と「Horizontal(水平の)」からです。

 「氏名(フリガナ)」入力用としてTextInputコンポーネント*14を利用しています。ここでは「imeMode」属性にIMEConversionModeクラス*15のJAPANESE_KATAKANA_FULL 定数(=日本語入力の全角カタカナ)を指定しています。そうすることでユーザーが入力エリアにフォーカスを合わせると同時に自動的に日本語入力モードが全角カタカナに変わります。このクラスにはALPHANUMERIC_HALF という定数も存在しますがこれは日本語入力モード状態の半角英数入力モードで,直接入力ではありません。また,このクラスはflash.systemパッケージに所属するのでFlex固有の機能ではなくFlash標準の機能です*16

 「誕生年月日」入力用としてDateFieldコンポーネント*17を使用しています。ここではユーザーに直接入力をさせないために「editable」属性をfalseにしています。また,年月日を指定するUIとして表示されるDateChooserコンポーネント*18の初期状態は「今日」が表示されるますが,顧客情報で誕生日が今日というのは無いと思うので「1970年1月1日」を指定しています。いろんな言語でもそうですがプログラム上で月を扱う場合は「0~11」です。「focusIn」に関数を指定していますが,「focusIn」は属性ではなくイベントです*19。したがって,focusIn = フォーカスを取得したときに指定したコードを実行するということを意味しています。

 このサンプルでは「birthdayInput.open()」を実行するように指定しています。つまり,自分自身の「open」メソッドを実行するわけです。DateFieldのopenメソッドはDateChooserを表示するメソッドで,サンプルではタブ移動で誕生年月日にフォーカスが移動すると同時にDateChooserを表示するような動作になります(もちろん,クリックでもDateChooserが表示されます)。試しに,「氏名(漢字)」用入力エリアをクリックしてフォーカスを当て,タブキーでフォーカスを移動してみてください。Flashにおいてタブ移動は自動的に制御されますが,カスタマイズすることも可能です*20

 「性別」選択ではRadioButtonコンポーネント*21を使用しています。「女性」と「男性」の二つのRadioButtonをグループ化しているのがRadioButtonGroupクラス*22で,そのグループに所属させるにはRadioButtonの「groupName」属性にRadioButtonGroupオブジェクトのid名を指定します。RadioButtonの初期選択状態を指定するのが「selected」属性にtrueを指定します。サンプルでは「女性」のRadioButtonに設定しています。

 「郵便番号」用入力にもTextInputを使用していますが,ここでは「restrict」属性に「0-9」と指定することで0から9の半角数値しか入力できないようになっています。さらに,「maxChars」属性に値を設定して入力可能文字数を制限しています。

ステップ3

 「OfficeInfo.mxml」はステップ3の画面コンポーネントで,勤務先情報を入力する画面です。使用しているコンポーネントでは前項の「BasicInfo.mxml」とほとんど変わらないので違う部分だけ説明します。

 まずはNumberFormatterタグ*23。これはUIコンポーネントではなく,指定されたフォーマットで文字列を返す関数系のクラスです。「mx.formatters」パッケージに所属し,Formatterクラスを拡張しています。サンプルでは「useThousandsSeparator」属性にtrueをセットして3桁ごとにカンマを表示するように指定しています。

 ここでは「年収」用入力エリアと連動していますので試しに「1000」と入力後,タブキーでフォーカスを移動してみてください。フォーカス移動後に「1,000」と変化するはずです。連動と言っても厳密に繋がっているわけではなく,「フォーカスが外れた」という「focusOut」イベントで「incomeChanged」関数をコールしています。この関数はソースの上の辺りの「mx:Script」タグ内にPrivate関数として定義しており,関数内でNumberFormatterクラスの「format」関数を実行し,NumberFormatterタグで指定したフォーマットの文字列を入力エリアにセットし直しています。また,ここで入力するのは数値なので「textAlign」スタイルにrightをセットして右揃えにしています。

 「勤続年数」入力にはNumericStepperコンポーネント*24を使用しています。「stepSize」属性に0.5をセットしているので0.5単位で値が加算・減算されます。「value」属性で初期表示値として3をセットし,「minimum」属性で最小値を「maximum」属性で最大値を指定しています。ここでふと「NumericStepperでカンマ付き表記はできないか?」と考えました。結論から言ってしまうと標準コンポーネントではできません(※NumericStepperでカンマ付きの数値を入力することは可能ですが,フォーカスが移動したとたんにカンマ無し表記になります)。

ステップ4

 「FamilyInfo.mxml」はステップ4の画面コンポーネントで,家族情報を入力する画面です。使用しているコンポーネントは既出のコンポーネントばかりなのですが,さりげなくActionScriptを使用して画面内のコンポーネントの有効・無効状態を制御しています。

 まずは「配偶者」の有り・無しに応じて配偶者情報入力エリアを有効にしたり,無効にしたりしています。試しに配偶者の「有り・無し」をクリックしてみてください。これはRadioButtonの「click」イベントで「spouseInfo」オブジェクトの「enabled」属性をtrueにしたり,falseにしたりすることで実装しています。「spouseInfo」オブジェクトというのは配偶者情報入力エリアの専用入れ物=VBoxです。

 このように配偶者情報入力項目は一つ上の階層,つまりそれらを格納している「コンテナ」オブジェクトが無効になると連動してUIからの操作ができなくなります。「UIから」と述べたのは,ユーザーは操作できないけれども,ActionScriptでは操作が可能だからです。実際に「子供」情報の入力エリアの操作では,子供「無し」を選択すると「子供の人数」用入力項目を抱える「childrenInfo」オブジェクト(コンテナ)を無効にすると同時に「子供の人数」用NumericStepperの値をゼロに変更しています。

ステップ5

 「OtherInfo.mxml」はステップ5の画面コンポーネントで,その他の情報を入力する画面です。ここではCheckBoxコンポーネント*25を使用しています。CheckBoxはButtonやRadioButtonとクラス的にほとんど違いがありません。「label」属性で表示文字列を指定し,「selected」属性で初期選択状態を指定します。

 UIと微妙に関係があるSpacerコンポーネント*26を使用しています。これは読んで字の如く,余白を制御するためのコンポーネントです。HTMLページでも「null.gif」などの何も表示しないイメージタグを使用してレイアウトを調整したりしますが,まさにこのSpacerは同じような用途で使用します。VBoxは「verticalGap」スタイル,HBoxは「horizontalGap」スタイルで子オブジェクトの配置間隔を制御するのですが,"部分的に"というのはできません。そこでSpacerというダミーコンポーネントで余白を取っています。

ステップ6

 「NoteInfo.mxml」はステップ6の画面コンポーネントで,備考欄用画面です。ここではTexAreaコンポーネント*27を使用しています。特に際立った設定は無いありません。強いて言えば,「width」や「height」に指定しているパーセント指定です。これはHTMLでもありましたように,親オブジェクトの幅・高さに対するパーセントです。ちなみにActionScriptでは「width」属性に"100%"という文字列を指定することはできません。その代わり,ActionScriptでは「percentWidth」「percentHeight」にパーセンテージの数値をセットする必要があります*28

 と,ここまでの説明で,かなりの分量になってしまいました。残りの「main.mxml」やmx:Modelタグ等については後編で解説したいと思います。

Flexの新バージョン2.0.1がリリース

 執筆時点では英語版だけではありますが,Flex 2.0.1 がリリースされました。主な特徴は以下の通りです。

○たくさんのバグがFIXされました。
○FlexBuilder2のサポート環境が増えました。Mac OS 10.4.7(PowerPC/IntelMac)および,Eclipse 3.2で動作するようになりました。
○JavaDocならぬASDocが製品にバンドルされました。ソースに決められた規約に従ってコメントを記述することで,Flex2 オンライン・リファレンスのようなドキュメントがソースから作成できるようになりました。
○mxmlcコンパイラがFlashTypeをサポートできるようになりました。
○「mx.modules」パッケージが新規に追加されました。Remote Shared Library(RSL)ととって代わる仕組みで,今後の設計にも大きく影響すると思われます。
○ランタイムCSSを備えるようになりました。前項の仕組みを利用して実現され,非常に簡単にランタイムでスキンやテーマを変えることができます。
○Flex Automation Packageがリリースされました。これはMercury QuickTest Professional 9を利用して,Flexアプリケーションのテストを自動化できるようです。但し,FDS2の有償ライセンス版用です。
○Flex Data Service も2.0.1になりました。

 「mx.modules」と「ランタイムCSS」については,別の形で詳細レポートをしようと思っています。