画像がうまく表示されない。
アプレットを作っています。
左クリックすると、次の画像へ進む、といった処理を実装したのですが、1回は次の画像へ進むのですが、2回目以降が進みません(しかも、「1.jpg」から「2.jpg」へ進めたいのですが、何故か「1.jpg」から「10.jpg」にいってしまいます。)以下が現在のコードです。
余分な部分は削除しました。よろしくお願いします。
public class Main extends Applet implements MouseListener, Runnable{
Image nowImage, nextImage;
static int i;
MediaTracker mt = new MediaTracker(this);
MediaTracker mt2 = new MediaTracker(this);
int yousosu,w,h;
Thread thread;
static float alpha;
static boolean runflag = true;
static boolean flag = true;
static int j = 1;
Image buf;
Graphics ct;
int sleeptime = 300;
Image img;
Vector imgs = new Vector();
public void init(){
i = 0;
thread = new Thread(this);
yousosu = Integer.parseInt(getParameter("NumImage"));//配列(画像)の要素数
for(int t = 0; t < yousosu; t++){
img = getImage(getDocumentBase(),"imagesyukusyo/" + t+1 + ".JPG");
imgs.addElement(img);
img = null;
}
int kazu = imgs.size();
addMouseListener(this);
w = getSize().width;
h = getSize().height;
buf = createImage(w,h);//バッファ取得
//*******最初の画像のロード*******
nowImage = getImage(getDocumentBase(), "imagesyukusyo/1.JPG");//←Vectorの[0]要素?
}
public void update(Graphics g){
paint(g);
}
public void paint(Graphics g){//drawImageファイルを表示するだけ
ct = buf.getGraphics();
Graphics2D ct2 = (Graphics2D) ct;
Graphics2D g2 = (Graphics2D) g;//Grahics2Dクラス
AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
mt.addImage(nowImage,0);
mt2.addImage(nextImage, 0);
try {
mt.waitForID(0);
mt2.waitForID(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
ct2.drawImage(nowImage,0,0,w,h,this);
ct2.setComposite(composite);
//次からはcompositeを設定した後の描画になる。
ct2.drawImage(nextImage,0,0,w,h,this);
g2.drawImage(buf,0,0,w,h,this);
}
//*********マウスイベント************
public void mouseClicked(MouseEvent e) {
int btn = e.getButton();
//*******左クリック**********
if(btn == MouseEvent.BUTTON1){//左クリック=進め
System.out.println("左クリック");
System.out.println("iは"+i);
System.out.println("elementAtの数は"+imgs.size());
if(i >= yousosu){//要素数より多くなったら…
i = 0;
}
nowImage = (Image)imgs.elementAt(i);
if(i == yousosu-1){
nextImage = (Image) imgs.elementAt(0);
}else{
//通常こっち
nextImage = (Image) imgs.elementAt(i+1);
}
thread = new Thread(this);
thread.start();
thread = null;
i++;
}
}
public void run(){
alpha = 0.2f;
repaint();
try {
thread.sleep(sleeptime);
} catch (InterruptedException e) {
e.printStackTrace();
}
alpha = 0.3f;
repaint();
try {
thread.sleep(sleeptime);
} catch (InterruptedException e) {
e.printStackTrace();
}
alpha = 0.4f;
repaint();
try {
thread.sleep(sleeptime);
} catch (InterruptedException e) {
e.printStackTrace();
}
alpha = 0.5f;
repaint();
try {
thread.sleep(sleeptime);
} catch (InterruptedException e) {
e.printStackTrace();
}
alpha = 0.6f;
repaint();
try {
thread.sleep(sleeptime);
} catch (InterruptedException e) {
e.printStackTrace();
}
alpha = 0.7f;
repaint();
try {
thread.sleep(sleeptime);
} catch (InterruptedException e) {
e.printStackTrace();
}
alpha = 0.8f;
repaint();
try {
thread.sleep(sleeptime);
} catch (InterruptedException e) {
e.printStackTrace();
}
alpha = 0.9f;
repaint();
try {
thread.sleep(sleeptime);
} catch (InterruptedException e) {
e.printStackTrace();
}
alpha = 1f;
repaint();
}
}
お礼
OKTaro-さま 毎度、お世話になります。 貴方に教えて頂きましたコードに、Timerにより1ms毎に割込みを発生するルーチンをgenInterruptに実装しまし、このタイマー動作に同期しましてgenInterruptが割込みを 発生し、rcvInterrptがその割込みを受信する様に考えました。 下記のコードをご覧ください。 タイマーの割込み動作が遅く1msではなく、100ms毎に割込みを発生する様なかんじです。 この件に、関しまして、コメント頂けますと大変助かります。 import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.Timer; class T_thread { public static void main(String args[]) { new rcvInterrupt().start(); } } class genInterrupt extends Thread implements ActionListener{ static int CNT=2048; static int INDEX=0; static Timer timer; int H[]=new int[1024]; int ptrR=0; int ptrW=0; private rcvInterrupt target; genInterrupt(rcvInterrupt targetx) { this.target = targetx; timer = new Timer(1 , this); timer.start(); } public void actionPerformed(ActionEvent e){ if(ptrW<1000000) { H[ptrW++]=ptrW; ptrW&=1023; H[ptrW++]=ptrW; ptrW&=1023; System.out.println("================actionPerformed ptrW="+ptrW); } } public void run() { System.out.println("genInterupt start"); // for (int i = 0; i <CNT; i++) { while(CNT>0){ if(ptrW>ptrR){ //========================= //受信側が、wait()状態になった事を確認して、notifyAll()を実行する while (!target.isWaited) { //isWaitedがtrueになるのを待つ // rcvInterruptがsynchronizedブロックに入るまで待ち合わせ // これがないと連続してsynchronizedしてしまう可能性がある } synchronized (target) { target.notifyAll(); //notifyAllにより、wait()を抜け出る target.isWaited = false; // // System.out.println("===notify in genInterrupt"); } //synchronized (target) { //========================= ptrR++; ptrR&=1023; CNT--; INDEX++; } else if(ptrR>ptrW){ while (!target.isWaited) { //isWaitedがtrueになるのを待つ } synchronized (target) { target.notifyAll(); //notifyAllにより、wait()を抜け出る target.isWaited = false; // // System.out.println("===notify in genInterrupt"); } //synchronized (target) { ptrR++; ptrR&=1023; CNT--; INDEX++; } // } //for } } // public void run() { } //class genInterrupt extends Thread { class rcvInterrupt extends Thread { int CNTX=2048; volatile boolean isWaited; //========================= public synchronized void run() { new genInterrupt(this).start(); System.out.println("=============new genInterrupt(this).start()"); for (int i = 0; i <CNTX; i++) { try { isWaited = true; wait(); //notifyAllにより、rcvInterruptのwait()を抜け出る //isWaitedはfalseになる System.out.println("get interrupt i=" + i+" CNT="+genInterrupt.INDEX); //isWaited = true; } catch (InterruptedException e1) { } } //for System.out.println("==========End of rcvInterrupt"); genInterrupt.timer.stop(); System.exit(0); //************************** } //public synchronized void run() { //================================= } //class rcvInterrupt extends Thread {
補足
明快な回答有難うございます。 >絶対に大丈夫という保証をつけるのであればsynchronizedなどを用いて、キチンと同期処理を実装して意図した順番でコードが動作するようにする必要があります。 <--もし、出来ればsynchronizedをどの様に使用すれば良いのでしょうか?