0

何かを描画する単なるウィンドウであるプログラムがあります(計算なし、ユーザーとの対話なしなど)。このプログラムのメイン JPanel には、かなり複雑な paintComponent 関数があります。実行には約 5 ~ 10 ミリ秒かかります。

25 ミリ秒ごとに TimerTask を呼び出すタイマーを設定しました。その TimerTask は、パネルで repaint() を呼び出すだけです。そうすれば、プログラムは 40 FPS になるはずです。

ただし、パネルの paintComponent メソッドの実行には約 5 ~ 10 ミリ秒かかります。何らかの理由で、Timer は TimerTask の run() メソッドが完了するのを待ちます (つまり、パネルが再描画されるのを待ちます)。この方法では、25 ミリ秒ごとに再描画されるのではなく、30 ~ 35 ミリ秒ごとに再描画されるため、不安定で FPS が低下します。

明らかに、バックグラウンドで計算を実行したいのですが、描画を実行して残りの時間を待つのではなく、プログラムは描画を実行してから 25 ミリ秒待機するだけです。

私はutil.Timerの代わりにswing.Timerを使用しようとしましたが、うまくいきませんでした(同じでした)。

1つはBufferedImageにグラフィックを描画するためのもので、もう1つはJPanelにBufferedImageを配置するためのものです。それはパフォーマンスに関しては少し優れていましたが、ちらつきました。

では、バックグラウンドでグラフィックスを真に描画するにはどうすればよいでしょうか?

4

1 に答える 1

0

これを行うための最善の方法は、すでに答えの中にあります。

背景に描画します。

グラフィックスを別の画像にレンダリングする必要があり、JPanel が要求するたびにその画像を JPanel にレンダリングするだけです。

ただし、解決策の 1 つの問題は、静的な睡眠です。代わりに、新しいスレッドを作成することをお勧めします。このスレッドは、画像へのレンダリングを担当します。その後、経過時間に応じて、必要な残りの時間も睡眠します。

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.Timerこれを達成するために提供される静的な睡眠の形式はありませんjava.util.TimerTask

于 2013-11-05T23:45:26.257 に答える