6-1 スレッド処理
−ストップウォッチの作成−

練習問題

 まず、本節では次のようなデジタル・ストップウォッチを作成してみましょう。
これは、[開始] ボタンをクリックすると1秒刻みで時刻が進行し、[停止] ボタンを押すと、その進行が停止するというプログラムです。


 まず、上のようなフレームを作成します。C++Builderの場合、さらに Timer コンポーネントをフォームに貼り付けるのですが・・・
Java
にはTimerコンポーネント がありません。

その代わりとしてスレッドというものを用意します。

次に各コンポーネントの Name プロパティを次のように
指定してください。

コンポーネント Name
テキストフィールド jTextField
開始ボタン jButtonStart
停止ボタン jButtonStop


解説・・・

 スレッドとは、Delphi・C++BuilderにあるTimerコンポーネントの役割を果たすものです。
上記でも説明しましたが、JavaにはTimerコンポーネントが在りません。
変わりにスレッド処理を自分で記述するのです。前章で勉強した関数と似たような感じになります。

 それでは、以上を頭に入れておいてプログラミングに入りましょう。
まず、[開始]および[停止]ボタンクリックのイベントハンドラはそれぞれ次の様になります。


 いきなりthというのが出てきましたね。 これはスレッド(タイマー)の名前です。
(付ける名前は自由。わかりやすいようにThreadの頭文字をthにしています。)
スレッド の動作開始は th.start()で始まります。

なお、プログラムの上の部分にスレッドの名前、スレッドを行うという宣言をしなければいけません。
implements Runnable は「スレッド処理をします」という宣言です。
Thread th = null はスレッド(th)の初期化です。

 一方、[停止]ボタンをクリックした時に Timer を停止するのですが、th.stop() と考えますよね? 
しかし、これではプログラムは実行できるのですが、警告が出ます。
昔のバージョンなら実行でき、警告が出ないのですが、今のJavaでは警告が出ます。
 
 理由は、stopを使用すると、実行中の処理を強制終了させるからです。
まだストップウォッチ程度のプログラムなら問題ないのですが、膨大なプログラムなら正しく処理を終了させることが出来ないのです。
なので、終了させるときは th = null とし、スレッドの中でbreakを使用し、プログラムを終了させるのです。

続いて、スレッド処理のイベントハンドラは、次の様になります。

つまり、th.sleep で指定した1秒毎に jTextField の値を1ずつ増やせば良い訳です。これで、完成です。動作を確かめてください。

 このように、スレッド処理 を扱う場合、public void run() 中身(作成)がポイントになります。


基礎課題6−1
上の【練習問題】に[リセット]ボタンをつけ、これをクリックすると初期状態、つまり0秒の状態に戻るようにしてください。

基礎課題6−1の解答


応用課題6−1

【練習問題】を修正して、今度は次の様に制限時間をカウントダウンするタイマーを作成しましょう。
 動作内容は以下の通りです。なお、今の場合 [停止] ボタンは必要ないので削除しました。

今、適当に制限時間を設定します (下の例では10秒)。


[開始] ボタンをクリックするとカウントが開始され、残り時間 (秒数) が減って行きます。そして、残り時間が0となった時点で、
“終了しました!”という
メッセージが現れてプログラムは止まります。



ヒント:run() イベントの処理内容が変わります。その処理内容は次の様になるはずです。

残り時間を1つ (1秒) 減らす

if (残り時間 = 0) '終了しました!' を表示する
スレッドを止める
else 何もしない

応用課題6−1の解答


応用課題6−2
【応用課題6-1】に [リセット] ボタンをつけましょう。動作内容は以下の通りです。
制限時間が経過すると、次の状態になっているはずです。


ここで [リセット] ボタンをクリックすると、次のように、初期画面に戻るようにします。
ここに制限時間 (残り時間) も最初に設定した値 (この例では10秒) に戻るようにしてください。


ヒント:最初に設定した制限時間の値を何らかの変数に格納しておく必要があります。
そしてそれはグローバル変数でなければなりません。
応用課題6−2の解答