Java Swing - 在后台加载图形



我有一个程序,它只是一个绘制东西的窗口(没有计算,没有与用户的交互等)。该程序的主要JPanel具有相当复杂的paintComponent函数 - 大约需要5到10毫秒才能执行。

我设置了一个计时器,每 25 毫秒调用一次计时器任务。该计时器任务只是在面板上调用repaint()。这样程序应该有 40 FPS。

但是面板的paintComponent方法大约需要5到10毫秒才能执行。出于某种原因,计时器等待 TimerTask 的 run() 方法完成(这意味着它等待面板重新绘制)。这样,它就不会每 25 毫秒重新绘制一次,而是 30-35 毫秒,从而导致不稳定和糟糕的 FPS。

显然,我希望在后台执行计算 - 现在程序只执行绘图,然后闲置等待 25 毫秒,而不是执行绘图并等待剩余时间。

我试过使用秋千。计时器而不是实用工具。计时器,那不起作用(是一样的)。

我尝试使用两个单独的计时器,一个用于在缓冲图像上绘制图形,另一个用于将缓冲图像放在 JPanel 上。这在性能方面要好一些,但闪烁。

那么如何在背景中真实地绘制图形呢?

您要这样做的最好方法已经在答案中。

在背景中绘制。

您需要将图形渲染到单独的图像上,然后在 JPanel 请求时将该图像渲染到 JPanel 上。

但是,您的解决方案的一个问题是静态睡眠。您可能希望创建一个新线程。此线程将负责渲染到图像上。然后,根据过去的时间,在您需要的剩余时间睡觉。

private final BufferedImage render = new BufferedImage(screen_width, screen_height, BufferedImage.TYPE_RGB);
public void run(){
    final long start = System.nanoTime();
    renderGraphicsOnto(render.getGraphics());
    final renderTime = System.nanoTime() - start;
    try {
        Thread.sleep(25 - renderTime / 1000000); // convert to milliseconds
    } catch(final Exception ignored){
    }
}

这只是一个关于您可能想要如何处理这个问题的小例子。javax.swing.Timerjava.util.TimerTask提供的任何形式的静态睡眠都无法实现这一目标。

最新更新