/* FileName: BufferedCanvas.java Description: A double buffered canvas plus an overlay that supports animation. Created by: Dylan Hoen ( http://www.dylan.hoen.ca/ ) Change Log: 2010/02/23 | Dylan Hoen | Added this title block. */ import java.awt.*; import java.awt.image.*; public class BufferedCanvas extends Canvas { int imageWidth = -1; int imageHeight = -1; Image offscreen = null; Image overlay = null; Image memoryMappedImage = null; MemoryImageSource memoryImageSource = null; boolean useOverlay = false; public BufferedCanvas() { imageWidth = getWidth(); imageHeight = getHeight(); offscreen = createImage( imageWidth, imageHeight ); overlay = createImage( imageWidth, imageHeight ); this.setBackground( Color.BLACK ); if( offscreen != null ) { Graphics graphics = offscreen.getGraphics(); graphics.setColor( getBackground() ); graphics.fillRect( 0, 0, imageWidth, imageHeight ); } if( overlay != null ) { Graphics graphics = overlay.getGraphics(); graphics.setColor( getBackground() ); graphics.fillRect( 0, 0, imageWidth, imageHeight ); } repaint (); } public void update( Graphics graphics ) { paint( graphics ); } public void paint( Graphics graphics ) { if( imageWidth != getWidth() || imageHeight != getHeight() ) { imageWidth = getWidth(); imageHeight = getHeight(); Image tempImage = createImage( imageWidth, imageHeight ); Graphics tempGraphics = tempImage.getGraphics(); tempGraphics.setColor( getBackground() ); tempGraphics.fillRect( 0, 0, imageWidth, imageHeight ); tempGraphics.drawImage( offscreen, 0, 0, this ); offscreen = tempImage; tempImage = createImage( imageWidth, imageHeight ); tempGraphics = tempImage.getGraphics(); tempGraphics.setColor( getBackground() ); tempGraphics.fillRect( 0, 0, imageWidth, imageHeight ); tempGraphics.drawImage( overlay, 0, 0, this ); overlay = tempImage; } if( useOverlay ) { graphics.drawImage( overlay, 0, 0, this ); } else { graphics.drawImage( offscreen, 0, 0, this ); } } public Graphics getBufferedGraphics() { Graphics result = null; if( offscreen != null ) { result = offscreen.getGraphics(); } return result; } public Graphics getOverlayGraphics() { useOverlay = true; Graphics result = null; if( overlay != null ) { result = overlay.getGraphics(); } return result; } public void disableOverlayGraphics() { useOverlay = false; } public void copyBufferToOverlay() { Graphics graphics = overlay.getGraphics(); graphics.drawImage( offscreen, 0, 0, this ); } public int[] createMemoryMappedImage() { int[] pixels = new int[ imageWidth * imageHeight ]; int backgroundColor = getBackground().getRGB(); for( int i = 0; i < pixels.length; i++ ) { pixels[i] = backgroundColor; } createMemoryMappedImage( imageWidth, imageHeight, pixels ); return pixels; } public void createMemoryMappedImage( int width, int height, int[] pixels ) { memoryImageSource = new MemoryImageSource( width, height, pixels, 0, width ); memoryImageSource.setAnimated(true); memoryImageSource.setFullBufferUpdates(true); memoryMappedImage = createImage( memoryImageSource ); } public void drawMemoryMappedImageToBufer() { drawMemoryMappedImageToBufer( 0, 0 ); } public void drawMemoryMappedImageToBufer( int xOffset, int yOffset ) { if( memoryImageSource != null ) { memoryImageSource.newPixels(); Graphics graphics = getBufferedGraphics(); if( graphics != null ) { graphics.drawImage( memoryMappedImage, xOffset, yOffset, this ); } else { throw( new IllegalStateException( "Bufer not yet initialised" ) ); } } else { throw( new IllegalStateException( "Memory Mapped Image not yet initialised" ) ); } } public void drawMemoryMappedImageToOverlay() { drawMemoryMappedImageToOverlay( 0, 0 ); } public void drawMemoryMappedImageToOverlay( int xOffset, int yOffset ) { if( memoryImageSource != null ) { memoryImageSource.newPixels(); Graphics graphics = this.getOverlayGraphics(); if( graphics != null ) { graphics.drawImage( memoryMappedImage, xOffset, yOffset, this ); } else { throw( new IllegalStateException( "Overlay not yet initialised" ) ); } } else { throw( new IllegalStateException( "Memory Mapped Image not yet initialised" ) ); } } }