I'm making a proof-of-concept game in Java and decided (for practice but mostly for fun) to make my own simple component with thread-safe double buffering. However, I am not very experienced when it comes to concurrency (specially regarding Swing) and I'm wondering if there are any problems with my implementation that I'm missing.
Implementation as follows:
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
public class GamePanel extends JPanel
{
private static final long serialVersionUID = 1L;
private BufferedImage mBackImage = null;
private BufferedImage mFrontImage = null;
public BufferedImage getBackImage ()
{
return mBackImage;
}
public void swap ()
{
BufferedImage new_back;
//
synchronized (this)
{
new_back = mFrontImage;
mFrontImage = mBackImage;
}
//
int width = getWidth (), height = getHeight ();
if (width > 0 && height > 0)
{
if (new_back == null || new_back.getWidth () != width
|| new_back.getHeight () != height)
new_back = new BufferedImage (width, height,
BufferedImage.TYPE_INT_ARGB);
//
mBackImage = new_back;
}
else
mBackImage = null;
}
@Override
public void paintComponent (Graphics g)
{
synchronized (this)
{
if (mFrontImage == null)
super.paintComponent (g);
else
g.drawImage (mFrontImage, 0, 0, null);
}
}
}
I'm assuming that getBackImage()
and swap()
will only be called by a single thread (the game loop thread). The paints are triggered via a Swing timer and so are in the EDT. I believe that the simple synchronized-blocks around the use of mFrontImage
should be enough to protect against unwanted behavior, allowing the game loop thread to render to the back image and call swap without worrying about the Swing redraws. Am I missing something?