Question

The following code just brings up a canvas in a window which just fills its content with red. However, when resizing the window it flickers a lot, because before each repaint the canvas appears to clear itself. After a bit of trivial searching it seemed to be because the update() method called g.clearRect(), but I've overriden that now and the flicker remains there, the canvas is still clearing itself before repaint.

I've played around with double buffering and that as far as I can tell that doesn't seem to fix things - I'm not sure how helpful it'd be anyway since the issue appears to be more with preventing the canvas from clearing before its repaint.

As an aside before everyone rushes in and suggests it, I have to use Canvas in this instance, not JPanel, because at a different point in time I'm using the same Canvas for native video playing with VLCJ.

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);
    }
}
Was it helpful?

Solution

Double buffering, as expected, turned out not to be the issue - either way the canvas was cleared before painting from code that seemed to be deep in the internals of the AWT library.

After tracing through the relevant internals, it seems that the "clear before paint" behaviour can be overridden by a property:

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

Adding the following stopped the background from being erased on the canvas before repainting, and therefore the associated flickering.

It should be noted this property is obviously Sun VM specific, so no idea if you get similar behaviour or not on another VM. It does however work perfectly for my use case.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top