Cogs and Levers A blog full of technical stuff

Animation in Java

The abstract window toolkit provide the programmer with a great level of flexibility when creating user interfaces. Today’s blog post is going to go through the basic setup of a double-buffered animation loop implemented in Java, using AWT.

Settings

First off, we start by making some system settings; setting up to use OpenGL, etc:

static {
  System.setProperty("sun.java2d.trace", "timestamp,log,count");
  
  System.setProperty("sun.java2d.transaccel", "True");
  System.setProperty("sun.java2d.opengl", "True");
  
  System.setProperty("sun.java2d.d3d", "false"); //default on windows
  System.setProperty("sun.java2d.ddforcevram", "true");
}

The particulars of these flags can be found in the documentation. These flags,

  • Setup trace logging
  • Use hardware acceleration for translucency
  • Use OpenGL
  • Turn off Direct3D
  • Put images into vram

Canvas

We’ll draw to a Canvas and flip that onto our Frame. We need to configure the Canvas so that it’ll behave in a render-loop fashion, rather than responding to paint messages as it does normally.

We ignore these repaints using setIgnoreRepaint.

Now comes the double-buffer part. We create a BufferStrategy using createBufferStrategy. The strategy is what holds our graphics objects that we’ll render to.

this.createBufferStrategy(2);
strategy = this.getBufferStrategy();

Rendering

The pump for the application is the renderer. It’s pretty simple:

public void render() {
  // get the graphics object
  Graphics2D bkG = (Graphics2D) strategy.getDrawGraphics();

  // start with a black canvas
  bkG.setPaint(backgroundGradient);
  bkG.fillRect(0, 0, getWidth(), getHeight());

  // TODO: Here's where the render code goes

  // release the resources held by the background image
  bkG.dispose();

  // flip the back buffer now
  strategy.show();
  Toolkit.getDefaultToolkit().sync();
}

Get running

Here is a class that you can use to get running immediately.