我正在编写一个代码来移动特定数量的形状。我已将此代码放在循环中,以便程序将形状移动10次。但是,我不想仅显示最后一个输出,而是希望看到形状移动。所以,我在一个单独的线程中实现了sleep方法。但是,形状仍然快速移动,我只看到最终输出。
有人知道这里有什么问题,我该如何解决?
代码:
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand().equals("START"))
{
for(int i=0;i<100;i++)
{
pf.particleFilter();
repaint();
sleepFunction();
}
}
}
private void sleepFunction()
{
System.out.println("In sleep thread");
Thread mythread = new Thread()
{
public void run()
{
try
{
System.out.println("Going to sleep!");
Thread.sleep(1000);
}
catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
}
};
mythread.start();
}
public void particleFilter()
{
move();
}
public void move()
{
setXPosition_robot(robot_x);
setYPosition_robot(robot_y);
setXPosition_particle(particle_x);
setYPosition_particle(particle_y);
}
答案 0 :(得分:4)
sleep函数在一个单独的线程中执行,因此它不会导致Event Dispatch Thread (EDT)
进入睡眠状态,因此EDT会继续执行。
这是一件好事,因为你不想让EDT睡觉,因为这会阻止GUI重新绘制。
要制作动画,您需要使用Swing Timer
。有关详细信息,请阅读How to Use Swing Timers上Swing教程中的部分。
我发现教程中的示例有点复杂,所以这是我能想到的最基本的例子:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
public class TimerTime extends JPanel implements ActionListener
{
private JLabel timeLabel;
public TimerTime()
{
timeLabel = new JLabel( new Date().toString() );
add( timeLabel );
Timer timer = new Timer(1000, this);
timer.setInitialDelay(1);
timer.start();
}
@Override
public void actionPerformed(ActionEvent e)
{
timeLabel.setText( new Date().toString() );
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("TimerTime");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new TimerTime() );
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}