ソフトウェア演習 B GUI を持つ Java プログラムの 設計と実装
4.1 例題 :GUI を持った電卓を作ろう プロジェクトCalculator パッケージ名 :example ソースファイル : Calculator.java GUI.java EventProcessor.java 2
4.2 GUI とイベント処理 GUI の構成 :Swing GUI の場合 フレーム JFrame: コンポーネントのコンテナ コンテンツペインテキストフィールト JTextField パネルJPanel パネルJPanel ボタンJButton getcontentpane(): フレームからコンテンツペインを取り出す コンテンツペインにレイアウトマネージャを設定する. FlowLayout, BorderLayout, GridLayoutなど コンテンツペインにコンポーネントを配置する. JPanel, JButton, JTextFieldなど JPanelパネルに描画する ( 内部クラス利用 ). paintcomponent(graphics g) 3
インタフェース : 抽象的な共通動作仕様 ( 抽象メソッドとクラス定数 ) の集まり public interface インタフェース名 [extends スーパインタフェース名 [, ]] { public static final 型変数名 = 初期値 ; // 任意個記述可能 public 型メソッド名 ([ 引数並び ]); // 任意個記述可能 ( 例 )java.awt.event.actionlistener public interface ActionListener extends EventListener { public void actionperformed(actionevent e); インタフェースの実装 [public] class クラス名 implements インタフェース名 [, ] { public 型メソッド名 ([ 引数並び ]) { // インタフェースに含まれるメソッドの定義 // インタフェースに含まれるすべての // メソッドを定義しないといけない ( 例 ) public class EventProcessor implements ActionListener { public void actionperformed(actionevent evt) { 4
イベント処理の方法 : 委任イベントモデル イベントソースにイベントリスナーオブジェクトを登録. イベントリスナーオブジェクトは, イベントリスナーインタフェースを実装したクラスのインスタンスで, インタフェースで定められたイベント処理メソッドを実装している. イベントソースは, イベント発生時にそれをイベントリスナーオブジェクトに送信. イベントリスナーはイベントを解析して処理する. add イベント Listener( イベントリスナーオブジェクト ) GUI イベントリスナー登録 イベントリスナー implements イベント Listener イベント解析 イベントソース ( 例 : ボタン ) イベント イベント処理メソッド イベント処理 5
( 例 ) public class GUI extends JFrame { public void initgui(eventprocessor eventprocessor) { for(int i=0; i<5; i++) { for(int j = 0; j < 4; j++) { int p = i * 4 + j; button[p] = new JButton(buttonName[p]); buttonpanel.add(button[p]); button[p].addactionlistener(eventprocessor); public class EventProcessor implements ActionListener public void actionperformed(actionevent evt) { JButton b = (JButton)evt.getSource(); String value = b.gettext(); ボタンのイベントリスナーとして eventprocessor を登録 ActionListener インタフェースを実装して EventProcessor のインスタンスをリスナーオブジェクトとする ActionListener インタフェースの抽象メソッド actionperformed() の実装定義でイベント処理 6
4.3 電卓のイベント処理ロジック 7
4.4 Eclipse で電卓アプリケーションの UML クラス図と Java プログラムを作成 新規 Java プロジェクトの作成 プロジェクト名 :Calculator UML のクラス図を格納するフォルダを作成 フォルダ名 :uml Java プログラムを格納するパッケージを作成 名前 :example クラス図エディターを起動 クラス図フォルダ名 :example.cld ここまでが終了した状態のウインドウ 8
クラス図を作成 9
3 つのクラス Calculator.java, GUI.java, EventProcessor.java を作成 javax.swing.jframe java.awt.event.actionlistener [ 参照 ] をクリックして, Jframe と入力し一致する項目を選択 [ 追加 ] をクリックして, ActionListener と入力し一致する項目を選択 10
ソースコードエディターを用いて Calculator.java のコードを書く 11
ソースコードエディターを用いて GUI.java のコードを書く メソッド GUI コンポーネントの変数宣言 12
GUI コンポーネントの配置 ボタンを押したときに発生するイベントのリスナーを eventprocessor とする 13
ソースコードエディターを用いて EventProcessor.java のコードを書く メソッド 計算実行用の変数宣言 14
ボタンを押したときに発生するイベントを処理するイベントリスナーメソッド 15
( 再 ) public class GUI extends JFrame { public void initgui(eventprocessor eventprocessor) { for(int i=0; i<5; i++) { for(int j = 0; j < 4; j++) { int p = i * 4 + j; button[p] = new JButton(buttonName[p]); buttonpanel.add(button[p]); button[p].addactionlistener(eventprocessor); public class EventProcessor implements ActionListener public void actionperformed(actionevent evt) { JButton b = (JButton)evt.getSource(); String value = b.gettext(); ボタンのイベントリスナーとして eventprocessor を登録 ActionListener インタフェースを実装して EventProcessor のインスタンスをリスナーオブジェクトとする ActionListener インタフェースの抽象メソッド actionperformed() の実装定義でイベント処理 16
コンパイル 実行 コンパイル : プログラムを保存すると自動的にコンパイルされる. 実行 :Calculator.java を右クリックして現れるメニューから [ 実行 ]-[Java アプリケーション ] を選択. 17
4.5 例外処理 例外処理とは : 実行中に起こる例外的な事象 ( 特別な状態, エラー ) への対 処を, 正常な実行の流れとは分けて記述すること. 例外の種類 Throwable Exception Error ClassNotFoundException CloneNotFoundException IllegalAccessException InstantiationException InterruptedException NoSuchFieldException NoSuchMethodException IOException RuntimeException RuntimeException 以外のException 系例外 : 実行環境や実行状態に応じて発生する例外で, 例外の発生を捉えてそれに対処する例外処理コードを書かないといけない. RuntimeException 系例外 : シンタクス的には正しいが実行が正しくできない実行時エラー. デバッグで対処することが多い.( 不正なキャスト,nullオブジェクトアクセス等 ) Error 系例外 :Java 実行系の内部エラーやリソースの不足を示す回復不可能な重大エラー. デバッグで対処. 18
例外処理の方法と構文 メソッドの実行中に起こった例外の発生を呼び出し側に通知 throws: メソッドが例外を発生させる可能性があることを宣言する throw: メソッド内で例外を発生させる 型メソッド名 ([ 引数並び ]) throws 例外名 { throw new 例外名 (); ( 例 ) public static double valueof(string s) throws NumberFormatException { throw new NumberFormatException(); public String readline() throws IOException { throw new IOException(); ( 註 ) コンストラクタからも例外の発生を呼び出し側に通知できる. 19
通知された例外を呼び出し側で捉えて正常な実行の流れから離れて対処 try: 例外を発生させる可能性があるメソッドが例外を発生させたか検査する catch: メソッドが発生させた例外を捉えてそれに対処する finally: 例外発生の有無に関わらず共通に行う事後処理を記述する try { // 例外を発生させる可能性のあるメソッド呼び出し catch( 発生可能な例外名 1 変数 ) { // 例外 1 に対する処理 [ catch( 発生可能な例外名 n 変数 ) { // 例外 n に対する処理 ][finally { // 例外発生の有無に関わらず必ず実行する処理 ] 20
( 例 ) try { currentvalue = (Double.valueOf(ownerGUI.getDisplayFieldText())).doubleValue(); catch(numberformatexception e) { inputbuffer.delete(0, inputbuffer.length()); ownergui.setdisplayfieldtext(inputbuffer.tostring( )); return; try { reader = new BufferedReader(new FileReader(messageFile)); String line; while((line = reader.readline())!= null) array.add(line); catch(ioexception e) { message = new String[1]; message[0] = " メッセージファイルの読み込みに失敗しました."; sizeofmessage = 1; return message; finally { if(reader!= null) try { reader.close(); catch(ioexception e) { メソッドに通知された例外を try-catch 構文で捉えずに, その例外をそのメソッドの呼び出し側に伝播することもできる 型メソッド名 ([ 引数並び ]) throws 例外名 { 例外名の例外を通知する可能性のあるメソッド呼び出し ; 21
4.6 演習問題 1 Java.lang.Math クラスには各種の数学関数メソッドが定義されている. a. 絶対値を求める関数, 三角関数, 平方根を求める関数, べき乗を求める関数を調べよ. b. x,yを実数とするときそれらを引数として受け取り次の計算をする2つのメソッドを書け. また, そのメソッドにx=5, y=4を引数として渡して計算を行い結果を出力するプログラムを書け. (1) 2 2 x + y (2) x ( 1+ sin x + cos x ) 2 Java.lang.Math に定義されている数学関数メソッドのから 4 個 ( 以上 ) を選んで, それらの関数計算ができるように電卓プログラムを関数電卓プログラムに拡張せよ. 22