Java Timer Swing正好是60 fps

时间:2016-04-03 16:16:38

标签: java swing timer frame-rate

我在JPanel中有一个动画,它通过javax.swing.Timer更新自己。可以将此计时器构造为具有必须为整数的毫秒延迟。如果我每秒更新60次JPanel,我会将延迟设置为1000/60 = ~16.6666。但是,这个延迟必须是int,所以我可以选择向上或向下舍入。对于16毫秒的延迟,动画将以每秒62.5帧的速度更新。舍入到17毫秒的延迟将使帧率达到58.824。

我如何才能获得每秒正好60帧的帧速率?

提前致谢。

2 个答案:

答案 0 :(得分:0)

我看到两个可以帮助你的选择。他们最终以相同的方式实现同​​样的目标,但代码或多或少是一般的。我还没有找到任何适合你的工具,所以需要一些工作。

第一个选择是做这样的事情:

/**
 * Called by the timer when the next iteration is due. Assume that
 * this happens at the right moment.
 */
public void onTimerUpdate() {
  updateAnimation();

  // Compute the next point in time that corresponds to the
  // frame rate you want.
  long nextScheduledTimestamp = getNextTimestampInNanos();

  long nanos = System.timeNanos();
  timer.schedule(task, convertToMillis(nextScheduledTimestamp - nanos));
}

第二个选项是让你获得java.util.Timer的副本: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Timer.java

并重写特定于毫秒的位。 OpenJDK中的任何实现都没有显示其分辨率是毫秒特定的,因此您应该能够用Object.wait(millis)替换Object.wait(millis, nanos)次调用: https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#wait(long,%20int)

有趣的文章,只是为了好玩:https://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks

答案 1 :(得分:0)

它并不像那那么复杂!您可以轻松完成repaint()或其他任何需要每秒调用60次的方法,并且存在单个最大循环

while(true) {
    repaint ();
    try {
         Thread.sleep(1000/60);
    } catch (InterruptedException e) {
    }
}

我在我的脚本的主方法中调用它,但基本上它是一个无限循环,因为true总是等于true,然后它调用repaint,告诉循环睡眠一帧然后再调用repaint。而1000/60睡眠将导致此循环正好被称为每秒60次