[[Lecture]] #author("2022-01-13T19:18:06+09:00","","") #contents **第1章 Java言語とプログラミング, 第2章 Javaでプログラムを作ろう [#te58cf0f] ***教科書 [#a7e1ce26] http://gyazo.com/de3288074dae1c75f6df4ef3c0b9b3d4.png http://www.amazon.co.jp/dp/4883732258/ 買ってください。もしくは、先輩から安く譲ってもらってください。 ***javaのマニュアル [#k1f55100] //http://sdc.sun.co.jp/java/docs/j2se/1.4/ja/docs/ja/api/index.html http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/index.html *** この講義の目的 [#jc531379] +Javaでプログラムする +オブジェクト指向の概念を理解してプログラミングする +GUIプログラミングをする *** この講義の順序 [#x0e494ba] +Javaになれる(C言語などのプログラミング手法の復習) +オブジェクト指向について理解する +GUIプログラミングについて理解する(イベント駆動) +お絵描きプログラムを作ってみる *** 成績評価 [#l1d3fb5c] +お絵描きプログラムの完成度,作り込み +毎回の宿題の達成(参考程度) -不可になる条件(いかのいずれか) --出席回数60%未満(ただしJavaエキスパートを除く) --最終課題未提出 *** Mac OS XでJavaを使う [#k0516877] Mac OS XはJavaと相性が良く、最初からjavaがインストールされています。 ということでWindowsより簡単に(というか何もしなくても)javaが使えます。 *** terminalを起動する [#i4f33f00] //#ref(terminal.png) http://gyazo.com/7366bfab668207c6598c4d88ef70d2d4.png - terminalは、/Applications/Utilities/の中にあります。 ちなみに、/Applicationsはファインダでは/アプリケーションと日本語として見えます。 /Applications/Utilities/は、/アプリケーション/ユーティリティ/と日本語として見えています。 - ダブルクリックすると起動します。 よく使うことになると思いますので、dockにドラッグアンドドロップして 登録しておくと良いかと思います。(うちの子はこのアイコンを「顔テレビ」と呼んでいます」) - メニューのターミナル/環境設定...を開きます。 ここで、「テキストをアンチエイリアス処理」に チェック入れておくとフォントが奇麗なのでおすすめです。 - おなじウィンドウの詳細タブを選ぶと、「文字エンコーディング」という項目があります。 Javaの場合、ここで「Unicode (UTF-8)」を選んでおくと良いです。 ***Javaの起動を確認する [#td36bdc8] - ターミナルから、javacとタイプしてみてください。みなさんのマシンにはJavaがすでに入っているので、 オプションの説明が日本語で出てくると思います。 -最近のMac OS X (Mountain Lionなど)では、Javaが標準で入っていない場合もあります。 その場合は、ダインロードするかどうか聞かれますので、ダウンロードしましょう。 -ここでの日本語表示が化けていたら、javaがUnicodeじゃなくてShift-JISなどのコードで動いていることになります。ターミナルをShift-JISなどに設定しても良いのですが、ここは、JavaをUnicodeで動かすようにしましょう。 -JavaをUnicodeで動かす(javacなどを起動したときにメッセージが文字化けした場合の対処) --javacを起動するときに、javac -J-Dfile.encoding=UTF-8 とオプションを付けます --javaを起動するときには、java -Dfile.encoding=UTF-8 とオプションを付けます。 -でもいちいちこれを打ち込むのは面倒なので、.bash_profileに登録しておきましょう。 ~/.bash_profileを開いて以下の行を追加します alias javac='javac -J-Dfile.encoding=UTF-8' alias java='java -Dfile.encoding=UTF-8' *** miを用意しておく [#idadeee2] http://gyazo.com/2c0e58d1b83d396e1fbe6f5d247670ff.png - Javaのプログラムを作るエディタです。一番簡単にはterminalからviとかemacsとかpicoとかタイプして エディタを呼び出せば良いです。 - でも日本語の設定などが結構難しいので、GUIベースのエディタを使ってみましょう。 - いくつかありますが、おすすめの一つはmi (みみかきエディタ) という、便利なフリーウェアのテキストエディタです。 - miを使うには、http://www.mimikaki.net/からダウンロードして~/Applicationsにコピーします。 - これも便利なのでdockに入れておくとよいと思います。 http://gyazo.com/7579915fefe1ecd9c0e4e2ddfa55177d.png *** 超簡単なプログラム(hello world)を作ってみる [#y53c1bc0] - ターミナルから、vi Hello.javaとかemacs Hello.javaとかpico Hello.javaとかタイプしたり、 もしくは、miを起動してファイル/新規/javaを選んで新しいファイルを作って開きます。 - ここで、以下のようなプログラムを書いてみます。 class Hello { public static void main (String args[]) { System.out.println("hello java world!"); } } - これをHello.javaという名前で保存して、コンパイル実行します。すると以下のようになります。 javac Hello.java (コンパイルする) java Hello (実行する。.javaなどの拡張子は不要) hello java world! (結果) *** GUIのプログラムをする (Swing編) [#u725623c] - 次に簡単なウィンドウを出してみましょう。 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 とタイプしてコンパイル/実行します。 #ref(How2Java/simplewindow.png) 以上のプログラムが完成したら、以下の方法で提出してください。 *** 出来上がったプログラムの提出方法 [#bd9cbbf8] - フォルダを作ってその中にjavaファイルとclassファイルと、取扱説明書ファイルと、それ以外に必要なファイルがもしあればそれらを入れてください。フォルダの中のclassファイルをダブルクリックしたらプログラムが起動することを確認してください。 -このフォルダに名前を付けてください。フォルダの名前は、「出席番号+氏名(ローマ字の姓名)+必要ならばバージョン番号の数字」にしてください。たとえば09020999siioitiroのように。なお全部半角英数字でお願いします。 -このフォルダを圧縮してください --フォルダを選択してファイルメニューから圧縮を選択します -圧縮したファイルを以下の手順でサーバにおいてください +Finderの移動メニューから、「サーバへ接続...」を選んでください +サーバアドレスのところにsiio.jpと書いてください +接続ボタンを押してください +ゲストのラジオボタンを選んで、接続ボタンを押してください +Publicを選択してください +画面にjava_reportというフォルダが見えると思います +このフォルダに、上で用意したフォルダをドラッグアンドドロップしてください --書き込み専用なので確認できないけどokですかという意味のダイアログが出るかと思いますが問題ありません。 -レポート提出用フォルダは書き込み専用で見ることができません。アップロードできたかどうか不安でしたら教員まで質問してください。 -同じ名前のフォルダを投げ込むと、エラーになります。ということで新しいバージョンができたら別の名前のフォルダを作って提出し直してください。(フォルダ名最後に数字をつけてください) http://gyazo.com/4b3bd729de9a5bff13fadef9d2f3f1d7.png http://gyazo.com/78afe2136aced11e393a50336a5fa706.png http://gyazo.com/35618d5a0582802a7888b3ee50ba3cf2.png http://gyazo.com/bef6a572eb6adb1237c3358345a868e8.png **第3章 データ型, 第4章 演算子 [#t7f3581b] ***演習3.4をみて、自分の名前の最初の文字の文字コードを表示してみてください。 [#qca5b642] ***配列の定義方法 [#vf60df76] クラスのインスタンス化(後日説明します)と同じやりかたですので、 覚えておきましょう。教科書39ページにあるように、 int[] vec; vec = new int[3]; または、これを1行にまとめて、 int[] vec = new int[3]; と書きます。 vecというのは、ここで作った変数の名前です。 int型の変数を3個分だけ格納するメモリー領域を、new int[3]というコマンドで作ります。 C言語では、malloc()でメモリーを確保するのと同じことです。 その領域を、参照するために、vecという変数を使います。C言語のポインターと同じです。 ***コマンドライン引数の表示 [#n3d8fe0c] -args[0]も文字列です。表示してみましょう。 class ArgsTest { public static void main (String args[]) { System.out.println(args[0]); } } -args[1]もためしてみましょう。args[]は、引数文字列の配列です。 ***args[0]とargs[1]をprintlnの中で+でつないで表示するプログラムを作ってください [#ia64a567] http://gyazo.com/8159f78165e17781a7110de3763c833c.png 解答 class ArgsTest { public static void main (String args[]) { System.out.println(args[0] + " + " + args[1]); } } **第5章 制御構造 [#g07182bb] ***演習問題5.4(変更) [#u2eedd95] 乱数を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の基準に従ってABCDEを表示するプログラムを書け。 動作例を以下に示す。 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をやってみよう [#ff357276] 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.02%だと倍になるのに何年かかるだろうか。確かめてみよう。 http://gyazo.com/02e29fc82d2706a2a01516d325100b25.png //http://gyazo.com/95cd94db39b407e7961355b20da8fc67.png ***演習5.6をやってみよう [#ae1dd74b] 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); } } } http://gyazo.com/46937d835776a23a845ca5aa641b93c9.png *** 演習 (これを提出してください) [#t4c868c3] 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); } } //--arg[]の文字をすべてfor-each文で表示する // javac ArgsTest2 cat dog cow fox // catdogcowfox //ヒント //--arg[]の文字をすべて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章 クラスの基礎 [#j2fb0f21] ***クラスとインスタンスの説明をしました [#gc6def4c] -クラスは型、インスタンスはそれから作られたもの --クラスがたいやきの焼き型だとすると、インスタンスはそれから作られたたいやき --クラスは設計図でインスタンスはそれから作られたもの -クラスとインスタンスそれぞれにメソッドと変数がある --クラス変数 例:何個のインスタンスを作ったか? --クラスメソッド 例:インスタンスを作れ --インスタンス変数 例:ひとつのたいやきの重さ --インスタンスメソッド 例:たいやきをxxグラム食べる ***プログラム6.1-6.4を作ってみてください。 [#w206ed8a] ***public static void main の説明をしました [#p8e5e198] -javaコマンドは、引数のクラスのクラスメソッドmainを実行します --staticと付いているのがクラス変数、クラスメソッドの印です -Pointクラスにクラスメソッドmainを実装すれば自分自身をテストできます ***変数にはメソッド経由でアクセスするのが良いという説明をしました [#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(); } } ***演習 [#o7c6958e] -演習問題6.1, 6.2, 6.3 例えば以下のような実行結果が出るようにしてください http://gyazo.com/deeb78a70a724a01ce76945235d42ab8.png -クラスPoint3Dに自分自身をテストするクラスメソッドmainを作ってみよう http://gyazo.com/bdef2ab8e69f7f6e62273c2d67d7af2e.png -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(); } /////////////////////////////////// **第7章 クラスとオブジェクトの操作 [#i34ad133] *** 他の点との距離を返すメソッドの例を説明しました [#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という名前は同じでも、引数の違いで、異なる動作をさせることができます。 これをメソッドのオーバーロードと呼びます。 -Point3Dに、他の点との距離を返すメソッドを実装して、次の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 ( Point p ) { return this.distance(p.getx(), p.gety(), p.getz()); } *** Osaifuクラスを作ってみよう [#je470e19] -Osaifuクラスからはインスタンスがたくさん作られる --Osaifuクラスはお財布の設計図/工場、ここから実際のお財布(インスタンス)が複数作られる --工場出荷時の残金は0円だけど、その後、いろいろな値になるだろう(お金持ちのお財布には残金が多いだろうし、逆ならば少ないだろう) --ということで残金はインスタンス変数とすべきだろう -Osaifuクラスには次のメソッド、変数が必要だろう --残金を表すインスタンス変数 int okane --お金を入金するインスタンスメソッド void in(int x); --お金を出金するインスタンスメソッド int out(int x); 戻り値は実際に出金できた金額(残金が不足ならばあるだけしか出せない) --残金を印刷するインスタンスメソッドがあってもよいだろう void print(); -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章 継承 [#l920d42b] 継承の話をしました。 別のクラスを継承することで、 差分だけを書いて機能を拡張していくことができます。 *** 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(); } } または、outUSD, inUSDで親のin, outを活用して以下のようにしても良い public int outUSD(int usd) { return this.out(usd * 90) / 90; } public void inUSD(int usd) { this.in(usd * 90); } /////////////////// *** OsaifuUSDクラスの改造 [#sa44f577] OsaifuUSDにprint()メソッドを追加して、 円表示の次の行に ( xxx USD ) と残高をUSD表示するようにしてください。 円表示を行う部分はスーパークラスOsaifuのインスタンスメソッドprint()を利用することを考えてみてください。 http://gyazo.com/39a7b24a8c45e15ac55693592c2eb7cf.png -解答例 public void print() { super.print(); System.out.println("( " + (okane / 90) + " usd )" ); } **第9章 エラーと例外処理 [#q543b449] 次のプログラムを作って試してください。 引数が少ないとエラーが出るのを確認してください。 public class TestException { public static void main(String argv[]){ System.out.println(argv[0]+" "+argv[1]); System.out.println("Nice to meet you."); } } 以下のように動きます。 e100:java siio$ java TestException Itiro Siio Itiro Siio Nice to meet you. でも引数の数が足りないとエラーになります。 e100:java siio$ java TestException Itiro Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1 at TestException.main(TestException.java:3) エラーが出る可能性のある場所を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."); } } } このようにすると、エラーが起きたときに、catchのブロックに移行し、以下のようにメッセージが出力されます。 e100:java siio$ java TestException Itiro please input 2 words. **第10章 Stringクラスとコレクションフレームワーク [#befd1d97] *** 入力した文字を逆に出力するプログラムを作る [#p6f8c354] [e100:?/Documents/java] siio% java TestString ochanomizu ochanomizu uzimonahco [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>(); などと定義すると良い。 ***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章 入出力 [#s011d491] ***整数を出力する例 [#d5240008] 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.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.1 をやってください [#dae57c5c] 作ったファイルを od -h dout.dat または hexdump dout.dat してみてください 作った.java .class 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.4を参考にして、 このPrint Write 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, "JISAutoDetect"); でこれから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, "JISAutoDetect"); 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, "JISAutoDetect"); BufferedReader breader = new BufferedReader( isreader ); String line; while((line=breader.readLine()) != null) System.out.println(line); } catch (IOException e) { System.out.println("error..."); } } } ***宿題:写真ファイルのダウンロード [#hbca07a0] http://is.ocha.ac.jp/~gradthesis/cat.jpg をダウンロードして、cat.jpgというファイルを作るプログラムを作ってください。 データはテキストじゃなくて、バイナリーです。 ヒント1: InputStreamのインスタンスに対してread()メソッドを使うと1バイトのデータが得られます。読み終わると-1になります。 1バイトのデータを書き出すなら、FileOutputStreamだけで可能です。 ////////////// *** 写真ファイルのダウンロード (先週の宿題のヒント) [#e79b056e] http://is.ocha.ac.jp/~gradthesis/cat.jpg をダウンロードして、cat.jpgというファイルを作るプログラムを作ってください。 データはテキストじゃなくて、バイナリーです。 ヒント: InputStream?のインスタンスに対してread()メソッドを使うと1バイトのデータが得られます。読み終わると-1になります。 import java.io.*; import java.net.*; public class URLJpeg { public static void main (String argv[]) { try { URL targetURL = new URL("http://is.ocha.ac.jp/~gradthesis/cat.jpg"); InputStream istream = targetURL.openStream(); FileOutputStream fout = new FileOutputStream("cat.jpg"); というインスタンスを作って、 istream.read() で読んで、 fout.write(1バイト) で書き出します。 解答例 import java.io.*; import java.net.*; //http://is.ocha.ac.jp/~gradthesis/cat.jpg //をダウンロードして、cat.jpgというファイルを作るプログラム public class URLJpeg { public static void main (String argv[]) { try { URL targetURL = new URL("http://is.ocha.ac.jp/~gradthesis/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..."); } } } ***高度な課題 [#yd2e37ca] 上記の例では写真データを1バイトずつ読み書きしていました。 InputStreamのメソッドを調べると、複数バイト単位で読み込むメソッドがあります。 たとえば、512バイトずつ読み書きすることで、処理速度が向上すると期待できます。 そこで、複数バイト読み書きするよう、上記のプログラムを変更して、 実際にどの程度(実行速度にして何倍くらい)性能向上するか確認してみましょう。 read public int read(byte[] b) throws IOException 入力ストリームから配列長さだけのバイト数を読み込もうとし、それをバッファ配列 b に格納します。 実際に読み込まれたバイト数は整数として返されます。 このメソッドは、入力データが読み込めるようになるか、ファイルの終わりが検出されるか、 あるいは例外がスローされるまでブロックします。 を使って読みこみ、 write public void write(byte[] b, int off, int len) throws IOException 指定された byte 配列の、オフセット位置 off から始まる len バイトを出力ストリームに書き込みます。 を使ってください。 **第12章 Swing [#d6ca663c] ***とても簡単なウィンドウ [#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); } } ***継承を使ったプログラム [#p82228fc] 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(); } } ***ラベルを表示するウィンドウ [#ca9e7bd9] プログラム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(); } } ***ボタンを2個表示するウィンドウ [#cb6cf696] プログラム12.2をみてください。 getContentPane()で得られたContainerに直接ボタンを貼付けることもできますが、 貼付けられるのは一つのボタンだけのようです。 パネルに2個のボタンを貼付け、それをContainerに貼付けることで複数のボタンを表示しています。 プログラム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(); } } ***オブジェクト指向用語の復習 [#n8509799] import javax.swing.*; public class SimpleWindow extends JFrame { public static void main(String argv[]) { SimpleWindow sw = new SimpleWindow(); sw.setVisible(true); } } で,非常に簡単なウィンドウが出ます. ここで何をやっているのか,オブジェクト指向の用語を使って説明してみましょう. ***継承することのメリットを考えてみよう [#o2a6a75a] ***ボタンが押されたイベントを処理する方法 [#z994e16b] 先週作った, プログラム12.2をみてください。 このプログラムでは,ボタンを押しても何もおこりません. http://gyazo.com/4c3086ae9b6b5434d2ea741369f731c5.png プログラム12.2 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 ヒント1(最初の3行です) import java.awt.*; import java.awt.event.*; public class SimpleButton extends JFrame implements ActionListener { ヒント2(最初の5行です) 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(); } } **第13章 様々なコンポーネントとレイアウト [#t908a5d5] ***13.2節を読んで,プログラム13.2を実行させてください [#s05a9149] ボタンが一つしかないプログラムなので、ActionPerformedの中で、 ボタン種類のチェックを省略してしまっているところが特徴です。 ***演習13.1をやってください [#d9d8be20] http://gyazo.com/7932a0e8327be4ebd2f6c90e620d8c90.png BorderLayoutでもできるようですが、私はGridLayour使ってみました。 panel.setLayout(new GridLayout(2,2)); panel.add(textleft); panel.add(textright); panel.add(button); panel.add(clearbutton); ボタンが複数になるので、ActionPerformedの中で、ボタンを区別する必要があります。 演習ができそうにないという人は、飛ばして、次に進んでください。 ***13.5節を読んで,プログラム13.5を実行してください [#o616a647] http://gyazo.com/4755cce7280963b32050db455d265cc1.png メニューアイテムにcommandという情報をつけて、ActionPerformedではこれを使ってメニュー項目を区別しています。 ***演習13.2をやってください(メニュー項目は何でも良いです) [#rba61398] 演習ができそうにないという人は、飛ばして、次に進んでください。 http://gyazo.com/2d9c3b6534e7b87fcd3ec22be00d5fed.png ***13.6節を読んで,プログラム13.6を実行してください [#k36e1b9b] 教科書203ページのプログラム13.6の5行めのところに、 ... implements ActionListener6: { とありますが、これは、 ... implements ActionListener { の間違いのようです。 ***レポート提出 [#k8bca215] 演習ができたかどうかに従って、以下の3本から5本のプログラム(.javaと.class)を いつものように学籍番号+名前のフォルダに入れて、圧縮して提出してください。 +プログラム13.2 +演習13.1のプログラム +プログラム13.5 +演習13.2のプログラム +プログラム13.6 **おまけの章 [#acfdddd5] ***他の環境でのGUIプログラミングの例 [#r2f2f8d0] ***X11 [#dd5927c8] 以下の内容の新しいファイル,buttontest.cを作ってください. printfの逆スラッシュが正しくコピペできてないかもしれないので,注意してください. 入力が面倒なら,添付ファイルの [[buttontest.c:http://is.ocha.ac.jp/~gradthesis/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 を見てください *** 線を引く簡単なプログラム [#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(); } } ***Eclipseを使ってみよう [#vf7b5de5] http://gyazo.com/4383db7fb81f9eacbf5cc959ff77a33d.png Eclipseで出るwarningは、以下の変数を定義するとなおります private static final long serialVersionUID = 42L; ***(冬休みの宿題)上のお絵描きプログラムを改良してください [#z02373b0] 上のプログラムでは,描画すると一筆書きになってしまいます。 これを直して、普通に描画できるようにしてください。 また、 マウスの位置とずれたところに線が引かれるのも直してください。(すこしずらせばok) ヒント マウスのクリックで線を引く最初の座標を指定します. マウスのクリックを受け取れるようにMouse Listenerもimplementします http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/awt/event/MouseListener.html **最終課題 [#e81d4834] -課題:お絵描きプログラムを作成してさらに取扱説明書を作成して1月31日までに提出すること --この課題のヒントは SimpleDraw をみてください。 *** 提出課題として最低やってほしいこと [#hd791dc3] -ペンの太さをメニューで変えられるようにしてください -ペンの色をメニューとカラーパレットで変えられるようにしてください -消しゴム機能を追加してください -ウィンドウの大きさを変えても絵が消えてしまわないようにする (ダブルバッファを使う) *** 以下のことができれば加点します [#ibf935ab] -絵や写真のファイルを取り込めるようにする -いろいろな効果のペンを作る(たとえばペンの動きに従って文字が出る) -絵をファイルへ書き出す機能を作る -そのほか、世の中のお絵描きプログラムにありそうな機能を実現する 詳細はSimpleDrawを見てください *** 取扱説明書の作り方 [#l7aaa77b] -ApplicationsからMicrosoft Office 2004/Microsoft Wordもしくは、Text Editを選択して、これを使って、今回作成したプログラムの取扱説明書を書いてください。 -せっかくですので作った機能はぜんぶここで説明してください。(プログラムは私も試してみますが機能を見逃すかもしれません) -スクリーンキャプチャした図も入れてください。図は次のようにして作ります --スクリーンキャプチャしたいところで、コマンド(リンゴマーク)+シフト+3を押します。すると画面全体のスクリーンショットがとれます --もしくは、コマンド(リンゴマーク)+シフト+4を押すとマウスドラッグで任意の場所の部分的なスクリーンショットがとれます --もしくは、コマンド(リンゴマーク)+シフト+4を押し、さらにスペースキーを押し、任意のウィンドウをクリックすると、そのウィンドウのスクリーンショットがとれます --以上の操作で、デスクトップにピクチャファイルができます。これをWordかText Editにドラッグアンドドロップします。 --もしくは、デスクトップのピクチャファイルをダブルクリックで開き、欲しい部分を矩形ツールで選択してコピーし、WordかText Editにペーストします -Control キーを押しながらキーボードショートカットを押すと、画像はファイルではなく、クリップボードに保存されるので、直後に書類にペーストできます。 -がんばったところ、大変だったところなどを書いていただいても結構です。また、できれば自力でやって欲しいのですが、だれかに教えてもらったり、web上のサンプルプログラムを参考にした場合は、そのことを説明書に書いてください。また、クラスメートににプログラムを教えた場合も、だれのどこを手伝ったかを書いておいてください。 *** 出来上がったプログラムの提出方法 [#i421b017] - フォルダを作ってその中にjavaファイルとclassファイルと、取扱説明書ファイルと、それ以外に必要なファイルがもしあればそれらを入れてください。フォルダの中のclassファイルをダブルクリックしたらプログラムが起動することを確認してください。 -このフォルダに名前を付けてください。フォルダの名前は、「出席番号+氏名(ローマ字の性か名)+必要ならばバージョン番号の数字」にしてください。 -このフォルダを圧縮してください -このフォルダを圧縮してください -圧縮したファイルを以下の手順でサーバにおいてください +Finderの移動メニューから、「サーバへ接続...」を選んでください +サーバアドレスのところにsiio.jpと書いてください +接続ボタンを押してください +ゲストのラジオボタンを選んで、接続ボタンを押してください +Publicを選択してください +画面にjava_reportというフォルダが見えると思います +このフォルダに、上で用意したフォルダをドラッグアンドドロップしてください --書き込み専用なので確認できないけどokですかという意味のダイアログが出るかと思いますが問題ありません。 -レポート提出用フォルダは書き込み専用で見ることができません。アップロードできたかどうか不安でしたら教員まで質問してください。 -同じ名前のフォルダを投げ込むと、エラーになります。ということで新しいバージョンができたら別の名前のフォルダを作って提出し直してください。(フォルダ名最後に数字をつけてください) *** 締切 [#sc18de64] -締め切りは1月31日とします --この日までに提出してください --どうしてもそのあともがんばりたい人は1月31日の11:59pmまでにsiio@mac.comまでメール添付で提出してください --可能な限り差し替えます(見落とす可能性がありますので保証はできません) ------ このページについてのお問い合わせはsiio@is.ocha.ac.jpまで。