简体   繁体   English

在ActionListener中使用Thread.sleep()进行简单动画

[英]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. 我通过创建一个for循环来完成此操作,该循环应将轮的状态从true更改为false,从而改变方向。 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(). 我所遇到的问题 :尽管我放置了repaint(),但我的轮子只在完成整个for循环后才重新绘制。 So, it only spins one tick. 因此,它只会旋转一个刻度。

Here is some sample code of my ActionListener: 这是我的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++;
        }
    }
}

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. Swing是一个单线程环境,任何阻塞“事件调度线程”的事物都将阻止它处理新事件,包括绘画事件。

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. actionPerformed方法中使用Thread.sleep会阻止EDT,从而阻止EDT处理新事件,包括绘画事件,直到退出actionPerformed方法为止。

You should use a javax.swing.Timer instead. 您应该改为使用javax.swing.Timer

Take a look at Concurrency in Swing and How to Use Swing Timers for more details 查看Swing中的并发性如何使用Swing计时器以了解更多详细信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM