Flickering during resizing of a window

To avoid flickering during the resize of my game window I’am using the sun.awt.noerasebackground property. This works oké for simple drawings. However when the drawing complexity increases so does the flickering! I have tried different things to get rid of the flickering but I’am running out of options.

By the way… I don’t wan’t to use Toolkit.getDefaultToolkit().setDynamicLayout(false). This eliminates flickering completely but makes it impossible to resize the drawing during a resize.

OS: Vista 64bit;
JRE: build 1.6.0_26-b03

Because code says more than a thousand words :wink: see the example below. Use the static variable COMPLEXITY to increase the “complexity” of the drawing till the point the flickering starts.

Any suggestions to get rid of this flickering?


import java.awt.Canvas;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;

public class FlickerDemo 
{
	// The frame to contain this canvas
	private JFrame jFrame = null;
	
	// The canvas to draw on
	private Canvas canvas = null;
	
	// The buffer strategy
	private BufferStrategy strategy = null;
	
	// Drawing routine complexity
	private static final int COMPLEXITY = 10000;
	
	public static void main(String[] args) 
	{
		new FlickerDemo().start();

	}
	
	public FlickerDemo()
	{
		// No flickering during resize
		System.setProperty("sun.awt.noerasebackground", "true");
		
		// Acquiring the current Graphics Environment, Device and Configuration
		GraphicsEnvironment graphicsEnv = GraphicsEnvironment.getLocalGraphicsEnvironment();
		GraphicsDevice graphicsDev = graphicsEnv.getDefaultScreenDevice();
		GraphicsConfiguration graphicsConf = graphicsDev.getDefaultConfiguration();

		// Create a canvas
		canvas = new Canvas(graphicsConf);		
		canvas.setFocusTraversalKeysEnabled(false);
		canvas.setIgnoreRepaint(true);
		
		// Set background color to red to make flickering more visible
		canvas.setBackground(Color.red);
		
		// Create a frame
		jFrame = new JFrame(graphicsConf);
		jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		jFrame.setTitle("FlickerDemo");
		jFrame.setFocusTraversalKeysEnabled(false);
		jFrame.setIgnoreRepaint(true);
		jFrame.setAlwaysOnTop(false);
		jFrame.setUndecorated(false);				
		
		// Add canvas to the frame
		jFrame.add(canvas);
		
		// Make the window visible 
		jFrame.pack();
		jFrame.setResizable(true);
		jFrame.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
		jFrame.setVisible(true);
		
		// Set the size and location of the jframe
		jFrame.setSize(800, 600);
		jFrame.setLocation(0, 0);
		
		// Create the buffering strategy which will allow AWT to manage the accelerated graphics
		canvas.createBufferStrategy(2);
		strategy = canvas.getBufferStrategy();
	}

	public void start()
	{
		while(true)
		{			
			// Get the size of the canvas
			Dimension windowSize = canvas.getSize();
			int screenX = windowSize.width;
			int screenY = windowSize.height;
			
			// Get hold of a graphics context for the accelerated surface
			Graphics2D g = (Graphics2D)strategy.getDrawGraphics();
			
			// Fill background
			g.setColor(Color.black);
			g.fillRect(0, 0, screenX,screenY);

			// Draw contents of window
			draw(g, screenX, screenY);
			
			// finally, we've completed drawing so clear up the graphics
			// and flip the buffer over
			g.dispose();
			strategy.show();
		}
	}
	
	/*
	 * Draw a square in the center of the canvas
	 */
	private void draw(Graphics2D g, int screenX, int screenY)
	{
		g.setColor(Color.red);
		for(int i=0; i<COMPLEXITY; i++)
		{
			g.fillRect(screenX / 2 - 10, screenY / 2 - 10, 20, 20);
		}
	}	
}

Did you try to use setDoubleBuffered(true) on canvas?

@TheUzo007

  1. Please don’t revive old threads.
  2. All Swing components are automatically double buffered.