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 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);
}
}
}