プログラムの働き
上下左右のキーで移動し、プレスして図形を描いていく。 |
このiアプリは、上下左右のキーで描画位置を移動し、選択キーで描画をします。使用する色は、ソフトキーを使って白・赤・緑・青・黒をローテーションして選択します。
描画した図形は、iアプリを終了する際に自動的にスクラッチパッドに保存されます。そして次にiアプリを起動したとき、スクラッチパッドからデータを読み込み、前回の図形を再現するようになっています。
描画やキー操作による選択の移動などは、前回作成したプログラムの応用ですからだいたいわかるでしょう。問題は、スクラッチパッドへの保存と、読み込み処理の部分ですね。
スクラッチパッドへの書き出し
では、ソースコードの中から、スクラッチパッド関係の部分を見ていきましょう。まずは、スクラッチパッドへの保存を行うsaveメソッドからです。スクラッチパッドへの保存は、ざっと整理すると以下のような流れで行います。
1.Connector.openOutputStreamを使い、OutputStreamを用意する。
2.OutputStreamの書き出しメソッドを呼び出してデータを出力する。
3.最後にcloseメソッドでOutputStreamを解放する。
これらのうち、OutputStreamの作成とcloseはそれぞれIOExceptionを発生させる場合があるため、例外処理を用意しておく必要があります。では、これを踏まえて、saveメソッドを見ていきましょう。
OutputStream output = null;
まず、OutputStreamを保管する変数を用意しておきます。そして、次のtry内にてインスタンスの生成を行います。
output = Connector.openOutputStream("scratchpad:///0;pos=0");
OutputStreamはopenOutputStreamメソッドを呼び出して作成しますが、この時の引数は以下のように指定することになっています。
"scratchpad:///ポインタ位置;pos=読み込み位置"
最初の「ポインタ位置」というのは、開始位置がどのアドレスにあるかを示すものです。通常は「0」すなわち一番先頭に置きます。また「読み込み位置」は、スクラッチパッドのどこから読み込むかを示すもので、これも通常は「0」を指定します。例えば、途中から読み込ませたいときは、この値を変更してやります。
こうして作成されたOutputStreamのメソッドを呼び出すことで、スクラッチパッドへデータを保存することができます。以下がその処理を行っている部分です。
for(int i = 0;i < 30;i++)
for(int j = 0;j < 30;j++)
output.write(data[i][j]);
ここで呼び出している「write」メソッドは、引数に指定したint値を1バイトの値としてスクラッチパッドに書き出します。注意してほしいのは、「1バイトの値」という点です。1バイト、すなわち0~255の範囲の値しか書き出すことはできないわけです。ここでは、保存するのは0~4の整数ですので、writeで十分役に立ちます。ただし、255以上の値を扱う場合には、別のメソッドを使用する必要があるでしょう。
最後に、closeでストリームを解放すればすべての作業は終わりです。スクラッチパッドというと、ちょっと特殊なもののように感じますが、基本的なストリームによるファイルアクセスなどが頭に入っていれば、それほど難しいものではありませんね。
スクラッチパッドからの読み込み
続いて、スクラッチパッドからデータを読み込むloadメソッドについて見ていきましょう。データの読み込みは、InputStreamを利用します。これも処理の流れを整理しておくことにしましょう。
1.Connector.openInputStreamを使い、InputStreamインスタンスを作成する。
2.InputStreamのメソッドを呼び出し、スクラッチパッドからデータを読み込む。
3.読み込み処理が終わったら、closeを呼び出しストリームを解放する。
では、実際にloadの処理の流れを見ていきましょう。まず、あらかじめInputStreamを保管するための変数を用意しておきます。
InputStream input = null;
続いて、try内でストリーム作成を行います。
input = Connector.openInputStream("scratchpad:///0;pos=0");
Connector.openInputStreamを呼び出してInputStreamを作成しています。引数には、"scratchpad:///0;pos=0"と指定をしていますね。この指定は、openOutputStreamの場合とまったく同じです。
for(int i = 0;i < 30;i++)
for(int j = 0;j < 30;j++)
data[i][j] = input.read();
そして、データの書き出しのときとまったく同じようにして、InputStreamの「read」を呼び出して読み込んだデータを配列に収めていきます。このreadは、スクラッチパッドから1バイトデータを読み込み、それをint値として返すものです。
最後にcloseでストリームを解放して、作業完了です。基本的な流れは保存の処理とほとんど同じですから、それほど悩むことはないでしょう。
スクラッチパッドへのアクセスでもっとも注意しておきたいのは、「読み込みと書き出しの値の順序」です。保存したときと読み込むときで取り出す値の順番が変わってしまったりすると、ただしく値が取り出せません。どういう値をどういう順番に保存したかということをしっかり管理する必要があります。
その他の読み書き用メソッド
ここではread/writeを使ってスクラッチパッドに値を保管しましたが、これらは「バイト単位でデータを読み書きする」ものです。このため、0~255範囲内の整数しか保存することができません。もっと他の値も保存できないと、スクラッチパッドの実用性はかなり落ちてしまいますね。
もちろん、そうしたメソッドもちゃんと用意されています。主な読み書き用メソッドについて、以下に整理しておきましょう。
●書き出し用メソッド
[OutoutStream].writeShort( [short値] );
[OutoutStream].writeInt( [int値] );
[OutoutStream].writeLong( [long値] );
[OutoutStream].writeBoolean( [boolean値] );
●読み込み用メソッド
short 変数 = [InputStream].readShort();
int 変数 = [InputStream].readInt();
long 変数 = [InputStream].readLong();
boolean 変数 = [InputStream].readBoolean();
これで、主な整数値と真偽値については読み書きできるようになります。スクラッチパッドは、だいぶ拡張されたとはいえ無限に使えるものではありませんから、バイト単位で済むものはread/writeを使い、それ以外のものは必要に応じて上記のメソッドを利用する、と考えておくとよいでしょう。