KVM for Palmチュートリアル
- Beta Version 1.0対応、2000年4月5日版 -

     
KVM for Palmとは?

J2ME CLDC

Java 2プラットフォームの仕様には、サーバ環境向けのEnterprise Edition(J2EE)、デスクトップ環境向けのStandard Edition(J2SE)、そして組み込み機器向けのMicro Edition(J2ME)の3つの仕様グループがあります。J2MEについてはさらに、ネットワーク情報機器用のConnected Device Configuration(CDC)と、CPU能力やメモリ容量が制限された携帯ネットワーク情報機器用のConnected, Limited Device Configuration(CLDC)の2つの基本ライブラリ構成が、標準化活動(Java Community Process)によって策定されつつあります。PalmプラットフォームのJavaは、このJ2ME CLDC仕様に準拠した最初のJavaになる予定です。

MIDP

J2ME CLDC仕様に準拠したJava対応製品としては、携帯電話やページャ、携帯情報端末(PDA)などが各社によって計画されています。CLDC仕様は、さまざまな製品ジャンルに共通する基本ライブラリ仕様を定義したものであり、ユーザインタフェースなどの詳細な仕様は、Mobile Information Device Profile(MIDP)と呼ばれるプロファイルとして上位のレイヤで規定されることになっています。すなわち組み込み機器のJava仕様は、Edition、Configuration、Profileの3つのレイヤからなる仕様の組み合わせによってはじめて完全に定まることになります。

KVM

KVM(K Virtual Machine)は、J2ME CLDC仕様との組み合わせで使用することが想定されている新しいJavaの実行環境(Java仮想マシン)で、Kバイトオーダー(64K〜128K程度)のメモリで動作することからそのように呼ばれています。現時点では、Palm、Solaris、Windowsの3つのプラットフォームについて、リファレンス実装のEarly Access版をSunから入手することができます。

KJava

JavaOne '99では、KVMのプロトタイプ実装であるKJavaがプリインストールされたPalm Vが参加者に低価格で提供されて話題になりました。KJavaはJavaOneでのデモストレーション用に用意されたバージョンにすぎないため、J2ME CLDC仕様とは大きく異なっている部分もあり、また実装の完成度も決して高いものではありませんでした。

Spotless

KVMのプロトタイプ実装としては、この他にSpotlessと呼ばれるシステムがSun Labsによって公開されています。SpotlessはKJava開発のベースになったシステムです。このため両者は多くの共通点をもっていますが、動作アプリケーションや開発ツールには残念ながら互換性がありません。

KVM for Palm

このチュートリアルでは、Palmプラットフォームで動作するJ2ME CLDC/KVM対応アプリケーション(以下、単にKVMアプリケーションと称する)を作成する手順を説明します。説明とプログラムサンプルは、2000年3月27日にリリースされたBeta Version 1.0に対応しています。以前のバージョンに対応した説明については、過去のチュートリアル(Version 0.1対応版またはVersion 0.2対応版)をご参照ください。

開発キットをセットアップする

ダウンロード

KVMのソフトウェア開発キットは、SunのJava Developer Connectionサイト(はじめて利用する場合は、利用者としての登録が必要)のEarly Accessのページからダウンロードすることができます。

J2ME CLDC Beta Version 1.0

指示にしたがってダウンロードすると、j2me_cldc-1_0-beta-palm.zip(2,082,141バイト)というアーカイブファイルが得られます。KVMアプリケーションに必要なファイルはすべてこのアーカイブにまとめられています。

フォルダ構成

j2me_cldc-1_0-beta-palm.zipアーカイブファイルを展開すると、KVMの開発キットは、bindoclibsrcの計4つのフォルダから構成されていることがわかります。このフォルダ(以降は、KVMフォルダと呼ぶ)を適当な場所に移動すれば、開発キットのセットアップは完了です。

HotSyncでプログラムをインストールする

ファイル構成

Palmマシンにインストールするファイルは、binフォルダにまとめられています。この中のKVM.prcがJava実行環境とクラスライブラリ、KVMutil.prcがユーティリティで、この2つのファイルは必ずインストールしなければなりません。kvm.exepreverify.exeはWindowsで動作する開発用ツール(kvmpreverifyはSolaris用)ですから、Palmマシンにはインストールしません。.prcの拡張子をもつ他のファイルは、すべてデモアプリケーションです。

HotSync

Palm Desktop(Mac OSの場合はHotSync Manager)を起動して、アプリケーションのインストールリストにKVM.prcファイルとKVMutil.prcファイルを追加します。サイズも大きくないので、とりあえずデモアプリケーションもすべてインストールしておくとよいでしょう。

ファイルの追加が完了したら、HotSyncを実行します。これでKVMのJava実行環境の準備が整いました。

デモアプリケーションを動かしてみる

KVMアイコン

KVMとデモアプリケーションをインストールすると、右図のようなアイコンが表示されます。JavaのマスコットであるDukeのアイコンがついているのが、KVMのJava実行環境とユーティリティです。

KVMのアイコンをタップするとはじめにライセンス条項が表示され、「Accept」ボタンをタップするとKVMutilのオプション設定画面が表示されます。ここでは最大ヒープメモリサイズを指定したり、実際に割り当てられたヒープメモリサイズをアプリケーションの起動時に表示するように設定したりすることができます。なお、このオプション設定の画面は、KVMのアイコンとKVMutilアイコンのどちらをタップした場合にも表示されます。

デモアプリケーション

デモアプリケーションは、それぞれのアイコンをタップすることによって起動します。起動するとDukeの画像が表示され、初期化のために数秒間待たされます。

右図は、フラクタル図形を表示するデモアプリケーション、Dragonを実行しているところです。

Hello Worldプログラムを作成する

Spotletクラス

プログラムのソースファイルは任意の場所に作成すれば良いのですが、ここではKVMフォルダにprojectsフォルダを新規に作成し、その中に以下の内容のHelloWorld.javaファイルを作成することにします。KVMアプリケーションは、この例のようにSpotletクラスをサブクラス化することにより定義します。

import com.sun.kjava.*;

public class HelloWorld extends Spotlet {
    Graphics g = Graphics.getGraphics();

    public static void main(String[] args) {
        (new HelloWorld()).register(NO_EVENT_OPTIONS);
    }

    public HelloWorld() {
        g.clearScreen();
        g.drawString("Hello, world!", 50, 50, g.PLAIN);
    }

    public void penDown(int x, int y) {
        System.exit(0);
    }
}

コンパイル

作成したソースファイルをコンパイルするには、作業ディレクトリをprojectsフォルダに移動して、以下のようにjavaコマンドのコマンドラインを入力します(ここではCドライブにKVMフォルダをセットアップしたと仮定しています)。

> cd C:\kvm\projects
> mkdir classes
> javac -bootclasspath C:\kvm\lib\classes -d classes HelloWorld.java

Mac OSの場合は、javacアプリケーションにHelloWorld.javaファイルをドラッグ&ドロップします。そしてjavacの設定フィールドに以下のように入力し、「Do Javac」ボタンをクリックします(ここではMac OSボリュームにKVMフォルダをセットアップしたと仮定しています)。

Source files:       /Mac OS/KVM/projects/HelloWorld.java
Destination folder: /Mac OS/KVM/projects/classes
Classpath:          /Mac OS/KVM/lib/classes.zip

検証とテスト

次に作成したクラスファイルを検証します。デスクトップ環境のJavaでは、Java仮想マシンによって実行時に検証がおこなわれますが、J2ME CLDC環境では、実行時の負担を軽くするために検証プロセスは2段階に分けておこなわれます。すなわち、preverifyツールによって事前に生成したスタックマップ情報をクラスファイルに追加することによって、少ないメモリ容量でも実行時の検証ができるようにしています。

クラスファイルを事前検証するには、以下のようにpreverifyコマンドのコマンドラインを入力します。これによってclassesフォルダ内のクラスファイルが検証され、検証済のクラスファイルがoutputフォルダに作成されます。

> C:\kvm\bin\preverify -classpath C:\kvm\lib\classes classes

こうして作成したクラスファイルは、kvmコマンドを利用してテスト実行することができます。kvmコマンドは、後述するPalm OS Emulatorのような本格的なエミュレータではありませんが、簡易的な動作確認には非常に便利です。

> C:\kvm\bin\kvm -classpath output HelloWorld

Mac OSの場合は、現時点ではコマンドツールが提供されていないため、検証とテストをおこなうことはできません。

コンバージョン

クラスファイルをPalmマシンで扱えるようにするためには、最終的にはPRC形式に変換する必要があります。このコンバージョンをおこなうためのMakePalmAppクラスは、classesフォルダのpalm.databaseパッケージに格納されています。以下のようにjavaコマンドのコマンドラインを入力すると、HelloWorld.classファイルからHelloWorld.prcファイルを生成することができます。

> java -classpath C:\kvm\lib\classes palm.database.MakePalmApp
  -bootclasspath C:\kvm\lib\classes -classpath output HelloWorld

Mac OSの場合は、JBinderyアプリケーションにHelloWorld.classファイルをドラッグ&ドロップします。そしてJBinderyの設定フィールドに以下のように入力し、「Run」ボタンをクリックしてください。

Command Panel
    Class name:          palm.database.MakePalmApp
    Optional parameters: -bootclasspath /Mac OS/KVM/lib/classes
                         -classpath output HelloWorld
Classpath Panel
    Addtions to class path: $CLASSPATH
                            /Mac OS/KVM/lib/classes

projectフォルダに生成されたHelloWorld.prcファイルをHotSyncでPalmマシンにインストールすれば、他のデモアプリケーションと同様にHelloWorldプログラムを実行することができます。

スクリーンの任意の場所をタップするとHelloWorldプログラムは終了します。

アプリケーションプログラムの作成方法とオプションの詳細については、docフォルダ内のtools.htmlファイルにまとめられていますので、一度目を通しておくとよいでしょう。

Palm OSエミュレータを利用 する

POSE

KVMで動作するアプリケーションを開発するときに、作成中のプログラムをその都度Palmマシンにインストールして動作テストをしていたら大変手間がかかります。そこで、Palmの開発ツールのひとつであるPalm OS Emulator(POSE)を利用することをお勧めします。

ダウンロード

POSEは、3Com/Palm Computingの開発者サイトからダウンロードすることができます。POSEにはWindows用(4,889,680バイト)とMac OS用(5,169,641バイト)があり、どちらも最新版はバージョン3.0a4となっています。

Palm OS Emulator Version 3.0a4

インストール

ダウンロードしたファイルを展開すると、エミュレータプログラムのEmulator.exe(Mac OSの場合はPalm OS Emulator)やドキュメントフォルダなどから構成されるフォルダが得られます。このフォルダを適当な場所に移動すれば、インストールはほぼ完了です。

ROMイメージの作成

最後に自分が使用しているPalmマシンのROMイメージファイルを作成します。ROMイメージファイルのは、POSEに付属のROM Transfer.prcファイルをPalmマシンにインストールしてからPOSEを起動し、「File」メニューの「Transfer ROM」コマンドを実行して指示に従うだけで簡単に作成することができます。

日本語を表示する

日本語文字列

KVMでは、日本語の文字列をそのままdrawString() メソッドに与えても正しく表示することができません。これはKVMがUnicodeの文字列処理をサポートしていないためです。ところが以下 の例のように、Shift JISの漢字コードをcharの2文字に分割したものを使うと日本語を表示することができます。

import com.sun.kjava.*;

public class HelloJapan extends Spotlet {
    Graphics g = Graphics.getGraphics();

    public static void main(String[] args) {
        (new HelloJapan()).register(NO_EVENT_OPTIONS);
    }

    public HelloJapan() {
        char message[] = { 0x0082, 0x00cd, 0x0082, 0x00b6, 0x0082,
            0x00df, 0x0082, 0x00c4, 0x0082, 0x00cc, 0x0093, 0x00fa,
            0x0096, 0x007b, 0x008c, 0x00ea };
        g.clearScreen();
        g.drawString(new String(message), 50, 50, g.PLAIN);
    }

    public void penDown(int x, int y) {
        System.exit(0);
    }
}

コンパイルから実行まで

プログラムのコンパイルから実行までの手順は、HelloWorldプログラムの場合と同じで、以下のようにjavaコマンドのコマンドラインを入力するとHelloJapan.prcファイルを作成することができます。

> cd C:\kvm\projects
> javac -bootclasspath C:\kvm\lib\classes -d classes HelloJapan.java
> C:\kvm\bin\preverify -classpath C:\kvm\lib\classes classes
> java -classpath C:\kvm\lib\classes palm.database.MakePalmApp
  -bootclasspath C:\kvm\lib\classes -classpath output HelloJapan

Mac OSの場合も、HelloWorldと同一の手順でコンパイルとコンバージョンをおこないます。

コンバージョンが完了したら、POSEにインストールして動作を確認してみることにしましょう。POSEを起動して「File」メニューの「Install Application/Database」コマンドを実行し、作成したHelloJapan.prcファイルを選択します。これでKVMアプリケーションがPOSEにインストールされていますので、実行してみてください。

スクリーンの任意の場所をタップするとHelloJapanプログラムは終了します。

イメージを表示する

Bitmapクラス

KVMには、イメージを扱うためのクラスとしてBitmapクラスが用意されています。ところがBitmapクラスのインスタンスは、GIF形式やJPEG形式のイメージファイルから生成することができないので、ビットマップデータのバイト列を直接与えることによって生成しなければなりません。

classesフォルダのpalm.databaseパッケージに格納されているBitmapクラスは、Windowsビットマップファイル(BMP形式ファイル)からこのビットマップデータのバイト列を出力するためのツールです。例えば、DukeIcon.bmpファイルからdukeBitmapという名前の変数としてDukeIcon.txtファイルにビットマップデータを生成するには、以下のようにjavaコマンドのコマンドラインを入力します。

> java -classpath C:\kvm\lib\classes palm.database.Bitmap
  DukeIcon.bmp -dump dukeBitmap DukeIcon.txt

Mac OSの場合は、JBinderyの設定フィールドに以下のように入力して、「Run」ボタンをクリックしてください。

Command Panel
    Class name:          palm.database.Bitmap
    Optional parameters: DukeIcon.bmp -dump dukeBitmap DukeIcon.txt
Classpath Panel
    Addtions to class path: $CLASSPATH
                            /Mac OS/KVM/lib/classes

イメージの描画

以下は、KVMのアイコンでもあるDukeのイメージ(24 X 24ピクセル)から出力したビットマップデータ(ボールドで表示された部分)を使った簡単なプログラム例です。

import com.sun.kjava.*;

public class DukeImage extends Spotlet {
    Graphics g = Graphics.getGraphics();
    Bitmap dukeBitmap = new Bitmap((short)4, new byte[] {
        // File DukeIcon.bmp;  size: 24x24
           0,    0,    0,    0,   24,    0,   24,    0,
          14,    0,   56,    0,   15,    3,   48,    0,
           7, -125,   -2,    0,    7,  -63,   -2,    0,
           7,  -32,  -16,    0,    7,  -15,   -8,    0,
           6,  -79, -104,    0,    5,   90,    0,    0,
           6,  -90,    0,    0,   13,  -58,    0,    0,
          56,    2,    0,    0,   72,    2,    0,    0,
          40,    1,    0,    0,   16,    1,    0,    0,
          48,    1,  122,    0,   48,    0,  -82,    0,
          48,    0,  -86,    0,  112,  -32, -128,    0,
          35,   16,  -86,    0,   36,   89,   84,    0,
          26,  -82,  -86,    0,    0,    0,    0,    0
    });

    public static void main(String[] args) {
        (new DukeImage()).register(NO_EVENT_OPTIONS);
    }

    public DukeImage() {
        g.clearScreen();
        g.drawBitmap(68, 68, dukeBitmap);
    }

    public void penDown(int x, int y) {
        System.exit(0);
    }
}

生成したイメージを表示するには、GraphicsクラスのdrawBitmap()メソッドを使用し、描画始点の座標とBitmapオブジェクトを指定して描画をおこないます。

プログラムのコンパイルから実行までの手順は、これまでの例題とほとんど同じなので、これ以降の説明では省略することにします。

Dukeのアイコンが表示できることを確認したら、スクリーンの任意の場所をタップしてプログラムを終了します。

データの入出力

Databaseクラス

Palm OSにおけるデータの入出力は、ファイルシステムではなく簡単なデータベースの機能を使って実現されています。KVMからデータベースの機能を利用するには、Databaseクラスを使います。

Databaseクラスを利用してデータを出力するには、はじめにcreate()クラスメソッドによってテータベースを作成します。このときに、英字4文字からなるタイプとクリエータを整数値で指定する必要があります。一方、データベースからデータを入力するときには、このタイプとクリエータを指定することによって、特定のアプリケーションの特定のデータにアクセスすることができます。例えば、タイプとして"DATA"、クリエータとして"memo"を指定してDatabaseクラスのインスタンスを生成すると、メモ帳のデータをオープンすることができます。

int dbType = 0x44415441;    // "DATA"
int dbCreator = 0x6d656d6f; // "memo"
Database db = new Database(dbType, dbCreator, Database.READONLY);

電話帳プログラム

以下のプログラム例は、Databaseクラスを使って作った簡単な電話帳プログラムです。

import com.sun.kjava.*;

public class PhoneBook extends Spotlet {
    Database db;
    Graphics g = Graphics.getGraphics();
    TextBox textBox;
    TextField textField;
    Button addButton, clearButton, quitButton;

    public static void main(String[] args) {
        (new PhoneBook()).register(NO_EVENT_OPTIONS);
    }

    public PhoneBook() {
        int dbType = 0x44415441;    // "DATA"
        int dbCreator = 0x70686f6e; // "phon"
        db = new Database(dbType, dbCreator, Database.READWRITE);
        if (!db.isOpen()) {
            Database.create(0, "PhoneDB", dbCreator, dbType, false);
            db = new Database(dbType, dbCreator, Database.READWRITE);
        }
        textBox = new TextBox("", 8, 8, 144, 106);
        textField = new TextField("Phone", 5, 122, 150, 10);
        addButton = new Button("Add", 135, 142);
        clearButton = new Button("Clear", 105, 142);
        quitButton = new Button("Quit", 78, 142);
        paint();
    }

    public void paint() {
        g.clearScreen();
        g.drawBorder(5, 5, 150, 112, g.PLAIN, g.SIMPLE);
        StringBuffer buffer = new StringBuffer();
        int records = db.getNumberOfRecords();
        for (int i = 0; i < records; i++)
            buffer.append(new String(db.getRecord(i))).append('\n');
        textBox.setText(buffer.toString());
        textBox.paint();
        textField.paint();
        addButton.paint();
        clearButton.paint();
        quitButton.paint();
        textField.setFocus();
    }
    
    public void keyDown(int keyCode) {
        textField.handleKeyDown(keyCode);
    }
    
    public void penDown(int x, int y) {
        if (addButton.pressed(x, y)) {
            String text = textField.getText();
            if (text.length() > 0) {
                textField.loseFocus();
                db.setRecord(db.getNumberOfRecords(), text.getBytes());
                textField.setText("");
                paint();
            }
        } else if (clearButton.pressed(x, y)) {
            textField.loseFocus();
            int records = db.getNumberOfRecords();
            while (records-- > 0)
                db.deleteRecord(records);
            paint();
        } else if (quitButton.pressed(x, y)) {
            db.close();
            System.exit(0);
        }
    }
}

このプログラム実行すると、最初に"PhoneDB"という名前のデータベースが作成され、プログラム終了後もそこに入力した電話番号のデータが保存されます。

電話番号を登録するには、 テキストフィールドに情報を入力して「Add」ボタンをタップします。また、「Clear」ボタンをタップすると、これまでに登録した電話番号がすべて削除されます。

プログラムを終了するときは、「Quit」ボタンをタップしてください。

© 1999, 2000 Jun Fujisawa. All rights reserved.

[Home | Mailing List | Tutorial]