如何延迟while循环?

时间:2016-02-07 16:27:32

标签: java loops freeze

我正在尝试制作一个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()运行,程序就会冻结。我也尝试将while循环放在try内,但这也不起作用。控制台中没有错误,没有冻结的Thread.sleep部分

2 个答案:

答案 0 :(得分:1)

你应该看一下javax.swing.Timer类。

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循环。 Timer有效地为您完成睡眠部分。

另外,当我使用Timer类时,我已经将ActionListener类(我的实现)作为内部类,因此它共享实例变量。

答案 1 :(得分:1)

以下是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();