'double buffering' Sample program in J2ME

By: Charles Emailed: 1765 times Printed: 2515 times    

Latest comments
By: rohit kumar - how this program is work
By: Kirti - Hi..thx for the hadoop in
By: Spijker - I have altered the code a
By: ali mohammed - why we use the java in ne
By: ali mohammed - why we use the java in ne
By: mizhelle - when I exported the data
By: raul - no output as well, i'm ge
By: Rajesh - thanx very much...
By: Suindu De - Suppose we are executing

The term double buffering refers to a technique for buffering a graphics context before displaying it. The idiom requires that you use two graphics contexts -or buffers - hence its name.

You first draw graphics in a secondary graphics context, and later copy its contents to the graphics context that represents the device's display. This secondary graphics context is called an off-screen buffer. An off-screen buffer is one that doesn't render to the display.

The motivation for this technique is performance. Drawing operations can result in frequent updates to the display, causing the user to perceive display flicker. To avoid flicker, you first perform your drawing to an off-screen graphics context, then copy the whole off-screen graphics context to the original device graphics. A copy operation is usually faster than the multitude of drawing operations required of even a relatively complex canvas, so it can be done with almost no perceptible flicker.

The sample program below demonstrates the use of double buffering. It performs some simple drawing functions in an off-screen buffer, then copies the contents of that buffer to the primary graphics context that represents the device's display. Although the drawing routines in this example are relatively simple, a real-life application might perform much more complicated drawing, truly warranting the need for double buffering.

/* Double buffering uses two graphics contexts. The only way to obtain a
second graphics context in MIDP is through the Image class.*/
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import java.io.IOException;

/**
Demonstrates double buffering of graphics context for
display on a Canvas.
*/
public class DoubleBufferDemo extends Canvas
implements CommandListener
{
// A constant that represents the color white.
private static final int WHITE =
0xFF << 16 | 0xFF << 8 | 0xFF;
private static Command back =
new Command("Back", Command.BACK, 1);
GraphicsDemo gDemo = GraphicsDemo.getInstance();
private Display display = Display.getDisplay(gDemo);
// The image object to use to obtain an off-screen
// Graphics object.
private Image offscreen;
// A variable used for determining if the implementation
// is automatically double buffered. Holds the value
// true if the implementation automatically does double
// buffering, false otherwise.
private boolean autoDoubleBuffered = true;

/**
No-arg constructor.
*/
public DoubleBufferDemo()
{
super();
addCommand(back);
setCommandListener(this);
display.setCurrent(this);
if (!isDoubleBuffered())
{
// If the implementation doesn't automatically
// use double buffering, get an Image so we
// can get an off-screen Graphics from it.
// This Image is mutable! Its dimensions are the
// width and height of this Canvas.
offscreen = Image.createImage(getWidth(), getHeight());
autoDoubleBuffered = false;
}
}
protected void paintClipRect(Graphics g)
{
int clipX = g.getClipX();
int clipY = g.getClipY();
 

int clipH = g.getClipHeight();
int clipW = g.getClipWidth();
int color = g.getColor();
g.setColor(WHITE);
g.fillRect(clipX, clipY, clipW, clipH);
g.setColor(color);
}
public void paint(Graphics g)
{
Graphics originalG = null;
int width = getWidth();
int height = getHeight();
if (!autoDoubleBuffered)
{
// Save original graphics context and get a new
// off-screen Graphics from the utility Image.
originalG = g;
g = offscreen.getGraphics();
// Clear the clip rectangle using the new Graphics
// object. This way we're using double buffering
// to clear the Canvas, thereby avoiding
// flickering. Clearing the Canvas is drawing
// like all other drawing operations.
paintClipRect(g);
}
else
{
// Clear the Canvas with the original graphics
// because the implementation does double
// buffering automatically.
paintClipRect(g);
}
for (int x = 0, y = 0; (x < width / 2); x = x + 2)
{
g.drawRect(x, y, (width - x) - x, (height - y) - y);
y++; y++;
}
// Drawing the image actually copies the contents of
// the image's off-screen Graphics context to the
// device's Graphics context.
if (!autoDoubleBuffered)
{
originalG.drawImage(offscreen, 0, 0,
Graphics.TOP | Graphics.LEFT);
}
}
public void commandAction(Command c, Displayable d)
{
if (c == back)
{
GraphicsDemo.getInstance().display();
}
}
 

}

The constructor contains the first code related to double buffering. The statement below, taken from the DoubleBufferDemo no-argument constructor, determines whether the implementation automatically supports double buffering.

if (!isDoubleBuffered())
{
offscreen = Image.createImage(getWidth(), getHeight());
autoDoubleBuffered = false;
}

If the implementation does support double buffering, the application doesn't need to execute it. The Canvas.isDoubleBuffered() method tells you whether the implementation does double buffering implicitly. Notice the construction of the Image object. This call to Image.createImage() produces a mutable Image object. The application needs a mutable Image because it will perform its drawing in the Image object's Graphics context, which is the off-screen buffer we need. This is the only way to obtain an additional Graphics in MIDP.

The paint() method contains the rest of the double-buffering code. If there is no automatic double buffering, the application must perform it. This requires a second graphics context. The following fragment from the paint() method demonstrates the idiom.

public void paint(Graphics g)
{
...
if (!autoDoubleBuffered)
{
originalG = g;
g = offscreen.getGraphics();
}
else
{
paintClipRect(g);
}
...
}

A temporary variable saves a reference to the original Graphics object, which represents the device's graphics context. The new graphics context is obtained through the Image object constructed earlier. This Graphics is associated with the Image

Now the paint(Graphics g) method performs its drawing operations to the off-screen Graphics context. When it's done, it copies the contents of the off-screen Graphics to the original Graphics context, which results in rendering to the display. The copy operation is done by the call to the Graphics.drawImage() method. This method says, in effect, "Copy the contents of this image argument's graphics context to me."

The MIDP double buffering mechanism differs from Swing's double buffering. In Swing, you can double-buffer drawing operations on any Component, not just Canvas objects. Swing applications call java.awt.Component.getGraphics() to obtain an off-screen graphics context. The application can draw in this context. It then sets this off-screen graphics context to be the one associated with the native device.

MIDP has no such call. The only reference to a Graphics object that's associated with the native device is the one passed to the paint(Graphics g) method of a Canvas.


J2ME Home | All J2ME Tutorials | Latest J2ME Tutorials

Sponsored Links

If this tutorial doesn't answer your question, or you have a specific question, just ask an expert here. Post your question to get a direct answer.



Bookmark and Share

Comments(2)


1. View Comment

plz,sent me a sample j2me programm for chnging colour of texr using timers

View Tutorial          By: su at 2007-12-19 21:54:30
2. View Comment

int myColor = 0xFFFF00;
paint(Graphics graphics)
{
graphics.setColor(myColor);
graphics.fillrect(0,0,getWidth(),getHeight());
callTimer();
}
int i=0;
public void callTimer()
{
Thread t= new Thread();
t.sleep(500);//show initial paint screen for 1/2 sec.
myColor = i;
i++;
repaint();
}


View Tutorial          By: krishna mohan at 2010-02-01 05:22:12

Your name (required):


Your email(required, will not be shown to the public):


Your sites URL (optional):


Your comments:



More Tutorials by Charles
arraycopy example in Java
Action listeners in JSF
Automatically Including Preludes and Codas in JSP
Using realloc() Function in C
Handling multiple buttons in HTML Form in Struts
Fopen and Getc implementation program in C
Pointers to Structures example program in C
Pointers vs. Multi-dimensional Arrays in C
getch and ungetch in C
Bitwise Operators in C
Variables and Arithmetic Expressions in C
Differences between JavaServer Faces technology and Struts
assert() example program in C++
'double buffering' Sample program in J2ME
Converting Default Function Arguments in C++ to Java

More Tutorials in J2ME
Code sample to Send SMS from a J2ME application.
Adding your own Application icon for your J2ME application (jar file)
Play a multimedia file in J2ME Program (Audio/Video) using MMAPI
Datagrams in J2ME (UDP Programming sample)
Client Server in J2ME (Socket Programming sample)
Using HttpConnection in J2ME (Retrieve web content from a website to a phone)
Using HTTP vs UDP vs Socket in J2ME
RMSCookieConnector - Using Cookies in J2ME
POST UTF-8 encoded data to the server in J2ME
lists, forms, choices, gauges, text fields, text boxes in J2ME
Using List to create a Menu and Menu items in J2ME
Using alerts and tickers in J2ME
J2ME Canvas sample to show games programming in J2ME
Timer and TimerTask example in J2ME
List of GPRS Access points for all countries

More Latest News
Most Viewed Articles (in J2ME )
Sample program to draw a rectangle in J2ME
'double buffering' Sample program in J2ME
What is J2ME?
Download a file over a network in J2ME midlet
How to load J2ME applications to the IDEN handsets
Y.S. Sun Green Building Research Center
'LINK.EXE' is not recognized as an internal or ext
Sample Java program shows how to Read a file over a network using J2ME midlet
Sample J2ME code that shows various functionality of RMS.
A sample J2ME midlet that shows an example of using a Timer and a TimerTask.
GUI components and menu based J2ME Applications.
Your first J2ME program and a midlet lifecycle explained.
java.lang.SecurityException: MIDP lifecycle does not support system exit.
How to get the CLDC and MIDP version from a J2ME program
DateField sample program in J2ME
Most Emailed Articles (in J2ME)
How to load J2ME applications to the IDEN handsets
GUI components and menu based J2ME Applications.
Ticker sample program in J2ME
Using List to create a Menu and Menu items in J2ME
What is J2ME?
'LINK.EXE' is not recognized as an internal or ext
DateField sample program in J2ME
Sample program to draw a rectangle in J2ME
Types of configurations in J2ME
Types of Profiles in J2ME
A sample J2ME Auto-resume program.
getPosition() the right strategy in getting GPS
Client Server in J2ME (Socket Programming sample)
Using HttpConnection in J2ME (Retrieve web content from a website to a phone)
What is J2ME?