如何延迟 while 循环?

How do I delay a while loop?

我正在尝试制作一个 while 循环,使 double 每秒递增 0.1:

    public void keyReleased(KeyEvent e)
    {
    //When a key is released, look for any collision problems
    airOrGround(xPos, yPos);
    collision(xPos, yPos);
    //As long as onGround (which is set to false or true in airOrGround) is false,
    //yPos should increment by 1 every second
    while(onGround == false)
    {
        try {
            Thread.sleep(1*1000);
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        yPos += 0.1;
        yPos = (Math.round(yPos * 10) / 10.0);
        start.setText("X = " + xPos + ", Y = " + yPos);
        airOrGround(xPos, yPos);
    }
}

一旦我运行它,一旦keyReleased()运行s,程序就会冻结。我也试过将 while 循环放在 try 中,但这也不起作用。控制台中没有出现任何错误,并且没有 Thread.sleep 部分它不会冻结

你应该看看 javax.swing.Timer class。

public class Whatever
{
    javax.swing.Timer t = new javax.swing.Timer( 1000, new MyListener() );
    ...
    t.start();
}

public class MyListener() implements ActionListener
{
    public void actionPerformed( ActionEvent e )
    {
        if( !onGround )
        {
            ...
        }
    }
}

为清楚起见,我应该解释一下,这意味着您实际上不需要 while 循环。计时器可以有效地为您完成睡眠部分。

此外,当我使用定时器 class 时,我的 ActionListener class(我的实现)是一个内部 class,因此它共享实例变量。

这是一个 SwingWorker

的例子

如果您想要一个需要更新组件的多线程 Swing 应用程序,我建议您使用它。它在 EDT 上安全地执行此操作,因此您的应用程序不会冻结。

SwingWorker<Void, Integer> updater = new SwingWorker<Void, Integer>()
    {
        @Override
        protected Void doInBackground() throws Exception
        {
            boolean something = false;
            int someInt = 3;

            while(!something)
            {
                publish(someInt++); 
                //publish() adds someInt to the chunks list 
                //in the process method so you can access it later.

                Thread.sleep(1000);

                if(someInt == 10)
                {
                    something = true;
                }
            }
            return null;
        }

        @Override
        protected void process(java.util.List<Integer> chunks)
        {
            for(int num : chunks)
            {
                label.setText(String.valueOf(num));
            }
            //This gets each value you added to the chunks list
            //So you can update the label with each value
        }

        @Override
        protected void done()
        {
            //Leave blank or add something to do when the process is finished
        }
    };
    updater.execute();