12/7 課題講評


問題(GUI雪だるま)


講評


オプション課題解答例

AppYukidaruma
// 名前:XXXXX
// 学生証番号:XXXXX


  // AWTを使うので java.awt.*を import する
import java.awt.*;
  // イベント駆動関係のクラスを用いるため
import java.awt.event.*;
import java.util.*;
import java.applet.*;

  // 独立したウィンドウを開くので,Frameクラスのサブクラスにする
public class AppYukidaruma extends Applet implements ActionListener,Runnable,MouseListener{
    // 表示する際に必要なインスタンス変数を宣言しておく
    int mx=250,my=225;
    Button quit,start;
    Checkbox snow,moon,snowman;
    public AppYukidaruma(){
        // GUI部品と,Event Listenerを関連づける
        addMouseListener(this);
	Panel pa=new Panel();
	pa.setLayout(new FlowLayout());
	pa.add(start=new Button("start"));
	pa.add(snowman=new Checkbox("snowman"));
	pa.add(snow=new Checkbox("snow"));
	pa.add(moon=new Checkbox("moon"));
        start.addActionListener(this);
	add(pa,"North");
	//	setSize(400,400);
	//        setVisible(true);
    }
    // MouseListenerを実装するためのメソッド
    public void mousePressed(MouseEvent e){
        // 押された時のマウスカーソルの位置を得る
	if(snowman.getState()==true){
	    mx=e.getX();
	    my=e.getY();
	    // 再表示をおこなう
	    repaint();
	}
    }
    // 要らないイベントに対応するメソッドも中身は空で書いておく必要がある.
    public void mouseReleased(MouseEvent e){}
    public void mouseExited(MouseEvent e){}
    public void mouseEntered(MouseEvent e){}
    public void mouseClicked(MouseEvent e){}
    public void run(){
	try{
	    for(;;){
		repaint();
		Thread.sleep(1000);
	    }
	}
	catch(InterruptedException e){}
    }
    public void init(){
	AppYukidaruma window=new AppYukidaruma();
    }
    public void actionPerformed(ActionEvent e){
	Object source=e.getSource();
	if(source instanceof Button){
	    String la=e.getActionCommand();
	    if(la.equals("start")){
		Thread th=new Thread(this);
		th.start();
		start.setEnabled(false);
	    }
	}
    }
    public void paint(Graphics g){
	g.setColor(Color.gray);
	g.fillRect(0,250,400,150);
	g.setColor(Color.darkGray);
	g.fillRect(0,0,400,250);
	if(moon.getState()==true){
	    g.setColor(Color.yellow);
	    g.fillArc(80,80,40,40,0,360);
	}
	Random r=new Random();
	int sx,sy;
	g.setColor(Color.lightGray);
	if(snow.getState()==true){
	    for(int i=0;i< 100;i++){
		sx=r.nextInt(401);
		sy=r.nextInt(251);
		g.fillArc(sx,sy,10,10,0,360);
	    }
	}
	if(snowman.getState()==true){
	    g.setColor(Color.white);
	    g.fillArc(mx-50,my,100,100,0,360);
	    g.fillArc(mx-37,my-60,70,70,0,360);
	    g.setColor(Color.black);
	    g.fillArc(mx-25,my-40,5,5,0,360);
	    g.fillArc(mx+5,my-40,5,5,0,360);
	    int nx[]={mx-45,mx-10,mx-10};
	    int ny[]={my-10,my-30,my-20};
	    g.setColor(Color.red);
	    g.fillPolygon(nx,ny,3);
	    g.setColor(new Color(200,100,100));
	    int lhx[]={mx-25,mx-30,mx-85,mx-80};
	    int lhy[]={my+40,my+35,my,my+5};
	    g.fillPolygon(lhx,lhy,4);
	    int rhx[]={mx+20,mx+25,mx+80,mx+75};
	    int rhy[]={my+40,my+35,my,my+5};
	    g.fillPolygon(rhx,rhy,4);
	}
    }
}
コメント
上手にアニメーションもできていますね.なお,initの中でnew AppYukidarumaしている部分は不要です(田中).
YukidarumaApplet
 // appletを使うため
import java.applet.*;
  // AWTを使うため,
import java.awt.*;
  // イベント駆動関係のクラスを用いるため
import java.awt.event.*;
  // Vectorクラスを用いるため
import java.util.*;

  // 線分のクラスを定義する.

// 外側のFrameに直接 paintするのではなく, お絵書き領域を作る.


class Yukidaruma4 extends Frame implements ActionListener,MouseListener{
  int mx=100,my=100,state1=1,state2=1;
 // 画面に表示するメッセージの変数.空文字列 "" で初期化する必要がある.
 String message1="",message2="";
 Button button1, button3;
 Checkbox check1, check2;
 TextField textField;

 public Yukidaruma4(){
 addMouseListener(this);
 setLayout(new FlowLayout());
 // 「Check1」というラベルを持つチェックボックスを作り,window中に配置
 add(check1=new Checkbox("Check1"));
 // 「Button1」というラベルを持つボタンを作り,window中に配置
 add(button1=new Button("Button1"));
 button1.addActionListener(this);
 add(button3=new Button("Quit"));
 button3.addActionListener(this);
 // windowのサイズを 500 x 500 に変更
 setSize(400,400);
 // windowを表示する.
 setVisible(true);
 addMouseListener(this);
 }
 public static void main(String args[]){
 // GUITest2クラスのインスタンスを生成
 Yukidaruma4 window=new Yukidaruma4();
 // window内部に GUI部品を置くときのレイアウトをFlowLayoutに指定
 }


 // 内部の GUI 部品以外のところでマウスが押された時に呼ばれる.
 public void mousePressed(MouseEvent e){
 mx=e.getX(); my=e.getY();
 // マウスが押された時に渡される Event と押された時のX座標,Y座標を表示
 System.out.println("mouseDown("+e+","+mx+","+my+")");
 repaint();
 // イベントの処理をおこなったことを表すため true を返す
 }
 public void mouseReleased(MouseEvent e){}
 public void mouseClicked(MouseEvent e){}
 public void mouseEntered(MouseEvent e){}
 public void mouseExited(MouseEvent e){}
 // GUI部品がイベントを処理して,その部品を含むクラスに処理結果を渡す
 // 際に呼ばれる.
 public void actionPerformed(ActionEvent e){
 // イベントのターゲットは GUI 部品のオブジェクトだが,
 // これが Button クラスのインスタンスかどうかのチェック
 System.out.println(e);
 Object source=e.getSource();
 if(source instanceof Button){
 String label=e.getActionCommand();
 // 押されたボタンのラベルが"Button1"かどうかのチェック
 if(label.equals("Quit")){
 System.exit(0);
 }
 else if(label.equals("Button1")){
 // その時は表示する messageは "Button1"
 if(check1.getState()==false){
 message1="Button1を押せばロウソクが乗る。" + "Check1を押すと。。。";
 message2="";}
 if(check1.getState()==true){message1="Merry X'mas!!しかしクリスマスは彼女と過ごすものであって";
message2="雪だるまと過ごすものではない。";}
 state1=state1*(-1);
 }
 }

 // イベントのターゲットが Checkbox クラスのインスタンスかどうかのチェック
 // を入れたが,チェックボックスの内容が変化した時に起きるのは
 // ItemEventなので削除
 // else if(source instanceof Checkbox){
 // // その時は チェックボックスの内容を表示
 // message="Checkbox"+(Checkbox)source;
 // }
 // イベントのターゲットが TextField クラスのインスタンスかどうかのチェック
 else if(source instanceof TextField){
 // その時は 内容を表示
 message1="TextField"+(TextField)source;
 }
 // 明示的に,書き直しをする
 repaint();
 } public void paint(Graphics g){
 g.setColor(new Color(0,0,100));
 g.fillRect(0,0,400,400);
 g.setColor(new Color(220,190,190));
 g.fillRect(0,200,400,200);
 g.fillRect(120,0,280,200);
 int[] xs6={90,120,120};
 int[] ys6={0,0,40};
 g.fillPolygon(xs6,ys6,3);
 g.setColor(Color.yellow);
 g.fillOval(0,20,95,95);
 g.setColor(Color.black);
 g.fillRect(0,200,120,5);
 g.fillRect(115,40,5,160);
 g.fillRect(20,0,5,200);
 g.fillRect(0,40,120,5);
 g.fillRect(0,120,120,5);
 int[] xs5={115,117,90,85};
 int[] ys5={40,40,0,0};
 g.fillPolygon(xs5,ys5,4); 
 g.setColor(new Color(0,100,0));
 int[] xs7={400,340,310,330,260,290,220,400};
 int[] ys7={0,0,50,50,160,160,280,280};
 g.fillPolygon(xs7,ys7,8); 
 g.setColor(new Color(220,0,0));
 g.fillOval(300,140,10,10);
 g.fillOval(330,220,10,10);
 g.fillOval(380,180,10,10);
 g.fillOval(350,60,10,10);
 g.fillOval(355,143,10,10);
 g.setColor(new Color(160,160,0));
 g.fillOval(270,230,10,10);
 g.fillOval(340,200,10,10);
 g.fillOval(380,70,10,10);
 g.fillOval(325,132,10,10);
 g.setColor(Color.white);
 g.fillOval(mx,my,100,100);
 g.fillOval(mx-25,my+75,150,150);
 g.setColor(Color.black);
 g.fillOval(mx+27,my+30,10,10);
 g.fillOval(mx+63,my+30,10,10);
 g.setColor(new Color(200,100,0));
 int[] xs0={mx,mx-10,mx-60,mx-50};
 int[] ys0={my+140,my+150,my+100,my+90};
 g.fillPolygon(xs0,ys0,4);
 int[] xs1={mx+100,mx+110,mx+160,mx+150};
 int[] ys1={my+140,my+150,my+100,my+90};
 g.fillPolygon(xs1,ys1,4);
 g.setColor(new Color(150,150,200));
 g.fillRoundRect(mx+145,my+50,20,80,10,10);
 g.fillRoundRect(mx-65,my+50,20,80,10,10);
 g.fillRoundRect(mx+125,my+35,60,20,10,10);
 int[] xs2={mx+155,mx+145,mx+165};
 int[] ys2={my-10,my+38,my+38};
 g.fillPolygon(xs2,ys2,3);
 int[] xs3={mx+185,mx+185,mx+165};
 int[] ys3={my-10,my+38,my+38};
 g.fillPolygon(xs3,ys3,3);
 int[] xs4={mx+125,mx+125,mx+145};
 int[] ys4={my-10,my+38,my+38};
 g.fillPolygon(xs4,ys4,3);
 g.fillArc(mx-95,my-10,60,170,0,90);
 g.setColor(new Color(150,50,0));
 g.fillRect(0,320,400,100);
 g.setColor(new Color(150,150,200));
 g.fillOval(130,330,150,75);
 g.setColor(new Color(250,255,240));
 g.fillOval(145,322,120,60);
 g.fillRect(145,322,122,30);
 g.fillOval(145,292,120,60);
 if(state1==-1){
 if(check1.getState()==true){g.setColor(Color.red);
 g.fillOval(201,266,7,18);
 g.setColor(Color.yellow);
 g.fillOval(202,275,5,8);}
 g.setColor(Color.green);
 g.fillRect(202,280,6,25);}
 if(state1==-1){
 if(check1.getState()==true){g.setColor(Color.red);
 g.fillOval(164,278,7,18);
 g.setColor(Color.yellow);
 g.fillOval(165,287,5,8);}
 g.setColor(Color.orange);
 g.fillRect(165,292,6,25);}
 if(state1==-1){
 if(check1.getState()==true){g.setColor(Color.red);
 g.fillOval(238,278,7,18);
 g.setColor(Color.yellow);
 g.fillOval(239,287,5,8);}
 g.setColor(new Color(255,0,255));
 g.fillRect(239,292,6,25);}
 if(state1==-1){
 if(check1.getState()==true){g.setColor(Color.red);
 g.fillOval(179,293,7,18);
 g.setColor(Color.yellow);
 g.fillOval(180,302,5,8);}
 g.setColor(Color.blue);
 g.fillRect(180,307,6,25);}
 if(state1==-1){
 if(check1.getState()==true){g.setColor(Color.red);
 g.fillOval(223,293,7,18);
 g.setColor(Color.yellow);
 g.fillOval(224,302,5,8);}
 g.setColor(new Color(255,10,10));
 g.fillRect(224,307,6,25);}
 g.setColor(Color.black);
 g.drawString(message1,45,350);
 g.drawString(message2,135,370);} 
}
public class YukidarumaApplet extends Applet{
  Yukidaruma4 frame;
  public void init(){
    frame=new Yukidaruma4();
  }
  public void start(){
    frame.setVisible(true);
    //    frame.start();
  }
  public void stop(){
    frame.setVisible(false);
    //frame.stop();
  }
}
コメント
うまく書けていますね.GUI部品はpanelでまとめた方が奇麗に配置されると思います(田中).
Snowman_ap
//<applet code=Snowman_ap width=600 height=600>

// 名前:XXXXX
// 学生証番号:XXXXXXX
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.applet.*;
class Circle{
    double x,y;
    int r;
    Color c;
    Circle(int x1,int y1,int r1,int c1){
	x=(double)x1;
	y=(double)y1;
	r=r1;
	c=new Color(c1);
    }
    public void move(int x1,int y1){
	move((double)x1,(double)y1);
    }
    public void move(double x1,double y1){
	x=x1;
	y=y1;
    }
    public void enlarge(int r1){
	r=r1;
    }
    public void changeColor(int c1){
	c=new Color(c1);
    }
    public void draw(Graphics g){
	g.setColor(c);
	g.fillOval((int)x-r,(int)y-r,2*r,2*r);
    }
}
class Face extends Circle{
    Image image;
    Face(int x1,int y1,int r1,int c1){
	super(x1,y1,r1,c1);
	image=Toolkit.getDefaultToolkit().getImage("face.png");
    }
    public void draw(Graphics g,Snowman_ap Yuki){
	g.drawImage(image,(int)x-r+4,(int)y-r,2*r,2*r,Yuki);
    }
}
class Y_move extends Thread{
    Face nf;
    Circle nb;
    int nx;
    int ny;
    double dx=0;
    double dy=0;
    Snowman_ap nYuki;
    Y_move(Face f,Circle b,int x,int y,Snowman_ap Yuki){
	nf=f;
	nb=b;
	nx=x;
	ny=y;
	dx=(double)(nx-nf.x)/100.0;
	dy=(double)(ny-nf.y)/100.0;
	nYuki=Yuki;
    }
    public void change_XY(int x,int y){
	nx=x;
	ny=y;
	dx=(double)(nx-nf.x)/20.0;
	dy=(double)(ny-nf.y)/20.0;
    }
    public void run(){
	boolean flag=false;
	try{
	    while(true){
		if(flag)break;
		nf.move(nf.x+dx,nf.y+dy);
		nb.move(nf.x,nf.y+nf.r+nb.r-10);
		nYuki.repaint();
		if(Math.abs(nf.x-nx)<=1 && Math.abs(nf.y-ny)<=1)break;
		this.sleep(33,3333);
	    }
	}catch(Exception e){flag=true;}finally{dx=0;dy=0;}
    }
}
public class Snowman_ap extends Applet implements ActionListener, KeyListener, MouseListener, MouseMotionListener{
    public void init(){
	daru_up=new Face(450,300,50,0xfffafa);
	daru_down=new Circle(450,400,60,0xfffafa);
	moon=new Circle(120,120,30,0xffff80);
	moon_shadow=new Circle((int)(120-40*Math.cos(Math.PI/4)),(int)(120-40*Math.sin(Math.PI/4)),50,0x90);

	GridBagLayout gridbag=new GridBagLayout();
	GridBagConstraints c=new GridBagConstraints();
	setLayout(gridbag);
	c.fill=GridBagConstraints.NONE;
	c.weighty=1.0;
	c.gridheight=GridBagConstraints.REMAINDER;
	c.anchor=GridBagConstraints.NORTHWEST;
	c.weightx=0;
	gridbag.setConstraints(label_1=new Label("Snowmans's size:"),c);
	add(label_1);
	c.weightx=1.0;
	gridbag.setConstraints(txt_1=new TextField(3),c);
	add(txt_1);
	//c.gridwidth=GridBagConstraints.RELATIVE;
	c.anchor=GridBagConstraints.NORTHEAST;
	c.weightx=0;
	gridbag.setConstraints(button_3=new Button("Play"),c);
	add(button_3);
	c.gridwidth=GridBagConstraints.REMAINDER;
	gridbag.setConstraints(button_1=new Button("Reset"),c);
	add(button_1);
	    /*gridbag.setConstraints(button_2=new Button("Quit"),c);
	add(button_2);*/

	setSize(600,600);
	setVisible(true);
 
	txt_1.addActionListener(this);
	button_1.addActionListener(this);
	//button_2.addActionListener(this);
	button_3.addActionListener(this);
	addKeyListener(this);
	label_1.addKeyListener(this);
	txt_1.addKeyListener(this);
	button_1.addKeyListener(this);
	//button_2.addKeyListener(this);
	button_3.addKeyListener(this);
	addMouseListener(this);
        addMouseMotionListener(this);
	//addWindowListener(new WindowAdapter(){public void windowClosing(WindowEvent e){System.exit(0);}});

	ac=java.applet.Applet.newAudioClip(Snowman_ap.class.getResource("yuki.mid"));
    }
    Face daru_up;
    Circle daru_down;
    Circle moon;
    Circle moon_shadow;
    int dx,dy;
    boolean flag=false;
    Vector StarArray=new Vector();
    Y_move Thrd;

    Label label_1;
    TextField txt_1;
    Button button_1,button_3;//,button_2;
    AudioClip ac;
    /*public static void main(String[] args){
	Snowman mainframe=new Snowman("Snowman");
	}*/

    public void keyPressed(KeyEvent e){
	/*char key=e.getKeyChar();
	  if(key=='q') System.exit(0);*/
    }
    public void keyReleased(KeyEvent e){}
    public void keyTyped(KeyEvent e){}
    public void mousePressed(MouseEvent e){
	int mx=e.getX(),my=e.getY();
	//daru_up.move(mx,my);
	//daru_down.move(daru_up.x,daru_up.y+100);
	if(flag)if(Thrd.dx==0 && Thrd.dy==0)flag=false;
	if(flag){
	    Thrd.change_XY(mx,my);
	}else{
	    Thrd=new Y_move(daru_up,daru_down,mx,my,this);
	    Thrd.start();
	    repaint();
	    flag=true;
	}
    }
    public void mouseReleased(MouseEvent e){}
    public void mouseClicked(MouseEvent e){
	int mx=e.getX(),my=e.getY();
	if(my< 320){
	    StarArray.addElement(new Circle(mx,my,(int)(5*Math.random()+1),0xffff80));
	}
    }
    public void mouseEntered(MouseEvent e){}
    public void mouseExited(MouseEvent e){}
    public void mouseDragged(MouseEvent e){}
    public void mouseMoved(MouseEvent e){}
    public void actionPerformed(ActionEvent e){
	Object src=e.getSource();
	if(src instanceof Button){
	    /*if((((Button)src).getLabel()).equals("Quit")){
		System.exit(0);
		}else */if((((Button)src).getLabel()).equals("Reset")){
		daru_up=new Face(450,300,50,0xfffafa);
		daru_down=new Circle(450,400,60,0xfffafa);
		moon=new Circle(120,120,30,0xffff80);
		moon_shadow=new Circle((int)(120-40*Math.cos(Math.PI/4)),(int)(120-40*Math.sin(Math.PI/4)),50,0x90);
		StarArray.clear();
		repaint();
	    }else if((((Button)src).getLabel()).equals("Play")){
		((Button)src).setLabel("Stop");
		ac.play();
	    }else if((((Button)src).getLabel()).equals("Stop")){
		((Button)src).setLabel("Play");
		ac.stop();
	    }
	}else if(src instanceof TextField){
	    String str=((TextField)src).getText();
	    daru_up.enlarge(Integer.parseInt(str));
	    daru_down.enlarge(daru_up.r+10);
	    daru_down.move(daru_up.x,daru_up.y+daru_up.r+daru_down.r-10);
	    repaint();
	}
    }
    public void update(Graphics g){
	paint(g);
    }
    public void paint(Graphics g){
	Image subframe=createImage(600,600);
	Graphics g1=subframe.getGraphics();
	g1.setColor(new Color(0x90));
	g1.fillRect(0,0,600,600);
	moon.draw(g1);
	moon_shadow.draw(g1);
	for(int i=0;i< StarArray.size();i++){
	    Circle star=(Circle)StarArray.elementAt(i);
	    star.draw(g1);
	}
	g1.setColor(new Color(0xd0e8ee));
	g1.fillRect(0,320,600,280);
	daru_down.draw(g1);
	daru_up.draw(g1,this);
	g.drawImage(subframe,0,0,this);
    }
}
コメント
講義では扱っていない音楽関係のAPIも調べてうまく使っていますね(田中). appletviewerでは見ることができますが,Safariのなかだと
java.security.AccessControlException: access denied (java.io.FilePermission face.png read)
	at java.security.AccessControlContext.checkPermission(AccessControlContext.java:264)
	at java.security.AccessController.checkPermission(AccessController.java:427)
	at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
	at java.lang.SecurityManager.checkRead(SecurityManager.java:871)
	at sun.awt.SunToolkit.getImageFromHash(SunToolkit.java:632)
	at sun.awt.SunToolkit.getImage(SunToolkit.java:646)
	at Face.(Snowman_ap.java:41)
	at Snowman_ap.init(Snowman_ap.java:86)
	at sun.applet.AppletPanel.run(AppletPanel.java:374)
	at java.lang.Thread.run(Thread.java:613)
のようなエラーが出るようですね.この解決法は,アプレットプログラミングのところで,
イメージの読み込みの際には,ファ イルからのイメージのロードと描画で使った 「Toolkit.getDefaultToolkit().getImage(ファイル名)」というテクニックが 使えない.代わりに,AppletクラスのgetImageメソッドを使う. initの中で,
    frame=new DrawImage();
    frame.image=getImage(getCodeBase(),"test.gif");
のように使う.
と書いたとおりにしてください.