swing.Timer在其他程序运行时的行为方式不同

时间:2014-06-17 16:30:21

标签: java swing timer

我现在有点困惑,我甚至不知道这个问题是否符合这个问题,但我也不知道其他任何问题。

我开始编写一个带有灯光和东西的小型2D游戏引擎,我在测试期间偶然发现了这个问题。我实现了一个Timer来重新绘制每16毫秒重绘一次,以获得60 fps的帧速率。 它完美运行,直到我重新启动程序并意识到帧速率已降至约32 fps。 我找不到任何解释,因为我知道我没有太大变化。在一天结束时,我只是更改了一些值,使程序再次看起来很好。一段时间后我再次重新启动,只是意识到,帧速率再次增加到60.

这一次,我真的想到了我所做的一切。我知道我最后一次听音乐,而我之前没有听过。

我做的是,我在程序运行时关闭了iTunes并且帧率再次下降。我启动了iTunes并且帧率增加了。我做了几次这样做,甚至重新启动计算机并发生了同样的效果。 我还尝试了在运行另一个程序(这次是Star Citizen Launcher)时会发生什么,并且发生了同样的事情。另一方面,Firefox和GIMP似乎没有任何影响。

所以,这就是故事。现在的问题是,有没有人听说过这个。为什么会发生这种情况,这可能只是我实施中的一个错误?为了保证它与我的引擎没有任何关系,我在这里写了一个简单的小应用程序,我可以看到完全相同的效果。在小应用程序中,我还打印出自上次重绘后已过期的毫秒数,当没有iTunes或Star Citizen Launcher运行时,此值确实增加,而当其他正在运行时,它保持给定值。

所以我希望你们中的任何人都可以帮助我,因为我根本没有任何想法。我希望这个问题能够得到解答,因为我不知道这个答案会是什么样子......谢谢!

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

@SuppressWarnings("serial")
public class TimerTest extends JPanel implements ActionListener {

private final Timer timer;

private long lastFrame;
private long fps;

private long lastMilis;

public static void main(String[] args) {

    JFrame frame = new JFrame();
    frame.setSize(200, 100);
    frame.setLocationRelativeTo(null);
    frame.setResizable(false);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(new TimerTest());
    frame.setVisible(true);
}

public TimerTest() {

    this.timer = new Timer(16, this);
    this.timer.start();

    // exclude the following for simple Timer run (I get ~32 fps) include for some stress-testing (I get between 55 and 200 fps)
    //      Thread thread = new Thread(new TestThread());
    //      thread.start();
}

@Override
public void actionPerformed(ActionEvent e) {

    System.out.println(System.currentTimeMillis() - this.lastMilis);

    if (e.getSource() == this.timer) {

        this.fps = 1000000000 / (System.nanoTime() - this.lastFrame);

        this.repaint();

        this.lastFrame = System.nanoTime();
    }

    this.lastMilis = System.currentTimeMillis();
}

@Override
public void paint(Graphics g) {

    g.setColor(Color.WHITE);
    g.fillRect(0, 0, 200, 100);
    g.setColor(Color.RED);
    g.drawString("FPS: " + this.fps, 80, 40);
    g.dispose();
}
}

class TestThread implements Runnable {

@Override
public void run() {

    while (true)
        System.out.println("TEST THREAD: " + System.nanoTime());
}
}

0 个答案:

没有答案