1

次のコードは、コンテンツを赤で塗りつぶすだけのウィンドウにキャンバスを表示します。ただし、ウィンドウのサイズを変更すると、キャンバスが自動的にクリアされるように見えるため、ウィンドウのサイズを変更するたびにちらつきが発生します。update()少し簡単な検索を行った後、メソッドが呼び出されたことが原因のように見えましたがg.clearRect()、これをオーバーライドしましたが、ちらつきが残っているため、キャンバスは再描画前にクリアされています。

私はダブルバッファリングを試してみましたが、それが問題を解決していないように見える限り、キャンバスがクリアされないようにすることで問題が発生しているように見えるので、とにかくそれがどれほど役立つかはわかりませんその塗り直しの前に。

みんなが急いで提案する前に、この例では、JPanelではなくCanvasを使用する必要があります。これは、別の時点で、VLCJで再生するネイティブビデオに同じCanvasを使用しているためです。

public class MyCanvas extends Canvas {

    @Override
    public void update(Graphics g) {
        paint(g);
    }

    @Override
    public void paint(Graphics g) {
        //By the time we get here, the canvas has been cleared to its background colour
        g.setColor(Color.RED);
        g.fillRect(0, 0, getWidth(), getHeight());
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        MyCanvas c = new MyCanvas();
        frame.add(c);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}
4

1 に答える 1

2

予想通り、ダブルバッファリングは問題ではないことが判明しました。いずれにしても、AWTライブラリの内部に深くあるように見えるコードからペイントする前に、キャンバスがクリアされました。

関連する内部をトレースした後、「ペイント前のクリア」動作はプロパティによってオーバーライドできるようです。

System.setProperty("sun.awt.noerasebackground", "true");

以下を追加すると、再描画する前にキャンバス上の背景が消去されなくなり、関連するちらつきがなくなりました。

このプロパティは明らかにSunVM固有であるため、別のVMで同様の動作が発生するかどうかはわかりません。ただし、私のユースケースでは完全に機能します。

于 2012-05-21T16:58:46.090 に答える