第11回 GUI(グラフィカル・ユーザ・インターフェース)の設計

Slides:



Advertisements
Similar presentations
オブジェクト指向 言語 論 第八回 知能情報学部 新田直也. 多相性(最も単純な例) class A { void m() { System.out.println( “ this is class A ” ); } } class A1 extends A { void m() { System.out.println(
Advertisements

Ver 準備 Java フォルダに移動して …… mkdir Swing Swing フォルダに移動して …… cp ~gundam/Java/Swing. コマンドプロンプト ( JDK ) でないと起動 しないので注意!!!
ソフトウェア工学 知能情報学部 新田直也. オブジェクト指向パラダイムと は  オブジェクト指向言語の発展に伴って形成され てきたソフトウェア開発上の概念.オブジェク ト指向分析,オブジェクト指向設計など,プロ グラミング以外の工程でも用いられる.  ソフトウェアを処理や関数ではなくオブジェク.
6.4継承とメソッド 6.5継承とコンストラクタ 11月28日 時田 陽一
社会人学習講座 「Javaプログラミング概論」
GridLayout オブジェクト(省略)
         第9回 Swing.
プログラミング基礎I(再) 山元進.
Applet 岡部 祐典 鈴木 敬幸.
~手続き指向からオブジェクト指向へ(Ⅰ)~
プログラミング基礎I(再) 山元進.
JAVA GUIプログラミング 第6回 TextFieldとLabel.
C#によるWindowsFormApplication入門
情報理工学部 情報システム工学科 ラシキアゼミ3年 H 岡田 貴大
アルゴリズムとデータ構造1 2007年6月12日
マルチエージェント・シミュレーション(2)
Javaのインタフェース についての補足 2006年5月17日 海谷 治彦.
第14回 GUIの構成とイベント・ドリブン ~GUIを使ったプログラム(Ⅰ)~.
JAVA GUIプログラミング 第5回 ボタンとそのイベント処理.
社会人学習講座 「Javaプログラミング概論」
第20章 Flyweight ~同じものを共有して無駄をなくす~
インタフェース プログラミング 第14回 インタフェース プログラミング第14回.
情報 第2回:状態遷移 その2.
オブジェクト プログラミング 第1回.
第6回独習Javaゼミ 第6章 セクション4~6 発表者 直江 宗紀.
プログラミング演習3 第2回 GUIの復習.
~手続き指向からオブジェクト指向へ[Ⅱ]~
第11回 アプリケーションの構成 ~CUI自動販売機の完成!~.
オブジェクト指向 プログラミング 第十四回 知能情報学部 新田直也.
Borland Delphi 6 でビジュアルプログラミング
ソフトウェア工学 知能情報学部 新田直也.
オブジェクト・プログラミング 第12回 状態遷移図 シーケンス図.
独習JAVA 6.8 コンストラクタの修飾子 6.9 メソッドの修飾子 6.10 ObjectクラスとClassクラス 11月28日(金)
オブジェクト指向 プログラミング 第十三回 知能情報学部 新田直也.
プログラミング演習3 第3回 ミニプロジェクト.
ローカル変数とグローバル変数 ローカル変数  定義された関数内だけで使用できる変数 グローバル変数 プログラム全体で使用できる変数.
オブジェクト指向 プログラミング 第十四回 知能情報学部 新田直也.
プログラミング演習3 第2回 GUIの復習.
Java/Swingについて (3) 2005年10月19日 海谷 治彦.
11 ソフトウェア工学 Software Engineering デザインパターン DESIGN PATTERNS.
Java/Swingについて+ (4) 2005年10月26日 海谷 治彦.
オブジェクト指向言語論 第十一回 知能情報学部 新田直也.
プログラミング基礎a 第10回 Javaによる図形処理入門(2) GUIの使い方
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
オブジェクト指向言語論 第十一回 知能情報学部 新田直也.
オブジェクト・プログラミング 第8回.
オブジェクト プログラミング 第2回 プログラムの基本.
アルゴリズムとプログラミング (Algorithms and Programming)
オブジェクト指向 プログラミング 第九回 知能情報学部 新田直也.
プログラミング言語論 第十三回 理工学部 情報システム工学科 新田直也.
ソフトウェア工学 知能情報学部 新田直也.
JAVA GUIプログラミング 第3回 イベント処理① マウスイベント.
オブジェクト指向言語論 第十二回 知能情報学部 新田直也.
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
アルゴリズムとデータ構造 2012年7月2日
C#プログラミング実習 第3回.
計算機プログラミングI 木曜日 1時限・5時限 担当: 増原英彦 第1回 2002年10月10日(木)
サブゼミ第7回 実装編① オブジェクト型とキャスト.
第8回 データを収納する (スタックとキュー)
アルゴリズムとデータ構造 2013年7月2日
JAVA入門⑥ クラスとインスタンス.
ソフトウェア工学 知能情報学部 新田直也.
GUI部品とイベント処理の例 マインスィーパもどきの作成 倉敷芸術科学大学 産業科学技術学部 梶浦文夫.
Javaとは Javaとはオブジェクト指向言語でJava VM(Java仮想マシン)と呼ばれるプログラム上で動作します。
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
オブジェクト・プログラミング 第10回 オブジェクト指向設計のキモ.
5.基本API 5-1 レイアウト ウィジェットの並べ方を指定するには、 パレットのレイアウト(Layoutでは以下の8種類)を配置する。
計算機プログラミングI 第2回 2002年10月17日(木) 履習登録 複習 ライブラリの利用 (2.6-7) 式・値・代入 (2.6-8)
計算機プログラミングI 第10回 2002年12月19日(木) メソッドの再定義と動的結合 クイズ メソッドの再定義 (オーバーライド)
計算機プログラミングI 第5回 2002年11月7日(木) 配列: 沢山のデータをまとめたデータ どんなものか どうやって使うのか
Presentation transcript:

第11回 GUI(グラフィカル・ユーザ・インターフェース)の設計 オブジェクト・プログラミング 第11回 GUI(グラフィカル・ユーザ・インターフェース)の設計

前回多かった質問 第6回で作った配列のsearchメソッドは、 public boolean search(int searchKey); という宣言でしたが、 第9回で作ったリストのsearchメソッドは、 public ItemInfo search(int searchKey); という宣言でした。 第10回の課題では、スーパークラスが、 public ItemInfo search(int searchKey); と宣言されているので、リストのほうは動くのですが、配列のほうのコンパイルが通りません。

前回の課題クラス図

前回多かった質問 解答(1) 第6回のメソッドは、検索し、値があるか無いかを調べるだけでしたので、返り値がbooleanでよかったのですが、第9回から、検索して、見つけたオブジェクトを返すように変更しました。 前回の課題は、配列、リストで実装した2つのFolderクラスをmainで性能評価する際に、同じスーパークラスのサブクラスとして、同じメソッドが使えるようにして、コードの重複を避けました。

前回多かった質問 解答(2) ですから、searchメソッドは同じ型のメソッド(同じ引数で、同じ返り値)でなければなりません。 前回多かった質問 解答(2) ですから、searchメソッドは同じ型のメソッド(同じ引数で、同じ返り値)でなければなりません。 ですから、前回の課題では、第6回で作ったメソッドの返り値をbooleanからItemInfoに変更し、見つけた商品情報を返り値として返すように変更する必要があります。

今日の目標 GUIを使った、簡単なプログラムが書けるようになる。 イベントドリブンの考え方について説明できるようになる Swingを使った簡単なGUIを作ることができるようになる。 イベントドリブンの考え方について説明できるようになる Javaでボタンを押されたときの動作をプログラミングすることができるようになる。 GUIの設計について説明できるようになる。 Model-View-Controller設計について説明できるようになる。

今日作る簡単な自販機 このウインドウが あなたのコンピュータ で開けるように、 プログラミングします。

今日作る自動販売機の仕様(1) ②投入金額表示 ウインドウの金額 が増える ①100円投入 ボタンが押される 今日は、いくら増えても かまわない。

今日作る自動販売機の仕様(2) ①ボタンを押す ②商品が出てくる 今日は、いくら商品が、 でてもかまわない。 投入金額と連携しなくて

JavaでGUIを取り扱う方法 Swingフレームワークを利用します。 フレームワークとは、アプリケーションを構築するための骨格を提供するコンポーネント群のこと。 フレームワークが提供されていれば、開発者は低レベルのコードを書かずにアプリケーションを構築することができる。 コンポーネントとは、「クラス利用の視点」によりオブジェクトを再利用する抽象的な単位をいう。 要するに、Swingで提供されているクラス群を使うと、簡単に、GUIなアプリケーションを作ることができます。 http://www.njk.co.jp/otg/Drop/Drop_v20/part1/chapter1.htmlより引用

Swingフレームワーク概要 すべてがオブジェクト! JFrame JLabel JTextField JButton

ウインドウを出してみよう! import javax.swing.*;//swingを使うときは宣言しなければならない import java.awt.*;//swingを使うときは宣言しなければならない //ただウインドウを出すだけのメインクラス public class SimpleWindowMain { public static void main(String args[]){ JFrame frame = new JFrame();//Swingで提供されるJFrameオブジェクト生成 frame.setTitle("初めてのウインドウ");//タイトル設定 frame.setSize(200,200);//大きさ設定 frame.setLocation(50,50);//位置設定 frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE); //ウインドウが閉じたときにプログラムが終了するように設定 frame.setVisible(true);//表示する }

実行結果 次はこのウインドウにボタンを 乗せてみましょう!

カスタムウインドウを作る import javax.swing.*;//swingを使うときは宣言しなければならない import java.awt.*;//swingを使うときは宣言しなければならない //JFrameクラスを継承したカスタムウインドウクラス public class SimpleWindow extends JFrame{ //コンストラクタ public SimpleWindow(){ //ボタンの設定 JButton button = new JButton();//ボタンをインスタンス化 button.setText("初めてのボタン");//ボタンのラベル名設定 button.setSize(150,20);//ボタンの大きさ設定 button.setLocation(20,50);//ボタンの位置設定(ウインドウからの相対位置) getContentPane().setLayout(null);//ウインドウに載せられるすべてのオブジェクト //の位置を自分で設定できるようにする。 getContentPane().add(button);//ボタンをウインドウに乗せる }

mainの修正 import javax.swing.*;//swingを使うときは宣言しなければならない //カスタムウインドウを出すために修正したクラス public class SimpleWindowMain { public static void main(String args[]){ JFrame frame = new SimpleWindow();//オブジェクト生成 frame.setTitle(“初めてのカスタムウインドウ");//タイトル設定 frame.setSize(200,200);//大きさ設定 frame.setLocation(50,50);//位置設定 frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE); //ウインドウが閉じたときにプログラムが終了するように設定 frame.setVisible(true);//表示する }

実行結果 ボタンが乗せられました。 しかし、押しても何も起こりません。 次は、ボタンが押されたとき、プログラムを 終了するようにしましょう!

ボタンが押されたときの処理を記述したい。 //まず、日本語でロジックを考えるための仮想言語です。 public void ボタンが押されたかどうかを調べて、押されていたら終了する(){  マウスの位置を調べる(); if(マウスの位置がButtonの中にある){ マウスの状態を調べる(); if(マウスが押されている){ if(押されているのは、マウスの左ボタンである){ System.exit(0);//プログラムを終了する。 } } このメソッドを一定期間ごとに動かせば、 一応できそうですね。

ハードウエアの状態を調べる 何処にいる? プログラム 動いてないよ! 押されてる? プログラム “a”が押されてます

しかし! 毎回毎回調べるのは大変で、時間がかかる。 もう一つボタンを作ったら、また、それが押されたかどうか調べるメソッドを用意して、一定期間ごとに調べなければならない。

そこで! イベント・ドリブンというプログラミングスタイルが考えられた。 処理をイベント毎に分割して記述して、 必要に応じて呼びだされ, 処理されるというものである。

イベント・ドリブンの考え方 ハードウエアを 常に見張っている 唯一のプログラム 押されたよ! プログラム プログラム 常に見張っている

用語 イベント・ディスパッチャー イベント イベント・ハンドラ ハードウエアを 常に見張っている 唯一のプログラム 押されたよ! プログラム

イベント・ドリブンプログラミング イベントドリブン型プログラムを作る時は、ただひたすら、イベントハンドラをどう書くかに集中すれば良い。 うれしい。 JavaのSwingフレームワークはこの機能を標準で持っています。 public void ボタンが押されたときの処理(){ System.exit(0); } これだけのメソッドを書けばよくなる。

Javaでイベントハンドラを作る JavaではイベントハンドラのことをEventListenerと呼び、オブジェクトとして表現します。

イベントハンドラのリスト ActionListenerは、 EventListenerを継承したクラス import java.awt.event.*; //Javaでのイベントハンドラの定義 public class SimpleButtonListener implements ActionListener{ public void actionPerformed(ActionEvent e){ System.exit(0); } ActionListenerは、 EventListenerを継承したクラス 「イベント」 を表わすオブジェクトが 引数になります。 メソッド名は決められて いるので間違えないように ※implementsの意味はここでは扱いません。 継承(extends)と似たような意味だという理解でよいです。

イベントハンドラを登録する //先ほどのプログラムのコンストラクタだけ抜粋 public SimpleWindow(){ JButton button = new JButton();   //大きさなどの設定は割愛 //イベントハンドラをインスタンス化 SimpleButtonListener listener = new SimpleButtonListener(); //イベントハンドラを受信者として登録する button.addActionListener(listener); //ウインドウにボタンを載せる処理を割愛 }

SimpleWindowの全リスト import javax.swing.*;//swingを使うときは宣言しなければならない import java.awt.*;//swingを使うときは宣言しなければならない import java.awt.event.*;//eventを使うときは宣言しなければならない //JFrameクラスを継承したカスタムウインドウクラス public class SimpleWindow extends JFrame{ //コンストラクタ public SimpleWindow(){ //ボタンの設定 JButton button = new JButton();//ボタンをインスタンス化 button.setText("初めてのボタン");//ボタンのラベル名設定 button.setSize(150,20);//ボタンの大きさ設定 button.setLocation(20,50);//ボタンの位置設定(ウインドウからの相対位置) button.addActionListener(new SimpleButtonListener());//ボタンを受信者登録 getContentPane().setLayout(null); getContentPane().add(button);//ボタンをウインドウに乗せる }

実行してみましょう! ボタンを押すと、ウインドウが 閉じて終了するはずです。

JBuilderを利用して設計する この作業を人力でやる のは、とても大変です。 JBuilderは、きっと、 あなたのプログラムを 助けてくれます。 しかし、とても重いです。 空のclass宣言を終わった  段階で、「設計」タブを クリックします。

JBuilderを利用したWindowのセッティング 右下の 「プロパティ」 から、layoutを nullに設定します。

何故Layoutをnullに設定するのか? 先ほども、 getContentPane().setLayout(null); というコードがでてきました。 Swingでは、標準で、ボタンの位置などを整形してくれるレイアウト機能がついています。 しかし、今回は、場所や大きさを自分で設定したいので、勝手にレイアウトされては困ります。 その機能を無効にするのが、このメソッドでレイアウトオブジェクトnullを設定する意味です。

JBuilderを利用したボタンの貼り付け Swingバーの Jbuttonをクリックし Frameキャンパスの設置 したい場所をクリックします。 コードが自動生成されます。 ソースコードに戻りたい場合は、 「ソース」タブをクリックします。

JBuilderを利用したイベントハンドラの登録 ②一番上の actionPerformed の右の空白を ダブルクリックします。 ①「イベント」タブを クリックします。

イベントハンドラの中身を書く イベントハンドラの外枠は自動生成されますが、中身は作ってくれません。(当然ですね。)自分でプログラムを書きます。

自動販売機用のコンポーネント オブジェクト・プログラミングの課題のために、自動販売機用のコンポーネントを作りました。 BackgroundPanelクラス 背景用のコンポーネントです。 この上に他の自販機コンポーネントを乗せる ことができます。 ItemInfoクラス 販売商品を表示するための コンポーネントです。

コンポーネント(続き) VMButtonクラス 自販機用のボタンです。 ProductOutletクラス 商品を最大10個 中に表示することができます。 CoinDepositクラス 投入金額を表示します。

カスタムコンポーネントの作成 この授業では、作られたコンポーネントを使って、プログラミングしてもらいます。 使うに当たり、中身がどのようにできているのか少し説明します。 金額表示ウインドウ(CoinDepositクラス)コンポーネントを例に説明します。

CoinDepositの構成 CoinDepositコンポーネントは、3つのクラスから成り立っています。 CoinDepositクラス CoinDepositModelクラス CoinDepositUIクラス 次ページ:クラス図

CoinDepositのクラス図

何故3つのクラスに分かれているか? CoinDepositの機能を実現するために一つのクラスで作ることもできます。 しかし、GUIのクラス設計では、責任ごとに3つのクラスに分割するのがよい方法とされています。 Swingの各コンポーネントも3つのクラスから同じ設計で作られています。 詳しく知りたいひとはデザインパターンなどのクラス設計法を勉強してみましょう。

GUIの基本クラス設計 Model-View-Controller設計 Model View 日本 = 100 アメリカ = 150 中国 = 130 Controller 日本 アメリカ 中国

各クラスの責任 Modelクラス Viewクラス Controllerクラス データ構造に責任を持つ 画面での表現に責任を持つ ユーザ入力に対するインターフェースに責任を持つ

何が嬉しいか?(1) View View 日本 アメリカ 中国 Model 日本 = 100 アメリカ = 150 中国 = 130 その逆も可能

何が嬉しいか?(2) Controller マウス・ イベントハンドラ Model 「メニュー」から やり直しを選ぶ 日本 = 100 アメリカ = 150 中国 = 130 キーボード・ イベントハンドラ Controller 様々なControllerに対して Modelの再利用が可能 また、その逆も可能 「Ctrl-Z」で ショートカット

もう一度クラス図を見てみよう! Controller Model View

簡単な実装の説明 CoinDepositModelクラス public class CoinDepositModel { private int amount; private CoinDeposit controller; public CoinDepositModel(CoinDeposit initController){ controller = initController; } public void addMoney(Money money){ amount = amount + money.getValue(); controller.repaint(); public int getAmount(){ return amount; public Money undo(){ //どうしたらできるか考えてみよう! ※コメントは省略 Model クラス 現在入れられたお金の 総量を計算して、 持っています。

簡単な実装の説明 CoinDepositUIクラス(1) Swingの 標準Viewクラス を継承します。 View クラス public class CoinDepositUI extends ComponentUI { private Image img; private int imgWidth = 160; private int imgHeight = 55; private String imgName = "image/coindeposit.gif";  public CoinDepositUI() { java.net.URL url = getClass().getClassLoader().getResource(imgName); img = Toolkit.getDefaultToolkit().getImage(url); } public Dimension getPreferredSize(JComponent component){ return new Dimension(imgWidth,imgHeight); 画像の読み込み を行ないます。 ※次ページに続く コンポーネントの推奨サイズを返すメソッドです。

簡単な実装の説明 CoinDepositUIクラス(2) Viewクラスは、 描画のアルゴリズム を備えています。 View クラス  public void update(Graphics g,JComponent c){ paint(g,c); }  public void paint(Graphics g,JComponent c){ CoinDepositModel model = ((CoinDeposit)c).getModel(); if(img != null){ g.drawImage(img,0,0,imgWidth,imgHeight,c); g.setColor(Color.red); g.setFont(new Font("Dialog",Font.PLAIN,32)); String amountStr = model.getAmount() + ""; g.drawString(amountStr,imgWidth/4,imgHeight*3/4); モデルから、 データを取ってきて、 描画します。

簡単な実装の説明 CoinDepositクラス Swingの 標準Controllerクラス を継承します。 簡単な実装の説明 CoinDepositクラス public class CoinDeposit extends JComponent { private CoinDepositModel model; public CoinDeposit() { model = new CoinDepositModel(this); setUI(new CoinDepositUI()); } public CoinDepositModel getModel(){ return model; Controller クラス すべての、 Controllerクラスは、 まだユーザの操作を 受け付けるように できていません。 これから皆さんがここにプログラムを書いていきます。

その他は質問してください。 優秀な(?)TA、SAに質問してください。 ソースにもコメントをたくさんつけてありますので、参照してください。

今日の課題(1) 授業の前半で説明した、シンプルなウインドウを表示し、ボタンを押すと、終了する簡単なプログラムを作りなさい。 提出すべきソース SimpleWindowクラス SimpleButtonListenerクラス SimpleWindowMainクラス

今日の課題(2) 最初に説明した仕様を満たす機能をもつ、簡単な自動販売機プログラムを作りなさい。 自動販売機コンポーネントを表示させる。 100円ボタンを押すと、金額表示ウインドウが更新される。 商品ボタンを押すと、商品が排出される。 お金が投入されていなくても出してよい。 何個排出されてもよい。 排出しても、投入金額を減らす必要はない。 やり方は、「課題の手順」にすべて書いてありますから、それどうりやってくれればかまいません。

発展課題 今日つかう、自動販売機プログラムのUMLクラス図を書きなさい。 手書きで書いて、 来週の授業の開始時に提出

提出方法 objprog-11@crew.sfc.keio.ac.jp宛て。 ただし、課題(2)のソースは、VendingMachineFrameだけでよい。 (感想を任意でお願いします。) Subjectはログイン名を必ず書いてください。 ex) t96844ym 余計な[]などをつけないでください。 来週の日曜(24:00)まで。(みんな、きつそうなので、変えました。がんばってください!)