ソフトウェア演習B
GUIを持つJavaプログラムの
設計と実装
4.1 例題:GUIを持った電卓を作ろう
プロジェクトCalculator
パッケージ名:example ソースファイル: Calculator.java GUI.java EventProcessor.java
GUIの構成:Swing GUIの場合
4.2 GUIとイベント処理
フレームJFrame:コンポーネントのコンテナ コンテンツペイン getContentPane():フレームからコンテンツペインを取り出す パネルJPanel コンテンツペインにレイアウトマネージャを設 定する. FlowLayout, BorderLayout, GridLayoutなど コンテンツペインにコンポーネントを配置する. JPanel, JButton, JTextFieldなど
JPanelパネルに描画する(内部クラス利用).
paintComponent(Graphics g)
パネルJPanel
ボタンJButton テキストフィールドJTextField
インタフェース:抽象的な共通動作仕様(抽象メソッドとクラス定数)の集まり
インタフェースの実装
public interface ActionListener extends EventListener { public void actionPerformed(ActionEvent e);
}
public interface インタフェース名 [extends スーパインタフェース名[,…]] { public static final 型 変数名 = 初期値; // 任意個記述可能
public 型 メソッド名([引数並び]); // 任意個記述可能 }
(例)java.awt.event.ActionListener
public class EventProcessor implements ActionListener { …
public void actionPerformed(ActionEvent evt) { …
}
[public] class クラス名 implements インタフェース名[,…] {
… public 型 メソッド名([引数並び]) { // インタフェースに含まれるメソッドの定義 … // インタフェースに含まれるすべての } // メソッドを定義しないといけない … } (例)
イベント処理の方法:委任イベントモデル
イベントソースにイベントリスナーオブジェクトを登録.イベントリスナー
オブジェクトは,イベントリスナーインタフェースを実装したクラスのイン
スタンスで,インタフェースで定められたイベント処理メソッドを実装して
いる.
イベントソースは,イベント発生時にそれをイベントリスナーオブジェクト
に送信.
イベントリスナーはイベントを解析して処理する.
GUI
イベントソース (例:ボタン) addイベントListener(イベントリスナーオブジェクト) イベントリスナー登録 イベント イベントリスナー イベント処理メソッド イベント解析 イベント処理 implements イベントListenerpublic 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() の実装定義でイベント処理
4.4 Eclipseで電卓アプリケーションの
UMLクラス図とJavaプログラムを作成
新規Javaプロジェクトの作成
プロジェクト名:Calculator UMLのクラス図を格納するフォルダを作成
フォルダ名:uml Javaプログラムを格納するパッケージを作成
名前:example クラス図エディターを起動
クラス図フォルダ名:example.cld ここまでが終了した状態のウインドウ
3つのクラスCalculator.java, GUI.java, EventProcessor.javaを作成
java.awt.event.ActionListener javax.swing.JFrame [参照]をクリックして, Jframeと入力し 一致する項目を選択 [追加]をクリックして, ActionListenerと入力し 一致する項目を選択
ソースコードエディターを用いてGUI.javaのコードを書く
GUIコンポーネントの変数宣言 メソッド
GUIコンポーネントの配置
ボタンを押したときに発生す るイベントのリスナーを eventProcessorとする
ソースコードエディターを用いてEventProcessor.javaのコードを書く
計算実行用の変数宣言 メソッド
ボタンを押したときに発生 するイベントを処理するイ
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() の実装定義でイベント処理
コンパイル・実行
コンパイル:プログラムを保存すると自動的にコンパイルされる.
実行:Calculator.javaを右クリックして現れるメニューから[実行]-[Javaアプリケーション
4.5 例外処理
例外処理とは:実行中に起こる例外的な事象(特別な状態,エラー)への対
処を,正常な実行の流れとは分けて記述すること.
例外の種類
RuntimeException以外のException系例外:実行環境や実行状態に応じて 発生する例外で,例外の発生を捉えてそれに対処する例外処理コードを書かな いといけない. RuntimeException系例外:シンタクス的には正しいが実行が正しくできない 実行時エラー.デバッグで対処することが多い.(不正なキャスト,nullオブジェク トアクセス等) Error系例外:Java実行系の内部エラーやリソースの不足を示す回復不可能な 重大エラー.デバッグで対処.Throwable
Exception
Error
ClassNotFoundException
CloneNotFoundException
IllegalAccessException
InstantiationException
InterruptedException
NoSuchFieldException
NoSuchMethodException
IOException
RuntimeException
例外処理の方法と構文
メソッドの実行中に起こった例外の発生を呼び出し側に通知
throws: メソッドが例外を発生させる可能性があることを宣言する
throw: メソッド内で例外を発生させる
型 メソッド名([引数並び]) throws 例外名 { ….. throw new 例外名(); ….. }public static double valueOf(String s) throws NumberFormatException { …..
throw new NumberFormatException(); …..
}
public String readLine() throws IOException { …..
throw new IOException(); …..
}
(例)
通知された例外を呼び出し側で捉えて正常な実行の流れから離れて
対処
try: 例外を発生させる可能性があるメソッドが例外を発生させたか
検査する
catch: メソッドが発生させた例外を捉えてそれに対処する
finally: 例外発生の有無に関わらず共通に行う事後処理を記述す
る
try { // 例外を発生させる可能性のあるメソッド呼び出し } catch(発生可能な例外名1 変数) { // 例外1に対する処理 } [ ….. } catch(発生可能な例外名n 変数) { // 例外nに対する処理 }][finally { // 例外発生の有無に関わらず必ず実行する処理 }]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 例外名 { ….. 例外名の例外を通知する可能性のあるメソッド呼び出し;①