Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
213 views
in Technique[技术] by (71.8m points)

java - Simple animation using Thread.sleep() in ActionListener

I'm having trouble with this code I am using to create a roulette wheel. The goal is to spin the wheel when I click the "SPIN!" button. I have done this by creating a for loop that should change the status of the wheel from true to false, which changes the orientation. This, when done fast enough, should create the illusion of movement.

THE PROBLEM I AM HAVING: is that my wheel is only repainting after the whole for loop is done, despite my placement of the repaint(). So, it only spins one tick.

Here is some sample code of my ActionListener:

public class spinListener implements ActionListener
{
    RouletteWheel wheel;
    int countEnd = (int)(Math.random()+25*2);
    public spinListener(RouletteWheel w)
    {
        wheel = w;
    }
    public void actionPerformed(ActionEvent e)
    {
        for (int i = 0; i <countEnd; i++)
        {
            try 
            {
                Thread.sleep(100);
                if (wheel.getStatus() == true)
                {
                    wheel.setStatus(false);
                    repaint();
                }
                if (wheel.getStatus() == false)
                {
                    wheel.setStatus(true);
                    repaint();
                }
            } 
            catch (InterruptedException ex) 
            {
                Logger.getLogger(WheelBuilder.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}

UPDATE: I figured out the problem. Here are the changes I made for anyone having a similar problem.

public class spinListener implements ActionListener
{
    Timer tm = new Timer(100, this);
    int count = 0;

    public void actionPerformed(ActionEvent e)
    {
        tm.start();
        changeWheel();
    }
    public void changeWheel()
    {
        int countEnd = (int)(Math.random()+20*2);
        if (count < countEnd)
        {
            wheel.setStatus(!wheel.getStatus());
            repaint();
            count++;
        }
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Swing is a single threaded environment, anything that blocks the Event Dispatching Thread, will prevent it from been able to process new events, including, paint events.

The use of Thread.sleep within the actionPerformed method is blocking the EDT, preventing it from processing new events, including paint events, until the actionPerformed method is exited.

You should use a javax.swing.Timer instead.

Take a look at Concurrency in Swing and How to Use Swing Timers for more details


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...