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){…}
对于trueloop(boolean){…}
。它冻结的原因是因为循环阻塞并且它在主线程上运行,所以它阻塞了主线程。使用计时器实现或异步运行循环。请将其作为编辑而不是注释添加。@River,对不起,我甚至没有想到它。我已经编辑了答案并删除了评论。