Report#8(Java)

Java Appletプログラミング Java Applet/AWTについて学び、Java Appletのオリジナルプログラムを作成し解説せよ。


<<夕日が沈むプログラム>>

【Yuuyake.java】

import java.applet.Applet;
import java.awt.*;

public class Yuuyake extends Applet implements Runnable{

    boolean is_on = false;                     //まずbooleanで、is_onを偽とする

    int Red=45;                                //太陽の色Red,Green,Blueの初期値
    int Green=190;
    int Blue=240;
    int er=2,eg=2,eb=2;                        //Red,Green,Blueの1度に変化する数値(2ずつ変化)
    
    int x=0,y=0;                               //太陽の中心の座標(x,y)=(0,0)
    double d=0.0;                              //太陽の軌跡の移動角度d=0から始める

    Image sea,sea2;                            //海の画像
    Image hosi,hosi2,hosi3,hosi4,hosi5;        //星の画像
    Image offs;                                //オフスクリーン

    Thread th=null;                            //スレッド

    public void init(){                        //initメソッド
        setBackground(Color.white);            //背景を白に設定
    }
    
    public void start(){                       //メソッド start() を用意してスレッドを始める
        if(th==null){
            th=new Thread(this);               //新しいスレッド生成
	    th.start();
	}
    }
    
    public void stop(){                //メソッド stop() を用意してスレッドをストップさせる
        th=null;                       //threadがnullのとき
        is_on = false;                 //is_onが偽のとき
    
	sea.flush();                   //flush()
	sea2.flush();
	hosi.flush();
	hosi2.flush();
	hosi3.flush();
	hosi4.flush();
	hosi5.flush();
	offs.flush();
	sea = null;                    //画像がnullのとき
	sea2 = null;                   //     〃
	hosi = null;                   //     〃
	hosi2 = null;                  //     〃
	hosi3 = null;                  //     〃
	hosi4 = null;                  //     〃
	hosi5 = null;                  //     〃
	offs = null;
    }
    
    public void update(Graphics g){              // updateメソッド
        paint(g);
    }
    

    public void drawSun(Graphics g, int a, int b){   //太陽の描き方
    
        double r=30.0;                            // double で r を30に設定
	final double RAD=Math.PI/180.0;           //ラジアンを設定をする
	double s=0.0;                             // double で s を0.0に設定
	
	
	for(int i=0; i<=180; i++){                // i を180になるまで1ずつ増やす 
            double ang1=90.0+s;
	    double ang2=90.0-s;
			                          //計算が大変(;_;)
	    int x1=(int)(Math.cos(ang1*RAD)*r);   //コサインを使って → x1はcos((90+s)*RAD)*30
            int x2=(int)(Math.cos(ang2*RAD)*r);   //コサインを使って → x2はcos((90-s)*RAD)*30
	    int y1=(int)(Math.sin(ang1*RAD)*r);   //サインで → y1はsin((90+s)*RAD)*30
	    int y2=(int)(Math.sin(ang2*RAD)*r);   //サインで → y2はcos((90-s)*RAD)*30
			 
	    g.setColor(new Color(255,185-i,0));   //setColorで色を設定する
	    g.drawLine(x1+a,b-y1,x2+a,b-y2);      //drawLineでラインを描く
			                          //それぞれの座標が変化していくからきれいな色ができます
	    s=s+1.0;
	}
    }
			 
  public void taiyou(Graphics g, double dd){         //太陽を描くメソッド
	final double RAD=Math.PI/180.0;              //ラジアンを設定する

        x=(int)(Math.cos((90.0-dd)*RAD)*180)-55;     //コサインを使ってxに代入
        y=200-(int)(Math.sin((90.0-dd)*RAD)*180);    //サインを使ってyに代入

        drawSun(g,x,y);                              //太陽を描く
    }

    public void paint(Graphics g){                   //コンポネートを描画するメソッド
        if(is_on){
            if(offs != null){                        //offsがnullではないとき〜
                Graphics og=offs.getGraphics();
                try{
                    paintSky(og, Red, Green, Blue);          //背景を描く
                    taiyou(og,d);                            //太陽を描く
                    og.drawImage(sea,0,150,this);            //海を描く座標(x,y)=(0,150)
                    if(Red<20){                              //Redが20より小さくなったら
	                og.drawImage(hosi,50,50,this);       //drawImageで星を貼り付け
                        og.drawImage(hosi2,80,20,this);      //        〃
                        og.drawImage(hosi3,130,0,this);      //        〃
                        og.drawImage(hosi4,1,10,this);       //        〃
                        og.drawImage(hosi5,170,45,this);     //        〃
                    }

                    if(Red<45){
                        og.drawImage(sea2,0,150,this);        //drawImageで海を貼り付け
                    }

                    g.drawImage(offs,0,0,this);              //オフスクリーンのとき
                }
                catch(NullPointerException e){               //例外をcatchする
	        return;
                }

                {
                    og.dispose();
                }
           }
        }

        {
            g.drawString("Sun goes down...",10,20);          //drawStringで文字列を並べる。
                                                             //座標(x,y)=(10,20)
        }
    }

    public void paintSky(Graphics g, int Red2, int Green2, int Blue2){    //背景を描くメソッド

        int dr=1,dg=1,db=1;                             //上から下へRed,Blue,Greenを1ずつ変化させる

        for(int i=0; i<200; i=i+2){                     //2ピクセルずつ色を変える

            g.setColor(new Color(Red2,Green2,Blue2));   //setColorで色を指定
            g.drawLine(0,i,200,i);
            g.drawLine(0,i+1,200,i+1);

            Red2=Red2+dr;                        //Redは1足していく
            Green2=Green2+dg;                    //Greenは1足していく
            Blue2=Blue2-db;                      //Blueは1減らしていく

            if(Red2>=255) Red2=255;              //Redは255になったらストップ
            if(Green2>=254) dg=-1;               //Greenは254になったら1減らしていく
            if(Green2<=0) Green2=0;              //1減らして0になったらストップ
            if(Blue2<=0) Blue2=0;                //Blueは0になったらストップ
        }
    }

    public void run(){                                //runメソッド

        sea=getImage(getCodeBase(),"sea.jpg");        // getImage で画像を取得
        sea2=getImage(getCodeBase(),"sea2.jpg");      //        〃
        hosi=getImage(getCodeBase(),"h10_3.gif");     //        〃
        hosi2=getImage(getCodeBase(),"h10_1.gif");    //        〃
        hosi3=getImage(getCodeBase(),"h10_4.gif");    //        〃
        hosi4=getImage(getCodeBase(),"h10_5.gif");    //        〃
        hosi5=getImage(getCodeBase(),"h10_6.gif");    //        〃
        MediaTracker mt=new MediaTracker(this);       //メディアトラッカー
        mt.addImage(sea,0);
        mt.addImage(sea2,0);
        mt.addImage(hosi,0);
        mt.addImage(hosi2,0);
        mt.addImage(hosi3,0);
        mt.addImage(hosi4,0);
        mt.addImage(hosi5,0);

        try{                                          //メディアトラッカー読み込み
            mt.waitForID(0);
        }catch(InterruptedException e){}

        offs=createImage(200,200);

        is_on = true;
        repaint();                                   //paintを呼ぶ。コンポネートを再描画する。

        Thread thisThread = Thread.currentThread();
        while( Red>0 && th==thisThread ){            //Redが0になるまで繰り返す
         
	    try{
                th.sleep(100);                       //100m/秒ごとに繰り返す
            }catch(InterruptedException e){
                return;
            }

            Red=Red+er;                        //Redは2ずつ増やす
            Green=Green+eg;                    //Greenは2ずつ増やす
            Blue=Blue-eb;                      //Blueは2ずつ減らす

            if(Red>=254) er=-2;                //Redは255になったら2ずつ減らす
            if(Red<=0) Red=0;                  //0になったらストップ
            if(Green>=254) eg=-2;              //Greenは255になったら2ずつ減らす
            if(Green<=0) Green=0;              //0になったらストップ
            if(Blue<=0) Blue=0;                //Blueは0になったらストップ

            d=d+0.5;                           //太陽の位置を0.5度動かす
            if(d>=90.0) d=90.0;                //太陽が山に消えたらその位置のまま

            repaint();                         //paintをよぶ。コンポネートを再描画する。
        }
    }
}

実行結果(夕焼けアプレット)

【考察】

AWT:Abstract Window Toolkit

AWTで使えるコンポーネントは二つに分けられる。自身に他のコンポーネントを追加できるコンテナと、 追加できないコンポーネントです。コンテナ自身もコンポーネントです。 1.トップレベル・コンポーネント 他の部品を追加可能。自分自身は他の部品に追加できない最上位の部品。 例)Window, Dialog, Frame 2.中間コンポーネント 他の部品を追加可能、自分自身も他の部品に追加されうる。 例)Panel,ScrollPane 3.アトミック・コンポーネント 他の部品を追加可能不可能で、自分自身が他の部品に追加されることで使われる。 例)Button, Label, Checkbox, etc.

●java.awtパッケージ

GUIアプリケーションを作成するためのAWT(Abstract Window Toolkit)機能を提供するパッケージ。 AWTはGUIコンポーネントを提供するほか、グラフィックスや画像処理のための機能を定義している。

(java.awtパッケージの主要なインターフェイスとクラスの表)

インターフェイス説明
LayoutManagerレイアウトマネージャの基本機能を定義する。
LayoutManager2LayoutManagerを拡張し、レイアウト制約を持つレイアウトマネージャの基本機能を定義する。
MenuContainerメニュー関連のコンテナの基本機能を定義する。
Adjustable特定の範囲内で調整可能な数値を持つオブジェクトを表す。
ItemSelectable選択可能な項目を持つクラスは、このインターフェイスを実装する。
クラス説明
ComponentAWTコンポーネントのルートになる。
Containerほかのコンポーネントを配置できるコンテナのルートになる。
Panelパネルを表す。
ScrollPaneスクロールペインを表す。
Windowトップレベルウィンドウを表す。
Dialogダイアログを表す。
FileDialogファイルを選択するためのファイルダイアログを表す。
Frameフレームを表す。
Buttonラベル付きのボタンを表す。
Canvas描画領域を提供するキャンバスを表す。
Checkboxチェックボックスを表す。
Choice複数の項目を含む選択範囲を表す。
Labelラベルを表す。
Listスクロールリストを表す。
Scrollbarスクロールバーを表す。
TextComponentテキスト関連のコンポーネントは、すべてこのクラスを拡張する。
TextAreaテキスト領域を表す。
TextFieldテキストフィールドを表す。
CheckboxGroupチェックボックスをグループ化し、ラジオボタンを作成する際に使用する。
MenuComponentメニュー関連のコンポーネントのルートにな る抽象クラスです。
MenuBarメニューバーを表す。
MenuItemメニュー項目を表す。
CheckboxMenuItemチェックボックスを持つメニュー項目を表す。
Menuプルダウンメニューを表す。
PopupMenuポップアップメニューを表す。
Graphicsグラフィックスコンテキストを表す抽象クラス。
Graphics2DGraphics2D機能を提供するためのグラフィックスコンテキスト。
Image画像を表すクラスのルートとなる抽象クラス。
FlowLayoutコンポーネントを左から右に順番に配置するレイアウトマネージャ。
BorderLayout上下左右中央の5つの領域に、コンポーネントを配置する。
GridLayoutコンポーネントを行列形式(格子状)に配置するレイアウトマネージャ。
CardLayoutカードを1枚ずつ表示するように、コンポーネントを配置する。
GridBagLayout制約(GridBagConstraints)を使ってコンポーネントを配置する。
AWTEventAWTイベントはすべてこのクラスを拡張する。
AWTEventMulticasterjava.awt.eventパッケージで定義されるAWTイベントにマルチキャストイベントディスパッチを行うしくみを実装する。
AWTPermissionAWTのアクセス権を表す。
Color色を表す。
Font文字のフォントを表す。
Cursorマウスカーソルを表す。
Point座標空間での位置(x,y)を表す。
ToolkitAWTの実装を表す抽象クラス。

(java.awt.Componentクラス)

画面にGUI部品として表示され、ユーザーとのやり取りを行うコンポーネントを表します。 すべてのGUIコンポーネントのルートとなる抽象クラスです。このクラスは、引数なしの デフォルトコンストラクタだけを提供しています。 <サブクラス> Button、Canvas、Checkbox、Choice、Container、Label、List、Scrollbar、TextComponent <実装インターフェイス> java.awt.image.ImageObserver、MenuContainer、java.io.Serializable

【感想】

ネットに載っていたアプレットのソースをいじってやってみました。 プログラムが長過ぎて、途中で意味がわからなくなったりしてかなり手こずりました。 特に、元のソースを解読するのに時間がかかった。 でも、いじった後ちゃんと実行できてくれたからうれしかったです。 アプレットは、これからも自分で自作アプレットを作っていろいろ試してみたいと思った。

【参考文献・URL】

<浅煎り珈琲〜Java アプリケーション入門> http://msugai.fc2web.com/java/#objective" <JAVA言語入門> http://black.sakura.ne.jp/~third/programming/java/java.html <Java入門> http://www5c.biglobe.ne.jp/~ecb/java/java00.html