Report6
		Day :2003/12/08
                ID  :035740F
		Name:根保光秀
		!!!  This Page Is Made By Shift JIS  !!!




   1.偶数奇数判定プログラム(GUIaa)をタイプし、その動作を考察せよ。
  2.例外処理について、考察せよ。
   3.上記のサンプルプログラムに出てきたGUI部品を、全て使ったプログラムを作成せよ。
   4.摂氏から華氏、華氏から摂氏への温度換算ができるプログラムを作成せよ。
   5.「電卓」プログラム。中身は自分の思うように。




もくじ

1.GUIaaの考察

2.例外処理

3.GUIプログラム

4.温度換算プログラム

5.電卓

6.反省・感想













1.偶数奇数判定プログラムの考察
○プログラム
[Mi:eclipse/workspace/rep#6] j03040% java List GUIaa.java
File name:GUIaa.java
 1:import java.awt.*;       //java.awtを読み込む
 2:import java.awt.event.*; //java.awt.eventを読み込む
 3:
 4:public class GUIaa extends Frame {  //Frameを継承
 5:    Button    b0 = new Button("Even/Odd?");   //GUI部品"Button"を生成&初期化
 6:    Label     x0 = new Label("Type a number and press...");//GUI部品"Label"
 7:    TextField t0 = new TextField();      //GUI部品"TextField"を生成&初期化
 8:    
 9:    public GUIaa() {          //コンストラクタ
 10:        setLayout(null);     //部品の自動配置機能をoffにする
 11:        add(t0); t0.setBounds(10, 40, 90, 30);    //TextFieldを貼付け
 12:        add(b0); b0.setBounds(110, 40, 80, 30);   //Buttonを張り付け
 13:        add(x0); x0.setBounds(10, 80, 180, 30);   //Labelを張り付け
 14:        b0.addActionListener(new ActionListener() {    //無名クラス、イベント
 15:            public void actionPerformed(ActionEvent evt) {
 16:                int i = (new Integer(t0.getText())).intValue();    //"TextField"の内容を読みこむ
 17:                t0.setText("");   //TextFieldを初期化
 18:                if(i % 2 == 0) {  //iが2で割り切れる(偶数)なら
 19:                    x0.setText(i + " is Even");  //"Label"にEvenと表示
 20:                } else {      //2で割り切れない(奇数)なら
 21:                    x0.setText(i + " is Odd");  //"Label"にOddと表示
 22:                }
 23:            }
 24:        });
 25:    }
 26:    public static void main(String[] args) {   //mainメソッド
 27:        Frame win = new GUIaa();                  //インスタンス生成
 28:        win.setSize(200, 150); win.setVisible(true);  //表示するウインドウのサイズを指定
 29:        win.addWindowListener(new WindowAdapter() {  //無名クラス&イベント
 30:            public void windowClosing(WindowEvent evt) { //ウインドウを閉じるときのイベント
 31:                System.exit(0);   //プログラムを終わる       
 32:            }
 33:        });
 34:    }
 35:} 

実行結果


考察
import java.awt.*;
1行目でGUIの部品を使うために必要なjava.awtを読み込んでいます。
import java.awt.event.*;
2行目でイベントを処理するために必要なjava.awt.eventを読み込んでいます。
5:6:7:行で、Frame内のButton,Label,TexeFieldを生成&初期化しています。
11:12:13:行で、上記のGUI部品を画面に貼付けています。
14:行はGUIプログラムの独特な書き方です、後で詳しく説明します。
簡単に説明すると、『ボタンが押された』事をプログラムが判断する時にこう書きます
15:〜24:行は、無名クラスと呼ばれる書き方です、後で詳しく説明します。
ここは、14:で『ボタンが押された』時の処理を書いておく所です。
26:行からは今まで通りのmainメソッドです。
27:行でGUIaaのオブジェクトを生成する
28:行setSizeも後々説明しますが、その名前の通りサイズを設定しています。
setVisibleは画面に表示するかしないかを指定します。
29:行も新しくでてきた文法です、簡単に説明すると『ウインドウを閉じた』時 をプログラムが判断しています。
30:行も新しく出てきた文法です、System.exit(0);でプログラムを終了させています。


新しく出てきた所

GUIプログラム

GUIとは、ユーザーインターフェースの手法の一つで
アイコンやボタン等を使ってコンピューターを操作する方法の事です。
初心者でも操作が分かりやすいという特徴があります。
この『アイコンをクリックした』『ボタンを押した』等の操作をイベントと言います。
GUIプログラムは、このイベントを受け取って初めて、処理を行います。
このようなプログラムのスタイルをイベント駆動型と言います。

javaでGUIプログラムを作るためには、3つのクラスが必要です。
(1)イベントを認識するクラス
(2)イベントに関するデータが格納されるクラス
(3)イベントが起きた時にどのような処理をするかを定義したクラス

(1)はFrameクラスやButtonクラスなどGUI部品(GUIコントロール)です。
(2)はEventクラス(サブクラス)です。
(3)はこのイベントが起きた時はこう言う処理をするという事を定義しておくListener系クラス(サブクラス)です。

(1)
GUIコントロールを扱う時にはjava.awtパッケージを読み込まなければなりません。
それが一行目の import java.awt.*です。こうする事でGUIコントロールが使用可能になります。
GUIコントロールにはButtonのほかに以下のような物が用意されています。
Eventに用意されているフィールド
動作
Checkbox チェックボックスを作る
チェックボックスとは、tureまたはfalseのどちらかの状態をとる
Label ラベルを作る
ラベルとは、テキストを表示させるところです
List リストを生成する
リストとは、いくつかのテキストを表示するものです。
Menu メニューを生成する
メニューは、メニューバーに表示されるボタンのようなもの
TextField テキストフィールドを生成する
テキストフィールドは、ユーザーが一行のテキストを編集できるところです。

このGUIコントロールをクリックしたりするとGUIコントロールは
イベントを確認して処理を行います。

(2)
発生したイベントのデータを格納するクラスが必要です。
それが二行目のimport java.awt.event.* です。
awt.eventには以下のようなフィールドが用意されています。
主なGUIコントロール
動作
KEY_PRESS ユーザーが普通のキーを押した
LIST_SELECT リストの項目が選択された
MOUSE_DOWN ユーザがマウスボタンを押した
clickCount MOUSE_DOWNイベントの場合、連続したクリックの数を示します。

イベント処理をする時には,(1),(2)は最初から用意されているので
そのまま使う事ができます、しかし(3)のイベントがおこった時にどのような処理をするかは
自分で処理を記述したクラスを作らなければいけません。

(3)
javaはGUIコントロールでイベントがあると、そのコントロールと関連づけされた
イベント処理用のクラスのメソッドが呼び出されるます。
このイベント処理用のクラスのメソッドを呼び出すためにListenerというインターフェースがあります。
Listenerにはいろいろな種類があります。マウスに関係するものや、キーボードに関するものがあります。
Listenerインターフェース名
動作
実装するメソッド名
ActionListener アクションイベントを受け取る actionPerformed(ActionEvent e)
MouseListener マウスイベントを受け取る mouseClicked(MouseEvent e)
mouseEntered(MouseEvent e)
mouseExited(MouseEvent e)
mousePressed(MouseEvent e)
mouseReleased(MouseEvent e)
KeyListener キーボードイベントを受け取る keyPressed(KeyEvent e)
keyReleased(KeyEvent e)
keyTyped(KeyEvent e)
WindowListener ウインドウイベントを受け取る windowClosed(WindowEvent e)
windowClosing(WindowEvent e)
windowDeiconified(WindowEvent e)
windowIconified(WindowEvent e)
windowOpened(WindowEvent e)

メソッドの働き
メソッド名
動作
actionPerformed(ActionEvent e) アクションが発生すると呼び出される
mouseClicked(MouseEvent e)
mouseEntered(MouseEvent e)
mouseExited(MouseEvent e)
mousePressed(MouseEvent e)
mouseReleased(MouseEvent e)
マウスがクリックされると呼び出される
コンポーネットにマウスが入ると呼び出される
コンポーネットからマウスが出ると呼び出される
マウスボタンが押されると呼び出される
マウスボタンが離されると呼び出される
keyPressed(KeyEvent e)
keyReleased(KeyEvent e)
keyTyped(KeyEvent e)
キーを押している時に呼び出される
キーを離した時に呼び出される
キーを押した時に呼び出される
windowClosed(WindowEvent e)
windowClosing(WindowEvent e)
windowDeiconified(WindowEvent e)
windowIconified(WindowEvent e)
windowOpened(WindowEvent e)
ウインドウがクローズされた時に呼び出される
ウインドウをクローズしようとした時に呼び出される
アクティブウインドウじゃなくなったら呼び出される
ウインドウが最小化された時に呼び出される
ウインドウが最初に可視になった時に呼び出される

と上記のListenerインターフェースを実装して、イベント処理用のクラスを作ります。

イベントを処理するときに読み込むインターフェースはあらかじめ用意されていますが
その中に含まれるメソッドはそのプログラムごとで定義したい。

そのようなクラス・メソッドの事をabstract、抽象クラス・メソッドと言いました。
だから、上記のリスナーインターフェースを実装した場合は
各メソッドを必ずオーバーライドしなければなりません。

ActionListenerの場合、メソッドはactionPerformed()だけなので別に問題はありませんが
MouseListenerやWindouListenerの場合だとメソッドがたくさんあるので
使わないメソッドまでオーバーライドしないといけなくなってしまいます。
例 MouseListnerの場合
class Ke inplements MouseListener{
  void mouseClicked(MouseEvent e){System.out.println("Click!!");}
  void mouseEntered(MouseEvent e){}
  Void mouseExited(MouseEvent e){}
  void mousePressed(MouseEvent e){}
  void mouseReleased(MouseEvent e){}
} 

というように、使うもの以外のメソッドも定義しなければいけません
これを解消するために、次項の~Adapterがあります。

○Adapter
~Adapterクラスは〜Listenerクラスを実装しています。
これを継承すれば、意味のない定義をする必要がなくなります。

AdapterクラスもListenerも同じ役割をします。継承できるならばAdapterを使って
何かほかのクラスを継承したいならListenerを使ったほうが良いです。

javaではGUIコントロールでイベントがおこると
そのコントロールと関連付けされたクラスのメソッドをを呼び出します。
しかし、クラスを作っただけでは関連付けはされません。
そこで、各クラスを関連づけるためにAdd~Listenerメソッドが用意されています。

○Add~Listener
コントロールにリスナクラスを関連づけるためにAdd~Listenerが用意されています。
文法は例えば、WindowListenerを関連づける場合は
AddWindowListner(WindowListener(サブクラス)のインスタンス)とします。
関連付けには、Listenerクラス自体を関連づけるのではなくて、
Listenerクラスのインスタンスを関連づける事に注意します。


○無名クラス
無名クラスとは、定義とインスタンス化を同時に行う手法です。
プログラムの中の一か所でしかインスタンスを生成しないクラス。
わざわざきちんとしたクラスを宣言するのが面倒な時に使うクラスです。
しかし、複数のオブジェクトがある処理には向きません

宣言方法はnewを使って宣言しなければなりません。
具体的には→new 名前() { 変数定義  メソッド定義 }







2.例外処理
○プログラム
[Mi:eclipse/workspace/rep#6] j03040% java List ColorRGBa.java
File name:ColorRGBa.java
 1:/*
 2: * @day    :2004/01/03
 3: * @author :j03040
 4: * @ST-ID  :035740F
 5: */
 6:import java.awt.*;
 7:import java.awt.event.*;
 8:
 9:public class ColorRGBa extends Frame {     //Frameを継承
 10:    Button      b0 = new Button("Display");          //Bottonを生成&初期化
 11:    Label[]     la = new Label[]{new Label ("Red"),      //Labelを生成&初期化
 12:                                 new Label ("Green"),    //Labelを配列で生成
 13:                                 new Label ("Blue")  };
 14:    TextField[] ta = new TextField[]{new TextField(),    //TextFieldを生成&初期化
 15:                                     new TextField(),
 16:                                     new TextField()};
 17:    Label       x0 = new Label("Input RGB values [0..255]");  //Labelを生成&初期化
 18:    
 19:    public ColorRGBa() {
 20:            setLayout(null);                         //自動配置機能をoff
 21:            for(int i = 0; i < la.length; i++) {     //配列で宣言したGUI部品の張り付け
 22:                    add(la[i]); la[i].setBounds(10, 40 + i*40, 60, 30);
 23:                    add(ta[i]); ta[i].setBounds(80, 40 + i*40, 60, 30);
 24:            }
 25:            add(b0); b0.setBounds(10, 160, 60, 30);       //Buttonの張り付け
 26:            add(x0); x0.setBounds(10, 200, 180, 30);      //Labelの張り付け
 27:            b0.addActionListener(new ActionListener() {   //ボタンが押されたときの処理 
 28:                    public void actionPerformed(ActionEvent evt) {
 29:                            try {                         //例外処理Try~catch文
 30:                                    x0.setBackground(new Color(  //ラベルの背景の色を変える
 31:                                            (new Integer(ta[0].getText())).intValue(),
 32:                                            (new Integer(ta[1].getText())).intValue(),
 33:                                            (new Integer(ta[2].getText())).intValue()));
 34:                            } catch(Exception ex) { x0.setText(ex.toString()); }
 35:                    }
 36:            });
 37:    }
 38:    public static void main(String[] args) {
 39:            Frame win = new ColorRGBa();       //ColorRGBaのインスタンス生成
 40:            win.setSize(200, 250); win.setVisible(true);   //可視にしてサイズを設定
 41:            win.addWindowListener(new WindowAdapter() {   //Window関係のイベントを処理
 42:                    public void windowClosing(WindowEvent evt) {  //ウインドウを閉じる時の処理
 43:                            System.exit(0);  //プログラムを終了させる
 44:                    }
 45:            });
 46:    }
 47:} 

○実行結果


Red,Green,Blueの値を入力して、Labelの色を変えるというプログラムです。
もし、入力された色の値が255を超えていたら例外処理を行います。
ここでの例外処理はおこったエラーをラベルに表示させています。

○例外処理の考察

例外処理とは、、、
プログラム実行時のエラーを処理するための手段です。
例外処理は問題が発生した時に発生します。
主な例外↓
エラー名
原因
ArithmeticException 数値演算のエラー
例、 0でわり算etc....
ArrayIndexOutOfBoundsException 配列の範囲を超えたアクセス
例、 配列a[1000000] etc.....
NullPointerException Nullポインタへの不正なアクセス
アプリケーションがNullを使おうとすると発生
NumberFormatException 数字以外のものを数値に変換
例、数字を入力するTextFiledにひらがなを入力
FileNotFoundException I/Oエラー
ファイルの入出力で発生
ClassNotFoundException 呼び出そうとしたクラスファイルがなかった時に発生
DataFormatException データ形式にエラーがあった場合に発生
NegativeArraySizeException 負のサイズを持った配列があった時に発生
例, 配列a[-2] etc....


上記のようなエラーが発生した場合、それを処理するために
Try~Catch文が用意されています。
Try~Catch文の使い方は、
エラーが起こりうるプログラムをtryで囲んで
エラーが発生した時の処理をcatchで囲むって感じです。
具体的には、上記のプログラムの29~36行です。
try{
        エラーの起こりうるプログラム

   }catch{
        エラーが起こったときの処理
   }


○例外処理のサンプルプログラム
[Mi:eclipse/workspace/rep#6] j03040% java List extest.java
File name:extest.java
 1:/*
 2: * @day: 2004/01/03
 3: * @author j03040
 4: * @ST-ID  035740F
 5: */
 6:public class extest {
 7:     public static void main(String[] args) {
 8:             System.out.println("Make Error!!");
 9:             System.out.println(Error());
 10:    }
 11:    public static int Error(){
 12:                    int total=0,e1=0;
 13:                    int abc[]={0,1,2,3};
 14:                    //Error1 ArithmeticException 
 15:                    total=100/e1;
 16:                    //Error2 ArrayIndexOutOfBoundsException 
 17:                    for(int i=0;i<=100;i++){
 18:                            total+=abc[i];
 19:                    }
 20:                    return total;
 21:    }
 22:}

上記のプログラムは、わざとエラーが起こるように作ってあります。
しかし、コンパイルしてもコンパイラはエラーを発見しません
それでは早速実行してみましょう、すると
[Mi:eclipse/workspace/rep#6] j03040% java extest
Make Error!!
Exception in thread "main" java.lang.ArithmeticException: / by zero
        at extest.Error(extest.java:15)
        at extest.main(extest.java:9)
と実行して初めて、エラー発見されます、そのうえプログラムを終了しています。
エラーが起こるとアプリケーションが終了するのは困ります。
こんな時にはプログラムを作りなすか例外処理をしなければいけません
今回は例外処理のtry~catchを使って強引にプログラムを完成させます。
上記のプログラムで発生するエラーは
1.ArithmeticException---------------演算エラー
2.ArrayIndexOutOfBoundsException ---配列エラー
と言うのが分かっているのでcatchでそれぞれのエラーを検出して
そのエラーの時の処理を付け加えれば良いので上記プログラムを書き換えればOK
○書き換えたプログラム
[Mi:eclipse/workspace/rep#6] j03040% java List extest.java
File name:extest.java
 1:/*
 2: * @day: 2004/01/03
 3: * @author j03040
 4: * @ST-ID  035740F
 5: */
 6:public class extest {
 7:     public static void main(String[] args) {
 8:             System.out.println("Make Error!!");
 9:             System.out.println(Error());
 10:    }
 11:    public static int Error(){
 12:             try{        //
 13:                    int total=0,e1=0;
 14:                    int abc[]={0,1,2,3};
 15:                    //Error1 ArithmeticException 
 16:                    total=100/e1;
 17:                    //Error2 ArrayIndexOutOfBoundsException 
 18:                    for(int i=0;i<=100;i++){
 19:                            total+=abc[i];
 20:                    }
 21:                    return total;
 22:             }catch(ArithmeticException e){   //catch 演算エラーを検出したら
 23:                    System.out.println("0で割ったらダメさ〜");
 24:             }catch(ArrayIndexOutOfBoundsException e){  //catch 配列エラーを検出したら
 25:                    System.out.println("配列そんなにないよ〜"); 
 26:             }
 27:             return 0;
 28:    }
 29:}


12行目にtryを足して
22〜からcatchでエラーを検出しています。
○実行結果↓
(1)
[Mi:eclipse/workspace/rep#6] j03040% java extest
Make Error!!
0で割ったらダメさ〜 
0

e1の値を1にして実行してみると
(2)
[Mi:eclipse/workspace/rep#6] j03040% java extest
Make Error!!
配列そんなにないよ〜
0


となりす、こうする事でたとえエラーが怒ってもプログラムは終了しません。
これが例外処理をする理由の一つです。
実行結果をよく見てみると(1)では演算エラーが検出されたあと18行目は実行されてない事が分かります
これは、エラーが発生した部分より下の部分は実行されずにcatchブロックにジャンプするからです。