2010年7月30日金曜日

カナダネタ:ホテル予約編

突然ですが、業務として8月から半年ほどバンクーバー(カナダ)に行くことになりました。

ということで以下、ホテルの予約メモ。
なにげに結構大変でしたw

まず、安い宿がほとんどありません。数年前シリコンバレーにいた時は、ダウンタウンの交通の便がよいところでさえシングルルーム(風呂、トイレ、朝食、電話、高速インターネット回線付き)で$1,050/month、ダブルでも$1,200/month程度で借りられました。飛び込みでも普通のシングルルームで45$あれば借りることができました。月極のフラットを1室借りる場合は、$1,000/month前後でした(電話回線の契約とか自分でする必要がありますが)。しかし、バンクーバーではそうはいかないようです。


ホテルを物色してみた

Shaughnessy Village Vancouver

かなり安い宿です。8月は最高値なのですが、それでも$1045/momth。安いです。よさそうなので、メールでいくつか質問してみました。すると、3ヶ月で$915/month, 6ヶ月で$885/monthとのこと。さらに安い! しかし、途中でのキャンセルについては支払った金額が全く払い戻されないということでした。個人的に、過去にこのような厳しい払い戻しルールの長期滞在用ホテルは経験したことも聞いたこともなく、メールが英文メールとしてもあまりにもぶっきらぼうであり、また、いくつかの質問をさらっと無視されてしまったので、念のため、評判をググッてみました。う~む。賛否両論ですが、事前に長期予約をするにはリスクが大きそうな感じですね。


YWCA of Vancouver

口コミの評価がかなり高いです。Single (1 single bed) with semi- private bath*, TV の weekly rate が $74/night ということで、かなりリーズナブル。semi- private bath* は、2部屋で共有とのこと。"We also offer residence rate if you stay for a minimum of 30 days"とのことで、もっと長く止まるなら、もう少し安くなりそうです。


The Kingston Hotel

シャワールームが共有で、シングルルームが $75 - $125 plus tax とのこと。8月はハイシーズンなので、125$/nightになりそうですね。monthlyのrateも乗っていないので、今回は見送り。


結局・・・

結局、とりあえずYWCAを1ヶ月だけおさえることにして、その間に家具付きのフラットを借りる方向で進めてみることにしました。その際、もし途中キャンセルが可能なら6ヶ月間の予約を入れるという選択肢も残しておきます。

ということで、availability と monthly rate の確認と、6ヶ月の予約を入れるが途中キャンセルする可能性があるという状況でよい案がないかなという質問をメールで確認したところ、非常に丁寧な回答メールを頂きました。以下要約。
  • 30日以上連続して宿泊する場合は、月単位のResidence形式を選択することが可能。その際、ホテルスタッフからの承認が必要になる(Residenceの情報)。しかし、8月はハイシーズンなので daily のレートのみ。
  • 長期滞在で部屋を出る日付が未定の場合は、ひとまず長期の予約をしておいて、部屋を出る1ヶ月前に話せばよい。
  • 全館禁煙。
  • 無線LANはロビーと各部屋で利用可能。価格は $6.00/day, $22.00/week, or $33.00/month。
weekly rate も residence rate も適用できないのは残念ですが、とりあえず8末まではここを押さえようとしたところ、シングルが空いてませんでした(´・ω・`)

となると、ダブルになるので1日 $98.00 です。う~む、高いな。シャワー共有でこの値段は割に合わないなぁ、、、。しかし、今後ここに residence rate で宿泊する可能性も考えると、事前調査という意味ではアリか、、、、。このシーズンはどこも満室だし、中級ホテルでも$200/day弱するし、、、。

ということで、到着日の8日から、某お祭りが終わって落ち着く頃ということで18日まで10夜分だけ予約を取ることにしました。(そして、PDF付きの確認メールがスパムフィルタにかかるのはお約束w)

2010年7月28日水曜日

就業規則の届出をしていない場合の旅費規程について

弊社は現在常時10人以上の労働者を使用していないため、労働基準監督署に就業規則を届けていません。そのため、旅費規程などについても届出をしていません。その場合、旅費規程により経費として扱われることが妥当な場合でも、所得税が課税される可能性がありうるのではという疑問があります。

ということで、労働基準監督署に聞いてみました。

労働基準監督署曰く
  • 旅費規定等を単独で届け出ることはできず、就業規則を含めて提出する必要がある。
  • 税金については関知しない。
  • 今回の件では特に届けでの必要はない。
とのこと。今度は税務署に聞いてみました。

税務署曰く
  • 労働基準監督署に届けるかどうかは関係ない。
  • 調査が必要な場合などに、該当する書類を見せられるようにしておけばよい。
  • 書類の内容の妥当性は、地域性その他を含めた全体的な視点で判断される。
とのことでした。

妥当な規則を事前に用意していれば、特に問題なさそうです。

2010年6月7日月曜日

Utils.as

package {
    import flash.filesystem.File;
    import flash.filesystem.FileMode;
    import flash.filesystem.FileStream;
    
    /**
     * とりあえず、静的な便利メソッドを入れ込んでおくクラス。
     * 
     * TODO: Air 以外の開発をする際に、Air 専用とそれ以外を分離しましょう。
     * 
     * 方針
     *         ・ActionScriptはオーバーロードができないので、メソッド名に引数情報もいれる。
     *         ・見かけの簡潔さを求めず、分かりやすさを求める。初めて見る人でもシグニチャだけで機能を確実に理解できることを目指す。
     *         ・管理しきれなくなって『具体的に困る』ことになったら別ライブラリへの分割を考える。
     */
    public class Utils {
        
        /**
         * 指定された XML ファイルを読み込み XML オブジェクトを返します。
         */
        public static function readXmlFromFile(xmlFile:File):XML {
            return new XML(readUTFBytesFromFile(xmlFile));
        }
        
        /**
         * 指定されたファイルを読み込み UTFBytes を返します。
         */
        public static function readUTFBytesFromFile(utfFile:File):String {
            var fileStream:FileStream = new FileStream();
            fileStream.open(utfFile, FileMode.READ);
            var utfBytes:String = fileStream.readUTFBytes(utfFile.size);
            fileStream.close();
            return utfBytes;
        }
        
        /**
         * 指定されたファイルに対して指定された XML を書き込みます。
         */
        public static function writeXmlToFile(xml:XML, file:File):void {
            writeUTFBytesToFile(xml.toXMLString(), file);
        }
        
        /**
         * 指定されたファイルに対して UTFBytes を書き込みます。
         */
        public static function writeUTFBytesToFile(utfBytes:String, file:File):void {
            var fileStream:FileStream = new FileStream();
            fileStream.open(file, FileMode.WRITE);
            fileStream.writeUTFBytes(utfBytes);
            fileStream.close();
        }
        
        /**
         * 指定されたファイルをファイルシステム中に作成します。既に指定されたファイルが存在する場合には何もしません。
         */
        public static function createFile(file:File):void {
            if (!file.exists) {
                var fileStream:FileStream = new FileStream();
                fileStream.open(file, FileMode.WRITE);
                fileStream.close();
            }
        }
    }
}

2010年6月2日水曜日

FlashのUI系コンポーネント調査

FlashのUI系のコンポーネントについて全く知識がないので、少し調査してみました。

クラス階層

Object
・言うまでもなく、あらゆるクラスのベースとなるクラス。特にUIであるかどうかとは無関係。
・パッケージはトップレベル。

flash.events.EventDispatcher
flash.events.IEventDispatcher の実装クラス。
・イベントを扱うための汎用的な機能を持つクラス。リスナーの追加削除とかイベントの送信とか。
・特にUIであるかどうかとは無関係。

flash.display.DisplayObject
・display list に配置されるすべてのオブジェクトのベースクラス。
・x,y,zとかalphaとかwidthとかvisibleとかマウス位置とか、表示されるものとしての基本機能を持っている。

flash.display.InteractiveObject
・表示されるオブジェクトでマウスやキーボードやその他の入力デバイスを扱うものすべての抽象クラス。
・このクラスはnewできないし、上記までのクラスもUIを作成するうえでプログラマが明示的に new することはなさそうです。

flash.display.DisplayObjectContainer
・display object の入れ物クラス。
・z 軸上に複数の display object を child として配置できる。
・このサブクラスには Loader, Sprite, Stage, TextLine があります。

flash.display.Loader
・java の ClassLoader のようなものを想像していると DisplayObjectContainer のサブクラスということに違和感を感じるが、実際は swf ファイルおよび画像ファイルをロードして表示するものなので、表示オブジェクトのローダーと言える。
・flex 用のサブクラスとして mx.core.FlexLoader があり、toString() メソッドが DisplayObjects の階層を表すようになっている。

flash.text.engine.TextLine
・display text 上に文字列を表示するためのオブジェクト。
・final クラスなので継承できないし、ユーザが直接 new することもできない。
・flash.text.engine 系のパッケージと関わらない限りは必要なさそう。

flash.display.Stage
・ブラウザ内なら flash の表示領域が Stage で、Airなら各 NativeWindow が Stage を持つ。

flash.display.Sprite
・UI 系の一般的なベースクラスで、MovieClip からtimelineを抜いたようなもの。

2010年5月23日日曜日

開発環境メモ

WindowsXP環境開発環境メモ

GAE, git, svn, maven を前提とした環境。
今のところ、GAE系やGITの環境の試行錯誤中。

TODO: とりあえずメモなので、あとでちゃんと書きましょう。
  • 7zip
    • http://www.7-zip.org/ からダウンロードしてすべてデフォルトでインストール。
    • 以降、アーカイブの展開は7zipを使います。(Windows付属のはどうもバギーなので)
  • ブラウザのインストール
    各種ブラウザの動作確認を行うため、複数のブラウザをインストールする。
    • Firefoxのインストール
      • http://mozilla.jp/firefox/ から最新版をダウンロードしてすべてデフォルト設定でインストールする。
    • Google Chrome のインストール
  • Java
    • http://java.sun.com/ から Java SE の最新版をダウンロードして、すべてデフォルト設定でインストールする。
    • 環境変数 JAVA_HOME を適切に設定する。(C:\Program Files\Java\jdk1.6.0_20 等)
    • 環境変数 PATH に %JAVA_HOME%\bin を設定する。
  • maven
    • http://maven.apache.org/ から安定版の最新のバイナリをダウンロード。(ex. apache-maven-2.2.1-bin.zip)
    • C:\Program Files 直下にコピー。(ex. C:\Program Files\apache-maven-2.2.1)
    • 環境変数 MAVEN_HOME を設定。
    • 環境変数 Path に %MAVEN_HOME%\bin を追加。
  • Eclipse
    • http://www.eclipse.org/downloads/ から Eclipse IDE for Java EE Developers の galileo の最新版をダウンロード。
    • C:\Program Files\eclipse として展開する。
    • 文字コードの設定
      • Window -> Preferences -> General -> Workspace -> Text file encoding を utf-8 に設定。
    • xmlのwidthを999、インデントをスペース2つに変更する。
    • eclipseにjdkのソースをアタッチ
      • Window -> Preferences... -> Java -> Installed JREs に移動。
      • jre を選択して、Edit... ボタンを押下。
      • C:\tmp\devenv\jdk\jre\lib\rt.jar を選択。
      • Source Attachement... ボタンを押下。
      • C:/Program Files/Java/jdk1.6.0_20/src.zip をアタッチ。
    • eclipseにJavaDocをアタッチ
      • Sunのサイトからドキュメントをダウンロードして、src.zipと同じフォルダに置く。
      • Window -> Preferences... -> Java -> Installed JREs に移動。
      • jre を選択して、Edit... ボタンを押
      • C:\tmp\devenv\eclipse\jre\lib\rt.jar を選択。
      • JavaDoc Location... ボタンを押下。
      • Javadoc in archive と Workspace file を選択。
      • Archive path を設定先ほどダウンロードしたドキュメントのzipに設定。
      • Path within archive を設定。(ex. docs/api)
      • ソース上の対象を選択してShift+F2キーを押せば、システム設定のブラウザ経由でJavaDocが起動します。
    • m2eclipseの設定
      • アップデートサイト http://m2eclipse.sonatype.org/sites/m2e からインストールする。
      • [Window] -> [Preferences...] -> [Maven] にて、以下のオプションをチェック。
        • Download Artifact Sources
        • Download Artifact JavaDoc
      • デフォルトのmavenが3.0系のSNAPSHOT版の場合は、[Window] -> [Preferences...] -> [Maven]  -> [Installations] -> [Add] から Program Files 以下にインストールした maven を指定する。
    • Google 関連プラグインの設定
    • subclipse プラグインの設定
      • アップデートサイト http://subclipse.tigris.org/update_1.6.x からインストールする。その際、オプショナルコンポーネントはすべて無視する。
      • SVN インタフェースを SVNKit (Pure Java) に設定する。
        • [Window] -> [Preferences...] -> [Team] -> [SVN] -> [SVNインタフェース] -> [SVNKit (Pure Java)]
    • EGit プラグインの設定。


    2010年5月11日火曜日

    Flex のコンポーネント遅延ロードとデータバインディングとモデリングに関する考察

    Flexではコンポーネントの遅延ローディングがデフォルトで行われるようになっています。そのため、mxml ファイル内で定義されたコンポーネントに対して同一の mxml ファイル内の ActionScript からアクセスしても、null が返る可能性があります。

    そのような場合、内部コンポーネントを定義するXML要素の属性として、ActionScript 内の変数をバインディングするというワークアラウンドで乗り切ることができます。しかし、データバインディングをする場合、モデルが既にあったとしても、バインディング用の変数をわざわざ用意する必要があります。モデルの中で配列で100要素バインディングするとしたら、100種類の変数を用意する必要があります。

    これも、ArrayCollection 型を使用することで解決できますが、既に Vector でデータを持っているモデルがあるとしたら、毎回移し変えなければなりません。

    このように、ワークアラウンドで乗り切ることもできますが、あまり建設的ではないように思えます。まだまだ落とし穴があるように思えますし、、、。

    ということで、今後の作業効率や成果物の品質にも大きく影響すると考えられるので、この機会に確認しておこうと思います。


    例1:ある state で生成された情報を、これから初めて遷移される state に表示する場合。

    ソース
    思惑
    • State 1 が初期状態。
    • State 1 上の入力フォームから結果表示用ラベルに A と B の値を入力し、add ボタンを押下する。
    • State 2 に遷移し、A + B の結果が表示される。
    結果
    • State 2 で表示される結果表示用ラベルの値が null となり、エラーが発生。
    考察
    • creationPolicy を all にすることにより遅延ロードを抑制できないか?
    • ドキュメントによると、単一ビューコンテナでは、auto でも all でも同じ動作となり、『デフォルトでは、アプリケーションが最初に起動されたときに単一ビューコンテナのすべての子が生成されます。』となるらしい。生成されてるのに null なのはなぜ? (´・ω・`)
    • State が絡む場合はダメらしい。結局、State の遷移を先に行うしかないらしい。
    解決法
    • ある State に含まれるコンポーネントへのアクセスは、その State に遷移してから行う。
    解決後のソース

    例2:複雑なモデル内部のデータを参照する場合。

    バインディング版
    • ソース:Ex2.mxml
    • 特に問題なく動作する。


    例3:配列へバインディングしようとして失敗する版
    • ソース:Ex2_1.mxml
    • 最初の1回目はうまく行くが、2回目以降も最初の結果が出続ける。

    例4:ArrayCollection を用いて対応する版
    • ソース:Ex2_2.mxml
    • 問題なく動作するが、バインディングのために設計を崩すことになった。バインディングするよりも、特定のタイミングでデータをリロードしてくれるような設計の方がありがたいのだが。例えば状態遷移のタイミングとか。
    例5:ボタンクリックのタイミングでデータを格納する版
    • ソース:Ex2_3.mxml
    • サブコンポーネントに対する text の指定を、親コンポーネント側で決定することが自然な設計であれば、無理にバインディングする必要はない。そのため、クリックのハンドラでラベルの表示を行っている。
    例6:Stateに入るタイミングでデータを格納する版
    • ソース:Ex2_4.mxml
    • サブコンポーネントに対する text の指定を、親コンポーネント側で決定することが自然な設計であれば、無理にバインディングする必要はない。状態遷移をする箇所が一箇所であればその場所にラベルにデータを書き込む処理を埋め込めば良いのだが、ソースの様々な箇所から状態遷移が発生する場合には同様の処理を複数回記述することになる。その際、状態遷移をトリガーにした方がシンプルになる場合は、State に入るイベントを用いた方がよい。
    付録:ソース


    Ex1.mxml
    <?xml version="1.0" encoding="utf-8"?>
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
          xmlns:s="library://ns.adobe.com/flex/spark" 
          xmlns:mx="library://ns.adobe.com/flex/mx" width="100%" height="100%">
     <s:layout>
      <s:VerticalLayout horizontalAlign="center" verticalAlign="middle"/>
     </s:layout>
    
     <fx:Script>
      <![CDATA[
       import mx.controls.Alert;
       <!--- A + B の計算をして resultLabel に値を設定し、State2 に遷移するメソッド -->
       private function addButton_clickHandler(event:MouseEvent):void {
        var a:String = aNs.value.toString();
        var b:String = bNs.value.toString();
        var result:String = (aNs.value + bNs.value).toString();
        Alert.show("resultLabel = " + resultLabel); // ここで、resultLabel が null になる。
        resultLabel.text = a + " + " + b + " = " + result;
        currentState = "State2";
       }
      ]]>
     </fx:Script>
    
     <!-- state を用いて画面遷移を模倣 -->
     <s:states>
      <!-- A と B の値を入力する画面 -->
      <s:State name="State1"/>
      <!-- A + B の結果を表示する画面 -->
      <s:State name="State2"/>
     </s:states>
     
     <!-- State1用コンポーネント群 -->
     <mx:Form includeIn="State1">
      <mx:FormItem label="A">
       <!--- A の値入力用 NumericStepper -->
       <s:NumericStepper id="aNs"/>
      </mx:FormItem>
      <mx:FormItem label="B">
       <!--- B の値入力用 NumericStepper -->
       <s:NumericStepper id="bNs"/>
      </mx:FormItem>
     </mx:Form>
     <s:Button includeIn="State1" label="add" id="addButton" click="addButton_clickHandler(event)"/>
     
     <!-- State2用コンポーネント群 -->
     <!--- A + B = (A+Bの結果) という文字列を表示するためのラベル -->
     <s:Label id="resultLabel" includeIn="State2"/>
     
    </s:Application>
    


    Ex1_1.mxml
    <?xml version="1.0" encoding="utf-8"?>
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
          xmlns:s="library://ns.adobe.com/flex/spark" 
          xmlns:mx="library://ns.adobe.com/flex/mx" width="100%" height="100%">
     <s:layout>
      <s:VerticalLayout horizontalAlign="center" verticalAlign="middle"/>
     </s:layout>
    
     <fx:Script>
      <![CDATA[
       import mx.controls.Alert;
       <!--- A + B の計算をして resultLabel に値を設定し、State2 に遷移するメソッド -->
       private function addButton_clickHandler(event:MouseEvent):void {
        var a:String = aNs.value.toString();
        var b:String = bNs.value.toString();
        var result:String = (aNs.value + bNs.value).toString();
        currentState = "State2";
        Alert.show("resultLabel = " + resultLabel); // ここで、resultLabel が null ではなく、きちんと表示される。
        resultLabel.text = a + " + " + b + " = " + result;
       }
      ]]>
     </fx:Script>
    
     <!-- state を用いて画面遷移を模倣 -->
     <s:states>
      <!-- A と B の値を入力する画面 -->
      <s:State name="State1"/>
      <!-- A + B の結果を表示する画面 -->
      <s:State name="State2"/>
     </s:states>
     
     <!-- State1用コンポーネント群 -->
     <mx:Form includeIn="State1">
      <mx:FormItem label="A">
       <!--- A の値入力用 NumericStepper -->
       <s:NumericStepper id="aNs"/>
      </mx:FormItem>
      <mx:FormItem label="B">
       <!--- B の値入力用 NumericStepper -->
       <s:NumericStepper id="bNs"/>
      </mx:FormItem>
     </mx:Form>
     <s:Button includeIn="State1" label="add" id="addButton" click="addButton_clickHandler(event)"/>
     
     <!-- State2用コンポーネント群 -->
     <!--- A + B = (A+Bの結果) という文字列を表示するためのラベル -->
     <s:Label id="resultLabel" includeIn="State2"/>
     
    </s:Application>
    


    Ex2.mxml
    <?xml version="1.0" encoding="utf-8"?>
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
          xmlns:s="library://ns.adobe.com/flex/spark" 
          xmlns:mx="library://ns.adobe.com/flex/mx" width="100%" height="100%">
     <s:layout>
      <s:VerticalLayout horizontalAlign="center" verticalAlign="middle"/>
     </s:layout>
    
     <fx:Script>
      <![CDATA[
       import mx.controls.Alert;
       <!--- A + B の計算をして resultLabel に値を設定し、State2 に遷移するメソッド -->
       private function addButton_clickHandler(event:MouseEvent):void {
        currentState = "State2";
       }
    
       <!--- State2 から State1 に戻るボタン -->
       private function backButton_clickHandler(event:MouseEvent):void {
        currentState = "State1";
       }
    
      ]]>
     </fx:Script>
    
     <!-- state を用いて画面遷移を模倣 -->
     <s:states>
      <!-- A と B の値を入力する画面 -->
      <s:State name="State1"/>
      <!-- A + B の結果を表示する画面 -->
      <s:State name="State2"/>
     </s:states>
     
     <!-- State1用コンポーネント群 -->
     <mx:Form includeIn="State1">
      <mx:FormItem label="Value 1">
       <!--- 値1 の値入力用 NumericStepper -->
       <s:NumericStepper id="v1Ns"/>
      </mx:FormItem>
      <mx:FormItem label="Value 2">
       <!--- 値2 の値入力用 NumericStepper -->
       <s:NumericStepper id="v2Ns"/>
      </mx:FormItem>
      <mx:FormItem label="Value 3">
       <!--- 値3 の値入力用 NumericStepper -->
       <s:NumericStepper id="v3Ns"/>
      </mx:FormItem>
     </mx:Form>
     <s:Button includeIn="State1" label="add" id="addButton" click="addButton_clickHandler(event)"/>
     
     <!-- State2用コンポーネント群 -->
     <!--- v1 + v2 + v3 = (v1+v2+v3の結果) という文字列を表示するためのラベル -->
     <s:Label id="resultLabel" includeIn="State2" text="{v1Ns.value} + {v2Ns.value} + {v3Ns.value} = {v1Ns.value + v2Ns.value + v3Ns.value}"/>
     <s:Button includeIn="State2" label="back" id="backButton" click="backButton_clickHandler(event)"/>
     
    </s:Application>
    


    Ex2_1.mxml
    <?xml version="1.0" encoding="utf-8"?>
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
          xmlns:s="library://ns.adobe.com/flex/spark" 
          xmlns:mx="library://ns.adobe.com/flex/mx" width="100%" height="100%">
     <s:layout>
      <s:VerticalLayout horizontalAlign="center" verticalAlign="middle"/>
     </s:layout>
    
     <fx:Script>
      <![CDATA[
       import mx.controls.Alert;
       
       <!--- 値を保持する Vector -->
       private var values:Vector.<Number> = new Vector.<Number>();
       
       <!--- A + B の計算をして resultLabel に値を設定し、State2 に遷移するメソッド -->
       private function addButton_clickHandler(event:MouseEvent):void {
        // コンポーネントの値を values に格納。
        values.push(v1Ns.value);
        values.push(v2Ns.value);
        values.push(v3Ns.value);
        
        currentState = "State2";
       }
    
       <!--- State2 から State1 に戻るボタン -->
       private function backButton_clickHandler(event:MouseEvent):void {
        currentState = "State1";
       }
    
      ]]>
     </fx:Script>
    
     <!-- state を用いて画面遷移を模倣 -->
     <s:states>
      <!-- A と B の値を入力する画面 -->
      <s:State name="State1"/>
      <!-- A + B の結果を表示する画面 -->
      <s:State name="State2"/>
     </s:states>
     
     <!-- State1用コンポーネント群 -->
     <mx:Form includeIn="State1">
      <mx:FormItem label="Value 1">
       <!--- 値1 の値入力用 NumericStepper -->
       <s:NumericStepper id="v1Ns"/>
      </mx:FormItem>
      <mx:FormItem label="Value 2">
       <!--- 値2 の値入力用 NumericStepper -->
       <s:NumericStepper id="v2Ns"/>
      </mx:FormItem>
      <mx:FormItem label="Value 3">
       <!--- 値3 の値入力用 NumericStepper -->
       <s:NumericStepper id="v3Ns"/>
      </mx:FormItem>
     </mx:Form>
     <s:Button includeIn="State1" label="add" id="addButton" click="addButton_clickHandler(event)"/>
     
     <!-- State2用コンポーネント群 -->
     <!--- v1 + v2 + v3 = (v1+v2+v3の結果) という文字列を表示するためのラベル -->
     <s:Label id="resultLabel" includeIn="State2" text="{values[0]} + {values[1]} + {values[2]} = {values[0] + values[1] + values[2]}"/>
     <s:Button includeIn="State2" label="back" id="backButton" click="backButton_clickHandler(event)"/>
     
    </s:Application>
    


    Ex2_2.mxml
    <?xml version="1.0" encoding="utf-8"?>
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
          xmlns:s="library://ns.adobe.com/flex/spark" 
          xmlns:mx="library://ns.adobe.com/flex/mx" width="100%" height="100%">
     <s:layout>
      <s:VerticalLayout horizontalAlign="center" verticalAlign="middle"/>
     </s:layout>
    
     <fx:Script>
      <![CDATA[
       import mx.collections.ArrayCollection;
       import mx.controls.Alert;
       
       [Bindable]
       /**
        * 値を保持する ArrayCollection
        */
       private var values:ArrayCollection = new ArrayCollection(new Array(3));
       
       /**
        * A + B の計算をして resultLabel に値を設定し、State2 に遷移するメソッド
        */
       private function addButton_clickHandler(event:MouseEvent):void {
        // コンポーネントの値を values に格納。
        values.setItemAt(v1Ns.value, 0);
        values.setItemAt(v2Ns.value, 1);
        values.setItemAt(v3Ns.value, 2);
        
        currentState = "State2";
       }
    
       <!--- State2 から State1 に戻るボタン -->
       private function backButton_clickHandler(event:MouseEvent):void {
        currentState = "State1";
       }
    
      ]]>
     </fx:Script>
    
     <!-- state を用いて画面遷移を模倣 -->
     <s:states>
      <!-- A と B の値を入力する画面 -->
      <s:State name="State1"/>
      <!-- A + B の結果を表示する画面 -->
      <s:State name="State2"/>
     </s:states>
     
     <!-- State1用コンポーネント群 -->
     <mx:Form includeIn="State1">
      <mx:FormItem label="Value 1">
       <!--- 値1 の値入力用 NumericStepper -->
       <s:NumericStepper id="v1Ns"/>
      </mx:FormItem>
      <mx:FormItem label="Value 2">
       <!--- 値2 の値入力用 NumericStepper -->
       <s:NumericStepper id="v2Ns"/>
      </mx:FormItem>
      <mx:FormItem label="Value 3">
       <!--- 値3 の値入力用 NumericStepper -->
       <s:NumericStepper id="v3Ns"/>
      </mx:FormItem>
     </mx:Form>
     <s:Button includeIn="State1" label="add" id="addButton" click="addButton_clickHandler(event)"/>
     
     <!-- State2用コンポーネント群 -->
     <!--- v1 + v2 + v3 = (v1+v2+v3の結果) という文字列を表示するためのラベル -->
     <s:Label id="resultLabel" includeIn="State2" text="{values.getItemAt(0)} + {values.getItemAt(1)} + {values.getItemAt(2)} = {values.getItemAt(0) + values.getItemAt(1) + values.getItemAt(2)}"/>
     <s:Button includeIn="State2" label="back" id="backButton" click="backButton_clickHandler(event)"/>
     
    </s:Application>
    


    Ex2_3.mxml
    <?xml version="1.0" encoding="utf-8"?>
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
          xmlns:s="library://ns.adobe.com/flex/spark" 
          xmlns:mx="library://ns.adobe.com/flex/mx" width="100%" height="100%">
     <s:layout>
      <s:VerticalLayout horizontalAlign="center" verticalAlign="middle"/>
     </s:layout>
    
     <fx:Script>
      <![CDATA[
       import mx.controls.Alert;
       
       <!--- 値を保持する Vector -->
       private var values:Vector.<Number> = new Vector.<Number>();
       
       <!--- A + B の計算をして resultLabel に値を設定し、State2 に遷移するメソッド -->
       private function addButton_clickHandler(event:MouseEvent):void {
        // コンポーネントの値を values に格納。
        if (values.length == 0) {
         values.push(v1Ns.value);
         values.push(v2Ns.value);
         values.push(v3Ns.value);
        } else {
         values[0] = v1Ns.value;
         values[1] = v2Ns.value;
         values[2] = v3Ns.value;
        }
            
        currentState = "State2";
        
        // ラベルの値を直接指定する。
        resultLabel.text = values[0].toString() + ' + ' + values[1].toString() + ' + ' + values[2].toString() + ' = ' + (values[0] + values[1] + values[2]);
    
       }
    
       <!--- State2 から State1 に戻るボタン -->
       private function backButton_clickHandler(event:MouseEvent):void {
        currentState = "State1";
       }
      ]]>
     </fx:Script>
    
     <!-- state を用いて画面遷移を模倣 -->
     <s:states>
      <!-- A と B の値を入力する画面 -->
      <s:State name="State1"/>
      <!-- A + B の結果を表示する画面 -->
      <s:State name="State2"/>
     </s:states>
     
     <!-- State1用コンポーネント群 -->
     <mx:Form includeIn="State1">
      <mx:FormItem label="Value 1">
       <!--- 値1 の値入力用 NumericStepper -->
       <s:NumericStepper id="v1Ns"/>
      </mx:FormItem>
      <mx:FormItem label="Value 2">
       <!--- 値2 の値入力用 NumericStepper -->
       <s:NumericStepper id="v2Ns"/>
      </mx:FormItem>
      <mx:FormItem label="Value 3">
       <!--- 値3 の値入力用 NumericStepper -->
       <s:NumericStepper id="v3Ns"/>
      </mx:FormItem>
     </mx:Form>
     <s:Button includeIn="State1" label="add" id="addButton" click="addButton_clickHandler(event)"/>
     
     <!-- State2用コンポーネント群 -->
     <!--- v1 + v2 + v3 = (v1+v2+v3の結果) という文字列を表示するためのラベル -->
     <s:Label id="resultLabel" includeIn="State2"/>
     <s:Button includeIn="State2" label="back" id="backButton" click="backButton_clickHandler(event)"/>
     
    </s:Application>
    


    Ex2_4.mxml
    <?xml version="1.0" encoding="utf-8"?>
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
          xmlns:s="library://ns.adobe.com/flex/spark" 
          xmlns:mx="library://ns.adobe.com/flex/mx" width="100%" height="100%">
     <s:layout>
      <s:VerticalLayout horizontalAlign="center" verticalAlign="middle"/>
     </s:layout>
    
     <fx:Script>
      <![CDATA[
       import mx.controls.Alert;
       
       <!--- 値を保持する Vector -->
       private var values:Vector.<Number> = new Vector.<Number>();
       
       <!--- A + B の計算をして resultLabel に値を設定し、State2 に遷移するメソッド -->
       private function addButton_clickHandler(event:MouseEvent):void {
        // コンポーネントの値を values に格納。
        if (values.length == 0) {
         values.push(v1Ns.value);
         values.push(v2Ns.value);
         values.push(v3Ns.value);
        } else {
         values[0] = v1Ns.value;
         values[1] = v2Ns.value;
         values[2] = v3Ns.value;
        }
            
        currentState = "State2";
       }
    
       <!--- State2 から State1 に戻るボタン -->
       private function backButton_clickHandler(event:MouseEvent):void {
        currentState = "State1";
       }
      ]]>
     </fx:Script>
    
     <!-- state を用いて画面遷移を模倣 -->
     <s:states>
      <!-- A と B の値を入力する画面 -->
      <s:State name="State1"/>
      <!-- A + B の結果を表示する画面 -->
      <s:State name="State2" enterState="resultLabel.text = values[0].toString() + ' + ' + values[1].toString() + ' + ' + values[2].toString() + ' = ' + (values[0] + values[1] + values[2])"/>
     </s:states>
     
     <!-- State1用コンポーネント群 -->
     <mx:Form includeIn="State1">
      <mx:FormItem label="Value 1">
       <!--- 値1 の値入力用 NumericStepper -->
       <s:NumericStepper id="v1Ns"/>
      </mx:FormItem>
      <mx:FormItem label="Value 2">
       <!--- 値2 の値入力用 NumericStepper -->
       <s:NumericStepper id="v2Ns"/>
      </mx:FormItem>
      <mx:FormItem label="Value 3">
       <!--- 値3 の値入力用 NumericStepper -->
       <s:NumericStepper id="v3Ns"/>
      </mx:FormItem>
     </mx:Form>
     <s:Button includeIn="State1" label="add" id="addButton" click="addButton_clickHandler(event)"/>
     
     <!-- State2用コンポーネント群 -->
     <!--- v1 + v2 + v3 = (v1+v2+v3の結果) という文字列を表示するためのラベル -->
     <s:Label id="resultLabel" includeIn="State2"/>
     <s:Button includeIn="State2" label="back" id="backButton" click="backButton_clickHandler(event)"/>
     
    </s:Application>
    

    2010年5月6日木曜日

    flex で creationComplete 時に stage == null になる問題。

    ドキュメントによると、少なくとも activate されている間は stage が生きているらしいです。

    そのため、Event.ACTIVATE と Event.RESIZE イベント内なら確実に stage を扱えそうです。