libro
www.tuyano.com
初心者のためのJava SEプログラミング入門

スレッドとアニメーション (5/9)

作成:2010-01-14 21:11
更新:2014-09-04 07:54

■スレッドの停止と再開

これで一応スレッドの基本はわかりましたが、これだけでは、いろいろと問題もあります。なにより「一度スタートしたらプログラムを終了するまで動きっぱなし」というんじゃ、ちょっと辛いものがありますね。

 Threadクラスには、スレッドを一時停止したり再開したりするメソッドが備わっていたんですが、Java2になってそれらのメソッドは全て「推奨しない」とされてしまいました。つまり「あるけど、使わないでくれ」ということですね。これらのメソッドは、「デッドロック」といってプログラムがフリーズしたりする可能性を含んでいるためです。 では一体どうすればいいか?というと、スレッドを終了する必要があった場合にはrunメソッドを最後まで実行し終了させてしまうのです。こうすればスレッドは自然に消滅します。そして再開する必要が生じたら、再びThreadを作って実行するわけです。プログラムの状態などは変数などにおさめて保存しておけば、再開した時も前の状態を再現できるでしょう。

そこで、先のサンプルを修正してみましょう。(下リスト参照)

今回はボタンが2つあります。「GO」ボタンをクリックすると、円が動き出し、もう1度クリックすると、止まります。またクリックすれば動きだし、またまたクリックすれば止まる…というわけ。「change」ボタンは、動く方向をランダムに変更します。つまり、「実行/停止」と「方向変更」を分けてみたわけですね。一番最初は、動く方向は縦横どちらも0ですから、「GO」しても円は動きません。GOした後に「change」で方向を設定すると動くようになります。

※プログラムリストが表示されない場合

AddBlockなどの広告ブロックツールがONになっていると、プログラムリスト等が表示されない場合があります。これらのツールをOFFにしてみてください。

●プログラム・リスト●

import java.awt.*;
import java.awt.event.*;

public class Test12 extends Frame implements ActionListener,Runnable {
    MyCanvas c1;
    Button b1,b2;
    Thread t1;
    int lastX,lastY,moveX,moveY;
    boolean KissOfDeath;
        
    public Test12() {
        super();
        setTitle("Hello");
        setSize(300,250);
        setLayout(null);
        
        lastX = 0;
        lastY = 0;
        KissOfDeath = false;
        
        c1 = new MyCanvas();
        c1.setBounds(25,25,250,150);
        this.add(c1);
        
        b1 = new Button("GO");
        b1.setBounds(25,200,100,25);
        b1.addActionListener(this);
        this.add(b1);
        
        b2 = new Button("change");
        b2.setBounds(175,200,100,25);
        b2.addActionListener(this);
        this.add(b2);
    }
        
     public static void main (String args []) {
        new Test12().setVisible(true);
    }
        
    public void actionPerformed(ActionEvent ev) {
        if (ev.getSource() == b1) {
            KissOfDeath = ! KissOfDeath;
            if (KissOfDeath){
                t1 = new Thread(this);
                t1.start();
            }
        }
        if (ev.getSource() == b2) {
            moveX = (int)(Math.random() * 21 - 11);
            moveY = (int)(Math.random() * 21 - 11);
        }
    }
        
    public void run(){
        try {
            while(KissOfDeath){
                if (lastX + moveX < 0 || lastX + moveX > c1.getWidth()){
                    moveX *= -1;
                }
                if (lastY + moveY < 0 || lastY + moveY > c1.getHeight()){
                    moveY *= -1;
                }
                lastX += moveX;
                lastY += moveY;
                c1.repaint();
                t1.sleep(100);
            }
        } catch(Exception e){
            System.out.println(e);
        }
    }
        
    class MyCanvas extends Canvas{
        
        public void paint(Graphics g){
            g.setColor(Color.blue);
            g.fillOval(lastX - 10,lastY - 10,20,20);
        }
    }
}

※関連コンテンツ

「初心者のためのJava SEプログラミング入門」に戻る