我有一个简单的 Java/Swing 应用程序,它尝试通过从左向右移动框来为框设置动画:
public class TestFrame extends JFrame {
protected long startTime = new Date().getTime();
public class MainPanel extends JPanel {
@Override
protected void paintComponent(Graphics g) {
// calculate elapsed time
long currentTime = new Date().getTime();
long timeDiff = currentTime - TestFrame.this.startTime;
// animation time dependent
g.fillRect((int) (timeDiff / 100), 10, 10, 10);
}
}
public class MainLoop implements Runnable {
@Override
public void run() {
while (true) {
// trigger repaint
TestFrame.this.repaint();
}
}
}
public static void main(String[] args) {
new TestFrame();
}
public TestFrame() {
// init window
this.setTitle("Test");
this.setSize(500, 500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.add(new MainPanel());
this.setVisible(true);
// start render loop
Thread loop = new Thread(new MainLoop());
loop.start();
}
}
问题是动画不干净并且盒子(有时)跳跃几个像素。我已经做了一些研究,根据他们的说法,如果使用paintComponent(而不是绘画)并执行基于时间的动画(不是基于帧的),它应该可以正常工作。我都做了,但动画仍然不干净。
有人可以告诉我出了什么问题吗?
最佳答案
你应该让你的 while-true-loop 稍微休息一下。你的CPU有点烧毁了!您正在生成大量的绘制事件;在线程调度程序决定的某个时间,调度程序会将任务交给事件分派(dispatch)线程,据我记得,这可能会将数以万亿计的绘制事件折叠为单个事件,并最终执行paintComponent。
在以下示例中,线程 hibernate 20 毫秒,这为您提供了 50 fps 的最大帧速率。这应该足够了。
while (true) {
// trigger repaint
TestFrame.this.repaint();
try {
Thread.sleep(20);
} catch(InterruptedException exc() {
}
}
关于java - 尽管使用paintComponent和动画线程,但使用Java/Swing的动画还是跳跃的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28706000/