Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何延迟一段时间循环?_Java_Loops_Freeze - Fatal编程技术网

Java 如何延迟一段时间循环?

Java 如何延迟一段时间循环?,java,loops,freeze,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

我正在尝试创建一个
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);
    }
}

一旦我运行它,只要
keyreased()
运行,程序就会冻结。我还尝试将
while
循环放入
try
中,但这也不起作用。控制台中没有出现错误,并且没有
线程.sleep
部分它不会冻结

您应该查看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类时,ActionListener类(我的实现)是一个内部类,因此它共享实例变量

如果您希望有一个需要更新组件的多线程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();
SwingWorker更新程序=新的SwingWorker()
{
@凌驾
受保护的Void doInBackground()引发异常
{
布尔值=假;
int-someInt=3;
而(!某物)
{
发布(someInt++);
//publish()将someInt添加到块列表中
//在process方法中,以便以后可以访问它。
睡眠(1000);
if(someInt==10)
{
某物=真实;
}
}
返回null;
}
@凌驾
受保护的void进程(java.util.List块)
{
for(int num:chunks)
{
label.setText(String.valueOf(num));
}
//这将获取添加到chunks列表中的每个值
//因此,可以使用每个值更新标签
}
@凌驾
受保护的void done()
{
//在流程完成时留空或添加要执行的操作
}
};
updater.execute();

它冻结了,因为您正在将事件发送线程置于睡眠状态。您可能需要阅读以下内容:也许
onGround
永远不会更改为'true'?
线程。睡眠(1*1000)
?为什么不干脆
1000
?我建议看一看。有了它,你可以安全地在EDT上更新一个Swing组件,同时在一个单独的线程上进行延迟计算。顺便说一下,你不需要将布尔值与true或false进行比较。为了在布尔值为false时循环,需要执行以下操作:
loop(!boolean){…}
对于true
loop(boolean){…}
。它冻结的原因是因为循环阻塞并且它在主线程上运行,所以它阻塞了主线程。使用计时器实现或异步运行循环。请将其作为编辑而不是注释添加。@River,对不起,我甚至没有想到它。我已经编辑了答案并删除了评论。