カレンダ時計

  1. カレンダ時計

    1. 目的

      日付と時刻を表示します。1秒ごとに表示を繰り返すため、スレッドを利用します。
    2. スレッド

      1. スレッドとは
        時刻を更新するには、一定時間間隔で表示を更新する必要があります。しかし、次の1秒間描画変化するまで繰り返しループで待つのは、プロセッサの無駄です。本体とは別に並列処理するプログラム:スレッド を起動し、そこから、定期的に「描き直し」のイベントを出すことにします。実は、アプレットも一つのスレッドとして動作します。スレッドが別のスレッドを作成するころになります。

      2. スレッドの組み込み
        アプレットでスレッドを組み込むには、インターフェースを利用します。先頭の
         public class digwatch extends Applet
        に続けて次のように implements Runnable を付加します。これで、スレッド機能が利用できるようになります。
         public class digwatch extends Applet implements Runnable
        次に、スレッドの宣言をします。クラス宣言の次に
         Thread w_clock ;
        を追加します。本当は、スレッドクラスのThreadを用いて
        public class digwatch extends Applet , Thread
        としたいところですが、Javaでは複数のクラスの継承(extends)ができません。そこで、Threadの別形式であるRunnable(インタフェースといいます)を用いて、これをimplementsで組み込みます。
        アプレットとは別のクラスで、Treadを単独で組み込むことは可能です。こちらの例を参照してください。

      3. スレッドの起動
        次に、init()メソッドの最後で、スレッドを生成し起動します。スレッドの生成は
          w_clock = new Thread(this);
        です。thisは自分(この場合、Applet1クラス)の意味でスレッドを生成したオブジェクトを知らせます。。スレッドを起動するのは start() メソッドを実行する必要があります。
         w_clock.start();
        で、スレッドが実行を開始します。

      4. run()
         スレッドの処理は run() メソッド で制御します。run()ではまず、repaint()で再描画を要求し、sleep(1000)で1000m秒休止します。休止後再び、repaint() で再描画を要求します。これで、時計の表示が更新されます。スレッドは1秒間に1度repaint()を出すだけで、他の時間はお休み(sleep)しています。本体のアプレットも、1秒に一度表示をするだけで、他は何もすることがないので、開店休業状態です。
         なお、Thread.sleep(1000); の外側のtryとcatchは、エラー処理を行う仕掛けです。ここでは、特にエラー処理をしていませんが、一部のメソッドではこのエラー処理がないと、「try節がありません」とコンパイラーが注意をします。

      5. スレッドの必要性
         sleep() を実行すると、そのスレッドは一切のメッセージも受け付けなくなります。したがって、GUI 部品をもつ Applet で sleep を行うことはできません。別の スレッド を起動し、そこで sleep を実行する必要があります。

    3. 時刻の取得

      日付と時刻情報の取得は簡単です。
       Date w_date;
       w_date = new Date();
      で、w_dateに日付と時刻情報が取得できます。Dateを利用するには、先頭で
       import java.util.*;
      が必要です。

  2. プロジェクトの作成

    1. ソース

       digwatch.java を作成して下さい。

      //digwatch.java
      import java.awt.*;
      import java.awt.event.*;
      import java.applet.*;
      import java.util.*;
      
      public class digwatch extends Applet implements Runnable
      {
      
        Thread w_clock = null;
        Date w_date;
      
        /**アプレットの初期化*/
        public void init() {
          //スレッドの起動
          w_clock = new Thread(this);
          w_clock.start();
        }
      
        public void paint(Graphics g) {
          g.setColor(Color.darkGray);
          g.fillRect(0,0,200,60); //背景を塗る
          g.setColor(Color.green);//  緑色でテキストの色を設定
          w_date = new Date();
          g.drawString(w_date.toString(), 10, 30);
        }
      
        public void run() {
         while (true) {
           // 再描画
           repaint();
           try
           {
            Thread.sleep(1000);
            }
            catch(Exception e) {}
           }
          }
      }

       >javac digwatch.java
      で、digwatch.classを作成します。

    2. html

      また、以下の html ファイルを作成し、digwatch.html とします。ブラウザでdigwatch.htmlを開くと、ディジタル時計が表示されます。

      <HTML>
      <HEAD>
      <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
      <TITLE>
      HTML テストページ
      </TITLE>
      </HEAD>
      <BODY>
      ディジタルカレンダ時計です。<BR>
      <APPLET
        CODEBASE = "."  CODE = "digwatch.class"
        NAME     = "TestApplet"  WIDTH    =230  HEIGHT   = 60 > </APPLET>
      </BODY>
      </HTML>

    3. プログラム

      1. init():初期設定されるメソッド(関数)
        アプレットでは、ブラウザから起動されるとき、最初に初期化する関数 init() が呼び出されます。このメソッドは自動生成されます。このメソッドで、後から説明するスレッドを起動します。

      2. paint():表示
        アプレットの画面に表示を行う関数です。
        new Date(); で時刻情報を取得します。次に、g.setColor(Color.darkGray);で背景をdarkGrayに設定し、g.fillRect(0,0,240,60) で塗りつぶしてます。240,60 は背景のサイズです。
         次に、g.setColor(Color.green);で表示の文字の色をgreenとし、
         g.drawString(w_date.toString(), 10, 30); 
        で、時刻の文字w_dateを(10,30)の位置から表示します。
        グラフィックの詳細は、別の項目で詳しく説明します。

    4. 実行例

      アプレットによりカレンダ時計を表示します。



  3. アニメーション


    1. 壁で跳ね返るボール

      スレッドを利用してアニメーションを行います。スレッドを利用して再表示をするとき、位置の移動を行います。

    2. 手法

       ボールの位置を nowx, nowy とします。再描画するたびに、一定値 gox,goy を加えます。
         nowx += gox;
         nowy += goy;
       ただし、ボールが表示枠の右、左に達したら、gox の符号を変えて、移動方向を逆にします。これが「跳ね返り」になります。
         if(nowx > this.getWidth() - 8 || nowx < 0)
          gox = -gox;
       ここで、this.getWidth() は枠(アプレットウインドウ)を示します。上下方向にも同様な処理が必要です。
      また、背景色は setBackground(Color.yellow); で黄色に指定できます。 setForeground(Color.orange) では、前景色(表示するモノの色:この場合オレンジ)が指定できます。

    3. ソース


      import java.applet.*;
      import java.awt.*;
      
      /*
      <applet code="ballmove" width="100" height="100"></applet>
      */
      
      public class ballmove extends Applet implements Runnable{
      
       int gox = 2;//動く距離
       int goy = 2;
       int nowx,nowy;//現在地
      
       Thread move;
       boolean go = false;
      
       public void init(){
        nowx = this.getWidth()/2;//中心から開始
        nowy = this.getHeight()/2;
      //色の設定
      //  setBackground(Color.white);//背景
        setBackground(Color.yellow);//背景
      //  setForeground(Color.blue);//前景
        setForeground(Color.orange);//前景
      
        go = true;
        move = new Thread(this);//スレッド生成
        move.start();
      
       }//init
      /*
       public void start(){
        go = true;
        move = new Thread(this);//スレッド生成
        move.start();
       }//start
      */
       public void run(){
      
        while(go){
      
      //端まできたら折り返す
         if(nowx > this.getWidth() - 8 || nowx < 0)
          gox = -gox;
         if(nowy > this.getHeight() - 8 || nowy < 0)
          goy = -goy;
      
      //現在の座標に移動分を加える
         nowx += gox;
         nowy += goy;
         repaint();//再描画
         try{
          Thread.sleep(250);
         }
         catch(Exception e){
          go = false;
         }
        }//while
       }//run
      
       public void paint(Graphics g){
        g.fillOval(nowx,nowy,8,8);//円を描く
       }//paint
      
      }

    4. 実行

      スレッドでボールを動かします。


  4. 演習・課題・アンケート

     
    1. 演習

      ディジタル時計で、表示色を変更してください。
      ボールが壁で跳ね返りながら動くアニメーションプログラムを作成してください。

    2. スレッド

      スレッドは多くの言語やOSで利用される概念です。webでスレッドを検索し、調べてください。

    3. 課題

      時刻を文字盤と針(アナログ時計)で表示してください。
      提出期限 6月26日 
      提出先 指定フォルダ

    4. アンケート

      1:スレッドの役割は理解できました  1:できた 2:多分  3:わからん
      2:ディジタル時計  1:実行できた 2;できない
      3:色変更 1:できた 2:できない
      4:アナログ時計 1:できる 2:多分できる  3:よくわからん