テンプレートで学ぶJavaアプリのグラフィックの基本携帯アプリを作って学ぶJava文法の基礎(6)(3/3 ページ)

» 2008年06月16日 00時00分 公開
[緒方聡エスマテック株式会社]
前のページへ 1|2|3       

コラム 「DoJaとMIDPで異なる描画のタイミングと制御」

テンプレートでは、DoJaもMIDPもCanvasクラスを使用しています。Canvasクラスは、以下のような仕組みで描画を行います。

図6 DoJaとMIDPのCanvasのrepaintの仕組み 図6 DoJaとMIDPのCanvasのrepaintの仕組み

アプリケーションからCanvasクラスのインスタンスに描画を行わせるには、Canvasクラスのrepaintメソッドを呼び出すことによってCanvasクラスのインスタンスはそのうちpaintを実行します。このように、描画をCanvasクラスのインスタンス任せにすると、アプリケーションの期待するタイミングで描画が行えません。描画のタイミングをアプリでコントロールするには、MIDPなら以下のように行います。

図7 MIDPのCanvasのserviceRepaintsの仕組み 図7 MIDPのCanvasのserviceRepaintsの仕組み

repaintメソッドの後に、続けてserviceRepaintsメソッドを呼び出すことで、即座にpaintが実行されます。そして、serviceRepaintsはpaintが終わるまで呼び出しが返ってきません。このようにして、MIDPでは描画タイミングを制御します。では、DoJaではどうでしょうか。

図8 DoJaのGraphicsのlockとunlock 図8 DoJaのGraphicsのlockとunlock

DoJaでは、MIDPのserviceRepaintsに相当するメソッドがCanvasクラスに用意されていないため、CanvasクラスのインスタンスからgetGraphicsメソッドでグラフィックスコンテキストを取得し、そこに直接描画を行い、描画タイミングを制御します。グラフィックスコンテキストは必要がなくなったらdisposeしますが、今回のテンプレートではずっと使うのでdisposeはしていません。


DoJaでは、このようにして描画タイミングを制御します。


iアプリのキー入力処理 DoJa

 テンプレートでは、Canvsクラスを使っているので、キー入力を受け付けるのもCanvsクラスのインスタンスです。その入力をプログラムから取得して処理したい場合は、Canvsクラスのメソッドをオーバーライドします。要するに、Canvsクラスで定義されているメソッドをもう一度定義し直す、ということです。

 DoJaのCanvsクラスでキーイベントが通知されるのは、processEventメソッドです。

22     public void processEvent(int type, int param) {
23         if (type == Display.KEY_PRESSED_EVENT) {
24             if (Display.getCurrent() == this) {
25                 Dialog dialog = new Dialog(
                       Dialog.DIALOG_INFO, "Information");
26                 dialog.setText("button has been pushed");
27                 dialog.show();
28             }
29         }
30     }

 22行目でprocessEventメソッドをオーバーライドしています。

 引数のtypeでイベントのタイプが判定できるので、23行目でキーが押されたときだけ処理するようにif文で場合分けしています。

 24行目からは、画面に表示されているのがCanvsクラスのインスタンスなら、ダイアログを作成して表示させています。ダイアログの動作は、すでに動画で見てもらっていると思います。

MIDPアプリのキー入力処理 MIDP

 テンプレートでは、Canvsクラスを使っているのでキー入力を受け付けるのもCanvsクラスのインスタンスです。その入力をプログラムから取得して処理したい場合は、Canvsクラスのメソッドをオーバーライドします。要するに、Canvsクラスで定義されているメソッドをもう一度定義し直す、ということです。

 MIDPのCanvsクラスでキーイベントが通知されるのはいくつかありますが、今回はキーが押された場合に通知されるkeyPressedメソッドを使用します。

27     protected void keyPressed(int keyCode) {
28         if (Display.getDisplay(TemplateMIDlet.this)
           .getCurrent() == this) {
29             Display.getDisplay(TemplateMIDlet.this)
                   .setCurrent(new Alert("Information",
                   "button has been pushed", null,
                   AlertType.INFO), this);
30         }
31     }

 27行目でkeyPressedメソッドをオーバーライドしています。

 28行目からは、画面に表示されているのがCanvsクラスのインスタンスなら、アラート画面を出す処理を行っています。アラートの動作はすでに動画で見てもらっていると思います。

移植性を考慮して

 今回は、DoJaとMIDPのそれぞれのテンプレートとその解説を行いました。解説中にはさまざまな個所に移植を考慮した説明を織り交ぜました。

 初めはDoJaで、またはMIDPで作成し、後からMIDPへ、またはDoJaへ移植する、ということはよくある話です。最初から移植することを計画に入れて作成するのと、まったく考えずに作成するのでは、移植作業に掛かる手間が全然違ってきます。

 この連載の題材アプリである連載第1回「あなたの携帯電話でJavaアプリは動きますか?」でデモした、テトリスみたいなゲーム「Trimis」のアプレット版もそうですが、今回紹介したテンプレートも移植性を十分に考慮して作ってあります。もっともっと移植性を高くするテクニックはあるのですが、それは本連載の範囲を超えてしまうので、以下のコラムで少しだけ紹介します。

コラム 「移植性を高めるためには?」

アプリの移植性を高めるためには、移植が必要な個所を呼び出しているクラスの「ラッパークラス」を作るのが効果的です。

例えば、今回の例では、GraphicsクラスのsetColorやdrawStringの仕様がDoJaとMIDPで違っていると説明しました。これらは以下の疑似コードのようにします。

// 独自のグラフィックスコンテキストラッパーのインスタンスを生成
MyGraphics g = new MyGraphics(offi.getGraphics());

……【省略】……

g.setColor(COLOR_WHITE); // RGBのintを渡す
g.drawString(time, 0, 0); // 文字列とx座標とy座標を渡す

MyGraphicsは以下のようにします(DoJaのsetColorの場合)。

class MyGraphics {
    Graphics stub;
    public MyGraphics(Graphics g) {
        stub = g;
    }

    public void setColor(int argb) {

……(省略)…….

        stub.setColor(Graphics.getColorOfRGB(r, g, b));
    }
}

こうした具合に、行いたい処理で呼び出し方が違うところを共通の呼び出し方にして、本来の呼び出しを行うのはその内部に集約するということを行えば、アプリケーションのソースコードから移植が必要な個所がなくなります。ただし、アプリケーションを作っているんだか移植用ライブラリを作っているんだか分からないような状態にならないように、注意してください。


そして、最も効果的な移植性を高める方法は、移植先にない機能は使用しないということを徹底することです。GraphicsのsetColorなら、DoJaでは半透明をサポートしていますがMIDPではサポートしていないため、半透明か移植かどちらが大事なのかを検討し、場合によっては半透明をあきらめるということを行うのです。



前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。