#author("2018-12-20T06:13:01+00:00","ocha","ocha") #author("2018-12-20T06:40:46+00:00","ocha","ocha") [[Lecture]] #contents *Java プログラミング入門 [#s6899a39] このページは、学部2年生向け授業である、「マルチメディアプログラミング実習」 のために用意しました。 **javaのマニュアル [#beafbfad] //http://sdc.sun.co.jp/java/docs/j2se/1.5.0/ja/docs/ja/api/index.html //http://java.sun.com/javase/ja/6/docs/ja/api/index.html //http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/index.html //http://docs.oracle.com/javase/jp/6/api/ http://docs.oracle.com/javase/jp/8/docs/api/index.html ** 出来上がったプログラムの提出方法 [#bd9cbbf8] - フォルダを作ってその中にjavaファイルとclassファイル //と、取扱説明書ファイルと、それ以外に必要なファイルがもしあればそれら を入れてください。 フォルダの中のclassファイルをダブルクリックしたらプログラムが起動することを確認してください。 -このフォルダに名前を付けてください。フォルダの名前は、「出席番号+氏名(ローマ字の姓名)+必要ならばバージョン番号の数字」にしてください。たとえば09020999siioitiro01のように。なお全部半角英数字でお願いします。 -このフォルダを圧縮してください --フォルダを選択してファイルメニューから圧縮を選択します -圧縮したファイルを以下の手順で /home/isstaff/siio/Public/Drop Box/. に提出してください。ターミナル.appからなら cp 123456siioitiro.zip /home/isstaff/siio/Public/Drop\ Box としてください。ファインダーからなら、メニューから「移動」「フォルダへ移動...」を選んで 以下のように入力して、移動ボタンを押して、そこに現れるドロップボックスホルダに、ドラッグアンドドロップしてください。 http://siio.jp/gyazo/dropbox.png --書き込み専用なので確認できないけどokですかという意味のダイアログが出るかと思いますが問題ありません。 -レポート提出用フォルダは書き込み専用で見ることができません。アップロードできたかどうか不安でしたら教員まで質問してください。 -授業中でしたら、[[ココを見ると:http://siio.jp/lecture/java_report.html]]一覧をみることができます。 -同じ名前のフォルダを投げ込むと、エラーになります。ということで新しいバージョンができたら別の名前のフォルダを作って提出し直してください。(フォルダ名最後に数字をつけてください) ***教科書 [#a7e1ce26] http://gyazo.com/de3288074dae1c75f6df4ef3c0b9b3d4.png http://www.amazon.co.jp/dp/4883732258/ 買ってください。もしくは、先輩から安く譲ってもらってください。 *** この講義の目的 [#l5592b29] +Javaでプログラムする +オブジェクト指向の概念を理解してプログラミングする +GUIプログラミングをする *** この講義の順序 [#gcf48d66] +Javaになれる(C言語などのプログラミング手法の復習) +オブジェクト指向について理解する +GUIプログラミングについて理解する(イベント駆動) +お絵描きプログラムを作ってみる *** 成績評価 [#c732dbb9] +お絵描きプログラムの完成度,作り込み +毎回の宿題の達成(参考程度) +出席状況(参考程度) **第1章および第2章 [#y3ae1beb] *** terminalを起動する [#ia8beba9] //#ref(How2Java/terminal.png) http://siio.jp/gyazo/7366bfab668207c6598c4d88ef70d2d4.png - terminalは、/Applications/Utilities/の中にあります。 ちなみに、/Applicationsはファインダでは/アプリケーションと日本語として見えます。 /Applications/Utilities/は、/アプリケーション/ユーティリティ/と日本語として見えています。 - ダブルクリックすると起動します。 よく使うことになると思いますので、dockにドラッグアンドドロップして 登録しておくと良いかと思います。 - ターミナルから、javacとタイプしてみてください。Javaがすでに入っているので、 オプションの説明が日本語で出てくると思います。 ***おすすめテキストエディタCotEditor[#c7258b9c] https://coteditor.com/img/appicon/128@2x.png - Javaのプログラムを作るテキストエディタです。一番簡単にはterminalからviとかemacsとかpicoとかタイプして エディタを呼び出せば良いです。 - でも日本語の設定などが結構難しいので、GUIベースのエディタを使ってみましょう。 - いくつかありますが、おすすめの一つはCotEditorという、便利なフリーウェアのテキストエディタです。 - これも便利なのでdockに入れておくとよいと思います。 こちらからダウンロードできます。 演習室のOSにあわせたバージョンをダウンロードして~/Applicationsにコピーします。 https://coteditor.com/archives.ja *** 超簡単なプログラム(hello world)を作ってみる [#v4ccc293] - ターミナルから、vi Hello.javaとかemacs Hello.javaとかpico Hello.javaとかタイプしたり、 もしくは、cotEditerを起動して作成します。 - ここで、以下のようなプログラムを書いてみます。 class Hello { public static void main (String args[]) { System.out.println("hello java world!"); } } http://siio.jp/gyazo/20121004010107.png - これをHello.javaという名前で保存して、コンパイル実行します。すると以下のようになります。 javac Hello.java (コンパイルする) java Hello (実行する。.javaなどの拡張子は不要) hello java world! (結果) - 次に簡単なウィンドウを出してみましょう。 授業の最後の方で紹介する,Swingというフレームワークを使ってウィンドウを出してみます. import javax.swing.JFrame; public class SimpleWindow { public static void main(String argv[]) { JFrame f = new JFrame("私が作った最初の窓"); f.setSize(200,100); // f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); } } これをSimpleWindow.javaという名前で保存して、 javac SimpleWindow.java java SimpleWindow とタイプしてコンパイル/実行します。 このプログラムは,ウィンドウのクローズボタンを押しても終了しません. プログラムを停止するには,ターミナルでコントロール-cを押します. #ref(How2Java/simplewindow.png) **第3章 [#xc22f04b] -演習1 --演習3.4をみて、自分の名前の最初の文字の文字コードを表示してみてください。 -演習2 --コマンドの引数はarg[0], arg[1] ... などにString型の配列としてプログラムに引き渡されます。 --二つの引数を与えたときに、それが+でつないで表示されるプログラムを作りましょう。 http://gyazo.com/8159f78165e17781a7110de3763c833c.png ヒント --以下は引数一つを表示するだけのサンプルです。これをもとに考えてください。 --arg[0]とarg[1]をprintlnの中で+でつないで表示すれば良いです。 class ArgsTest { public static void main (String args[]) { System.out.println(args[0]); } } 解答 --後で公開します class ArgsTest { public static void main (String args[]) { System.out.println(args[0] + " + " + args[1]); } } **第4章 [#f2e95643] --演習4.2をやってみよう **第5章 [#p54c6568] ***演習 [#leda55b3] -演習問題5.4(変更) 乱数を10個表示する public class Score { public static void main (String argv[]) { int i,a; for(i=0;i<10;i++) { a=(int)(Math.random() * 100); System.out.println(a); } } } 次にこの乱数を点数とみなして、演習問題5.4の基準に従ってABCDを表示するプログラムを書け。 動作例を以下に示す。 http://gyazo.com/829b04a7fc82cdfe9dd0dfa650af873e.png 解答例: public class Score { public static void main (String argv[]) { int i,a; for(i=0;i<10;i++) { a=(int)(Math.random() * 100); System.out.print(a + " "); if(a<40) System.out.println("D"); else if(a<60) System.out.println("C"); else if(a<80) System.out.println("B"); else System.out.println("A"); } } } -演習問題5.5をやってみよう http://gyazo.com/1733defca0c709c41c69ea729320ab61.png 解答例: class Kinri { public static void main (String args[]) { double okane=100000; int year; year=1; while(okane < 200000) { okane = okane * 1.05; System.out.println("year = " + year + " okane= " + okane); year++; } } } 現在の普通預金の金利0.04%だと倍になるのに何年かかるだろうか。確かめてみよう。 http://gyazo.com/95cd94db39b407e7961355b20da8fc67.png -演習5.6をやってみよう while文をfor文に変えてみる 解答例: class Kinri { public static void main (String args[]) { double okane=100000; int year; for(year=1;okane < 200000; year++) { okane = okane * 1.05; System.out.println("year = " + year + " okane= " + okane); } } } ***モンテカルロ法で円周率を計算してみる(ループの練習) [#s7c57350] --1x1の正方形のエリアにランダムに矢を当てた場合、1/4円の中に当たる矢の数は、 面積に比例すると考えられます。あたりの矢の割合を調べれば円周率がわかります。 http://gyazo.com/e4f68c7ed1045c10801ec201ed00b5e6.png -- MonteCarlo.java というファイルを作ります。 --まずは100個乱数を表示するプログラムを作ってみましょう。 class MonteCarlo { public static void main (String args[]) { int i; for(i=0;i<100;i++) System.out.println(Math.random()); } } 矢の落下点x,yをランダムな位置にするには、乱数で指定します。 これがあたりかどうかは、原点からの距離で調べます x = Math.random(); y = Math.random(); if(x*x + y*y < 1) hit++; --100個の矢、1000個の矢などいろいろためしてで円周率を計算してみてください -- 解答例です class MonteCarlo { public static void main (String args[]) { int i; double hit = 0; double x, y; for(i=0;i<1000;i++) { x = Math.random(); y = Math.random(); if(x*x + y*y < 1) { hit++; } } System.out.println(4 * hit / 1000); } } ***for-each文は新しい手法なので練習しましょう [#s17e2f54] -プログラム5.7の代わりに以下をやってみよう class ArrayTest { public static void main (String args[]) { int[] vec = new int[3]; vec[0]=1; vec[1]=2; vec[2]=3; for (int x: vec) { System.out.println(x); } } } *** 演習 [#vc946bd9] mainの引数argsは、Stringの配列で、コマンドラインで起動したとき、 コマンドの後に続けた書いた文字が入っています。 args[0], args[1], args[2] .... をすべてfor-each文で 表示するプログラムを書いてみましょう。 http://gyazo.com/8d8effac163e0dc939e74f237d8507b1.png ヒント:for(String s: args)を使います -解答例 class ArgsTest2 { public static void main (String args[]) { for(String s: args) System.out.println(s); } } //--args[]の文字をすべてfor-each文で表示する // javac ArgsTest2 cat dog cow fox // catdogcowfox //ヒント //--args[]の文字をすべてfor-each文で+つけて表示する // // javac ArgsTest2 cat dog cow fox // cat + dog + cow + fox //arg[0]とarg[1]をつないで表示する //演習5.5 10万円が20万円になる年 //arg[]の文字をすべてfor-each文で表示する //--演習4.2をarg[0]に対してやってみよう **第6章 クラスの基礎 [#h5b270c6] ***クラスとインスタンスの説明をしました [#gc6def4c] -クラスは型、インスタンスはそれから作られたもの --クラスがたいやきの焼き型だとすると、インスタンスはそれから作られたたいやき --クラスは設計図でインスタンスはそれから作られたもの -クラスとインスタンスそれぞれにメソッドと変数がある --クラス変数 例:何個のインスタンスを作ったか? --クラスメソッド 例:インスタンスを作れ --インスタンス変数 例:ひとつのたいやきの重さ --インスタンスメソッド 例:たいやきをxxグラム食べる http://gyazo.com/bbdd3587977a172f7fa7f00c4f5787e0.png -演習問題6.1, 6.2, 6.3 例えば以下のような実行結果が出るようにしてください http://gyazo.com/deeb78a70a724a01ce76945235d42ab8.png ***クラス変数・メソッドとインスタンス変数・メソッド [#w88794f1] - staticとついているのがクラス変数、クラスメソッド - staticが付いていないのがインスタンス変数、インスタンスメソッドです ***public static void main の説明をしました [#p8e5e198] -javaコマンドは、引数のクラスのクラスメソッドmainを実行します --staticと付いているのがクラス変数、クラスメソッドの印です -Pointクラスにクラスメソッドmainを実装すれば自分自身をテストできます -クラスPoint3Dに自分自身をテストするクラスメソッドmainを作ってみよう http://gyazo.com/bdef2ab8e69f7f6e62273c2d67d7af2e.png ***変数にはメソッド経由でアクセスするのが良いという説明をしました [#c813a888] -変数の型などを将来変更してもメソッドの書き換えで対応できます public class Point { private int x, y; void set(int newx, int newy) {x=newx; y=newy;} int getx() { return x;} int gety() { return y;} void print () { System.out.println(x + ", " + y); } public static void main(String argv[]) { Point pt1= new Point(); Point pt2 = new Point(); pt1.set(10,20); pt2.set(-pt1.getx(), -pt1.gety()); pt1.print(); pt2.print(); } } -Point3Dのメソッドを充実させて次のmain()メソッドで 10, 20, 30 -10, -20, -30 という結果が出るようにしましょう public static void main(String argv[]) { Point3D pt1 = new Point3D(); Point3D pt2 = new Point3D(); pt1.set(10, 20, 30);//インスタンス変数を設定 pt2.set(-pt1.getx(), -pt1.gety(), -pt1.getz()); pt1.print();//インスタンスメソッド呼出 pt2.print(); } -Point3Dに、他の点との距離を返すメソッド distance ( Point3D p ) を実装して、次のmain()メソッドで 10, 20, 30 -10, -20, -30 74.83314773547883 という結果が出るようにしましょう public static void main(String argv[]) { Point3D pt1 = new Point3D(); Point3D pt2 = new Point3D(); pt1.set(10, 20, 30);//インスタンス変数を設定 pt2.set(-pt1.getx(), -pt1.gety(), -pt1.getz()); pt1.print();//インスタンスメソッド呼出 pt2.print(); System.out.println(pt1.distance(pt2)); } --解答例 double distance ( int ptx, int pty, int ptz ) { int dx = ptx - this.x; int dy = pty - this.y; int dz = ptz - this.z; return Math.sqrt(dx * dx + dy * dy + dz * dz); } double distance ( Point3D p ) { return this.distance(p.getx(), p.gety(), p.getz()); } **第7章 クラスとオブジェクトの操作 [#k1b96e7b] *** 他の点との距離を返すメソッドの例を説明しました [#xfa5f246] double distance ( int ptx, int pty ) { int dx = ptx - this.x; int dy = pty - this.y; return Math.sqrt(dx * dx + dy * dy); } double distance ( Point p ) { return this.distance(p.getx(), p.gety()); } distanceという名前は同じでも、引数の違いで、異なる動作をさせることができます。 *** Osaifuクラスを作ってみよう [#i9df5c2e] -Osaifuクラスからはインスタンスがたくさん作られる --Osaifuクラスはお財布の設計図/工場、ここから実際のお財布(インスタンス)が複数作られる --工場出荷時の残金は0円だけど、その後、いろいろな値になるだろう(お金持ちのお財布には残金が多いだろうし、逆ならば少ないだろう) --ということで残金はインスタンス変数とすべきだろう -Osaifuクラスには次のメソッド、変数が必要だろう --残金を表すインスタンス変数 int okane --お金を入金するインスタンスメソッド void in(int x); --お金を出金するインスタンスメソッド int out(int x); 戻り値は実際に出金できた金額(残金が不足ならばあるだけしか出せない) --残金を印刷するインスタンスメソッドがあってもよいだろう void print(); &br; http://gyazo.com/bd6eaafd220dc7ff791288089f293b28.png -Osaifuクラスをテストするmain()メソッドでは次のことをやってください -- Osaifuインスタンスを一つ作ってそれをsaifu1という名前にする -- Osaifuインスタンスをもう一つ作ってそれをsaifu2という名前にする --saifu1に1000円入金する --saifu2に500円入金する --saifu1とsaifu2が持っている金額を印刷する --saifu1から200円出金してそれをsaifu2に入金する --saifu1とsaifu2が持っている金額を印刷する public static void main(String argv[]) { Osaifu saifu1 = new Osaifu(); Osaifu saifu2 = new Osaifu(); saifu1.in(1000); saifu2.in(500); saifu1.print(); saifu2.print(); saifu2.in(saifu1.out(200)); saifu1.print(); saifu2.print(); } http://gyazo.com/c618901458edc1ba338cab87d2810157.png -Osaifu.java 解答編 public class Osaifu { int okane; public void in (int x) { okane += x; } public int out(int x) { okane -= x; return x; } public void print() { System.out.println( "okane = " + okane +" yen"); } public static void main(String argv[]) { Osaifu saifu1 = new Osaifu(); Osaifu saifu2 = new Osaifu(); saifu1.in(1000); saifu2.in(500); saifu1.print(); saifu2.print(); saifu2.in(saifu1.out(200)); saifu1.print(); saifu2.print(); } } --このプログラムでは残金がマイナスになってしまってもかまわない設計になってしまっています。実際には残金だけの金額しか出せないはずなので、outメソッドを改良して、残金以上の金額を要求されたら、残金分だけしか出さないように変更してみてください。 --このためには、例えばoutメソッドを以下のようにすれば良い public int out(int x) { if(x < okane ) { okane = okane -x; return x; } else { int nokori = okane; okane =0; return nokori; } } *** つぎにOsaifuクラスにコンストラクタを追加してみよう [#a8a56d7e] -Osaifu() で残金0のインスタンスを作る -Osaifu(int x) で引数を残金の初期値としたインスタンスを作る ことができるコンストラクタを作ろう。 これをmainから呼んで、上記のプログラムと同じことをするためには、 Osaifu saifu1 = new Osaifu(1000);//インスタンスを作る //最初の保持金額を1000円にする Osaifu saifu2 = new Osaifu(500);//インスタンスを作る //最初の保持金額を500円にする とすることになる。 ***コンストラクタ解答編 [#w62499a7] 以下のコンストラクタを作ることになる。 Osaifu() { okane = 0; } Osaifu(int x) { okane = x; } これは以下のように書いても良い。 Osaifu() { this(0); } Osaifu(int x) { okane = x; } **第8章 継承 [#ka97b6ac] 継承の話をしました。 別のクラスを継承することで、 差分だけを書いて機能を拡張していくことができます。 http://gyazo.com/2c8ef14d8be63b9fc18c58d79f2f3879.png *** Osaifuクラスを継承してOsaifuUSDクラスを作ってみよう [#fc83e4ee] -OsaifuUSDクラスはアメリカで買い物をするときに便利な、アメリカドルでお金を出し入れできる財布です。 -あたらしく追加するメソッドは以下です -- void inUSD(int x) xドルをお財布に入金します。このとき円に換算して残高に追加します -- int outUSD(int x) xドルをお財布から出金します。このとき円に換算した金額だけ残高が減ります。戻り値はドルにしましょう。 --1ドルは90円にしてください //-スーパークラスのメソッドを上書きするメソッドは以下です //-- void print() お財布の残高を円とドルで表示します -OsaifuUSDクラスをテストするmain()メソッドでは次のことをやってください -- OsaifuUSDインスタンスを一つ作ってそれをsaifu1という名前にする -- OsaifuUSDインスタンスをもう一つ作ってそれをsaifu2という名前にする --saifu1に1000円入金する --saifu2に5ドル入金する --saifu1とsaifu2が持っている金額を印刷する --saifu1から2ドル出金してそれをsaifu2に入金する --saifu1とsaifu2が持っている金額を印刷する -動作例 http://gyazo.com/f51ea5895aaab32bb30b9a940d91515d.png -ヒント:一行目はこれ public class OsaifuUSD extends Osaifu { -ヒント:mainはこんな感じ public static void main(String argv[]) { OsaifuUSD saifu1= new OsaifuUSD(); OsaifuUSD saifu2=new OsaifuUSD(); saifu1.in(1000); saifu2.inUSD(5); saifu1.print(); saifu2.print(); saifu2.inUSD(saifu1.outUSD(2)); saifu1.print(); saifu2.print(); } -解答例 public class OsaifuUSD extends Osaifu { public int outUSD(int usd) { okane-=usd * 90; return usd; } public void inUSD(int usd) { okane+=usd * 90; } public static void main(String argv[]) { OsaifuUSD saifu1 = new OsaifuUSD(); OsaifuUSD saifu2 = new OsaifuUSD(); saifu1.in(1000); saifu2.inUSD(5); saifu1.print(); saifu2.print(); saifu2.inUSD(saifu1.outUSD(2)); saifu1.print(); saifu2.print(); } } 為替レートを90円にしたが、多分現在の為替レートとはかけ離れていると思う。 為替レートを変数として持たせるとしたら、どうしたら良いだろうか。 - インスタンス変数 - クラス変数 のどちらにするか、考えてみよう。 *** OsaifuUSDクラスの改造(1) [#g8c0b7a2] 親のメソッドを活用しても良い public class OsaifuUSD extends Osaifu { public int outUSD(int usd) { return ( out( use * 90) / 90 ); } public void inUSD(int usd) { in( usd * 90 ); } … } 親のメソッドを呼ぶことを明示的に書くためにsuper.をつかってもよい。 public class OsaifuUSD extends Osaifu { public int outUSD(int usd) { return ( super.out( use * 90) / 90 ); } public void inUSD(int usd) { super.in( usd * 90 ); } … } *** OsaifuUSDクラスの改造(2) [#sa44f577] OsaifuUSDにprint()メソッドを追加して、 円表示の次の行に ( xxx USD ) と残高をUSD表示するようにしてください。 円表示を行う部分はスーパークラスOsaifuのインスタンスメソッドprint()を利用することを考えてみてください。 http://gyazo.com/39a7b24a8c45e15ac55693592c2eb7cf.png -解答例 public void print() { super.print(); System.out.println("( " + (okane / 90) + " usd )" ); } ***小テスト練習 [#g4c60a6e] 以下のプログラムの中で、 クラス、インスタンス、サブクラス、スーパクラス、クラスメソッド、インスタンスメソッドがどれであり、 インスタンス化、継承がどこで行われているのか確認してください。 (importで始まる一行目はまだ説明していない内容なので小テストでは扱いません。無視してください) import javax.swing.JFrame; public class SampleWindow extends JFrame { public static void main(String args[]) { SampleWindow w = new SampleWindow(); w.setVisible(true); } } **第9章 エラーと例外処理 [#gd4f8eae] 次のプログラムを作って試してください。 引数が少ないとエラーが出るのを確認してください。 public class TestException { public static void main(String argv[]){ System.out.println(argv[0]+" "+argv[1]); System.out.println("Nice to meet you."); } } エラーが出る可能性のある場所をtryでくくっておき、 エラーが出たらそれを捕捉する処置をcatchで指定します。 public class TestException { public static void main(String argv[]){ try{ System.out.println(argv[0]+" "+argv[1]); System.out.println("Nice to meet you."); } catch (Exception e) { System.out.println("please input 2 words."); } } } **第10章 Stringクラスとコレクションフレームワーク [#w938c6ce] **第10章 Stringクラスとコレクションフレームワーク [#w938c6ce] ***最初の引数(文字列)を表示するプログラムを作る。クラス名はTestString [#xb389032] public class TestString { public static void main(String argv[]) { System.out.println(argv[0]); } } ***演習10.1改:最初の引数(文字列)を逆に出力するプログラムを作る [#k9b3a112] [e100:?/Documents/java] siio% java TestString ochanomizu ochanomizu uzimonahco [e100:?/Documents/java] siio% さらには、引数がない場合は引数入力を促すことを表示してみよう。 [e100:?/Documents/java] siio% java TestString please input a word [e100:?/Documents/java] siio% このソースは、 public class TestString { public static void main (String argv[]) { try{ System.out.println(argv[0]); int len = argv[0].length(); for(int i = len - 1; i>=0; i--) { System.out.print(argv[0].charAt(i)); } System.out.println(); } catch (Exception e) { System.out.println("please input a word"); } } } である。 ***Linked List の練習 [#d2a5cbd0] サンプルプログラムを実行するときは、 LinkedList<String> list = new LinkedList<String>(); などと定義すると良い。 ***program 10.2 改造 [#j2f946c0] Alice --> Bob --> Cindy --> DaveというLinkedListをつくって、 それからtoArray()メソッドでString配列を作ってfor each文で要素を印刷する import java.util.*; public class LinkedListTest{ public static void main(String[] argv) { LinkedList<String> list = new LinkedList<String>(); list.add("Alice"); list.add("Bob"); list.add("Dave"); list.add("Cindy"); Object[] names = list.toArray(); for(Object s: names ) System.out.println(s); } } ***Hash Mapの練習 [#jf7eb616] プログラム10.4を参考にして、 以下のように動作する英語ー日本語単語変換プログラムを作れ。 [e100:?/Documents/java] siio% java EtoJ banana バナナ [e100:?/Documents/java] siio% java EtoJ apple りんご [e100:?/Documents/java] siio% java EtoJ Please input an English word ヒント: import java.util.*; public class EtoJ{ public static void main(String args[]) { HashMap<String,String> map = new HashMap<String,String>(); map.put("apple","りんご"); map.put("banana","バナナ"); map.put("orange","みかん"); map.put("pineapple","パイナップル"); map.put("grape","ぶどう"); map.put("peach","もも"); map.put("melon","メロン"); map.put("lemon","レモン"); try { System.out.println(map.get(args[0])); } catch(Exception e) { System.out.println("Please input an English word"); } } } **第11章 入出力 [#hb3a05b8] ***一番簡単なファイル書き出し [#y92c37db] import java.io.*; public class FoutTest { public static void main(String[] args) { try { FileOutputStream fout = new FileOutputStream("fout.dat"); fout.write(1234); fout.close(); } catch (IOException e) { System.out.println(e); } } } これでfout.datという名前のファイルができあがるはずです。 作ったファイルを od -h fout.dat または hexdump fout.dat してみてください $ hexdump fout.dat 0000000 d2 0000001 1234は0x4d2だったのでその下1バイトが書き込まれました。 ***整数を出力する例 [#j899e2e7] import java.io.*; public class DoutTest { public static void main (String[] args) { try { FileOutputStream fout = new FileOutputStream("dout.dat"); DataOutputStream dout = new DataOutputStream(fout); dout.writeInt(100); dout.close(); }catch (Exception e) { System.out.println(e); } } } これでdout.datという名前のファイルができあがるはずです。 作ったファイルを od -h dout.dat または hexdump dout.dat してみてください e100:java siio$ hexdump dout.dat 0000000 00 00 00 64 0000004 ***整数を入出力する例 [#j899e2e7] import java.io.*; public class DoutTest { public static void main (String[] args) { try { FileOutputStream fout = new FileOutputStream("dout.dat"); DataOutputStream dout = new DataOutputStream(fout); dout.writeInt(100); dout.close(); FileInputStream finput = new FileInputStream("dout.dat"); DataInputStream dinput = new DataInputStream(finput); System.out.println(dinput.readInt()); dinput.close(); }catch (Exception e) { System.out.println(e); } } } ***演習11.1 をやってください [#z72d00c6] 作ったファイルを od -h dout.dat または hexdump dout.dat してみてください 解答例 import java.io.*; public class En111 { public static void main (String[] args) { int i; try { FileOutputStream fout = new FileOutputStream ("dout.dat"); DataOutputStream dout = new DataOutputStream(fout); for(i=1;i<101;i++) dout.writeInt(i); dout.close(); FileInputStream fin = new FileInputStream ("dout.dat"); DataInputStream din = new DataInputStream(fin); for(i=1;i<101;i++) System.out.println(din.readInt()); din.close(); } catch (FileNotFoundException e) { System.out.println(e); } catch (IOException e) { System.out.println(e); } } } ***プログラム11.3をやってみてください [#h15edee7] 作ったファイルを od -h または hexdump してみてください http://gyazo.com/74c061dfe2fcd6b72885878f867c78ba.png import java.io.*; public class PrintWriterTest{ public static void main(String[] args) { try { //writer.txtというファイルを作って文字を書き込む FileWriter fwriter = new FileWriter("writer.txt"); PrintWriter pwriter = new PrintWriter(fwriter); pwriter.println(2006); pwriter.println("Java教科書"); //fwriter.write("Java教科書"); pwriter.close(); } catch (IOException e) { System.out.println(e); } } } つぎに、プログラム11.4を参考にして、 このPrint Writer Testに書き足して、 書き込んだデータを読み出して画面に表示するプログラムを作ってください。 ヒント: import java.io.*; public class PrintWriterTest{ public static void main(String[] args) { try { //writer.txtというファイルを作って文字を書き込む FileWriter fwriter = new FileWriter("writer.txt"); PrintWriter pwriter = new PrintWriter(fwriter); pwriter.println(2006); pwriter.println("Java教科書"); //fwriter.write("Java教科書"); pwriter.close(); ここに書き足す } catch (IOException e) { System.out.println(e); } } } ***文字ストリームをファイルに書いて読み込むプログラム [#bed8144f] import java.io.*; public class PrintWriterTest{ public static void main(String[] args) { try { //writer.txtというファイルを作って文字を書き込む FileWriter fwriter = new FileWriter("writer.txt"); PrintWriter pwriter = new PrintWriter(fwriter); pwriter.println("java 教科書" + 2001 ); pwriter.close(); //writer.txtのファイルの中身をSystem.out.printlnで表示する FileReader freader = new FileReader("writer.txt"); BufferedReader breader = new BufferedReader(freader); String tmp; while( (tmp=breader.readLine() ) != null) { System.out.println(tmp); } breader.close(); } catch (IOException e) { System.out.println(e); } } } ***プログラム11.5をやってこれを拡張して演習11.2をやってください [#ya1ca508] キーボードから1行入力された文字列によるテキストファイルを作る http://gyazo.com/f9aee7f492d574f870e85e2022df374c.png ヒント import java.io.*; public class En112 { public static void main(String[] args) { try { ここにプログラムを書く } catch(IOException e) { System.out.println(e); } } } 解答例 import java.io.*; public class En112 { public static void main(String[] args) { try { InputStreamReader ireader = new InputStreamReader (System.in); BufferedReader breaderK = new BufferedReader(ireader); String line = breaderK.readLine(); FileWriter fwriter = new FileWriter("writer.txt"); PrintWriter pwriter = new PrintWriter(fwriter); pwriter.println(line); pwriter.close(); FileReader freader = new FileReader("writer.txt"); BufferedReader breaderF = new BufferedReader(freader); String tmp=null; while( (tmp=breaderF.readLine()) != null) System.out.println(tmp); breaderF.close(); } catch(IOException e) { System.out.println(e); } } } ***http://www.ocha.ac.jp/の内容を表示するプログラムを書いてみよう [#kf0c5bf6] http://gyazo.com/13044fdd9d372118a1f6fe93896eadb3.png ヒント1 import java.net.*; が必要です。 URL targetURL = new URL("http://www.ocha.ac.jp/"); でURLクラスのインスタンスが得られる。 InputStream istream = targetURL.openStream(); でこれからInputStreamのインスタンスが得られる。 InputStreamReader isreader = new InputStreamReader(istream); でこれからInputStreamReaderのインスタンスが得られる。 BufferedReader breader = new BufferedReader( isreader ); でこれからBufferedReader のインスタンスが得られる。 ヒント2 import java.io.*; import java.net.*; public class URLTest { public static void main (String argv[]) { try { ここにプログラムを書く } catch (IOException e) { System.out.println("error..."); } } } ヒント3: import java.io.*; import java.net.*; public class URLTest { public static void main (String argv[]) { try { URL targetURL = new URL("http://www.ocha.ac.jp/"); InputStream istream = targetURL.openStream(); InputStreamReader isreader = new InputStreamReader(istream); BufferedReader breader = new BufferedReader( isreader ); ここで一行ずつ読み込む } catch (IOException e) { System.out.println("error..."); } } } 解答例: import java.io.*; import java.net.*; public class URLTest { public static void main (String argv[]) { try { URL targetURL = new URL("http://www.ocha.ac.jp/"); InputStream istream = targetURL.openStream(); InputStreamReader isreader = new InputStreamReader(istream); BufferedReader breader = new BufferedReader( isreader ); String line; while((line=breader.readLine()) != null) System.out.println(line); } catch (IOException e) { System.out.println("error..."); } } } ***写真ファイルのダウンロード [#edb3e256] http://siio.jp/cat.jpg をダウンロードして、cat.jpgというファイルを作るプログラムを作ってください。 データはテキストじゃなくて、バイナリーです。 ヒント1: InputStreamのインスタンスに対してread()メソッドを使うと1バイトのデータが得られます。読み終わると-1になります。 1バイトのデータを書き出すなら、FileOutputStreamだけで可能です。 ヒント2: import java.io.*; import java.net.*; public class URLJpeg { public static void main (String argv[]) { try { URL targetURL = new URL("http://siio.jp/cat.jpg"); InputStream istream = targetURL.openStream(); FileOutputStream fout = new FileOutputStream("cat.jpg"); というインスタンスを作って、 istream.read() で読んで、 fout.write(1バイト) で書き出します。 解答例 import java.io.*; import java.net.*; //http://siio.jp/cat.jpg //をダウンロードして、cat.jpgというファイルを作るプログラム public class URLJpeg { public static void main (String argv[]) { try { URL targetURL = new URL("http://siio.jp/cat.jpg"); InputStream istream = targetURL.openStream(); FileOutputStream fout = new FileOutputStream("cat.jpg"); int aData; while((aData = istream.read()) != -1) fout.write(aData); istream.close(); fout.close(); } catch (IOException e) { System.out.println("error..."); } } } ***本日のレポート [#o4524903] 上記のプログラム(URLJpeg.java, URLJpeg.class) を、出席番号+名前のフォルダにいれて、ZIP圧縮して提出してください。` ***写真読み込みの高速化 [#ia7ce1f8] 上記の例では写真データを1バイトずつ読み書きしていました。 InputStreamのメソッドを調べると、複数バイト単位で読み込むメソッドがあります。 たとえば、1024バイトずつ読み書きすることで、処理速度が向上すると期待できます。 そこで、複数バイト読み書きするよう、上記のプログラムを変更して、 実際にどの程度(実行速度にして何倍くらい)性能向上するか確認してみましょう。 read public int read(byte[] b) throws IOException 入力ストリームから配列長さだけのバイト数を読み込もうとし、それをバッファ配列 b に格納します。 実際に読み込まれたバイト数は整数として返されます。 戻り値は、バッファに読み込まれたバイトの合計数。ストリームの終わりに達してデータがない場合は -1 を使って読みこみ、 write public void write(byte[] b, int off, int len) throws IOException 指定された byte 配列の、オフセット位置 off から始まる len バイトを出力ストリームに書き込みます。 を使ってください。 -ヒント byte[] data = new byte[1024]; という配列を用意して、 int datalength; while(( datalength=istream.read(data)) != -1) fout.write(data, 0, datalength); とします。 -解答例 import java.io.*; import java.net.*; //http://siio.jp/cat.jpg //をダウンロードして、cat.jpgというファイルを作るプログラムを作ってください。 //データはテキストじゃなくて、バイナリーです。 public class URLJpeg2 { public static void main (String argv[]) { byte[] data = new byte[1024]; try { URL targetURL = new URL("http://siio.jp/cat.jpg"); InputStream istream = targetURL.openStream(); FileOutputStream fout = new FileOutputStream("cat.jpg"); int datalength; while(( datalength=istream.read(data)) != -1) fout.write(data, 0, datalength); istream.close(); fout.close(); } catch (IOException e) { System.out.println("error..."); } } } ここでは1024バイトを読み込むことにしました。でも、InputStreamのメソッドを見ると、available()というのがあります。 available() この入力ストリームのメソッドの次の呼出しによって、ブロックせずにこの入力ストリームから読み込むことができる(またはスキップできる)推定バイト数を返します。 これを使えば、適切な長さを見積もれるかもしれません。 ***引数のURLをファイルにするプログラムを考えてみましょう [#mc747214] curlというコマンドがあります。 curl http://ocha.ac.jp/ などとすると、htmlが見られますし、 curl http://siio.jp/cat.jpg > cat.jpg などとすると、ファイルとして保存できます。これに近いプログラムを作ってみましょう。 ***宿題 [#wb66142e] 上記の引数のURLをファイルにするプログラムを作ってください。 また、cat.jpgのファイル取得でまとめて読むことでどれくらい速度が改善したかを、 レポートにしてください。レポートの書式は任意です。(テキストファイルでかまいません) これらのjava, class, レポートのファイルをまとめて、出席番号+名前のフォルダに入れて、圧縮して、12月10日の授業の開始時間に提出してください。 **第12章 Swing [#w5863135] ***とても簡単なウィンドウ [#r57b34f9] import javax.swing.JFrame; public class SimpleWindow { public static void main(String argv[]) { JFrame f = new JFrame("私が作った最初の窓"); f.setSize(200,100); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); } } *** JFrameを継承するプログラミング [#y09a72d9] import javax.swing.JFrame; public class SimpleWindow extends JFrame { public void initialize () { this.setTitle("私が作った最初の窓"); this.setSize(200,100); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } public static void main (String argv[]) { SimpleWindow sw = new SimpleWindow(); sw.initialize(); } } ***ラベルを表示するウィンドウ [#xedfffec] プログラム12.1を参考にして、上記の、継承を使ったプログラムによるウィンドウの中に、 Hello!という文字を出してみよう。 http://gyazo.com/c6efe47de19436f7564660377fe8b98c.png 解答例: import javax.swing.*; import java.awt.*; public class SimpleWindow extends JFrame { public void initialize () { this.setTitle("私が作った最初の窓"); JLabel label = new JLabel("Hello!"); Container container = this.getContentPane(); container.add(label); this.pack(); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String argv[]) { SimpleWindow sw = new SimpleWindow(); sw.initialize(); } } ***ボタンを1個表示するウィンドウ [#p41c305c] 上記のプログラムのJPanelのところをJButtonにしてみましょう。 解答例: import javax.swing.*; import java.awt.*; public class SimpleWindow extends JFrame { public void initialize () { this.setTitle("私が作った最初の窓"); JButton button = new JButton("Hello!"); Container container = this.getContentPane(); container.add(button); this.pack(); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String argv[]) { SimpleWindow sw = new SimpleWindow(); sw.initialize(); } } http://www.siio.jp/index.php?plugin=attach&pcmd=open&file=button.png&refer=How2JavaProgramming ***ボタンを2個表示するウィンドウ [#cb6cf696] プログラム12.2をみてください。 getContentPane()で得られたContainerに直接ボタンを貼付けることもできますが、 貼付けられるのは一つのボタンだけのようです。 そこで、JPanel (パネル) に2個のボタンを貼付け、それをContainerに貼付けることで複数のボタンを表示しています。 http://gyazo.com/03c28df2419065241b8736b7b69d7fd3.png プログラム12.2を参考にして、継承を使ったプログラムによるウィンドウの中に、 2個のボタンを出してみよう。 http://gyazo.com/4c3086ae9b6b5434d2ea741369f731c5.png 解答例: import javax.swing.*; import java.awt.*; public class SimpleButton extends JFrame { public void initialize () { this.setTitle("私が作った最初の窓"); JPanel panel = new JPanel(); JButton button1 = new JButton("button1"); JButton button2 = new JButton("button2"); panel.add(button1); panel.add(button2); Container container = this.getContentPane(); container.add(panel); this.pack(); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String argv[]) { SimpleButton sw = new SimpleButton(); sw.initialize(); } } このプログラムでは,ボタンを押しても何もおこりません. ボタンが押されたイベントを受け取るためには, +ActionListenerをimplementしたクラスを作る +そのインスタンスを作る +これをボタンにaddActionListener()で登録する 必要があります. プログラム12.3を参考に,ボタンを押したらprintlnで次のようなメッセージを表示するプログラムを作ってみましょう. http://gyazo.com/67d27d0588f4dd5d11410e1107165994.png ヒント(最初の6行です) import javax.swing.*; import java.awt.*; import java.awt.event.*; public class SimpleButton extends JFrame implements ActionListener { JButton button1, button2; public void initialize () { 解答例 import javax.swing.*; import java.awt.*; import java.awt.event.*; public class SimpleButton extends JFrame implements ActionListener { JButton button1, button2; public void initialize () { this.setTitle("私が作った最初の窓"); JPanel panel = new JPanel(); button1 = new JButton("button1"); button2 = new JButton("button2"); button1.addActionListener(this); button2.addActionListener(this); panel.add(button1); panel.add(button2); Container container = this.getContentPane(); container.add(panel); this.pack(); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public void actionPerformed (ActionEvent e) { if(e.getSource()==button1) System.out.println("Hello"); else System.out.println("Goodbye"); } public static void main(String argv[]) { SimpleButton sw = new SimpleButton(); sw.initialize(); } } ここではボタンを区別するために、インスタンス(への参照)を比較した。それ以外の方法もある。 一つは、ボタンのテキストを入手することである。ボタンのテキストを入手してそれを比較しても良い。 ボタンのテキストを表示するだけなら以下のようにしても良い。 public void actionPerformed(ActionEvent e){ System.out.println(((JButton)e.getSource()).getText()); } もう一つは、ボタンにコマンドを書く方法である。 ボタンにsetActionCommand(String)を定義しておくと、getActionCommand()で知ることができる。 button1.setActionCommand("hello"); としておけば、actionPerformedの中で e.getActionCommand(); で文字列を得られる。例えば、 public void actionPerformed(ActionEvent e){ System.out.println(e.getActionCommand()); } でコマンド部分を印刷できる。 //***宿題:プログラム12.4 [#sb6fece9] ***プログラム12.4をやってください。 [#k14ed280] ***演習12.2(改) [#q3f681b0] 上で作った二つのボタンのプログラムに対して、レイアウトマネージャのFlowLayoutを使って、左寄せ、センタリング、右寄せを試してください。 演習のヒント bt1 = new JButton("button1"); bt2 = new JButton("button2"); panel.setLayout(new FlowLayout(FlowLayout.RIGHT)); bt1.setActionCommand("this is b1"); bt2.setActionCommand("this is b2"); FlowLayoutにはCENTER, LEFT, RIGHTなどの揃え方の指定がありますが、これをコンストラクタの引数で指定できるようです。addのところではレイアウト指定しないようです。 **第13章 様々なコンポーネントとレイアウト [#nfdf4f5e] ***プログラム13.1の説明図 [#ec2d7584] http://gyazo.com/649bbe400f96c8c31923bcf7e5aebbd4.png ***演習:プログラム13.1のようにボタンを配置して、それぞれを押すと、それぞれのボタンの名前が表示されるプログラムを作ってください。 [#f4fb000e] ヒント:プログラム12.4を見て、上記のプログラムを拡張して5個のボタンに対応して, WEST, EAST, SOUTH, NORTH, CENTERと表示されるプログラム作るとわかりやすいかもしれません。そうすれば、プログラム13.1のボタンの名前を表示するプログラムが作りやすいと思います。 なお、以下のようにすると、ボタンの名前を印刷することができます。 public void actionPerformed(ActionEvent e){ System.out.println(((JButton)e.getSource()).getText()); } プログラム12.4は継承を使っていないので以下のように書き直します。 import java.awt.*; import javax.swing.*; import java.awt.event.*; public class ComplicatedLayoutSample extends JFrame implements ActionListener { public void initialize() { JPanel panel1 = new JPanel(); JPanel panel2= new JPanel(); JPanel panel3= new JPanel(); JPanel panel4= new JPanel(); JPanel panel5= new JPanel(); panel1.setLayout(new FlowLayout()); for (int i=1; i<=3; i++) { panel1.add(new JButton("NORTH" + i)); } panel2.setLayout(new BoxLayout(panel2, BoxLayout.Y_AXIS)); for (int i=1; i<=3; i++) { panel2.add(new JButton("WEST" + i)); } panel3.setLayout(new GridLayout(3,2)); for (int i=1; i<=6; i++) { panel3.add(new JButton("CENTER" + i)); } panel4.setLayout(new BorderLayout()); panel4.add(new JButton("EAST1"), BorderLayout.NORTH); panel4.add(new JButton("EAST2"), BorderLayout.SOUTH); panel5.setLayout(new BoxLayout(panel5, BoxLayout.X_AXIS)); for (int i=1; i<=4; i++) { panel5.add(new JButton("SOUTN" + i)); } Container container = this.getContentPane(); container.add(panel1,BorderLayout.NORTH); container.add(panel2,BorderLayout.WEST); container.add(panel3,BorderLayout.CENTER); container.add(panel4,BorderLayout.EAST); container.add(panel5,BorderLayout.SOUTH); this.setSize(400,200); this.setVisible(true); } public void actionPerformed(ActionEvent e) { } public static void main(String[] args) { ComplicatedLayoutSample cls = new ComplicatedLayoutSample(); cls.initialize(); } } つぎにaction listenerとして自分自身を追加します。 import java.awt.*; import javax.swing.*; import java.awt.event.*; public class ComplicatedLayoutSample extends JFrame implements ActionListener { public void initialize() { JPanel panel1 = new JPanel(); JPanel panel2= new JPanel(); JPanel panel3= new JPanel(); JPanel panel4= new JPanel(); JPanel panel5= new JPanel(); panel1.setLayout(new FlowLayout()); for (int i=1; i<=3; i++) { JButton btn = new JButton("NORTH" + i); btn.addActionListener(this); panel1.add(btn); } panel2.setLayout(new BoxLayout(panel2, BoxLayout.Y_AXIS)); for (int i=1; i<=3; i++) { JButton btn = new JButton("WEST" + i); btn.addActionListener(this); panel2.add(btn); } panel3.setLayout(new GridLayout(3,2)); for (int i=1; i<=6; i++) { JButton btn = new JButton("CENTER" + i); btn.addActionListener(this); panel3.add(btn); } panel4.setLayout(new BorderLayout()); JButton btn1 = new JButton("EAST1"); btn1.addActionListener(this); panel4.add(btn1, BorderLayout.NORTH); JButton btn2 = new JButton("EAST2"); btn2.addActionListener(this); panel4.add(btn2, BorderLayout.SOUTH); panel5.setLayout(new BoxLayout(panel5, BoxLayout.X_AXIS)); for (int i=1; i<=4; i++) { JButton btn = new JButton("SOUTN" + i); btn.addActionListener(this); panel5.add(btn); } Container container = this.getContentPane(); container.add(panel1,BorderLayout.NORTH); container.add(panel2,BorderLayout.WEST); container.add(panel3,BorderLayout.CENTER); container.add(panel4,BorderLayout.EAST); container.add(panel5,BorderLayout.SOUTH); this.setSize(400,200); this.setVisible(true); } public void actionPerformed(ActionEvent e) { System.out.println( ((JButton)e.getSource()).getText() ); } public static void main(String[] args) { ComplicatedLayoutSample cls = new ComplicatedLayoutSample(); cls.initialize(); } } ***どのボタンからのイベントであるかを識別する方法 [#i076dba0] -プログラム12.3では --ボタンへの参照を、action Performedから参照できる変数に入れて --action Performedの中で、e.get Source()してButtonのインスタンスを得て比較している -プログラム12.4では、 --準備として button.set Action(button.get Text());でボタン文字をactionとして設定して -- action Performedの中で e.get Action Command()でアクションを得て文字比較している -ということで以下のようなことが可能です --acttion Performedの中で、get Source()してボタンを得る --そのボタンからget Textしてボタンの文字列を得て文字比較する --ただし、get Sourceで得られるのはボタンの親クラスなのでButtonにキャストする --以下をaction Performedのなかで試してみよう System.out.println((JButton)(e.getSource()).getText()); ***13.2節を読んで,プログラム13.2を実行させてください [#s05a9149] ボタンが一つしかないプログラムなので、ActionPerformedの中で、 ボタン種類のチェックを省略してしまっているところが特徴です。 import java.awt.*; import javax.swing.*; import java.awt.event.*; public class JTextFieldSample extends JFrame implements ActionListener { JButton button; JTextField textleft, textright; public void initialize() { button = new JButton("left to right"); button.addActionListener(this); textleft= new JTextField(10); textright= new JTextField(10); JPanel panel = new JPanel(); panel.setLayout(new BorderLayout()); panel.add(textleft, BorderLayout.WEST); panel.add(textright, BorderLayout.EAST); panel.add(button, BorderLayout.SOUTH); this.getContentPane().add(panel); this.setTitle("JTextFieldSample"); this.pack(); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } public void actionPerformed(ActionEvent e){ textright.setText(textleft.getText()); textleft.setText(""); } public static void main(String[] args){ JTextFieldSample sample = new JTextFieldSample(); sample.initialize(); } } ***演習13.1をやってください [#xc59c932] このプログラムに、右のテキストフィールドをクリアするclearボタンを追加してください。 こんなのをつくってください。 http://gyazo.com/999f1e766551a994186cc3d159bde0bf.png BorderLayoutでもできるようですが、私はGridLayour使ってみました。 panel.setLayout(new GridLayout(2,2)); panel.add(textleft); panel.add(textright); panel.add(button); panel.add(clearbutton); ボタンが複数になるので、ActionPerformedの中で、ボタンを区別する必要があります。 //演習ができそうにないという人は、飛ばして、次に進んでください。 解答例(コンストラクタで作る) import java.awt.*; import javax.swing.*; import java.awt.event.*; public class JTextFieldSample extends JFrame implements ActionListener { JButton button, clearButton; JTextField textleft, textright; JTextFieldSample(String title) { setTitle(title); button = new JButton("left to right"); clearButton = new JButton("clear"); button.addActionListener(this); clearButton.addActionListener(this); textleft = new JTextField(10); textright = new JTextField(10); JPanel panel=new JPanel(); panel.setLayout(new GridLayout(2,2)); panel.add(textleft); panel.add(textright); panel.add(button); panel.add(clearButton); Container container=this.getContentPane(); container.add(panel); } public void actionPerformed(ActionEvent e) { if(e.getSource()==(button)) { textright.setText(textleft.getText()); textleft.setText(""); }else if(e.getSource()==(clearButton)) { textright.setText(""); } } public static void main(String[] args) { JTextFieldSample sample = new JTextFieldSample("JTextFieldSample"); sample.pack(); sample.setVisible(true); sample.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } 解答例(初期化メソッドで作る) import java.awt.*; import javax.swing.*; import java.awt.event.*; public class JTextFieldSample extends JFrame implements ActionListener { JButton button, clearButton; JTextField textleft, textright; public void initialize() { button = new JButton("left to right"); button.addActionListener(this); clearButton = new JButton("clear"); clearButton.addActionListener(this); textleft= new JTextField(10); textright= new JTextField(10); JPanel panel = new JPanel(); panel.setLayout(new GridLayout(2,2)); panel.add(textleft); panel.add(textright); panel.add(button); panel.add(clearButton); this.getContentPane().add(panel); this.setTitle("JTextFieldSample"); this.pack(); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } public void actionPerformed(ActionEvent e){ if( e.getSource() == button) { textright.setText(textleft.getText()); textleft.setText(""); }else{ textright.setText(""); } } public static void main(String[] args){ JTextFieldSample sample = new JTextFieldSample(); sample.initialize(); } } ***どのボタンからのイベントであるかを識別する方法 [#i076dba0] action Performed (Action Event e) の中で、 -e.get Source()してButtonのインスタンスを得て比較する -e.get Action Command()でアクションを得て文字比較する --あらかじめbutton.set Action(”アクション名")しておく -ボタンからget Textしてボタンの文字列を得て文字比較する --get Sourceで得られるのはボタンの親クラスなのでButtonにキャストする System.out.println((JButton)(e.getSource()).getText()); ***13.4節を読んで、プログラム13.4を実行してください [#r6b71c7b] JListの型を指定しないとコンパイラの警告が出ます。警告を出さないためには、以下のように宣言すると良いようです。 JList<String> list = new JList<String>(data); こんな感じです。 import java.awt.*; import javax.swing.*; public class JListSample extends JFrame { JListSample(String title){ String[] data = {"Iced Coffee","Iced Tea","Iced Cafe-latte","Blended Coffee","Hot Tea","Espresso","Cappuccino"}; JList<String> list = new JList<String>(data); JScrollPane scroll = new JScrollPane(list); scroll.setPreferredSize(new Dimension(200,100)); JPanel panel = new JPanel(); this.getContentPane().add(scroll); this.setTitle(title); this.pack(); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args){ new JListSample("List Sample"); } } ***13.5節を読んで,プログラム13.5を実行してください [#o616a647] http://gyazo.com/dd4e103c011682b3a78b9ed0c8d5134b.png http://gyazo.com/4755cce7280963b32050db455d265cc1.png まずはシンプルなプルダウンメニューを作ってみましょう。 このプログラムは何もしません。 http://siio.jp/gyazo/JMenuSample1.png import java.awt.*; import javax.swing.*; import java.awt.event.*; public class JMenuSample extends JFrame implements ActionListener { public void initialize() { this.setTitle("MenuSample"); JMenuBar menubar = new JMenuBar(); JMenu menu = new JMenu("menu"); JMenuItem item1 = new JMenuItem("Sandwiches"); JMenuItem item2 = new JMenuItem("Side Orders"); JMenuItem item3 = new JMenuItem("Drinks"); menu.add(item1); menu.add(item2); menu.add(item3); menubar.add(menu); this.setJMenuBar(menubar); this.setSize(400,200); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public void actionPerformed(ActionEvent e){ } public static void main(String[] args) { JMenuSample sample = new JMenuSample(); sample.initialize(); } } メニューにはメニューを追加することもできます。 上でitem3をメニューに変更すると、これにitemを追加できます。 http://siio.jp/gyazo/JMenuSample2.png import java.awt.*; import javax.swing.*; import java.awt.event.*; public class JMenuSample extends JFrame implements ActionListener { public void initialize() { this.setTitle("MenuSample"); JMenuBar menubar = new JMenuBar(); JMenu menu = new JMenu("menu"); JMenuItem item1 = new JMenuItem("Sandwiches"); JMenuItem item2 = new JMenuItem("Side Orders"); JMenu item3 = new JMenu("Drinks"); menu.add(item1); menu.add(item2); menu.add(item3); JMenuItem subitem1 = new JMenuItem("Iced Coffee"); JMenuItem subitem2 = new JMenuItem("Iced Tea"); item3.add(subitem1); item3.add(subitem2); menubar.add(menu); this.setJMenuBar(menubar); this.setSize(400,200); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public void actionPerformed(ActionEvent e){ } } public static void main(String[] args) { JMenuSample sample = new JMenuSample(); sample.initialize(); } } それぞれのitemに、フレーム自身をaction Listenerとして登録すれば、イベントを受け付けることができます。 ここでは、メニューアイテムにcommandという情報をつけて、ActionPerformedではこれを使ってメニュー項目を区別しています。 import java.awt.*; import javax.swing.*; import java.awt.event.*; public class JMenuSample extends JFrame implements ActionListener { public void initialize() { this.setTitle("MenuSample"); JMenuBar menubar = new JMenuBar(); JMenu menu = new JMenu("menu"); JMenuItem item1 = new JMenuItem("Sandwiches"); item1.addActionListener(this); item1.setActionCommand("Sandwiches"); JMenuItem item2 = new JMenuItem("Side Orders"); item2.addActionListener(this); item2.setActionCommand("Side Orders"); JMenu item3 = new JMenu("Drinks"); menu.add(item1); menu.add(item2); menu.add(item3); JMenuItem subitem1 = new JMenuItem("Iced Coffee"); subitem1.addActionListener(this); subitem1.setActionCommand("Iced Coffee"); JMenuItem subitem2 = new JMenuItem("Iced Tea"); subitem2.addActionListener(this); subitem2.setActionCommand("Iced Tea"); item3.add(subitem1); item3.add(subitem2); menubar.add(menu); this.setJMenuBar(menubar); this.setSize(400,200); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public void actionPerformed(ActionEvent e){ String command = e.getActionCommand(); if(command != null){ System.out.println(command); } } public static void main(String[] args) { JMenuSample sample = new JMenuSample(); sample.initialize(); } } ***演習13.2をやってください(メニュー項目は何でも良いです) [#rba61398] 演習ができそうにないという人は、飛ばして、次に進んでください。 http://gyazo.com/2d9c3b6534e7b87fcd3ec22be00d5fed.png 他のメニューの追加も試してみましょう。例えばお支払いメニュー。 http://siio.jp/gyazo/JMenuSample3.png ***13.6節を読んで,プログラム13.6を実行してください [#k36e1b9b] ちなみに、今のjavaのバージョンではボタンの色は変わらないようです。 教科書203ページのプログラム13.6の5行めのところに、 ... implements ActionListener6: { とありますが、これは、 ... implements ActionListener { の間違いのようです。 **終章 おまけ [#s65aaa02] ***マウスイベント [#cc8c3961] マウスイベントを受け取るには、Mouse ListenerやMouse Motion Listenerなどをインプリメントします。 以下のようにするとイベントをうけとれるます。 まずはMouse Motion Listenerを試してみましょう。 マニュアル - https://docs.oracle.com/javase/jp/8/docs/api/java/awt/event/MouseMotionListener.html によると、実装しないといけないメソッドはmouse Draggedとmouse Movedです。 - void mouseDragged(MouseEvent e) コンポーネント上でマウス・ボタンを押してドラッグすると呼び出されます。 - void mouseMoved(MouseEvent e) ボタンを押さずにマウス・カーソルをコンポーネント上に移動すると呼び出されます。 import java.awt.*; import javax.swing.*; import java.awt.event.*; public class MouseTest extends JFrame implements MouseMotionListener{ public void mouseDragged(MouseEvent e) { System.out.println("mouse dragged!"); } public void mouseMoved(MouseEvent e) { System.out.println("mouse moved!"); } public static void main(String[] args) { MouseTest test = new MouseTest(); test.setTitle("MouseTest"); test.addMouseMotionListener(test); test.setSize(400,300); test.setVisible(true); test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } 次に、Mouse Listenerも実装してみましょう。マニュアル - https://docs.oracle.com/javase/jp/7/api/java/awt/event/MouseListener.html によると、 - void mouseClicked(MouseEvent e) コンポーネント上でマウスボタンをクリック (押してから離す) したときに呼び出されます。 - void mouseEntered(MouseEvent e) コンポーネントにマウスが入ると呼び出されます。 - void mouseExited(MouseEvent e) コンポーネントからマウスが出ると呼び出されます。 - void mousePressed(MouseEvent e) コンポーネント上でマウスボタンが押されると呼び出されます。 - void mouseReleased(MouseEvent e) コンポーネント上でマウスボタンが離されると呼び出されます。 これを追加します。 これを追加します。宣言で import java.awt.*; import javax.swing.*; import java.awt.event.*; public class MouseTest extends JFrame implements MouseListener, MouseMotionListener{ public void mouseClicked(MouseEvent e) { System.out.println("mouse clicked!"); } public void mouseEntered(MouseEvent e) { System.out.println("mouse entered!"); } public void mouseExited(MouseEvent e) { System.out.println("mouse exited!"); } public void mousePressed(MouseEvent e) { System.out.println("mouse pressed!"); } public void mouseReleased(MouseEvent e) { System.out.println("mouse released!"); } public void mouseDragged(MouseEvent e) { System.out.println("mouse dragged!"); } public void mouseMoved(MouseEvent e) { System.out.println("mouse moved!"); } public static void main(String[] args) { MouseTest test = new MouseTest(); test.setTitle("MouseTest"); test.addMouseListener(test); test.addMouseMotionListener(test); test.setSize(400,300); test.setVisible(true); test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } として、またmainに test.addMouseListener(test); を追加します。 import java.awt.*; import javax.swing.*; import java.awt.event.*; public class MouseTest extends JFrame implements MouseListener, MouseMotionListener{ public void mouseClicked(MouseEvent e) { System.out.println("mouse clicked!"); } public void mouseEntered(MouseEvent e) { System.out.println("mouse entered!"); } public void mouseExited(MouseEvent e) { System.out.println("mouse exited!"); } public void mousePressed(MouseEvent e) { System.out.println("mouse pressed!"); } public void mouseReleased(MouseEvent e) { System.out.println("mouse released!"); } public void mouseDragged(MouseEvent e) { System.out.println("mouse dragged!"); } public void mouseMoved(MouseEvent e) { System.out.println("mouse moved!"); } public static void main(String[] args) { MouseTest test = new MouseTest(); test.setTitle("MouseTest"); test.addMouseListener(test); test.addMouseMotionListener(test); test.setSize(400,300); test.setVisible(true); test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } ***サウンドファイルを再生する [#g86f7ead] -以下のファイルをダウンロードしてください。 http://siio.jp/lecture/Sounds/Ping.aiff (他にも、Basso.aiff Frog.aiff Hero.aiff Pop.aiff Submarine.aiff Blow.aiff Funk.aiff Morse.aiff Purr.aiff Tink.aiff Bottle.aiff Glass.aiff Ping.aiff Sosumi.aiff を置いておきました) これを再生するプログラムを作ってみましょう。以下で再生できます。 import java.io.File; import javax.sound.sampled.*; public class AudioInputStreamExample { public static void main(String[] args) { try { File file = new File("Ping.aiff"); AudioInputStream stream = AudioSystem.getAudioInputStream(file); Clip clip = AudioSystem.getClip(); clip.open(stream); clip.start(); // sleep to allow enough time for the clip to play Thread.sleep(500); stream.close(); } catch (Exception ex) { System.out.println(ex.getMessage()); } } } //(以下のプログラムは2015年以降のバージョンで音が出なかった) // // import java.io.*; // import javax.sound.sampled.*; // // public class AudioPlay { // public static void main(String[] args) { // try{ // File audioFile = new File("Ping.aiff"); // AudioFormat format = AudioSystem.getAudioFileFormat(audioFile).getFormat(); // DataLine.Info info = new DataLine.Info(Clip.class, format); // Clip clip = (Clip)AudioSystem.getLine(info); // // clip.open(AudioSystem.getAudioInputStream(audioFile)); // clip.start(); // clip.drain(); // clip.close(); // } // catch(Exception e){ // e.printStackTrace(); // } // } // } ***他の環境でのGUIプログラミングの例 [#r2f2f8d0] ***X11 [#dd5927c8] 以下の内容の新しいファイル,buttontest.cを作ってください. printfの逆スラッシュが正しくコピペできてないかもしれないので,注意してください. 入力が面倒なら,添付ファイルの [[buttontest.c:http://lab.siio.jp/index.php?plugin=attach&pcmd=open&file=buttontest.c&refer=Lecture]] をダウンロードしてください. #include <X11/Xlib.h> #include <stdio.h> int main (){ Display *display = XOpenDisplay (NULL); XEvent event; Window window = XCreateSimpleWindow(display, DefaultRootWindow(display),0,0,150,100,0,0,0); XSelectInput(display,window,KeyPressMask | ButtonPressMask | ButtonReleaseMask); XMapWindow(display, window); XFlush(display); while(1) { XNextEvent(display,&event); switch (event.type) { case KeyPress: printf("key\n"); break; case ButtonPress: printf("button down\n"); printf("button\n"); break; case ButtonRelease: printf("button up\n"); break; } } return 0; } 以下のコマンドでコンパイルしてください. cc -L/usr/X11R6/lib -I/usr/X11R6/include buttontest.c -lX11 出来上がったファイルを,./a.outで実行してください. ***Mac OS X [#nf4b4468] How2MacOSXProgramming を見てください ***iPhone [#f0103cac] How2iPhoneProgramming を見てください *** 簡単なアニメーション [#z5939b7b] -まずはなにもしないウィンドウを出します import java.awt.*; import javax.swing.*; import java.awt.event.*; class SimpleAnime extends JFrame { private void init() { this.setTitle("SimpleAnime"); this.setSize(300,200); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { SimpleAnime frame = new SimpleAnime(); frame.init(); } } -次に動くボールを出します import java.awt.*; import javax.swing.*; import java.awt.event.*; class SimpleAnime extends JFrame { JPanel panel; Graphics g; private void init() { this.setTitle("SimpleAnime"); this.setSize(300,200); panel = new JPanel(); this.getContentPane().add(panel); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); g=panel.getGraphics(); g.setColor(Color.blue); int x=0, xdelta=10; while(true) { g.fillOval(x,80,50,50); try{Thread.sleep(50);}catch(Exception e){} g.clearRect(x, 80, 52,52); x+=xdelta; if(x>250) xdelta=-10; if(x<0) xdelta=10; } } public static void main(String[] args) { SimpleAnime frame = new SimpleAnime(); frame.init(); } } http://gyazo.com/12d1f047af8d4f87f7199c8a7db66080.png -マルチスレッド化する 上記のプログラムでは、main()で、frame.init()したあと、このメソッドで無限にアニメーション書き換えを行うことになります。なので、二度とmain()には戻ってきません。(以下で示した、メニューは、また別のスレッドで動くので、このままでも動きます) アニメーションだけをするなら、これでも良いのですが、他にも仕事をしたい場合には難しいですし、やれないことはないですが、タイミングを計るのが難しいです。ということで、アニメーションする部分は、別のスレッドにして、そちらに任せてしまうのが通常です。 以下のように、別のインスタンスを別スレッドで動かします。別スレッドで動かすインスタンスを作るために、Animatorという名前のクラスを用意しました。別スレッドで動かすためには、Runnableをimplementする必要があります。ここで必須のrunというメソッドが、裏で実行されるので、そこに、上記のプログラムのアニメーション描画部分をそっくり移動させます。Graphics gの情報を伝えておく必要があるので、それを設定するメソッドも作りました。アニメーションしつつ、main()の方で数字を表示しています。 import java.awt.*; import javax.swing.*; import java.awt.event.*; import java.lang.Thread; class Animator implements Runnable { Graphics g; public void setGraphics(Graphics animeG) { g=animeG; } public void run() { int x=0, xdelta=10; while(true) { g.fillOval(x,80,50,50); try{Thread.sleep(50);}catch(Exception e){} g.clearRect(x, 80, 52,52); x+=xdelta; if(x>250) xdelta=-10; if(x<0) xdelta=10; } } } class SimpleAnime extends JFrame { JPanel panel; Graphics g; Animator animator; private void init() { animator=new Animator(); this.setTitle("SimpleAnime"); this.setSize(300,200); panel = new JPanel(); this.getContentPane().add(panel); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); g=panel.getGraphics(); g.setColor(Color.blue); animator.setGraphics(g); new Thread(animator).start(); } public static void main(String[] args) { SimpleAnime frame = new SimpleAnime(); frame.init(); for(int i=0;;i++) { System.out.println(i); try {Thread.sleep(500);}catch(Exception e){} } } } -アニメーションボールの設定ができるアプリケーションを作ってみよう こういうのを作ってほしい http://lab.siio.jp/index.php?plugin=attach&pcmd=open&file=SimpleAnime.class&refer=Lecture ヒント:上のアニメーションのプログラムに、メニューを取り付けて、 action Performedでメニューからのイベントを受け取れば良いです。 メニューの動きは、プログラム本来の動きと並列に動いてくれるので、 上のアニメーションのようなアニメーション以外何もできない手抜きアニメーションでも、 メニューは動いてくれます。 ヒント: action Performed ではこうしたら良い public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); if(command=="red") g.setColor(Color.red); if(command=="blue") g.setColor(Color.blue); -余力があれば、ボールが当たったら音が出るようにしてみよう。 ヒント:メニューはSimple Animeでつくって、action listenerをanimatorにしました。メニューを作るところがながいので、メソッドに分けました。 import java.awt.*; import javax.swing.*; import java.awt.event.*; import java.lang.Thread; class Animator implements Runnable, ActionListener { 略 public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); if(command !=null) { System.out.println(command); } if(command=="red") g.setColor(Color.red); if(command=="blue") g.setColor(Color.blue); if(command=="yellow") g.setColor(Color.yellow); if(command=="fast") xdelta=30; if(command=="slow") xdelta=5; } 略 } class SimpleAnime extends JFrame { 略 private void makeMenu() { JMenuBar menubar = new JMenuBar(); JMenu menu = new JMenu("color"); JMenu menuSpeed = new JMenu("speed"); JMenuItem item1 = new JMenuItem("red"); item1.addActionListener(animator); item1.setActionCommand("red"); JMenuItem item2 = new JMenuItem("blue"); item2.addActionListener(animator); item2.setActionCommand("blue"); JMenuItem item3 = new JMenuItem("yellow"); item3.addActionListener(animator); item3.setActionCommand("yellow"); menu.add(item1); menu.add(item2); menu.add(item3); JMenuItem item4 = new JMenuItem("fast"); item4.addActionListener(animator); item4.setActionCommand("fast"); JMenuItem item5 = new JMenuItem("slow"); item5.addActionListener(animator); item5.setActionCommand("slow"); menuSpeed.add(item4); menuSpeed.add(item5); menubar.add(menu); menubar.add(menuSpeed); this.setJMenuBar(menubar); } 略 } -ボールの色と早さをメニューで指定する(解答編) 上記のプログラムにメニューを追加して、 ボールの色と速さをメニューで指定するようにしました。 メニューはメインのJFrameインスタンスで作ってこれに貼りつけていますが、 Action Listenerは、別スレッドで動いているAnimatorクラスのインスタンスとしました。 import java.awt.*; import javax.swing.*; import java.awt.event.*; import java.lang.Thread; class Animator implements Runnable, ActionListener { Graphics g; int xdelta =5; public void setGraphics(Graphics animeG) { g=animeG; } public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); if(command !=null) { System.out.println(command); } if(command=="red") g.setColor(Color.red); if(command=="blue") g.setColor(Color.blue); if(command=="yellow") g.setColor(Color.yellow); if(command=="fast") xdelta=30; if(command=="slow") xdelta=5; } public void run() { int x=0; while(true) { g.fillOval(x,80,50,50); try{Thread.sleep(50);}catch(Exception e){} g.clearRect(x, 80, 52,52); x+=xdelta; if(x>250) xdelta=-xdelta; if(x<0) xdelta=-xdelta; } } } class SimpleAnime extends JFrame { JPanel panel; Graphics g; Animator animator; private void makeMenu() { JMenuBar menubar = new JMenuBar(); JMenu menu = new JMenu("color"); JMenu menuSpeed = new JMenu("speed"); JMenuItem item1 = new JMenuItem("red"); item1.addActionListener(animator); item1.setActionCommand("red"); JMenuItem item2 = new JMenuItem("blue"); item2.addActionListener(animator); item2.setActionCommand("blue"); JMenuItem item3 = new JMenuItem("yellow"); item3.addActionListener(animator); item3.setActionCommand("yellow"); menu.add(item1); menu.add(item2); menu.add(item3); JMenuItem item4 = new JMenuItem("fast"); item4.addActionListener(animator); item4.setActionCommand("fast"); JMenuItem item5 = new JMenuItem("slow"); item5.addActionListener(animator); item5.setActionCommand("slow"); menuSpeed.add(item4); menuSpeed.add(item5); menubar.add(menu); menubar.add(menuSpeed); this.setJMenuBar(menubar); } private void init() { animator = new Animator(); this.setTitle("SimpleAnime"); this.setSize(300,200); this.makeMenu(); panel = new JPanel(); this.getContentPane().add(panel); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); g=panel.getGraphics(); g.setColor(Color.blue); animator.setGraphics(g); new Thread(animator).start(); } public static void main(String[] args) { SimpleAnime frame = new SimpleAnime(); frame.init(); for(int i=0;;i++) { System.out.println(i); try {Thread.sleep(500);}catch(Exception e){} } } } http://gyazo.com/d5db8ca6fa153520e94ee7d2b7a93915.png -この先改良すべきこと [#u99ec852] アニメーションの途中で、ボールがちらつくことがあります。 ボールの場所を矩形で消して、新しいボールを描いているので、 その途中の作業が見えてしまうからです。 これを無くすには、ダブルバッファの手法を用います。 すなわち、描画する面をもう一枚用意して、 そちらに描画し、 描画が終わったところで、一気に更新する方法です。 ダブルバッファの手法は、授業の最終課題である「お絵かきプログラム」のところで説明します。 *** 線を引く簡単なプログラム [#y4c3a992] JPanelのサブクラスを作りました。 import javax.swing.JPanel; import java.awt.Graphics; public class DrawPanel extends JPanel { public void drawLine(int x1, int y1, int x2, int y2){ Graphics g = this.getGraphics(); g.drawLine(x1, y1, x2, y2); } } こちらはメインのプログラム。JFrameのサブクラスで、これに上記のJPanelのサブクラスを貼付けます。 リスナーになっているので、こちらでマウスなどのイベントを受け取ります。 import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import javax.swing.JFrame; public class SimpleDraw extends JFrame implements MouseMotionListener { int lastx=0, lasty=0, newx, newy; DrawPanel panel; public void mouseMoved(MouseEvent arg0) { } public void mouseDragged(MouseEvent arg0) { newx=arg0.getX(); newy=arg0.getY(); panel.drawLine(lastx,lasty,newx,newy); lastx=newx; lasty=newy; } private void init() { this.setTitle("Simple Draw"); this.setSize(300, 200); this.addMouseMotionListener(this); panel=new DrawPanel(); this.getContentPane().add(panel); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { SimpleDraw frame=new SimpleDraw(); frame.init(); } } ***Java Appletの作り方 [#h726edf9] いままでは、Java Applicationを作ってました。 これはjavaコマンドから実行するアプリケーションでした。 このほか、Javaには、Java Appletという実行形式式があります。 Appletは、webページなどで動かすことができます。 もともとは、webサービスでクライアント側でアプリケーションを動かすために 開発されました。 AppletはAppletクラスを継承して作ります。 Appletクラスは、java.awt.Panelを継承しています。 なにができるのかは、java のマニュアルをみてください。 たとえば、次のようなプログラムをAppletTest.javaとして作ります。 これをコンパイルします。 import java.awt.*; import java.applet.*; public class AppletTest extends Applet { public void paint(Graphics g) { g.drawString("Hello World!!", 60, 30); } } これはhtmlの中から呼び出すことができます。 たとえば、つぎのような、index.htmlをつくります。 <html> <head><title>Applet Test</title></head> <body> <applet code="AppletTest.class" width="300" height="150"> </applet> </body> </html> これを、さきほどコンパイルしたclassと同じディレクトリにおいて、 webブラウザで開くと、java appletのプログラムが動きます。 http://gyazo.com/637225a1c08bef7e853944ad9b8ed390.png または、このhtmlファイルをアップレットビューアでみることもできます。 appletviewer index.html などして動作を確認できます。 http://gyazo.com/d8174aace858dc50e603ee0fef62bcf7.png つぎのようにすれば、上の先の例で示す、お絵描きプログラムも作ることができます。 init()は、起動したときに最初に一度だけ呼び出されるメソッドです。 import java.awt.*; import java.applet.*; import java.awt.event.MouseMotionListener; import java.awt.event.*; public class AppletTest extends Applet implements MouseMotionListener { int lastx,lasty,newx,newy; Graphics g; public void mouseMoved(MouseEvent arg0) { } public void mouseDragged(MouseEvent arg0) { newx=arg0.getX(); newy=arg0.getY(); g.drawLine(lastx,lasty,newx,newy); lastx=newx; lasty=newy; } public void paint(Graphics g) { g.drawString("Hello World!!", 60, 30); } public void init() { g=this.getGraphics(); this.addMouseMotionListener(this); } } appletviewerで見てみます。 http://gyazo.com/2c88f97c8f7234e5e3eb72dcd9b2713a.png webブラウザでもみてみましょう。 (注意:Safariでは、読み込まれたappletが残っていますので、 更新したappletを試すためには、 Safariを一旦終了して起動しなおしてください。) http://gyazo.com/143be91363a277f04a0fa8b1f5d5a43a.png webサーバにおけば、世界中から使うこともできます。以下をクリックしてみてください。 //以下の例では、次に述べる一筆書き問題は解消されています。 http://siio.jp/lecture/applet/ //***今日の課題 // //上で紹介したappletを、一筆書きにならないように変更してみてください。 //やりかたは、前回やったお絵かきプログラムの改良と同じです。 ////本日までにできたところ(.java、.classファイルなど)を、 //完成したら、.html, .java、.classファイルを、 //いつものように、出席番号+名前のフォルダに入れて、 //zipで圧縮して、 //ファイルサーバから提出してください。 ***Eclipseを使ってみよう [#vf7b5de5] http://gyazo.com/4383db7fb81f9eacbf5cc959ff77a33d.png -Eclipseの警告を消す方法 private static final long serialVersionUID = 42L; という変数を定義しておきます。 ----------------------------------------------- *マルチメディアプログラミングの最終課題 [#fa431919] -課題:お絵描きプログラムを作成してさらに取扱説明書を作成して1月31日までに提出すること --この課題のヒントは SimpleDraw をみてください。 ** 提出課題として最低やってほしいこと [#hd791dc3] -ペンの太さをメニューで変えられるようにしてください -ペンの色をメニューとカラーパレットで変えられるようにしてください -消しゴム機能を追加してください -ウィンドウの大きさを変えても絵が消えてしまわないようにする (ダブルバッファを使う) ** 機能拡張:以下のことができれば加点します [#ibf935ab] -絵や写真のファイルを取り込めるようにする -いろいろな効果のペンを作る(たとえばペンの動きに従って文字が出る) -絵をファイルへ書き出す機能を作る -他の絵データをスタンプのように押す機能 -コピーアンドペースト -メニューバーだけでなく、スライダ、ボタン、別ウィンドウ(パレット)などを使って使いやすくする -そのほか、世の中のお絵描きプログラムにありそうな機能を実現する 機能拡張の詳細はSimpleDrawの -http://lab.siio.jp/index.php?SimpleDraw#extra を見てください。SimpleDrawのページでは、 -機能の拡充 -使いやすさの追求 の2通りの拡張を書いてあります。どちらの方針で進めていただいても結構です。 説明書に、工夫したところを書いておいてください。 ** 取扱説明書の作り方 [#j3398d0e] -ApplicationsからMicrosoft Office 2011/Microsoft Wordもしくは、テキストエディット(Text Edit)を選択して、これを使って、今回作成したプログラムの取扱説明書を書いてください。他のアプリで作ってもらっても良いですが、最後にPDFにしておいてもらえると助かります。 -せっかくですので作った機能はぜんぶここで説明してください。(プログラムは私も試してみますが機能を見逃すかもしれません) -スクリーンキャプチャした図も入れてください。図は次のようにして作ります --スクリーンキャプチャしたいところで、コマンド(リンゴマーク)+シフト+3を押します。すると画面全体のスクリーンショットがとれます --もしくは、コマンド(リンゴマーク)+シフト+4を押すとマウスドラッグで任意の場所の部分的なスクリーンショットがとれます --もしくは、コマンド(リンゴマーク)+シフト+4を押し、さらにスペースキーを押し、任意のウィンドウをクリックすると、そのウィンドウのスクリーンショットがとれます --以上の操作で、デスクトップにピクチャファイルができます。これをWordかText Editにドラッグアンドドロップします。 --もしくは、デスクトップのピクチャファイルをダブルクリックで開き、欲しい部分を矩形ツールで選択してコピーし、WordかText Editにペーストします -Control キーを押しながらキーボードショートカットを押すと、画像はファイルではなく、クリップボードに保存されるので、直後に書類にペーストできます。 -がんばったところ、大変だったところなどを書いていただいても結構です。また、できれば自力でやって欲しいのですが、だれかに教えてもらったり、web上のサンプルプログラムを参考にした場合は、そのことを説明書に書いてください。また、クラスメートににプログラムを教えた場合も、だれのどこを手伝ったかを書いておいてください。 ** 出来上がったプログラムの提出方法 [#i421b017] - フォルダを作ってその中にjavaファイルとclassファイルと、取扱説明書ファイルと、それ以外に必要なファイルがもしあればそれらを入れてください。フォルダの中のclassファイルをダブルクリックしたらプログラムが起動することを確認してください。 -このフォルダに名前を付けてください。フォルダの名前は、「出席番号+氏名(ローマ字の性か名)+必要ならばバージョン番号の数字」にしてください。 -このフォルダを圧縮してください -このフォルダを圧縮してください -圧縮したファイルを /home/isstaff/siio/Public/Drop Box/. に提出してください。ターミナル.appからなら cp 123456siioitiro.zip /home/isstaff/siio/Public/Drop\ Box としてください。ファインダーからなら、メニューから「移動」「フォルダへ移動...」を選んで 以下のように入力して、移動ボタンを押して、そこに現れるドロップボックスホルダに、ドラッグアンドドロップしてください。 http://siio.jp/gyazo/dropbox.png --書き込み専用なので確認できないけどokですかという意味のダイアログが出るかと思いますが問題ありません。 -レポート提出用フォルダは書き込み専用で見ることができません。アップロードできたかどうか不安でしたら教員まで質問してください。 -同じ名前のフォルダを投げ込むと、エラーになります。ということで新しいバージョンができたら別の名前のフォルダを作って提出し直してください。(フォルダ名最後に数字をつけてください) ** 締切 [#sc18de64] -締め切りは1月30日11:59pmとします --この日までに提出してください //--どうしてもそのあともがんばりたい人は1月31日の11:59pmまでにsiio@mac.comまでメール添付で提出してください //--可能な限り差し替えます(見落とす可能性がありますので保証はできません) **昨年度の優秀作品例 [#t2007b9e] -http://siio.jp/pdf/2013/manual1.pdf -http://siio.jp/pdf/2013/manual2.pdf -http://siio.jp/pdf/2013/manual3.pdf -http://siio.jp/pdf/2013/manual4.pdf -http://siio.jp/pdf/2013/manual5.pdf ---------------- ///////////////////////////////////////////////