< 前へ | 次へ >

演習 11: マップ・ロケーター・ハンドラーへのコードの追加

前回の演習で作成したユーザー・インターフェースの背景にあるコードを完成させます。

MapLocatorHandler.egl のソース・コードの仕上げ

  1. Rich UI エディターで MapLocatorHandler.egl ファイルを開いた状態にします。 「設計」ビューを表示している場合は、「ソース」タブをクリックします。
  2. start 関数の直前にブランク行を追加し、以下のように、作成したインターフェース・パーツに基づいた変数を宣言します。
    lookupService GooglePlacesService{@restbinding};

    @restbinding プロパティーは、サービス・アクセスの詳細が、EGL デプロイメント記述子ではなく、コード内にあることを示します。 このような決断は便利ではありますが、柔軟性には欠けます。 サービスのロケーションを変更する場合に、ソース・コードの変更が必要になります。 演習 14 では、EGL デプロイメント記述子を紹介します。開発作業の多くでは、サービス・アクセスの詳細をこの記述子に置くことが多くなります。

  3. インターフェース・パーツへの参照を解決するために、Ctrl + Shift + O を押します。 以下のステップでは、新規の赤いエラー・マークを追加します。これらはこの演習の最後の方まで取り除きません。
  4. start 関数には内容を追加しないでください。
  5. checkForEnter 関数を以下のようにして完成させます。
    function checkForEnter(event Event in)
       if(event.ch == 10)
          search();
       end
    end

    背景にある以下のような詳細を考慮に入れてください。EGL ランタイム・コードは、checkForEnter 関数を呼び出して、イベント・オブジェクト (イベントに関する詳細を含んだメモリー構造) を渡します。 この場合、呼び出しを実行したイベントは onKeyDown で、イベント・オブジェクトには、ユーザーのキー・ストロークを表す ASCII 文字が含まれています。 特に、数値 10 は ASCII 表の復帰 (Enter キー) を表す 10 進値です。これについては、ASCII Table and Description (http://www.asciitable.com) に説明があります。

    checkForEnter 関数が呼び出されるのは、テキスト・フィールドにフォーカスが置かれた状態で、ユーザーが Tab や Enter などのキーを押した場合のみです。 関数側では、キーが Enter であった場合にのみ、search 関数を呼び出します。 search 関数はこの後で作成します。

  6. buttonClicked() 関数を以下のようにして完成させます。
    function buttonClicked(event Event in)
       search();
    end

    buttonClicked 関数、およびボタン固有の onClick プロパティーに対するその関係により、ユーザーが「Search」ボタンをクリックした際に search 関数が呼び出されるようになります。

  7. search 関数を追加するには、ハンドラーの最後 (ファイル内の最後の end ステートメントの前) に以下のコードを配置します。
    function search()
       localMap.zoom = 10;
       	localMap.removeAllMarkers(); 
       // show an initial marker, as necessary to display the map at all
       localMap.addMarker(new MapMarker{ latitude = "37.47", longitude = "-122.26", 
    		address = "I am here!", description = "San Francisco"});
    
       // Call the remote Google service, passing the type value
       call lookupService.getSearchResults( typeComboBox.value ) returning to showResults
          onException displayError;
    end
    以下の詳細に注意してください。
    • EGL Google マップ・ウィジェットには、マップの縮尺を指定する zoom プロパティーが含まれています。 ノースカロライナのデフォルト・マップで使用されている大きな縮尺 (zoom 値 8) は指定せずに、個々の都市が示されたマップが生成されるように、zoom 値を 10 に設定します。
    • EGL Google マップ・ウィジェットには、MapMarker タイプのレコードを受け入れ、入力された住所のマップ上の位置を特定する addMarker 関数も含まれています。

      検索結果セットを表すこの初期表示でユーザーが localMap.addMarker() 関数に提供する唯一の詳細は、都市のロケーション・マーカーです。

  8. 次に、Google プレイス・サービスへのアクセスがエラーを出さずに正常に行われた場合に呼び出される showResults 関数を追加します。search 関数の後 (ファイル内の最後の end ステートメントの前) に以下のコードを配置します。
    linkListing HyperLink[0];
    
    for(i int from 1 to retResult.result.getSize() by 1)
    		newLink HyperLink{padding = 4, text = retResult.result[i].name, href = "#"};
    		newLink.setAttribute("title", retResult.result[i].vicinity );
    		newLink.setAttribute("lat",
    		retResult.result[i].geometry.location.lat);
    		newLink.setAttribute("lng",
    		retResult.result[i].geometry.location.lng);
    		newLink.onClick ::= mapAddress;
    		linkListing.appendElement(newLink);
    	end
    	listingBox.setChildren(linkListing);
    end
    サービスを呼び出すと、位置の詳細の配列が返されます。 showResults 関数について以下の点を考慮してください。
    • 各要素は、「title」(すなわち位置の名前) から構成されます。
    • showResults 関数は、ハイパーリンク・ウィジェットの配列を作成し、入力配列を最後まで読み取ります。 この関数は、入力配列内の要素ごとに、ハイパーリンク・ウィジェットの配列内に要素を作成します。
    • 以下の宣言に示されているとおり、各ハイパーリンク・ウィジェットには、表示可能なテキストおよび埋め込みがあり、Web アドレスの代わりにプレースホルダー (#) が含まれています。
      newLink HyperLink{padding = 4, text = retResult.result[i].title, href = "#"};

      このハイパーリンクでは、Web アドレスではなく、コードが呼び出されます。 ただし、プレースホルダーがあることで、ユーザーがハイパーリンクをクリックして Web サイトが開く場合と同様に、下線の引かれた色付きのテキストという一般的な方法でハイパーリンクが表示されます。

    • この関数は、DOM ツリー内のこのウィジェットに固有のメモリー域に値を配置する setAttribute 関数を呼び出します。 特に、この関数は他の関数から取得できるように、緯度と経度を格納します。
    • 各ハイパーリンク・ウィジェットに関して、showResults 関数は、mapAddress 関数を onClick イベントに割り当てることで、実行時動作をセットアップします。
    • ハイパーリンク・ウィジェットの完全な配列は、リスト表示ボックスの唯一の子として割り当てられます。
  9. showResults 関数の後に以下の関数を配置します。
    function mapAddress(e Event in)
    
    	// Show the marker when the user clicks the link
       businessAddress string = e.widget.getAttribute("address") as string;
       businessName string = e.widget.getAttribute("title") as string;
       lat string = e.widget.getAttribute("lat") as string;
       lng string = e.widget.getAttribute("lng") as string;
       localMap.addMarker( new MapMarker{ latitude = lat, 
       		longitude = lng, address = businessAddress, description = businessName});
    End

    ユーザーが実行時にハイパーリンクをクリックすると、mapAddress 関数は、showResults 関数で設定された属性を取得し、表示されたマップ上にマーカーを設定します。

  10. ここで、Google プレイス・サービスへのアクセスが失敗した場合にデータを受け取る例外ハンドラーを追加します。mapAddress 関数の後 (ファイル内の最後の end ステートメントの前) に以下のコードを配置します。
    function displayError(ex AnyException in)
       DojoDialogLib.showError("Google Service", 
                               "Cannot invoke Google Places service: " + ex.message, null);
    end

    DojoDialogLib は、演習 2 でワークスペースに追加した com.ibm.egl.rui.dojo.samples プロジェクトのライブラリー・パーツです。このライブラリーにある showError 関数によって、ダイアログ内に情報が表示されます。 この関数呼び出しには message という名前のストリングが含まれており、これは、EGL ランタイム・コードが displayError 関数に渡す例外レコード内にあります。

  11. Ctrl + Shift + F を押してコードのフォーマットを設定し、Ctrl + Shift + O を押して参照を解決してから、ファイルを保存します。 ソース・ファイルにエラーがある場合は、そのコードと演習 11 終了後の MapLocatorHandler.egl のコードのファイル内容を比較してください。

新規ポートレットのテスト

このポートレットは独立して動作するので、単独でテストできます。

  1. 必ずファイルを保存してから、「プレビュー」をクリックしてください。 EGL により、入力フォームがデフォルトのノースカロライナのマップと共に表示されます。
  2. タイプの選択リストで、住宅ローンを選択します。
  3. Enter キーを押すか、「Search」ボタンをクリックします。 画面の左側に、住宅ローンの位置のリストが表示されます。 右側は、サンフランシスコのマップです。
    マンハッタン中心部のマップ。
    注: 注: Google Places Search Service ではデータが返されないことがあります。その場合には、「null 例外」により、エラー・メッセージが表示されます。 このサービスを利用できない場合、またはデータが返されなかった場合には、「キャンセル」をクリックして、しばらく待ってからこのチュートリアルを最後まで実行してください。
  4. 左側の列にある任意の名前をクリックします。 その事業所の所在地を示すマーカーがマップ上に表示されます。 そのマーカーの上にカーソルを移動させると、その所在地の名前が表示されます。
  5. 同じ検索または近隣のカフェの検索を再実行します。 マップ上に置いたマーカーはそのままです。
  6. 検索を実行する前に毎回すべてのマーカーを取り除くようにする場合は、「ソース」タブをクリックして、showResults 関数の先頭に以下の行を追加します。
    localMap.removeAllMarkers();  
  7. 「プレビュー」タブで作業結果をテストします。
  8. ファイルを閉じます。

演習のチェックポイント

以下のタスクの実行方法を学習しました。
  • Local Search Service を基にした変数を作成して使用する。
  • ユーザーのキー・ストロークに応答する。
  • DOM ツリーを使用して、ある関数から別の関数に値を渡す。
  • マップ・ウィジェットの使用を開始する。

次の演習では、この新規ハンドラーをアプリケーションに組み込みます。

< 前へ | 次へ >

フィードバック