2010年9月アーカイブ

イベントフェーズについて その1では、3段階あるイベントフェーズの中で 「ターゲット段階」・「バブリング段階」 に着目し、その仕組みをサンプルアプリの結果を見ながら確認しました。

今回は、残りのイベントフェーズ 「キャプチャ段階」について、私が勘違いしてしまったポイントも交えながら確認していきたいと思います。

まずは、キャプチャ段階のイベントをリスナーでキャッチさせる為に addEventListener メソッドの3番目の引数である useCapture を true に設定します。
(useCapture はデフォルトでは false に設定されています。つまり、ここのスイッチを変えない限り通常のイベントリスナーではキャプチャ段階は無視されています)

Flex3 API はこんな感じに書かれています。

addEventListener.PNG

 

今回のサンプルアプリではキャプチャ段階もリスナー対象としたいので、前回サンプルコードのinnerBox・middleBox・outerBox に登録したイベントリスナーの useCapture を true にします。

            private function onCreationComplete():void{   
                innerBox.addEventListener(MouseEvent.CLICK, onCatchDispatcher, true);
                middleBox.addEventListener(MouseEvent.CLICK, onCatchDispatcher, true);
                outerBox.addEventListener(MouseEvent.CLICK, onCatchDispatcher, true);
            }

これでキャプチャ段階の設定がわかったので、前回サンプリコードの上記部分だけを変更して 実行すると 「キャプチャ段階」・「ターゲット段階」・「バブリング段階」 のすべてでイベントをキャッチできる!  ・・・・・と思っていましたが、そうはいきませんでした。

実際の実行結果はこれです。

capturePhase_only.PNG

・・・いくらクリックしてもキャプチャ段階のイベントしかキャッチできていません。

 

Flex3 API の続きを読んでみるとちゃんと書いてありました。以下はAPI 説明からの引用です。

「useCapturetrue に設定すると、リスナーはキャプチャ段階のみでイベントを処理し、ターゲット段階またはバブリング段階では処理しません。 useCapturefalse に設定すると、リスナーはターゲット段階またはバブリング段階のみでイベントを処理します。 3 つの段階すべてでイベントを受け取るには、addEventListener() を 2 回呼び出します。useCapturetrue に設定して 1 回呼び出し、useCapturefalse に設定してもう 1 回呼び出します。」

ポイントとしては、イベントフェーズは3段階存在しているけれども、実際にはキャプチャー段階 と ターゲット段階+バブリング段階 の2種類でリスナー処理を登録してやらないといけないこと。 つまり3段階すべてでリスナー処理をさせるには、useCapture スイッチを切り替えた2つの addEventListener を発行してやらなければいけないみたいです。 なるほど。

 

以下が、私の勘違いを正した今回のサンプルアプリ用のコードです。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal" horizontalAlign="center" backgroundColor="#FFFFFF"
     creationComplete="onCreationComplete()" >
     
    <mx:Script>
        <![CDATA[
            import mx.controls.Label;
       
            private var counter:int = 1;
           
            private function onCreationComplete():void{   
                innerBox.addEventListener(MouseEvent.CLICK, onCatchDispatcher);
                innerBox.addEventListener(MouseEvent.CLICK, onCatchDispatcher,true);
                middleBox.addEventListener(MouseEvent.CLICK, onCatchDispatcher);
                middleBox.addEventListener(MouseEvent.CLICK, onCatchDispatcher, true);
                outerBox.addEventListener(MouseEvent.CLICK, onCatchDispatcher);
                outerBox.addEventListener(MouseEvent.CLICK, onCatchDispatcher, true);
            }
           
            private function onCatchDispatcher(e:MouseEvent):void{
                var lbl:Label = new Label();
                var phase:String = getPhase(e.eventPhase);
                lbl.text = counter + " : " + e.currentTarget.id + " [" + phase + "]";
                setLabelColor(lbl, e.currentTarget.id);
                eventList.addChild(lbl);
                counter++;
            }
           
            private function getPhase(eventPhase:int):String{   
                var phase:String;
                //EventPhase 1=キャプチャ段階, 2=ターゲット段階, 3=バブリング段階
                switch(eventPhase){
                    case 1:
                        phase = "キャプチャ段階";
                        break;
                    case 2:
                        phase = "ターゲット段階";
                        break;
                    case 3:
                        phase = "バブリング段階";
                        break;
                }
               
                return phase;
            }
           
            private function setLabelColor(lbl:Label, targetBox:String):void{       
                if(targetBox == "innerBox"){
                    lbl.setStyle("color", "#CC0000");
                }else if(targetBox == "middleBox"){
                    lbl.setStyle("color", "#00cc00");
                }else if(targetBox == "outerBox"){
                    lbl.setStyle("color", "#0000CC");
                }
            }

        ]]>
    </mx:Script>
    <mx:HBox>
        <mx:VBox id="outerBox" minHeight="150" minWidth="150" horizontalAlign="center" verticalAlign="middle" backgroundColor="#0000CC">
            <mx:VBox id="middleBox" minHeight="100" minWidth="100" horizontalAlign="center" verticalAlign="middle" backgroundColor="#00CC00">
                <mx:VBox id="innerBox" minHeight="50" minWidth="50" horizontalAlign="center" verticalAlign="middle" backgroundColor="#CC0000" />
            </mx:VBox>
        </mx:VBox>
        <mx:VBox id="eventList" fontWeight="bold" />
    </mx:HBox>

</mx:Application>

 

実際にサンプルアプリを動かしてみるとちゃんと3段階のイベントフェーズを確認することができました。

① 一番内側の innerBox をクリックした場合

innerBox.PNG

② 次に内側の middleBox をクリックした場合

middleBox.PNG

③ 一番外側の outerBox をクリックした場合

outerBox.PNG

 

イベント伝播の機能はとても便利ですが、ここには伝播して欲しくないないんだよなーという場合もあると思います。

次回は伝播の止め方について確認していきたいと思います。

イベントフェーズとは、イベントがトリガされた時にイベントリスナーが存在するかを確認する順番(段階)のことで、次の3段階構成になっています。

[ キャプチャ段階 ] → [ ターゲット段階 ] → [ バブリング段階 ]

 ●キャプチャ段階
  イベントが発行されたターゲットの祖先の表示リストを親側から順に検査し、リスナーが登録されているかを確認します。

 ●ターゲット段階
  イベントが発行されたターゲットのリスナーが呼び出されます。

 ●バブリング段階
  イベントが発行されたターゲットの祖先の表示リストをターゲット側から順に検査し、リスナーが登録されているかを確認します。

今回の その1 ではターゲット段階とバブリング段階に着目し、サンプルソースを通してイベントフェーズを確認していきます。

以下のサンプルソースは、入れ子構造の3つのVBox (外側から outerBox - middleBox - innerBox という id を付加) を用意し、ApplicationのcreationCompleteイベント処理で各々のVBoxにクリックイベントのリスナーを発行します。
サンプルソースを実行し何れかのVBoxをクリックすると、クリックイベントの処理として
 「 "リスナー処理対象VBoxのid":"処理連番"["イベントフェーズ段階"] 」
が右側にリスト表示されます。 わかりやすい様に文字色はVBoxの背景色と同色にセットしています。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal" horizontalAlign="center" backgroundColor="#FFFFFF"
     creationComplete="onCreationComplete()" >
     
    <mx:Script>
        <![CDATA[
            import mx.controls.Label;
       
            private var counter:int = 1;
           
            private function onCreationComplete():void{   
                innerBox.addEventListener(MouseEvent.CLICK, onCatchDispatcher);
                middleBox.addEventListener(MouseEvent.CLICK, onCatchDispatcher);
                outerBox.addEventListener(MouseEvent.CLICK, onCatchDispatcher);
            }
           
            private function onCatchDispatcher(e:MouseEvent):void{
                var lbl:Label = new Label();
                var phase:String = getPhase(e.eventPhase);
                lbl.text = counter + " : " + e.currentTarget.id + " [" + phase + "]";
                setLabelColor(lbl, e.currentTarget.id);
                eventList.addChild(lbl);
                counter++;
            }
           
            private function getPhase(eventPhase:int):String{   
                var phase:String;
                //EventPhase 1=キャプチャ段階, 2=ターゲット段階, 3=バブリング段階
                switch(eventPhase){
                    case 1:
                        phase = "キャプチャ段階";
                        break;
                    case 2:
                        phase = "ターゲット段階";
                        break;
                    case 3:
                        phase = "バブリング段階";
                        break;
                }
               
                return phase;
            }
           
            private function setLabelColor(lbl:Label, targetBox:String):void{       
                if(targetBox == "innerBox"){
                    lbl.setStyle("color", "#CC0000");
                }else if(targetBox == "middleBox"){
                    lbl.setStyle("color", "#00CC00");
                }else if(targetBox == "outerBox"){
                    lbl.setStyle("color", "#0000CC");
                }
            }

        ]]>
    </mx:Script>
    <mx:HBox>
        <mx:VBox id="outerBox" minHeight="150" minWidth="150" horizontalAlign="center" verticalAlign="middle" backgroundColor="#0000CC">
            <mx:VBox id="middleBox" minHeight="100" minWidth="100" horizontalAlign="center" verticalAlign="middle" backgroundColor="#00CC00">
                <mx:VBox id="innerBox" minHeight="50" minWidth="50" horizontalAlign="center" verticalAlign="middle" backgroundColor="#CC0000" />
            </mx:VBox>
        </mx:VBox>
        <mx:VBox id="eventList" fontWeight="bold" />
    </mx:HBox>

</mx:Application>

 

【サンプルソースの実行】

① 一番内側の innerBox (赤色) を1回クリック
② 次に内側の middleBox (緑色) を1回クリック
③ 一番外側の outerBox (青色) を1回クリック

上記①~③の手順で実行した際の結果はこうなりました。

click_result.PNG

手順①では一番内側のコンポーネントがクリックされたことにより、ターゲット段階として innerBox がリスナーが実行されます。その後、親コンポーネントへの伝播が働くことにより、バブリング段階として middleBox・outerBox の順にリスナーが実行されます。

手順②では middleBox がクリックされたので ターゲット段階として middleBoxのリスナーが実行され、バブリング段階として 親コンポーネントである outerBox のリスナーが実行されます。

手順③では、一番外側のコンポーネントのouterBox がクリックされたので、バブリング段階対象のコンポーネントは存在せず、ターゲット段階の outerBox のリスナーのみ実行されます。

つまり、イベント発行したコンポーネントはターゲット段階としてリスナーを実行し、イベント発行したコンポーネントよりも親のコンポーネントはバブリング段階としてリスナーを実行しています。
考え方はシンプルですが、1つのアクション(イベント)で複数個所のリスナーを動かせる非常に強力なしくみですよね。

次回は、キャプチャ段階についてサンプルソースを見ながら確認したいと思います。

前回の「itemRendererで編集したデータをdataProviderに反映させる」では、
itemRendererにtextInputを使用しました。

今回はcheckBoxを使用してみます。
前回同様、2つのデータグリッド間でうまく連携できるでしょうか?

サンプルコードは次の通りです。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
	<mx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
			
            [Bindable]
            private var initDG:ArrayCollection = new ArrayCollection([
                {Album:true},
                {Album:true}
            ]);
 		]]>
	</mx:Script>
	<mx:VBox>
		<mx:DataGrid id="dg1" dataProvider="{initDG}" width="300" editable="true">
			<mx:columns>
				<mx:DataGridColumn headerText="Album" dataField="Album" rendererIsEditor="true">
					<mx:itemRenderer>
						<mx:Component>
							<mx:CheckBox/>
						</mx:Component>
					</mx:itemRenderer>
				</mx:DataGridColumn>
			</mx:columns>
		</mx:DataGrid>
		<mx:DataGrid id="dg2" dataProvider="{initDG}" width="300" editable="true">
			<mx:columns>
				<mx:DataGridColumn headerText="Album" dataField="Album" rendererIsEditor="true">
					<mx:itemRenderer>
						<mx:Component>
							<mx:CheckBox/>
						</mx:Component>
					</mx:itemRenderer>
				</mx:DataGridColumn>
			</mx:columns>
		</mx:DataGrid>
	</mx:VBox>
</mx:Application>



前回からの変更点は以下4点。
 ・itemRendererをテキストインプットからチェックボックスに変更
 ・DataGridColumnのプロパティに「rendererIsEditor=true」を追加
  ※アイテムレンダラーをアイテムエディタとして使用するため
 ・初期値(initDG)を文字列から「true」に変更
  ※チェックボックスに変更したため
 ・確認ボタンと、押下時の処理を削除

 

それでは起動してみます。

flex_itemrenderer2_01.jpg

 

1行目のチェックボックスの選択を解除してフォーカスアウトしてみます。

flex_itemrenderer2_02.jpg

 

そうすると次のエラーが発生しました。
ReferenceError: Error #1069: itemRendererSample_inlineComponent1 にプロパティ text が見つからず、デフォルト値もありません。

これは、DataGridColumnのeditorDataField プロパティのデフォルト値が 「text」なためです。
アイテムレンダラーで使用しているチェックボックスはtextプロパティを持っていません。

これを解消するにはDataGridColumnのediterDataFieldプロパティにcheckBoxのプロパティである「selected」を指定します。
実際のコードは以下のようになります。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
	<mx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
			
            [Bindable]
            private var initDG:ArrayCollection = new ArrayCollection([
                {Album:true},
                {Album:true}
            ]);
 		]]>
	</mx:Script>
	<mx:VBox>
		<mx:DataGrid id="dg1" dataProvider="{initDG}" width="300" editable="true">
			<mx:columns>
				<mx:DataGridColumn headerText="Album" dataField="Album" rendererIsEditor="true" editorDataField="selected">
					<mx:itemRenderer>
						<mx:Component>
							<mx:CheckBox/>
						</mx:Component>
					</mx:itemRenderer>
				</mx:DataGridColumn>
			</mx:columns>
		</mx:DataGrid>
		<mx:DataGrid id="dg2" dataProvider="{initDG}" width="300" editable="true">
			<mx:columns>
				<mx:DataGridColumn headerText="Album" dataField="Album" rendererIsEditor="true" editorDataField="selected">
					<mx:itemRenderer>
						<mx:Component>
							<mx:CheckBox/>
						</mx:Component>
					</mx:itemRenderer>
				</mx:DataGridColumn>
			</mx:columns>
		</mx:DataGrid>
	</mx:VBox>
</mx:Application>


 

早速起動して、先程と同じように1行目のチェックボックスの選択を解除してフォーカスアウトします。

flex_itemrenderer2_03.jpg

 

すると、今度はエラーも発生せず、データグリッド間の連携もうまくいきました。

意外とはまりそうなので、覚え書きしておきました…

データグリッドなどのリストコントロールで、アイテムレンダラーに編集可能なコンポーネントを使用して
変更したデータ内容をデータプロバイダに戻す方法をご紹介します。

早速、検証用アプリで動作確認を行っていきましょう。
サンプルソースは以下の通りです。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
	<mx:Script>
		<![CDATA[
			import mx.controls.Alert;
			import mx.collections.ArrayCollection;
			
            [Bindable]
            private var initDG:ArrayCollection = new ArrayCollection([
                {Album:'Slanted and Enchanted'},
                {Album:'Brighten the Corners'}
            ]);
            
            //inidDGの内容を表示します
            private function checkBtnHandler():void {
            	Alert.show(
            		"initDGの内容確認" + "\n\n" +
            		"(0)=" + Object(initDG.getItemAt(0))["Album"].toString() + "\n" +
            		"(1)=" + Object(initDG.getItemAt(1))["Album"].toString()
            	);
            }
 		]]>
	</mx:Script>
	<mx:VBox>
		<mx:DataGrid id="dg1" dataProvider="{initDG}" width="300">
			<mx:columns>
				<mx:DataGridColumn headerText="Album" dataField="Album">
					<mx:itemRenderer>
						<mx:Component>
							<mx:TextInput/>
						</mx:Component>
					</mx:itemRenderer>
				</mx:DataGridColumn>
			</mx:columns>
		</mx:DataGrid>
				
		<mx:Button label="check!!" id="checkBtn" click="checkBtnHandler()"/>
	</mx:VBox>
</mx:Application>


 

起動直後の画面です。

flex_itemrenderer1_01.jpg

 

「check!!」ボタンを押下し、データプロバイダにバインディングしている変数(initDG)の内容を確認しておきます。

flex_itemrenderer1_02.jpg

 

次に1行目のデータを変更します。

flex_itemrenderer1_03.jpg

 

再度「check!!」ボタンで変数(initDG)の内容を確認してみます。

flex_itemrenderer1_04.jpg

 

結果は、先程と変わっていません。
つまり、データプロバイダに反映されていないことになります。

 

では、サンプルコードを修正してみましょう。
データグリッドのeditableプロパティに「true」を設定してみます。

		<mx:DataGrid id="dg1" dataProvider="{initDG}" width="300" editable="true">
			<mx:columns>
				<mx:DataGridColumn headerText="Album" dataField="Album">
					<mx:itemRenderer>
						<mx:Component>
							<mx:TextInput/>
						</mx:Component>
					</mx:itemRenderer>
				</mx:DataGridColumn>
			</mx:columns>
		</mx:DataGrid>


起動後、先程と同様に1行目のデータを変更して「check!!」ボタンを押下します。

flex_itemrenderer1_05.jpg

 

データプロバイダに反映されていることが確認できました。
editableを「true」にすることで、データプロバイダ内のアイテムを編集することが可能となります。

これを拡張して、2つのデータグリッド間でデータの同期を取るように作り変えてみましょう。
サンプルソースは以下になります。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
	<mx:Script>
		<![CDATA[
			import mx.controls.Alert;
			import mx.collections.ArrayCollection;
			
            [Bindable]
            private var initDG:ArrayCollection = new ArrayCollection([
                {Album:'Slanted and Enchanted'},
                {Album:'Brighten the Corners'}
            ]);
            
            //inidDGの内容を表示します
            private function checkBtnHandler():void {
            	Alert.show(
            		"initDGの内容確認" + "\n\n" +
            		"(0)=" + Object(initDG.getItemAt(0))["Album"].toString() + "\n" +
            		"(1)=" + Object(initDG.getItemAt(1))["Album"].toString()
            	);
            }
 		]]>
	</mx:Script>
	<mx:VBox>
		<mx:DataGrid id="dg1" dataProvider="{initDG}" width="300" editable="true">
			<mx:columns>
				<mx:DataGridColumn headerText="Album" dataField="Album">
					<mx:itemRenderer>
						<mx:Component>
							<mx:TextInput/>
						</mx:Component>
					</mx:itemRenderer>
				</mx:DataGridColumn>
			</mx:columns>
		</mx:DataGrid>
		<mx:DataGrid id="dg2" dataProvider="{initDG}" width="300" editable="true">
			<mx:columns>
				<mx:DataGridColumn headerText="Album" dataField="Album">
					<mx:itemRenderer>
						<mx:Component>
							<mx:TextInput/>
						</mx:Component>
					</mx:itemRenderer>
				</mx:DataGridColumn>
			</mx:columns>
		</mx:DataGrid>
						
		<mx:Button label="check!!" id="checkBtn" click="checkBtnHandler()"/>
	</mx:VBox>
</mx:Application>


 

起動直後の画面です。

flex_itemrenderer1_06.jpg

 

1つ目のデータグリッドの1行目を変更します。

flex_itemrenderer1_07.jpg

 

2つ目のデータグリッドも変更されました。
データプロバイダの参照先を同じ変数(initDG)にしているため、このようなことが可能となります。

応用次第では、何か面白いことが出来そうです。

次回はアイテムレンダラーにチェックボックスを使ってみます。

<mx:DataGrid>のデータが変更された場合(dataProviderが変更された場合)に処理を行うとします。
その際、changeイベントをリスニングしていませんか?
変更と言うとchangeイベントを思い浮かべる方多いようです。

ですが、AdobeFlexBuilderのヘルプを参照すると、changeイベントは
selectedIndex またはselectedItem プロパティの値が変更された場合に送出されるイベントと記載されています

0926-1.jpg

実際に検証してみます。

サンプルでは、コンボボックス変更時のイベントハンドラで
  データグリッドのdataProviderの値を変更し、
データグリッドがchangeイベントを送出した際にアラートを表示するサンプルです。

0926-2.jpg

サンプルコードは以下の通り。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application creationcomplete="init(event)" layout="absolute" xmlns:mx="http://www.adobe.com/2006/mxml">    <mx:Script>
        <![CDATA[
            import mx.controls.Alert;
            import mx.collections.ArrayCollection;
            
            protected function init(event:Event):void
            {
                // コンボボックスのデータを設定
                dataChooser.dataProvider = new ArrayCollection([    
                                                                {data:"1",label:"データ1"},
                                                                {data:"2",label:"データ2"}
                                                                ]);
            }
            
            protected function combo_changeHandler(event:Event):void
            {
                // コンボボックスの選択状態によってデータグリッドの値を変更
                switch(dataChooser.selectedIndex)
                {
                    case 0:
                    {
                        resultDg.dataProvider = new ArrayCollection([
                                                                    {name:"プラズマTV-20型",price:"10,000"},
                                                                    {name:"プラズマTV-27型",price:"50,000"},
                                                                    {name:"プラズマTV-32型",price:"70,000"},
                                                                    {name:"プラズマTV-37型",price:"75,000"}
                                                                    ]);
                        break;
                    }
                    case 1:
                    {
                        resultDg.dataProvider = new ArrayCollection([
                                                                    {name:"ミニ掃除機",price:"8,000"},
                                                                    {name:"サイクロン式掃除機",price:"56,800"},
                                                                    {name:"スーパーサイクロン式掃除機",price:"98,000"},
                                                                    {name:"ロケット式掃除機",price:"888,000"}
                                                                    ]);
                        break;
                    }
                    default:
                    {
                        resultDg.dataProvider = null;
                        break;
                    }
                }
            }
            
            protected function datagrid_changeHandler(event:Event):void
            {
                Alert.show("データグリッドchangeイベント","DataGrid");
            }
            
            
            
        ]]>
    </mx:Script>


    <mx:Panel x="0" y="0" width="100%" height="100%" layout="absolute" title="データグリッド変更">
        <mx:VBox x="0" y="0" width="100%" height="100%">
            <mx:Form width="100%" height="50%">
                <mx:FormItem label="データ選択">
                    <mx:ComboBox id="dataChooser" change="combo_changeHandler(event)" prompt="▼選択してください"/>
                </mx:FormItem>
            </mx:Form>
            <mx:DataGrid width="100%" height="100%" id="resultDg" change="datagrid_changeHandler(event)">
                <mx:columns>
                    <mx:DataGridColumn headerText="商品名" dataField="name"/>
                    <mx:DataGridColumn headerText="金額" dataField="price"/>
                </mx:columns>
            </mx:DataGrid>
        </mx:VBox>
    </mx:Panel>
</mx:Application>

サンプルを実行し、コンボボックスの値を変更した際
DataGridのchangeイベントハンドラで実装したアラートは表示されません。

データグリッドの値が変更されたタイミングで処理を実行したい場合、changeイベントではなく
valueCommitを指定する必要があります。

0926-3.jpg

<mx:DataGrid width="100%" height="100%" id="resultDg" valueCommit="datagrid_changeHandler(event)">

<実行結果>

0926-4.jpg

普通にテストを行っていれば、UTで発見できるとは思いますが、
うっかりテストで気が付けな買った場合、コード上は問題ないように見えてしまうので注意が必要です

前回までで、Ruby開発環境(RadRails)を構築しました。

 【前回までの記事】
 第1回:Rubyのダウンロード
 第2回:Rubyのインストール
 第3回:eclipseにRuby開発環境(RadRails)を構築する

今回は、動作確認も兼ねて実際にeclipseでRubyスクリプトを作成します。
定番の「Hello World」を表示してみましょう!

 

1.Eclipseのパースペクティブから「その他」をクリックします。

Ruby-04-01.jpg

 

2.「Ruby」を選択して「OK」ボタンをクリックします。

Ruby-04-02.jpg

 

3.Eclipeseのメニューから「ファイル→新規→Rubyプロジェクト」をクリックします。

Ruby-04-03.jpg

 

4.任意のプロジェクト名を入力して「完了」ボタンをクリックします。

Ruby-04-04.jpg

 

5.作成したプロジェクトを右クリックして「新規→Rubyファイル」をクリックします。

Ruby-04-05.jpg

 

6.任意のファイル名(拡張子「rb」)を入力して「完了」ボタンをクリックします。

Ruby-04-06.jpg

 

7.作成したファイルを開いて「puts "Hello World!!」を入力します。

Ruby-04-07.jpg

 

8.ファイルを右クリックして「実行→1 Perlローカル」をクリックします。

Ruby-04-08.jpg

 

9.コンソールビューに「Hello World!!」が表示されれば成功です。

Ruby-04-09.jpg

 

簡単でしたが、以上でRubyプログラムの作成は終了です。

前回までで、Perl開発環境(EPIC)を構築しました。

 【前回までの記事】
 第1回:ActivePerlのダウンロード
 第2回:ActivePerlのインストール
 第3回:eclipseにPerl開発環境(EPIC)を構築する

今回は、動作確認も兼ねて実際にeclipseでPerlスクリプトを作成します。
定番の「Hello World」を表示してみましょう!

 

1.Eclipseのパースペクティブから「その他」をクリックします。

ActivePerl_04_01.jpg

 

2.「Perl」を選択して「OK」ボタンをクリックします。

ActivePerl_04_02.jpg

 

3.Eclipeseのメニューから「ファイル→新規→Perlプロジェクト」をクリックします。

ActivePerl_04_03.jpg

 

4.任意のプロジェクト名を入力して「完了」ボタンをクリックします。

ActivePerl_04_04.jpg

 

5.作成したプロジェクトを右クリックして「新規→Perlファイル」をクリックします。

ActivePerl_04_05.jpg

 

6.任意のファイル名(拡張子「pl」)を入力して「完了」ボタンをクリックします。

ActivePerl_04_06.jpg

 

7.作成したファイルを開いて「print "Hello World!!」を入力します。

ActivePerl_04_07.jpg

 

8.ファイルを右クリックして「実行→1 Perlローカル」をクリックします。

ActivePerl_04_08.jpg

 

9.コンソールビューに「Hello World!!」が表示されれば成功です。

ActivePerl_04_09.jpg

 

簡単でしたが、以上でPerlプログラムの作成は終了です。

前回までで、Rubyのインストールが完了しました。

 【前回までの記事】
 第1回:Rubyのダウンロード
 第2回:Rubyのインストール

今回は、eclipseにRuby開発環境を構築していきます。
※eclipseは予めインストールされている必要があります。
 私の環境ではeclipse3.6(HELIOS)がインストールされています。

そこで必要となるのがRadRailsプラグインです。
RadRailsプラグインは、Ruby と Ruby on Rails の開発環境です。

それでは早速始めていきます。

1.Eclipseのメニューから「ヘルプ→新規ソフトウェアのインストール」をクリックします。

Ruby-03-01.jpg

 

2.「追加」ボタンをクリックします。

Ruby-03-02.jpg

 

3.下記の情報を入力して「OK」ボタンをクリックします。

名前:任意の名前を入力します。
ロケーション:「http://download.aptana.com/tools/radrails/plugin/install/radrails-bundle」を入力します。

Ruby-03-03.jpg

 

4.「Rails」を選択して「次へ」ボタンをクリックします。

Ruby-03-04.jpg

 

5.「次へ」ボタンをクリックします。

Ruby-03-05.jpg

 

6.「使用条件の条項に同意します」を選択して「完了」ボタンをクリックします。

Ruby-03-06.jpg

 

インストールが開始します。

Ruby-03-07.jpg

 

途中で以下の警告が表示された場合は「OK」ボタンをクリックします。

Ruby-03-08.jpg

 

インストールが完了したらeclipseを再起動します。

Ruby-03-09.jpg

 

7.インストールの確認

eclipseのパースベクティブから「その他」をクリックします。

Ruby-03-10.jpg

 

「Ruby」が表示されていればRadRailsプラグインのインストールは完了です。

Ruby-03-11.jpg

 

以上で、Ruby開発環境(RadRails)の構築は終了です。

前回までの記事で、GAE用Pythonのアプリケーションをローカルで動作させるところまでを記述しました。
最終回として今回は、Google App Engineに実際にデプロイし、GAE上で動作するところまで行ってみたのでご紹介したいと思います。

 

Google App Engineアプリケーションの登録

1.Google App Engine のアプリケーション登録のために、下記URLにアクセスします

http://appengine.google.com/

Python_GAE_Upload1.jpg

この際、Googleアカウントが必要になります。
Googleアカウントを持っていない場合は、アカウントを作成するため、画面上の「アカウントを作成」をクリックします。
Googleアカウント作成については、下記に詳細が記されています。
http://www.google.com/support/accounts/bin/topic.py?hl=jp&topic=14123

アカウントをお持ちの場合は、ログイン情報を入力してログインします。

2.「Create an Application」ボタンをクリックします

Python_GAE_Upload2.jpg

SMS認証の画面が表示されます。

3.必要項目を入力して「Send」ボタンをクリックします

Python_GAE_Upload3A.jpg

Country and Carrier: 国と通信事業者を選択します
Mobile Number: 電話番号、またはメールアドレス(@以降は入力してはいけません)を入力します

Country and Carrier は、「Japan」を選択すると下記のように日本の携帯事業者が選択できるようになります。

Python_GAE_Upload3B.jpg

「Send」ボタンクリック後、Googleから下記内容のメールが携帯に送信されてきます。

Google App Engine Code: xxxxxxx

※xxxxxxxの部分に数字7桁のコードがあります。


GAE登録時 Mobile Number 入力時に起きた問題

Movile Number には電話番号ではなく、メールアドレス(ドメインなし)を入力したほうが良い(らしい)

Mobile Number には電話番号を入力するかと思いきや、電話番号を入力したときに下記のように怒られました。

Python_GAE_Upload4.jpg

私の携帯はDocomoなのですが、Googleの下記のページにも書いてあるように DocomoとKDDIには問題があるらしいです。

アプリケーション作成のための SMS 検証

http://code.google.com/intl/ja/appengine/kb/sms.html

ソフトバンクであれば、電話番号の先頭に"+81"を付ければ良いみたいですが、ソフトバンク携帯を持っていないためこちらは未検証です。

4.「Enter Account Code」に 3の手順後Googleから送られてきたコードを入力して、「Send」ボタンをクリックします

Python_GAE_Upload5.jpg

5.アプリケーション作成に必要な情報を入力します

Python_GAE_Upload6.jpg

Application Identifier アプリケーションIDを入力します
※アプリケーションIDは全世界でユニークでなければなりません
 使用可能であるかは「Check Availability」ボタンを押すことで確認できます
Application Title: アプリケーションタイトルを入力します
アプリケーションタイトルは任意で大丈夫です

 

6.「I accept theese terms.」チェックボックスにチェックし、[Create Application]ボタンをクリックします

Python_GAE_Upload8.jpg

アプリケーション作成が成功した場合、下記の画面が表示されます。

Python_GAE_Upload9.jpg

 

アプリケーションのアップロード

実際に作成したアプリケーションをアップロードします。
ここでアップロードするファイルは、前回の記事で作成した「Hello world」アプリケーションです。

1.app.yaml ファイルを編集します

application設定値を上記「Google App Engineアプリケーションの登録」の「5.アプリケーション作成に必要な情報を入力します」で設定したApplication Identifierの値にします。

application: gae-python
version: 1
runtime: python
api_version: 1

handlers:
- url: /.*
  script: helloworld.py

2.下記コマンドを入力して、アップロードを行います

> appcfg.py update helloworld/

helloworld/ の部分は、実際に開発を行っている appl.yaml(1の手順で編集したファイル)、helloworld.py が存在するフォルダー名を指定します。
 私の環境はWindowsで、eclipseのworkspace をCドライブ直下に作成していますので「C:\workspace\HelloWorld\src」でした。
 この場合のコマンドは appcfg.py update C:\workspace\HelloWorld\src となりました。

コマンド実行後、コマンド プロンプト には下記のようなメッセージが出力されます。

Application: gae-python; version: 1.
Server: appengine.google.com.
****************************************************************
There is a new release of the SDK available.
-----------
Latest SDK:
api_versions: ['1']
release: 1.3.7
timestamp: 1282688496

-----------
Your SDK:
api_versions: ['1']
release: 1.3.6
timestamp: 1278528410

-----------
Please visit http://code.google.com/appengine for the latest SDK
****************************************************************
Scanning files on local disk.
Initiating update.
Email: <Googleアカウントのメールアドレスを入力します>
Password for xxx@brainchild.co.jp:<Googleアカウントのパスワードを入力します>
Cloning 1 application file.
Deploying new version.
Checking if new version is ready to serve.
Will check again in 1 seconds.
Checking if new version is ready to serve.
Will check again in 2 seconds.
Checking if new version is ready to serve.
Will check again in 4 seconds.
Checking if new version is ready to serve.
Will check again in 8 seconds.
Checking if new version is ready to serve.
Will check again in 16 seconds.
Checking if new version is ready to serve.
Closing update: new version is ready to start serving.

途中で、GoogleアカウントのユーザーID(メールアドレス)、パスワード入力を求められる(<Googleアカウントのメールアドレスを入力します>、<Googleアカウントのパスワードを入力します>となっている部分)ので入力します。
アップロードが正常に終了すると、GAEにアプリケーションが登録されます。
実際に今回の手順で、私が作成したGAEのHelloWorldアプリケーションは下記になります。
http://gae-python.appspot.com/

[Ruby] Rubyのインストール

第1回目の「Rubyのダウンロード」に引き続き、
第2回目は「Rubyのインストール」をご紹介します。

 

はじめに、前回ダウンロードしたRubyのインストーラを用意して下さい。

 

1.インストーラの実行

インストーラを起動(ダブルクリック)します。

Ruby-02-01.jpg

 

2.セットアップウィザードが起動したら「Next」ボタンをクリックします。

Ruby-02-02.jpg

 

3.「I accept the Licence」を選択して「Next」ボタンをクリックします。

Ruby-02-03.jpg

※「「I accept the Licence」:ライセンス(使用許諾条件)に同意する。

 

4.インストールディレクトリを指定して「Install」ボタンをクリックします。

ここでは、インストールディレクトリはデフォルトの「C:\Ruby192」のまま進めます。

 

RubyをPATH(環境変数)に追加する場合は「Add Ruby executables to your PATH」にチェックを入れます。
「.rb」、「.rbw」拡張子をRubyに関連付ける場合は「Associate .rb and .rbw files with this Ruby installation」にチェックを入れます。

Ruby-02-04.jpg

 

インストールが開始します。
Ruby-02-05.jpg

 

5.「Finish」ボタンをクリックします。

Ruby-02-06.jpg

 

6.動作確認を行います。

コマンドプロンプトを起動して「ruby -v」を入力して下さい。
下記のメッセージ(バージョン情報)に相当するものが出力されればOKです。

Ruby-02-07.jpg

Rubyのパスが通っていない場合は上記コマンドが正常に動作しません。
環境変数の「Path」を確認して下さい。

 

以上で「Rubyのインストール」は終了です。

前回までで、ActivePerlのインストールが完了しました。

 【前回までの記事】
 第1回:ActivePerlのダウンロード
 第2回:ActivePerlのインストール

今回は、eclipseにPerl開発環境を構築していきます。
※eclipseは予めインストールされている必要があります。
 私の環境ではeclipse3.6(HELIOS)がインストールされています。

そこで必要となるのがEPIC(Eclipse Perl Integration)プラグインです。
EPICプラグインは、Eclipse上でPerlのプログラム開発を行うためのプラグインです。
※デバッガをより便利に利用したい方は、CPANのPadWalkerモジュールを別途インストールして下さい。

それでは早速始めていきます。

 

1.Eclipseのメニューから「ヘルプ→新規ソフトウェアのインストール」をクリックします。

ActivePerl_03_01.jpg

 

2.「追加」ボタンをクリックします。

ActivePerl_03_02.jpg

 

3.下記の情報を入力して「OK」ボタンをクリックします。

名前:任意の名前を入力します。
ロケーション:「http://e-p-i-c.sf.net/updates」を入力します。

ActivePerl_03_03.jpg

 

4.「EPIC メイン・コンポーネント」を選択して「次へ」ボタンをクリックします。

ActivePerl_03_04.jpg

 

5.「次へ」ボタンをクリックします。

ActivePerl_03_05.jpg

 

6.「使用条件の条項に同意します」を選択して「完了」ボタンをクリックします。

ActivePerl_03_06.jpg

 

インストールが開始します。

ActivePerl_03_07.jpg

 

途中で以下の警告が表示された場合は「OK」ボタンをクリックします。

ActivePerl_03_08.jpg

 

インストールが完了したらeclipseを再起動します。

ActivePerl_03_09.jpg

 

7.インストールの確認

eclipseのパースベクティブから「その他」をクリックします。

ActivePerl_03_10.jpg

 

「Perl」が表示されていればEPICプラグインのインストールは完了です。

ActivePerl_03_11.jpg

 

以上で、Perl開発環境(EPIC)の構築は終了です。

[Ruby] Rubyのダウンロード

Rubyについて、開発環境構築までの手順を全3回構成でご紹介していきます。
第1回は「Rubyのダウンロード」です。

私が使用しているPCのOSは「Windows7 Home Premium 32bit」、
今回インストールするRubyのバージョンは「1.9.2-p0」となります。

Rubyの公式サイトではソースコードしか入手できないため、
今回は有志の方のサイトからバイナリ版をダウンロードします。
※公式サイトのURLは「http://www.ruby-lang.org/ja/」です。

 

1.はじめに、下記のサイトにアクセスします。

  http://rubyforge.org/projects/rubyinstaller/

 

2.「ダウンロード」をクリックします。

Ruby-01-01.jpg

 

3.「rubyinstaller-1.9.2-p0.exe」をクリックします。

Windows版のインストーラです。

Ruby-01-02.jpg

 

4.任意の場所にファイルを保存(ダウンロード)します。

Ruby-01-03.jpg

 

非常に簡単でしたが、ここまでが「Rubyのダウンロード」です。
続編として「Rubyのインストール」をご紹介しているので、そちらもご覧ください。

第1回目の「ActivePerlのダウンロード」に引き続き、
第2回目は「ActivePerlのインストール」をご紹介します。

はじめに、前回ダウンロードしたActivePerlのインストーラを用意して下さい。

 

1.インストーラの実行

インストーラを起動(ダブルクリック)します。

ActivePerl_02_01.jpg

 

環境によっては以下の画面が出る場合がありますが、そのまま実行をクリックします。

ActivePerl_02_02.jpg

 

2.セットアップウィザードが起動したら「Next」ボタンをクリックします。

ActivePerl_02_03.jpg

 

3.「I accept the terms in the License Agreement」を選択して「Next」ボタンをクリックします。

ActivePerl_02_04.jpg

※「I accept the terms in the License Agreement」:ライセンス(使用許諾条件)に同意する。

 

4.インストール先に「Location:C:\Perl\」を指定して「Next」ボタンをクリックします。

デフォルトでは「C:\Perl\」となっています。

ActivePerl_02_05.jpg

 

5.「Add Perl to the PATH environment variable」、「Create Perl file extension association」を選択して「Next」ボタンをクリックします。

ActivePerl_02_06.jpg

※「Add Perl to the PATH environment variable」:PerlをPATH(環境変数)に追加する。
 「Create Perl file extension association」:「.pl」拡張子をActivePerlに関連付ける。

 

6.「Install」をクリックします。

ActivePerl_02_07.jpg

インストールを開始します。

ActivePerl_02_08.jpg

 

7.「Finish」ボタンをクリックします。

ActivePerl_02_09.jpg

※「Display the release notes」:リリースノートを表示する。

 

8.動作確認を行います。

コマンドプロンプトを起動して「perl -v」を入力して下さい。
下記のメッセージ(バージョン情報)に相当するものが出力されればOKです。

ActivePerl_02_10.jpg

Perlにパスが通っていない場合は上記コマンドが正常に動作しません。
環境変数の「Path」を確認して下さい。

以上で「ActivePerlのインストール」は終了です。
次回は「eclipseにActivePerl開発環境(EPIC)を構築する」をご紹介する予定です。

ActivePerlについて、開発環境構築までの手順を全3回構成でご紹介していきます。
第1回は「ActivePerlのダウンロード」です。

私が使用しているPCのOSは「Windows7 Home Premium 32bit」、
今回インストールするActivePerlのバージョンは「5.12.1」となります。
 

1.まずはじめに、公式サイトにアクセスします。

  http://www.activestate.com/activeperl/
 

2.「Free Downroad」をクリックします。

ActivePerl_01_01.jpg

 

3.「Download ActivePerl 5.12.1 for Windows(x86)」をクリックします。

  ※ご自身の環境に合わせて選択して下さい。

ActivePerl_01_02.jpg

 

4.任意の場所にファイルを保存(ダウンロード)します。

ActivePerl_01_03.jpg

 

非常に簡単でしたが、ここまでが「ActivePerlのダウンロード」です。
続編として「ActivePerlのインストール」をご紹介しているので、そちらもご覧ください。

以前に書いた記事 「boolean型の値は false=0,true=1 になっている」 で記載した内容に関して、一部誤りが発覚しましたので、こちらにその検証の続きを記載します。

解釈が誤っていた点

★ false=0 / true=1 ではなくて、 0=false / 0以外の値は true となる

 

下記のソースで検証します。
if文の条件に true/false ではなく、0, 1, 255 という数字を使用して評価します。評価対象になった場合には、VBoxコンテナの中にLabelを追加してメッセージを表示するつくりになっています。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" horizontalAlign="center" creationComplete="onCreationComplete()">

<mx:Script>
    <![CDATA[
        import mx.controls.Label;
        
        private function onCreationComplete():void
        {
            if (0) {
                 addLabel("0");
                 trace(0 as Boolean);
            }
            
            // 評価される → as演算子でキャストした結果は「true」
            if (!0) {
                addLabel("!0");
                trace(!0 as Boolean);
            }
            
            // 評価される → as演算子でキャストした結果は「null」
            if (1) {
                addLabel("1");
                trace(1 as Boolean);
            }
            
            if (!1) {
                addLabel("!1");
                trace(!1 as Boolean);
            }
            
            // 評価される → as演算子でキャストした結果は「null」
            if (255) {
                addLabel("255");
                trace(255 as Boolean);
            }
            
            if (!255) {
                addLabel("!255");
                trace(!255 as Boolean);
            }     
        }
        
        private function addLabel(msg:String):void
        {
            var lbl:Label = new Label();
            lbl.text = "「" + msg + "」 は評価されました";
            showList.addChild(lbl);
        }
        
    ]]>
</mx:Script>

    <mx:VBox id="showList" horizontalAlign="center" fontSize="15" fontWeight="bold" />

</mx:Application>

【実行結果】

booleanEvaluation.png

実行結果としてわかったことは、

  • 「0」という数字は false として評価される
  • false の否定である 「!0」 は true として評価される (当たり前ですが…)
  • 「0」以外の数字は、条件式ですべて true として評価される
  • 「0」以外の数字は as演算子でキャストすると null になっている (Booleanでキャストできていない)

ソースにはありませんが、if("あああ")  などの様に文字列を使用した場合にも、必ず true として評価されていました。

つまり、 boolean型の true/false の代替としては、0 を false の代わりに使うことはできるが、0 以外の値はすべて true と評価されてしまうので使用することができないことがわかりました。

画面上のコンポーネントに対しカーソルが当たっている状態で、Tabキーを押下した際に、 次のコンポーネントにフォーカスを移動させることができます。

VBox、HBox、Canvasコンテナにコンポーネントを配置したときに、Tabキーを押下した場合の遷移をそれぞれ検証してみました。

 

VBoxの場合

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
 <mx:VBox height="100%">
  <mx:TextArea text="1"/>
  <mx:TextArea text="2"/>
  <mx:TextArea text="3"/>
  <mx:TextArea text="4"/>
  <mx:TextArea text="5"/>
 </mx:VBox>
</mx:Application>

サンプルのFlash

 

Vboxコンテナの場合は、上から下へ順に移動することが確認できます。
また、MXML上の配置と画面上の配置が同じためMXMLで配置した順=Tabキー押下時にフォーカスが移動する順番になるようです。

 

HBoxの場合

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
 <mx:HBox width="100%">
  <mx:TextArea text="1"/>
  <mx:TextArea text="2"/>
  <mx:TextArea text="3"/>
  <mx:TextArea text="4"/>
  <mx:TextArea text="5"/>
 </mx:HBox>
</mx:Application>

サンプルのFlash

Hboxコンテナの場合は、左から右へ順に移動することが確認できます。
また、MXML上の配置と画面上の配置が同じためMXMLで配置した順=Tabキー押下時にフォーカスが移動する順番になるようです。

 

Canvasの場合

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
 <mx:Canvas width="60" height="60">
  <mx:TextArea x="0" y="0" width="20" height="20" text="1"/>
  <mx:TextArea x="20" y="0" width="20" height="20" text="2"/>
  <mx:TextArea x="40" y="0" width="20" height="20" text="3"/>
  <mx:TextArea x="0" y="20" width="20" height="20" text="4"/>
  <mx:TextArea x="20" y="20" width="20" height="20" text="5"/>
  <mx:TextArea x="40" y="20" width="20" height="20" text="6"/>
  <mx:TextArea x="0" y="40" width="20" height="20" text="7"/>
  <mx:TextArea x="20" y="40" width="20" height="20" text="8"/>
  <mx:TextArea x="40" y="40" width="20" height="20" text="9"/>
 </mx:Canvas>
 <mx:Canvas width="60" height="60">
  <mx:TextArea x="40" y="40" width="20" height="20" text="1"/>
  <mx:TextArea x="20" y="40" width="20" height="20" text="2"/>
  <mx:TextArea x="0" y="40" width="20" height="20" text="3"/>
  <mx:TextArea x="40" y="20" width="20" height="20" text="4"/>
  <mx:TextArea x="20" y="20" width="20" height="20" text="5"/>
  <mx:TextArea x="0" y="20" width="20" height="20" text="6"/>
  <mx:TextArea x="40" y="0" width="20" height="20" text="7"/>
  <mx:TextArea x="20" y="0" width="20" height="20" text="8"/>
  <mx:TextArea x="0" y="0" width="20" height="20" text="9"/>
 </mx:Canvas>
</mx:Application>

サンプルのFlash

1つ目のCanvasは、左上から右下へ移動することが確認でき、2つ目のCanvasは、右下から左上へ移動することが確認できます。

2つ目のCanvasも画面上の見た目のコンポーネント配置は1つ目のCanvasとまったく同じですが、2つ目のCanvasは、MXMLのソースコード上では逆から並べているため、Tabキー移動で左下から右上に移動しています。

上記検証から、Tabキーの移動順序は、デフォルトでは MXMLソースファイル上での記述順で決定されているようです。

ボタンにフォーカスがある時、スペースキー(IMEオフのとき限定)を押下した際に、ボタンのクリックイベントが呼ばれます。

これをEnterキーでも押下できるようにしたいと考え、Buttonクラスを拡張して以下のCstmButtonクラスを作成してみました。

CstmButton.asファイル

package
{
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;
	
	import mx.controls.Button;

	public class CstmButton extends Button
	{
		public function CstmButton()
		{
			super();
		}
		
		override protected function keyDownHandler(event:KeyboardEvent):void
		{
	        if (event.keyCode == Keyboard.ENTER)
                event.keyCode = Keyboard.SPACE;
			super.keyDownHandler(event);
		}
	    override protected function keyUpHandler(event:KeyboardEvent):void
	    {
	        if (event.keyCode == Keyboard.ENTER)
                event.keyCode = Keyboard.SPACE;
            
            super.keyUpHandler(event);
	    }
		
	}
}

ソースコードを読んでもらえばわかるとは思いますが、この方法はかなりお手軽な方法(手抜き)です。
CstmButtonクラスの中身は、キーが押されたときに呼ばれているクラス(KeyboardEvent)内で、Enterキーが押されたときに呼ばれるメソッド(keyDownHandler)、離されたときに呼ばれるメソッド(keyUpHandler)をそれぞれオーバーライドして、パラメータで渡されたイベントクラス内の押されたキーの情報(keyCode)を、EnterキーからSpaceキーのKeyCodeに置き換えてからsuper()を呼んでます。

CstmButtonクラスの継承元であるButtonクラスのkeyDownHandlerメソッド、keyUpHandlerメソッドでは、押されたキー(keyCode)をみてSpaceキーの場合に処理が動いているので、Enterキー押下時にSpaceキーに置き換えることで、Enterキーでもボタンが押せるようになります。

 

以下、上記クラスを検証するためのサンプルソースです。

 .mxmlファイル

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*" horizontalAlign="left">
	<mx:Script>
	<[CDATA[
		import mx.controls.Alert;
		
		private function checkClicked():void{
			Alert.show("反応!");
		}
	]]>
	</mx:Script>

	<local:CstmButton label="カスタム" click="checkClicked()"/>
	<mx:Button label="普通" click="checkClicked()"/>
</mx:Application>

※ サンプルソースでは、ボタンが押されたという反応を確認するため、clickイベントを追加してます

前回の記事で、GAEを開発するための準備を整えました。
さっそくGAEで"Hello World."を出力するアプリケーションを開発してみることにします。
GAEで "Hello World."の記事ですが、大きくなるので3回に分けています。
第2回目は、『Google App Engine SDK for Python』のプロジェクト作成⇒ローカルでのテストまでの作業です。

 

eclipseでGAE for Python用プロジェクトを作成

1.パッケージエクスプローラー上で、マウスを右クリックし「新規 > プロジェクト」を選択します。
メニュー「ファイル > 新規 > プロジェクト」でも同じです。

Python_GAE_01.jpg


2.「Pydev Google App Engine Project」を選択し、[次へ]ボタンをクリックします。

Python_GAE_02.jpg


3.プロジェクト名、文法バージョン、インタープリターを選択し、[次へ]ボタンをクリックします。

Python_GAE_03.jpg

プロジェクトタイプ Python
文法バージョン 2.6
インタープリター

Python2X

文法バージョン、インタープリターについては、過去の記事「eclipseでPython開発を行ってみる」を参照してください。
 現在Python3については未検証です。

4.[参照]ボタンをクリックします。

Python_GAE_04.jpg


5.前回の記事でインストールした、「Google App Engine SDK for Python」をインストールしたフォルダーを指定します。

Python_GAE_05.jpg


6.[次へ]ボタンをクリックします。

Python_GAE_06.jpg


7.プロジェクト名、テンプレートを指定して[完了]ボタンをクリックします。

プロジェクト名は「helloworld」です。(理由は「設定ファイルの編集」で後述しています)
テンプレート名は目的次第ですが、今回は「Hello World」を選択します。

Python_GAE_07.jpg


下記のようにGAE for Python用のプロジェクトが作成されます。

Python_GAE_08.jpg

 

リクエストハンドラの編集

「eclipseでGAE for Python用プロジェクトを作成」で作成された helloworld.py を編集し、リクエストに応答し「Hello world」と出力するCGIプログラムを作成します。
といっても、最低限のソースコードはテンプレートで自動的に作成してくれていますので、中身を確認するだけです。
helloworld.py は下記内容になっています。

print 'Content-Type: text/plain'
print ''
print 'Hello, world!'

 

設定ファイルの編集

「eclipseでGAE for Python用プロジェクトを作成」で作成された app.yaml を編集します。
このファイルも既にテンプレートが作成してくれていますので、中身だけ確認します。
app.yaml は下記内容になっています。

application: helloworld
version: 1
runtime: python
api_version: 1

handlers:
- url: /.*
  script: helloworld.py

※application と script で指定する名前は同じにしないとうまく動作しないようです。

設定ファイルの詳細は下記URLを参照してください。
http://code.google.com/intl/ja/appengine/docs/python/config/appconfig.html

 

動作確認

まずはローカルで動作確認を行います。
コマンドプロンプトで下記のコマンドを入力します。

> dev_appserver.py helloworld/

※実行時は、Pythonインタープリター、Google App Engine SDK for Python のパスを確認してください。
helloworld/ の部分は、実際に開発を行っている helloworld.py が存在するフォルダー名を指定します。
 私の環境はWindowsで、eclipseのworkspace をCドライブ直下に作成していますので「C:\workspace\HelloWorld\src」でした。
 この場合のコマンドは dev_appserver.py C:\workspace\HelloWorld\src となりました。

テスト用Webサーバーが起動したら下記のURLで実際に「Hello World」が出力されることを確認します。
http://localhost:8080/

※使用するポートの変更などを行いたい場合、下記URLに詳細が記述してありますので参照してみてください。
http://code.google.com/intl/ja/appengine/docs/python/tools/devserver.html

 

次回の記事で実際に、GAE上で"Hello world."を出力するところまで行ってみています。そちらも参照してみてください。

GAEで "Hello World." その3

前回迄の記事で、eclipseでPythonの開発環境を整え、実際に簡単なプログラムを作ってみました。
現在の野望としては、せっかくPythonを使っているので、Webで簡単システムを作ってみたいな~と考えています。
ちょっと調べてみると、「Google App Engine」がPythonを開発言語に採用していますので、GAEにて自作のPythonプログラムを動かしてみたいと思っています。
この辺の手順は、Googleで調べると既にいろいろなブログで紹介されていますが、まずは自分で実践ということで私自身の体験としてここのブログでも紹介しようと思います。
まずは、定番「Hello World」出力までの手順です。

記事が大きくなるので、記事を3回に分けました。
第1回目は、『Google App Engine SDK for Python』のダウンロード⇒インストールまでの作業です。

尚この手順は、Google CODEにスタートガイドがあります。
http://code.google.com/intl/ja/appengine/docs/python/gettingstarted/

Google App Engine SDK for Pythonのインストール

【インストール環境】

  • OS:WindowsXP SP3

1.Google App Engine のホームページを開きます。

http://code.google.com/intl/ja/appengine/downloads.html

Python_GAE_SDK_01.jpg

2.「Google App Engine SDK for Python」をダウンロードします。

Python_GAE_SDK_02.jpg

3.ダウンロードした実行ファイルを実行します。

Python_GAE_SDK_03.jpg

4.『Google App Engine SDK for Python』のインストール画面が表示されるので、[Next]ボタンをクリックします。

Python_GAE_SDK_04.jpg

5.「I accept the terms in the License Agreement」をチェックし、[Next]ボタンをクリックします。

Python_GAE_SDK_05.jpg

6.インストールするフォルダー、インストール時のオプションのチェックを設定して、[Next]ボタンをクリックします。

Python_GAE_SDK_06.jpg

7.[Install]ボタンをクリックします。

Python_GAE_SDK_07_1.jpg

 インストールが開始されます。(しばらく待ちます)

Python_GAE_SDK_07_2.jpg

8.インストールが完了するので、[Finish]ボタンをクリックします。

Python_GAE_SDK_08.jpg


以上で、Google App Engine SDK for Python のインストールは完了です。

次回は実際に、ローカル上で"Hello world."を出力するところまで行っています。

GAEで "Hello World." その2

※記事の本数を2回⇒3回に修正しました。(2010/09/05)

このブログについて

このブログは吉祥寺にあるブレインチャイルド株式会社の社員で投稿しています。
業務ではまってしまったことや発見したこと。
自分達で新たに学習してみようと思って勉強し始めたことなどを綴っています。
こんな社員が働いているブレインチャイルドに興味がわいててきたなら、是非お問い合わせください。
会社案内
求人案内
先輩のコメント