Jump to content
  • Advertisement
Sign in to follow this  

Double Buffering Problem

This topic is 2810 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everyone,

I'm having a lot of trouble figuring out how to apply Double Buffering to this program I'm working on. I've tried several things, but none have worked so far. I've deleted my attempts to make the code more readable. Any help would be greatly appreciated!

My Main class:

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.image.*;
import java.io.File;
import java.io.IOException;
import java.util.Vector;
import java.awt.event.KeyListener;
import javax.imageio.*;
import javax.swing.*;

public class Map extends JFrame{

private BufferedImage overworld;
private GameCharacter character;
private Vector illegalPoints;

Image offscreenImage;
Graphics offscr;

public Map(){

overworld = ImageIO.read(new File("overworld.gif"));
catch(IOException e){
System.err.println("Unable to read the map");


illegalPoints = new Vector();
//Add the top, and bottom
for (int i = 0; i < 16; i++ ){
if (i != 7){
illegalPoints.add(new Point(i,0));
illegalPoints.add(new Point(i,8));
//add the middle points
illegalPoints.add(new Point(14,7));
illegalPoints.add(new Point(11,7));
illegalPoints.add(new Point(10,7));
illegalPoints.add(new Point(9,7));
illegalPoints.add(new Point(8,7));
illegalPoints.add(new Point(9,6));
illegalPoints.add(new Point(10,6));
illegalPoints.add(new Point(1,7));
illegalPoints.add(new Point(1,1));
illegalPoints.add(new Point(14,1));
illegalPoints.add(new Point(8,1));
illegalPoints.add(new Point(9,1));
illegalPoints.add(new Point(10,1));
illegalPoints.add(new Point(11,1));
illegalPoints.add(new Point(9,2));
illegalPoints.add(new Point(10,2));
illegalPoints.add(new Point(4,3));
illegalPoints.add(new Point(4,5));
illegalPoints.add(new Point(12,5));
illegalPoints.add(new Point(12,3));
illegalPoints.add(new Point(0,7));
illegalPoints.add(new Point(0,6));
illegalPoints.add(new Point(0,1));
illegalPoints.add(new Point(0,2));

offscreenImage = createImage(this.size().width, this.size().height);
offscr = offscreenImage.getGraphics();

myKeyListener listen = new myKeyListener();

public boolean isLegalMove(int x, int y){
if (x < 0 || x > 14 || y < 0 || y > 14 ){
return false;
else if (illegalPoints.contains(new Point(x,y))){
return false;
return true;

public void setCharacter(GameCharacter c){
character = c;

public void paint(Graphics g){

if (character != null){
character.draw((Graphics2D) g);

class myKeyListener implements KeyListener{

public void keyPressed(KeyEvent event) {
switch(event.getKeyCode()) {
case KeyEvent.VK_DOWN: GameCharacter.isDown = true; break;
case KeyEvent.VK_UP: GameCharacter.isUp = true; break;
case KeyEvent.VK_LEFT: GameCharacter.isLeft = true; break;
case KeyEvent.VK_RIGHT: GameCharacter.isRight = true; break;

public void keyReleased(KeyEvent event) {
switch(event.getKeyCode()) {
case KeyEvent.VK_DOWN: GameCharacter.isDown = false; break;
case KeyEvent.VK_UP: GameCharacter.isUp = false; break;
case KeyEvent.VK_LEFT: GameCharacter.isLeft = false; break;
case KeyEvent.VK_RIGHT: GameCharacter.isRight = false; break;

public void keyTyped(KeyEvent event) {
// TODO Auto-generated method stub


public static void main(String[] args){
Map m = new Map();
GameCharacter c = new GameCharacter(m);

My Character Class:

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.*;

public class GameCharacter {

public static BufferedImage up;
private BufferedImage down;
private BufferedImage left;
private BufferedImage right;
public static int moveDirection;
private static int x;
private static int y;
public static int iconSize;

private static Map map;

public static final int UP = 0;
public static final int DOWN = 1;
public static final int LEFT = 2;
public static final int RIGHT = 3;

public static boolean isUp;
public static boolean isDown;
public static boolean isLeft;
public static boolean isRight;

public static int drawX = 0;
public static int drawY = 0;

static int vX = 0;
static int vY = 0;

public GameCharacter(Map m){
up = ImageIO.read(new File("Link_back.gif"));
down = ImageIO.read(new File("Link_front.gif"));
left = ImageIO.read(new File("Link_left.gif"));
right = ImageIO.read(new File("Link_right.gif"));
catch(Exception e){
System.err.println("Unable to read the file");

moveDirection = DOWN;
iconSize = 32;
map = m;
x = 0;
y = 3;

public void afterMove(){
catch(InterruptedException e){
System.err.println("Woke up early");

public static boolean checkMapForMove(int x, int y){
if (map.isLegalMove(x, y)){
return true;
System.err.println("Illegal Move at " + x + " " + y);
return false;

public static void update() {
vX = 0;
vY = 0;
if (isUp) {
if(checkMapForMove(x, y-1)){
vY -= 1;
moveDirection = UP;
if (isDown) {
if(checkMapForMove(x, y+1)){
vY += 1;
moveDirection = DOWN;
if (isLeft) {
if(checkMapForMove(x-1, y)){
vX -= 1;
moveDirection = LEFT;
if (isRight) {
if(checkMapForMove(x+1, y)){
vX += 1;
moveDirection = RIGHT;

public void draw(Graphics2D g){
x += vX;
y += vY;
drawX = x * iconSize;
drawY = y * iconSize+iconSize;
if(moveDirection == UP){
else if (moveDirection == DOWN){
else if (moveDirection == LEFT){
else if (moveDirection == RIGHT){

Thanks again.

Share this post

Link to post
Share on other sites

A couple of points to take notice of:

1. You are overriding the paint() method. This is not the correct behavior to do painting in Swing. When you paint yourself you need to override the paintComponent method. that is the proper way in Java.

2. If you have no use for background painting, set the control to be opaque (provides drawing on all its area). This will prevent flickering due to the clearing of the area using the background color. The order of calls is:


So if the control is not opaque, the first one will always create flicker.

3. You don't need to manage the double buffering as it is by nature a part of some java controls. A better approach would be to create a JPanel which is double buffered by default (using BufferStrategy) and will handle everything for you, so draw into IT instead of the JFrame.

In short - use JPanel inside the JFrame and do all your drawing into the JPanel, which is double buffered (so no need for the offscreen members)

4. If you must provide consistent drawing rate like in a game loop, consider using setIgnoreRepaint on your JPanel to prevent the OS from sending paint updates to it. Then, you can update the panel in a loop, per time interval, even from another thread. Effectively creating a rendering loop.

Another nice thing is that you can quite easily enable hardware direct draw blitting when you work with BufferedImage. I don't recall the flags at the moment but it shouldn't be hard to find. If you need help with it let me know.
Also, its quite possible its on by default :-)

Share this post

Link to post
Share on other sites
Thanks, VogueMaster! The BufferStrategy worked perfectly! However, I'm not sure on how to move everything around to create a render loop. You said that I'm overriding the paint method? I'm not sure how to fix this, anymore help would be greatly, greatly appreciated!

Share this post

Link to post
Share on other sites
Original post by DranoMax
You said that I'm overriding the paint method?

Yes. I don't understand how you can not be aware of this, but I will try to begin the explanation at the beginning: to "override" a method is to provide an implementation in a derived class (in your case, your Map class) for a method that already exists (i.e. is not declared 'abstract') in the base class (JFrame).

You are not supposed to override the paint() method of JFrame. JFrame::paint() does some unspecified things that you aren't supposed to have to care about, except that one of those things is to call paintComponent() on the current object. Thus, you should override paintComponent() instead (since in the base class it does nothing).

I'm not sure how to fix this

You were told exactly what to do: override paintComponent() instead.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!