Simple animation using Thread.sleep() in ActionListener

为君一笑 提交于 2019-11-26 22:10:22

问题


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++;
        }
    }
}

回答1:


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



来源:https://stackoverflow.com/questions/23924373/simple-animation-using-thread-sleep-in-actionlistener

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!