ケータイJavaのいろは 第四回 低レベルAPI


IDGジャパン JavaWorld 2001年9月号 に掲載された記事の原文を公開します。 編集の手がかなり加えられて掲載されたため、 雑誌に掲載されたものとは異なる部分があります (無断転載禁止)。

低レベル API UI / 8 パズル / 8 パズル改良版 / コラム / 終わりに / 戻る / トップページ


低レベル API UI

まずは i モード対応 Java プロファイルのユーザーインタフェース API について少し復習しましょう。
 
i モード対応 Java プロファイルには「高レベル API」「低レベル API」 と呼ばれる 2 種類のユーザー・インタフェース API が用意されています。 高レベル API は、連載第二回・第三回とこれまで扱ってきた方法で、 UI コンポーネントを画面に追加することで、 ユーザーインタフェースを実現する API です。 一方、これから扱う低レベル API は自分で画面上への描画・ユーザー操作を 処理する方法で、手間がかかる一方で自由なユーザーインタフェースを 実現することができます。

8 パズル

低レベル API のサンプルとして8パズルを作ってみます (図 1)。 バラバラに並べられた絵のピースを上下左右にスライドさせて、 絵を完成させるパズルです。
 

Puzzle.java

 
画面構成は図 1 のとおりです。 ゲームを開始すると自動でピースがばらばらに並べ替えられます。 上下左右のボタンでピースの空いている位置を移動させ、 全てのピースが正しい位置に並ぶと絵が完成して終了します。
 
このソースファイルが Puzzle.java (リスト 1)、 PuzzleCanvas.java (リスト 2) の二つになります。 また、このサンプルを実行するには前もって KToolbar の 「アプリケーション属性設定」の AppParam キーに「3」を書いておきます。 各ピースの画像として image00.gif 〜 image22.gif の 9 つの画像ファイルも必要となります (図 2)。
 
(図1 Puzzle.java の実行結果 (ゲーム開始直後))
 
(図2 ピース画像)
 

低レベル API の基本

 
高レベル API の話しをした時と繰り返しになりますが、 画面そのものは Display クラス、画面に表示される内容は Frame オブジェクトで表されています。 高レベル API では、Frame クラスのサブクラスである Panel クラスのオブジェクトを setCurrent(Frame frame) クラスメソッドで Display クラスに設定しました。 低レベル API では Frame クラスのサブクラスの Canvas クラスを使います。
 
Canvas クラスは抽象クラスのため、 PuzzleCanvas クラスのように継承して使います。 そして、そのクラスのオブジェクトを setCurrent(Frame frame) クラスメソッドで Display クラスに設定します (リスト 1 の 14, 15 行目)。 i アプリは IApplication クラスを継承したクラスが必要なため、 必然的に少なくとも 2 つのクラスを作ることになります。
 
Canvas クラスを継承したクラスは paint(Graphics g) メソッドを オーバーライドする必要があります (リスト 2 の paint(Graphics g) メソッド)。 paint(Graphics g) メソッドでは画面へ表示する絵や文字の 描画を行う処理を書きます。
 

Graphics

 
画面への描画は paint(Graphics g) メソッドの引数で渡された Graphics オブジェクトを使って行います。 Graphics クラスの使い方は Standard Edition とほぼ同じですが、 ダブルバッファリング機能、色の指定方法が独特です。 それぞれについては後ほど説明します。
 
画像の描画は Standard Edition と同様に drawImage(Image img,int x,int y) メソッドで 描画します (リスト 2 の 101 行目)。 この時に使用する Image オブジェクトは高レベル API の場合と 同様の方法で読み込みます (リスト 2 の loadImage(String file) メソッド)。
 

ダブルバッファリング

 
画面への描画手順がそのまま表示されてしまい、 表示がちらつくことを防ぐ手段としてダブルバッファリングがあります。 これは画像オブジェクト (オフスクリーン画像) に描画を行い、 その画像を画面に書き込む方法です。 ところが、i モード対応 Java プロファイルにはオフスクリーン画像を 作るための手段がなく、その代わりにダブルバッファリング専用の 機能が用意されています。
 
ダブルバッファリングの使用方法は描画前に Graphics オブジェクトの lock() メソッドを呼び出し、 描画後に unlock() メソッドを呼びます。 通常、リスト 2 の 89, 105 行目のように paint(Graphics g) メソッドの始めに lock() メソッドを、 最後に unlock() メソッドを呼べば問題ありません。 携帯電話がダブルバッファリングに対応さえしていれば (脚注:6/24 現在、発売されている全ての機種が対応しています)、 これで表示がちらつくことはなくなります。
 

低レベル API のイベント処理

 
低レベル API を使った UI、すなわち Canvas クラスを使用している場合、 イベント処理はリスナーは使用せず、 processEvent(int type,int param) メソッドをオーバーライドして 処理を書きます (リスト 2 の processEvent(int type,int param) メソッド)。 イベントが発生するとこのメソッドに通知されます。 引数 type にはイベントの種類、 param にはイベントに応じたパラメータ値が渡されます。 イベントの種類は Display クラスの定数で定義されています。
 
このサンプルでも使用しているキーイベントの場合、 キーが押された時は type に Display.KEY_PRESSED_EVENT が、 param にキー番号が渡されます。 キー番号は Display クラスの定数で定義されています。 キーが離された時は同様に type に Display.RELEASED_EVENT、 param にキー番号が渡されます。
 
低レベル API ではソフトキー押下も通常のキー押下イベントで扱います (リスト 2 の processEvent(int type,int param) メソッド)。 ソフトキーのラベルの設定は高レベル API と同じ方法で、 Canvas オブジェクトの setSoftLabel(int key,String label) メソッドを 使います (リスト 2 の 24, 25 行目)。
 

半角カナ文字

 
メールなどインターネットの世界では文字化けの原因となりやすい などの理由から半角カナ文字は使うべきではありませんが、 画面が狭い携帯電話でのアプリケーション、 i アプリなどでは文字数を稼ぐために半角カナ文字を使ったほうが 良い場面もあります。 仕様書に明記はされてはいませんが、半角カナ文字を 問題なく使えるようです。
 
ソフトキーのラベルは全角で 2 文字までしか表示されませんので、 リスト 1 の 41 行目のように半角カナ文字を使うことで より多くの文字を詰め込むことが出来ます。
 

起動パラメーター

 
i アプリには起動パラメーターを渡すことが出来ます。 起動パラメーターは文字列の集まりで、ADF に記述して、 IApplication オブジェクトから getArgs() メソッドで取り出します (リスト 1 の 13 行目)。
 
ADF (jam ファイル) へは AppParam キーに起動パラメーターの 文字列を空白で区切って記述します。KToolbar を使っているのであれば、 「アプリケーション属性設定」ボタンから設定します。
 
このサンプルではピースの横と縦の数を起動パラメーターとして 渡しています。この値を「4」にして、image00.gif 〜 image33.gif の 16 個の画像ファイルを用意すれば 16 パズルになります。 このように起動パラメーターを活用することでプログラムコードの 変更を必要とせずにアプリケーションの動作を変えることが出来ます。
 

i アプリの終了

 
i アプリを終了させるためには IApplication オブジェクトの terminate() メソッドを呼び出しますが、terminate() メソッドは クラスメソッドではないために IApplication クラスの サブクラス以外のオブジェクト、ここでは PuzzleCanvas オブジェクト、 からは呼び出しにくくなります。
 
しかし、IApplication クラスには現在実行中の i アプリの IApplication オブジェクトを取得する getCurrentApp() クラスメソッドが 用意されています。i アプリを終了させたい時にはリスト 2 の 196 行目のように IApplication.getCurrentApp().terminate() とすることで、 IApplication オブジェクトへの参照を保持する必要がなくなり便利です。

8 パズル改良版

次はこの 8 パズルのそれぞれのピースに数字を書いて、 遊ぶときに並べ替えやすくしてみましょう。
 

改良点

 
画面構成は図 3 のとおりになります。ピースの上に数字が書かれており、 ピースの間にも隙間を空けました。 絵が完成したら数字は消えるようにしました (図 4)。
 
見栄えのみを改良するため、リスト 2 の paint(Graphics g) メソッドを 新しい リスト 3 と差し替えます。 その他のコードはリスト 1、リスト 2 のままです。
 
(図3 Puzzle.java の実行結果 (ゲーム開始直後)) (図4 Puzzle.java の実行結果 (パズル完成時))
 

色の扱い

 
先ほども述べましたように、色の扱いは Standard Edition とは 異なりますので、注意が必要です。
 
リスト 3 の 36, 38 行目のように setColor(int c) メソッドの 引数に指定する値は RGB 値ではなく色番号です。 色番号は Graphics クラスの定数から色の名前を表す定数を選び、 クラスメソッド getColorOfName(int name) の引数に渡すことで得ます。 また、クラスメソッド getColorOfRGB(int r,int g,int b) に RGB 値を渡すことでも色番号を得ることが出来ます。 色番号は携帯電話の機種に依存する値なので、 必ずこのようにした取得した値を設定します。
 

フォント

 
Font クラスを使うことでフォントの変更やその大きさを知ることも出来ます。 Standard Edition の AWT の Font クラスと FontMetrics クラスの合わさったものと考えれば良いでしょう。
 
Graphics クラスには Font オブジェクトを取得するメソッドが 用意されていないため、標準のフォントを得るにはリスト 3 の 33 行目のように Font クラスのクラスメソッド getDefaultFont() で Font オブジェクトを取得します。 drawString(java.lang.String str,int x,int y) メソッドで指定する 位置はベースラインの位置なので、 リスト 3 の 34, 35 行目のように Font オブジェクトを使って センタリング位置を算出します。

[コラム]

新しい仕様書と API リファレンス

 
6月25日頃、i モード対応 Java コンテンツ開発ガイド (詳細編、API リファレンス編) の 1.1 版、 API リファレンス JavaDoc 版が NTT ドコモの Web ページ (http://www.nttdocomo.co.jp/i/java.html) で新たに公開されました。 この新しい i モード対応 Java コンテンツ開発ガイドでは、 表記に細かい加筆・修正が行われていますので、 ダウンロードしておくと良いと思います。 また、JavaDoc 形式の API リファレンスは Web ブラウザで参照することが できて非常に便利です。今後はこの API リファレンスを中心に参照して、 なお不明な点がある場合にのみ仕様書を参照すると良いでしょう。 なお、英語版の仕様も公開されました (http://www.nttdocomo.com/i/index.html)。
 

ezplus の仕様公開

 
7 月 4 日、に au (KDDI) の Java 環境である 「ezplus」の仕様が EZweb on the street (http://info.ezweb.ne.jp/index.html) で公開されました。ezplus は CLDC に準拠し、 独自プロファイル「KDDI-P」を採用しています。 KDDI-P は MIDP のサポートに加え (HTTP 接続は未サポートのため、厳密にはMIDP 準拠であるとは言えません)、 ダウンロードした着メロや壁紙などのデータの操作や端末同士の通信である 「Cメール機能」が使用できるなど独自の拡張も施されています。 今後 SDK もリリースされる予定なので、それまでに仕様書を 読んでおいてはいかがでしょうか。

終わりに

今回は低レベル API をサンプルを使って解説しました。 次回は低レベル API でのタイマー処理を扱います。

戻る