http://www.amazon.co.jp/dp/4883732258/
買ってください。もしくは、先輩から安く譲ってもらってください。
http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/index.html
Mac OS XはJavaと相性が良く、最初からjavaがインストールされています。 ということでWindowsより簡単に(というか何もしなくても)javaが使えます。
~/.bash_profileを開いて以下の行を追加します alias javac='javac -J-Dfile.encoding=UTF-8' alias java='java -Dfile.encoding=UTF-8'
class Hello { public static void main (String args[]) { System.out.println("hello java world!"); } }
javac Hello.java (コンパイルする) java Hello (実行する。.javaなどの拡張子は不要) hello java world! (結果)
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
とタイプしてコンパイル/実行します。
以上のプログラムが完成したら、以下の方法で提出してください。
クラスのインスタンス化(後日説明します)と同じやりかたですので、 覚えておきましょう。教科書39ページにあるように、
int[] vec; vec = new int[3];
または、これを1行にまとめて、
int[] vec = new int[3];
と書きます。
vecというのは、ここで作った変数の名前です。 int型の変数を3個分だけ格納するメモリー領域を、new int[3]というコマンドで作ります。 C言語では、malloc()でメモリーを確保するのと同じことです。 その領域を、参照するために、vecという変数を使います。C言語のポインターと同じです。
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]); } }
乱数を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を表示するプログラムを書け。 動作例を以下に示す。
解答例:
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"); } } }
解答例:
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%だと倍になるのに何年かかるだろうか。確かめてみよう。
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); } } }
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++;
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); } }
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); } } }
mainの引数argsは、Stringの配列で、コマンドラインで起動したとき、 コマンドの後に続けた書いた文字が入っています。 args[0], args[1], args[2] .... をすべてfor-each文で 表示するプログラムを書いてみましょう。
ヒント:for(String s: args)を使います
class ArgsTest2 { public static void main (String args[]) { for(String s: args) System.out.println(s); } }
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(); } }
例えば以下のような実行結果が出るようにしてください
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(); }
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という名前は同じでも、引数の違いで、異なる動作をさせることができます。 これをメソッドのオーバーロードと呼びます。
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()); }
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(); }
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(); } }
public int out(int x) { if(x < okane ) { okane = okane -x; return x; } else { int nokori = okane; okane =0; return nokori; } }
ことができるコンストラクタを作ろう。
これをmainから呼んで、上記のプログラムと同じことをするためには、
Osaifu saifu1 = new Osaifu(1000);//インスタンスを作る //最初の保持金額を1000円にする Osaifu saifu2 = new Osaifu(500);//インスタンスを作る //最初の保持金額を500円にする
とすることになる。
以下のコンストラクタを作ることになる。
Osaifu() { okane = 0; } Osaifu(int x) { okane = x; }
これは以下のように書いても良い。
Osaifu() { this(0); } Osaifu(int x) { okane = x; }
継承の話をしました。 別のクラスを継承することで、 差分だけを書いて機能を拡張していくことができます。
public class OsaifuUSD extends Osaifu {
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にprint()メソッドを追加して、 円表示の次の行に ( xxx USD ) と残高をUSD表示するようにしてください。 円表示を行う部分はスーパークラスOsaifuのインスタンスメソッドprint()を利用することを考えてみてください。
public void print() { super.print(); System.out.println("( " + (okane / 90) + " usd )" ); }
次のプログラムを作って試してください。 引数が少ないとエラーが出るのを確認してください。
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.
[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"); } } }
である。
サンプルプログラムを実行するときは、
LinkedList<String> list = new LinkedList<String>();
などと定義すると良い。
プログラム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"); } } }
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
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); } } }
作ったファイルを
od -h
または
hexdump
してみてください
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); } } }
作ったファイルを
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); } } }
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); } } }
キーボードから1行入力された文字列によるテキストファイルを作る
ヒント
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); } } }
ヒント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..."); } } }
http://is.ocha.ac.jp/~gradthesis/cat.jpg
をダウンロードして、cat.jpgというファイルを作るプログラムを作ってください。 データはテキストじゃなくて、バイナリーです。
ヒント1:
InputStreamのインスタンスに対してread()メソッドを使うと1バイトのデータが得られます。読み終わると-1になります。 1バイトのデータを書き出すなら、FileOutputStreamだけで可能です。
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..."); } } }
上記の例では写真データを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 バイトを出力ストリームに書き込みます。
を使ってください。
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); } }
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(); } }
プログラム12.1を参考にして、上記の、継承を使ったプログラムによるウィンドウの中に、 Hello!という文字を出してみよう。
解答例:
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(); } }
プログラム12.2をみてください。 getContentPane()で得られたContainerに直接ボタンを貼付けることもできますが、 貼付けられるのは一つのボタンだけのようです。 パネルに2個のボタンを貼付け、それをContainerに貼付けることで複数のボタンを表示しています。
プログラム12.2を参考にして、継承を使ったプログラムによるウィンドウの中に、 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(); } }
import javax.swing.*; public class SimpleWindow extends JFrame { public static void main(String argv[]) { SimpleWindow sw = new SimpleWindow(); sw.setVisible(true); } }
で,非常に簡単なウィンドウが出ます. ここで何をやっているのか,オブジェクト指向の用語を使って説明してみましょう.
先週作った, プログラム12.2をみてください。 このプログラムでは,ボタンを押しても何もおこりません.
プログラム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(); } }
ボタンが押されたイベントを受け取るためには,
プログラム12.3を参考に,ボタンを押したらprintlnで次のようなメッセージを表示するプログラムを作ってみましょう.
ヒント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(); } }
ボタンが一つしかないプログラムなので、ActionPerformedの中で、 ボタン種類のチェックを省略してしまっているところが特徴です。
BorderLayoutでもできるようですが、私はGridLayour使ってみました。
panel.setLayout(new GridLayout(2,2)); panel.add(textleft); panel.add(textright); panel.add(button); panel.add(clearbutton);
ボタンが複数になるので、ActionPerformedの中で、ボタンを区別する必要があります。 演習ができそうにないという人は、飛ばして、次に進んでください。
メニューアイテムにcommandという情報をつけて、ActionPerformedではこれを使ってメニュー項目を区別しています。
演習ができそうにないという人は、飛ばして、次に進んでください。
教科書203ページのプログラム13.6の5行めのところに、
... implements ActionListener6: {
とありますが、これは、
... implements ActionListener {
の間違いのようです。
演習ができたかどうかに従って、以下の3本から5本のプログラム(.javaと.class)を いつものように学籍番号+名前のフォルダに入れて、圧縮して提出してください。
以下の内容の新しいファイル,buttontest.cを作ってください. printfの逆スラッシュが正しくコピペできてないかもしれないので,注意してください. 入力が面倒なら,添付ファイルの buttontest.c をダウンロードしてください.
#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で実行してください.
How2MacOSXProgramming を見てください
How2iPhoneProgramming を見てください
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で出るwarningは、以下の変数を定義するとなおります
private static final long serialVersionUID = 42L;
上のプログラムでは,描画すると一筆書きになってしまいます。 これを直して、普通に描画できるようにしてください。 また、 マウスの位置とずれたところに線が引かれるのも直してください。(すこしずらせばok)
ヒント
マウスのクリックで線を引く最初の座標を指定します. マウスのクリックを受け取れるようにMouse Listenerもimplementします http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/awt/event/MouseListener.html
詳細はSimpleDrawを見てください