2008年12月14日日曜日

TA関連2

大学が停電してなんも作業できなくなってチョー暇暇になる。まず研究がらみのこと以外基本することないんかい…てのがとても問題なんだけど。暇なんで掃除したりうだうだしたりついでにTAで面倒見ている課題の完成形を作ってみる。
前で一応「点滅」まではなんとかなったわけで、クリスマスツリーらしきものにするためには、背景画像を読み込んで、その上に描画する+描画する色を選択可能、点滅は色の系統ごとにばらばらに点滅する+点滅の開始、停止、クリアができるようにするという仕様にする。gif読み込んで表示するほうが速そうなので、電球とかも全部画像で保存しておく。

javaにおいてはインターフェースってのが多用されてるみたいだ。イベント処理とかにはそれに応じたインターフェースをimplement(なにそれ)してつかうっぽい。インターフェースってそもそもなんやねんって感じだが、こういう部品をつかいますよってのだけが定義されてて実際の動作は使う側で記述しなあかんものらしい。んーメソッドを直に書いたらだめなんかいな。なにが嬉しいんかちと分かりにくいぞ。(f90にもinterface文はあるけど形状引継ぎ配列使うときとかに要る、サブルーチンとかの引用時の仕様定義ってだけでどっちかというとめんどくさーって感じかなぁ。)

背景画像をアプレットの表示サイズが変えられてもリサイズして表示するようにするためには、インターフェースComponentListenerをimplementして必要なメソッドを記述&特にcomponentResizedにリサイズ処理を書けばよいらしい。
ボタン関連のイベント処理はActionListenerていうインターフェース+ボタンにActionListenerを追加+actionPerformedにボタンごとに処理をちまちま書いていけばいいぽい。
画像の読み込み待ちにMediaTrackerなるものをつかうといいらしい。
ボタンの配置をいじりたいときはPanel上にボタンを配置するようにする模様。
↓とりあえずできた物。たぶん効率悪い処理しまくり


import java.awt.*;

import java.applet.Applet;

import java.awt.Graphics;

import java.awt.event.*;

import java.net.URL;


public class test2 extends Applet
implements Runnable,MouseListener,ActionListener,ComponentListener{
private static final long serialVersionUID = 1L;

String status,msg;
int change=0;
int posX;
int posY;
int radius=20;
public int col=-1;
int radiuspink,radiusgreen,radiusblue;
int BUTTON_NUM=6;
Image off=null,img;
Image pink,blue,green;
int w,h;
boolean flag=false;
Graphics g;
public final int MAX=100; //かける最大数
private Button[] buttons ;
public int nump=0, numb=0,numg=0; //個数
public Point[] pinkoval=new Point[MAX];// 座標
public Point[] blueoval=new Point[MAX];
public Point[] greenoval=new Point[MAX];
Thread th;
boolean start=false;//点滅の制御
Color c0,c1,c2; //色の設定用

//イベント処理用のメソッド
//マウス関連(MouseListener)
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}

public void mouseClicked(MouseEvent e) {
if ( col != -1){
if (col==0){//pink
if(nump<MAX){ // for Max number
pinkoval[nump]=new Point(e.getX(),e.getY()); // get coodinate¸
nump++; //
repaint(); //
}
}
if (col==1){//blue
if(numb<MAX){ // for Max number
blueoval[numb]=new Point(e.getX(),e.getY()); // get coodinate¸
numb++; //
repaint(); //
}
}
if (col==2){//green
if(numg<MAX){ // for Max number
greenoval[numg]=new Point(e.getX(),e.getY()); // get coodinate¸
numg++; //
repaint(); //
}
}
}
}

public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}


//ボタンのイベント処理(ActionListener)
public void actionPerformed (ActionEvent e){
if (e.getSource()==buttons[0]){
col=0;
}
if (e.getSource()==buttons[1]){
col=1;
}
if (e.getSource()==buttons[2]){
col=2;
}
if (e.getSource()==buttons[3]){
start=true;
}
if (e.getSource()==buttons[4]){
start=false;
}//startボタン
if (e.getSource()==buttons[5]){
nump=0;numb=0;numg=0;
}//clearボタン
}

//リサイズ処理(ComponentListener)
public void componentResized(ComponentEvent e){
Dimension dim = getSize();
if( img != null)
/* サイズを変更した画像を作成する */
img = img.getScaledInstance(dim.width, dim.height, Image.SCALE_SMOOTH);
}

public void componentMoved(ComponentEvent e){}
public void componentShown(ComponentEvent e){}
public void componentHidden(ComponentEvent e){}


public void init(){
buttons = new Button[BUTTON_NUM] ;
setBackground(Color.white);
setForeground(Color.gray);
setFont(new Font("Serif", Font.BOLD, 20));
setLayout(new BorderLayout());
posX=0;
posY=0;

status="out";
Panel Panel1 = new Panel();
Panel1.setLayout(new GridLayout(2,3));
Panel1.setBackground(Color.WHITE);
this.addMouseListener(this);
this.addComponentListener(this);
//画像のリサイズ
this.componentResized(null);
//ボタン設定
buttons[0] = new Button("pink");
buttons[1] = new Button("blue");
buttons[2] = new Button("green");
buttons[3] = new Button("start");
buttons[4] = new Button("stop");
buttons[5] = new Button("clear");
for ( int i = 0 ; i < BUTTON_NUM ; ++i ){
//ボタンに処理を追加
buttons[i].addActionListener(this);
//パネルにボタンを追加
Panel1.add(buttons[i]);

}
//色の設定
c1=new Color(180,210,255);
c2=new Color(180,255,180);
buttons[0].setBackground(Color.PINK);
buttons[1].setBackground(c1);
buttons[2].setBackground(c2);
//下に配置
add ("South",Panel1);

}


public void start(){
//画像読み込み

pink=getImage(getCodeBase(),"pink.png");
green=getImage(getCodeBase(),"green.png");
blue=getImage(getCodeBase(),"blue.png");

String param0 = "tree.png";
if(param0 != null)
{
img = getImage(getCodeBase(), param0);
URL urlCode = getCodeBase();
System.out.println("Code : " + urlCode.getPath());

if(img == null)
{
String msg = "fail to read file";
System.out.print("fail to read file");

repaint();
return;
}
}
th = new Thread(this);
th.start();
}

private void loadBackground(Image back)
{
msg = "loading";
repaint();
// 画像が読み込み終わるのを待つ (Media Tracker)
MediaTracker mt = new MediaTracker(this);
mt.addImage(img, 0);
mt.addImage(pink, 1);
mt.addImage(green, 2);
mt.addImage(blue, 3);
while((img.getWidth(this)) == -1 || pink.getWidth(this)==-1
|| green.getWidth(this)==-1 || blue.getWidth(this)==-1)
{
try
{
mt.waitForID(0);
mt.waitForID(1);
mt.waitForID(2);
mt.waitForID(3);
if(mt.isErrorID(0) && mt.isErrorID(1)&& mt.isErrorID(2) && mt.isErrorID(3))
throw new NullPointerException();
}catch(Exception e)
{
msg="finish";
repaint();
return;
}
}

System.out.println("img.getWidth="+img.getWidth(this));
Graphics gg = back.getGraphics();
gg.drawImage(img, 0,0,this);
gg.dispose();
radiuspink=pink.getWidth(this);
radiusblue=blue.getWidth(this);
radiusgreen=green.getWidth(this);
// check for loading
System.out.println("pink"+radiuspink+"blue"+radiusblue);


}

public void run(){

Image back = null;
Dimension dim = getSize();
w = dim.width;
h = dim.height;
if(w <= 0 || h <= 0)
{
w = 500;
h = 500;
}
off = createImage(w, h);
back = createImage(w, h);
g = off.getGraphics();
loadBackground(back);

if (start=false){
repaint();
}
else{
for(;;){
repaint();
if (change< 300){
change=change+1;
}
else {change=0;}

try{
Thread.sleep(500);
}
catch(InterruptedException e){
}

}
}
}

public void update(Graphics g)
{
paint(g);
}

public void paint (Graphics g){

g.drawImage(img, 0, 0, this);

if (start==false){
for (int i=0;i<nump ;i++){
g.drawImage(pink,pinkoval[i].x-radiuspink/2,pinkoval[i].y-radiuspink/2,this);
}
for (int i=0;i<numb ;i++){
g.drawImage(blue,blueoval[i].x-radiusblue/2,blueoval[i].y-radiusblue/2,this);
}
for (int i=0;i<numg ;i++){
g.drawImage(green,greenoval[i].x-radiusgreen/2,greenoval[i].y-radiusgreen/2,this);
}

}

else{
if ((change%3)==0 ||(change%3)==1){
for (int i=0;i<nump ;i++){
g.drawImage(pink,pinkoval[i].x-radiuspink/2,pinkoval[i].y-radiuspink/2,this);
}}
if ((change%3)==1 || (change%3)==2){
for (int i=0;i<numb ;i++){
g.drawImage(blue,blueoval[i].x-radiusblue/2,blueoval[i].y-radiusblue/2,this);
}}
if ((change%3)==2||(change%3)==0 ){
for (int i=0;i<numg ;i++){
g.drawImage(green,greenoval[i].x-radiusgreen/2,greenoval[i].y-radiusgreen/2,this);
}}
}

}

public void stop(){}

public void destroy(){}

}

さて学生さんになんて説明したらええんやら。300行ぐらいのサンプルで「え、長い(読むのやだなぁ)」って言われるしなぁ。輪講とかでも思うけどダイレクトに答え言わずほのめかして、考えさせて、正解に持っていかせるのって超むずかしい…

0 コメント: