Important alert: (current site time 7/15/2013 3:09:14 PM EDT)
 

winzip icon

J2ME Prevent Screen Lock-ups

Email
Submitted on: 3/23/2004 7:25:25 AM
By: Thomas Tomlins 
Level: Intermediate
User Rating: By 1 Users
Compatibility: Java (JDK 1.1), Java (JDK 1.2)
Views: 14611
 
     Preventing Screen Lockups of Blocking Operations by Qusay H. Mahmoud October 2003 When you're developing networking MIDlets, pay special attention to blocking operations, such as methods that establish a connection to the network. These can lock up the screen, leaving your user frustrated with your application. To prevent screen lockups, you should perform all blocking operations in a separate thread. As an example, let's assume you've written a method called makeConnection() that establishes a connection to a remote server.
 

HTML:

Can't Copy and Paste this?
Click here for a copy-and-paste friendly version of this code!
//**************************************
//HTML for :J2ME Prevent Screen Lock-ups
//**************************************
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>
Wireless Technical Tips: March 22, 2004
</title>
<style type="text/css">
CODE {color: #333333; font-family: Verdana, Courier, Monospace; font-size: 10pt}
PRE {color: #333333; font-family: Verdana, Courier, Monospace; font-size: 10pt}
BODY, div, span {color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
td, th {color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
tr {color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
table {font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
p {color: #333333; font-family: arial,helvetica,sans-serif; font-size: 10pt}
li {color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
br {color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
div {color: #666699; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
sup {font-family: Arial, Helvetica, sans-serif; font-size: 5pt}
h3 {color: #666699; font-family: Arial, Helvetica, sans-serif; font-size: 11pt}
h4, b {color: #666699; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
blockquote, input, select {color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
ul, ol {color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
a:link {font-size: 10pt; font-family: Arial, Helvetica, sans-serif; color:#666699; }
span.purple {font-weight: bold; color: #666699; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
span.small {font-size: 8pt; font-family: Arial, Helvetica, sans-serif; color:#333333 }
span.link {font-size: 8pt; font-family: Arial, Helvetica, sans-serif; color:#666699 }
</style>
</head> 
<body bgcolor="ffffff">
<a name="top"></a>
<table border="0" cellpadding="0" cellspacing="0" width="611">
<tr>
<td colspan="3" bgcolor="#cccccc" width="1"><img src="http://developers.sun.com/techtopics/mobility/images/pixel.gif" width="1" height="1" border="0" alt="pixel"></td>
</tr>
<tr>
<td bgcolor="#cccccc" width="1"><img src="http://developers.sun.com/techtopics/mobility/images/pixel.gif" width="1" height="1" border="0" alt="pixel"></td>
<td>
<table border="0" cellpadding="0" cellspacing="0" width="611">
<tr>
<td colspan="2"><a href="http://enews.sun.com/CTServlet?id=56036723-1346146009:1080012083941"><img src="http://developers.sun.com/techtopics/mobility/images/headers/wireless_ttips_hdr.jpg" width="611" height="160" alt="Wireless Technical Tips" border="0"></a>
 </td>
</tr>
<!-- ================== -->
<!-- Start Main Content -->
<!-- ================== -->
<tr>
<td height="20">   </td>
<td height="20" align="right"><span class="purple">March 22, 2004</span>        </td>
</tr>
<tr>
<td colspan="2">
<table border="0" cellpadding="10" cellspacing="0" width="611">
<tr><td>
<form action="http://search.sun.com/search/wireless/index.jsp" 
method="post" style="margin-top: 0px; margin-bottom: 0px">
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td><h3>In this Issue</h3></td>
<td valign="middle" align="right">
<input type="text" name="qt" maxlength="40" class="textentry" size="7" style="font-size: 12px;">
<img src="http://developers.sun.com/techtopics/mobility/images/pixel.gif" width=9 height=1 alt="">
<input type="image" src="http://wireless.java.sun.com/pics/search_button.gif" width="55" height="20" border="0" name="Search" align="absmiddle" alt="search">
<img src="http://developers.sun.com/techtopics/mobility/images/pixel.gif" width=9 height=1 alt="">
</td>
</tr>
</table>
</form>
<p>
WELCOME to the Wireless Developer Java 2 Platform, Micro Edition (J2ME) Tech Tips, for March 22, 2004.
</p>
<p>
<a href="#1"><img src="http://developer.java.sun.com/images/anchor.gif" border="0" alt="">Preventing Screen Lockups of Blocking Operations</a>
<br>
<a href="#2"><img src="http://developer.java.sun.com/images/anchor.gif" border="0" alt="">Text Wrapping in MIDP</a>
</p>
<p>
You can view these J2ME Tech Tips on the Web, <a href="http://enews.sun.com/CTServlet?id=56036723-1346146009:1080012083958">Preventing 
Screen Lockups of Blocking Operations</a> and <a href="http://enews.sun.com/CTServlet?id=56036723-1346146009:1080012083970">Text Wrapping in MIDP</a>.
</p>
<table width="100%" border="0" cellspacing="0" cellpadding="0" align="center">
<!-- Grey Horizontal Line Begins Here -->
<tr>
<td bgcolor="#cccccc" height="1"><img src="http://developers.sun.com/techtopics/mobility/images/pixel.gif" width="1" height="1" ALT="Pixel" border="0"></td>
</tr>
</table> 
<!-- Grey Horizontal Line ends Here -->
<a name="1"></a>
<h3>Preventing Screen Lockups of Blocking Operations</h3>
<p>
by <a href="#author">Qusay H. Mahmoud</a><br>
<i>October 2003</i><br>
</p>
<p>
When you're developing networking MIDlets, pay special attention to blocking operations, such as methods that establish a connection to the network. These can lock up the screen, leaving your user frustrated with your application. To prevent screen lockups, you should perform all blocking operations in a separate thread. As an example, let's assume you've written a method called <code>makeConnection()</code> that establishes a connection to a remote server. You might try to call this method in response to a user click, from the commandAction() event handler:
</p>
<pre>
public class MyNetMIDlet implements CommandListener {
 // ...
 public void commandAction(Command c, Displayable d) {
if(c == startButton) {
 makeConnection(); // BUG: no blocking I/O should be in callback
 }
 }
 public void makeConnection() {
// ...
 }
}
</pre>
<p>
This approach will lead to screen lockups. To prevent the screen from locking up, have <code>makeConnection()</code> execute in a separate thread. A good way to do so entails having the MIDlet implement the <code>Runnable</code> interface. Instead of invoking <code>makeConnection()</code> directly, <code>commandAction()</code> starts a new thread whose <code>run()</code> method calls <code>makeConnection()</code>:
</p>
<pre>
public class MyNetMIDlet implements CommandListener, Runnable {
 public void commandAction(Command c, Displayable d) {
if(c == startButton) {
 Thread t = new Thread(this);
 t.start();
}
 }
 public void run() {
 makeConnection();
 }
 public void makeConnection() {
// ...
 }
}
</pre>
<p>
For a more extensive example, consider a networked MIDlet that retrieves the current date and time using the daytime server, which listens on port 13. When a client opens a connection to that port, the server immediately supplies the current date and time. In Listing 1 a MIDlet establishes a socket connection to the time server running on port 13 on a remote machine. The client doesn't send any data; the server treats the new connection itself as a service request, and immediately responds with the current date and time.
</p>
<p>
<b>Listing 1. TimeMIDlet.java</b>
</p>
<pre>
import javax.microedition.midlet.*;
import javax.microedition.io.*;
import javax.microedition.lcdui.*;
import java.io.*;
public class TimeMIDlet extends MIDlet implements CommandListener {
private static Display display;
private Form f;
private boolean isPaused;
private StringItem si;
private Command exitCommand = new Command("Exit", Command.EXIT, 1);
private Command startCommand = new Command("GetTime", Command.ITEM, 1);
public TimeMIDlet() {
 display = Display.getDisplay(this);
 f = new Form("Time Demo");
 si = new StringItem("Select GetTime to get the current Time! ", " ");
 f.append(si);
 f.addCommand(exitCommand);
 f.addCommand(startCommand);
 f.setCommandListener(this);
 display.setCurrent(f);
} 
public void startApp() {
 isPaused = false;
}
public void pauseApp() {
 isPaused = true;
}
public void destroyApp(boolean unconditional) {
}
public void commandAction(Command c, Displayable s) {
 if (c == exitCommand) {
 destroyApp(true);
 notifyDestroyed();
 } else if (c == startCommand) {
 getTime();
 }
}
public void getTime() {
 SocketConnection sc = null;
 InputStream is = null;
 Form f = new Form("Time Client");
 StringItem si = new StringItem("Time:" , " ");
 f.append(si);
 display.setCurrent(f);
 try {
sc = (SocketConnection)
Connector.open("socket://"+"remoteTimeServer"+":13");
is = sc.openInputStream();
StringBuffer sb = new StringBuffer();
int c = 0;
while (((c = is.read()) != '\n') && (c != -1)) {
sb.append((char) c);
}
si.setText(sb.toString());
 } catch(IOException e) {
 Alert a = new Alert
("TimeClient", "Cannot connect to server. Ping the server to 
 make sure it is running...", null, AlertType.ERROR);
 a.setTimeout(Alert.FOREVER);
 display.setCurrent(a);
 } finally {
 try {
if(is != null) {
 is.close();
}
if(sc != null) {
 sc.close();
}
 } catch(IOException e) {
e.printStackTrace();
 }
 }
 } 
}
</pre>
<p>
If you run this MIDlet from the J2ME Wireless Toolkit, it displays a
screen like the one in Figure 1, where the emulator prompts you to grant
or deny permission to make the connection. If you allow the connection,
the MIDlet continues normally. If you deny permission, <code>Connector.open()</code>
throws a <code>SecurityException</code>.
</p>
<p>
<img src="http://developers.sun.com/techtopics/mobility/allttips/mailers/2004/images/tt_0304_fig1.gif" border="0" alt="Permission Prompt"><br>
Figure 1: Permission Prompt
</p>
<p>
Unfortunately, you can't actually grant or deny permission, because at
this point the user interface locks up. The interesting thing to note
here is the warning you can see on the J2ME Wireless Toolkit's main
screen, shown in Figure 2, which advises you to avoid deadlocks and
screen lockups by performing blocking operations in a separate thread.
</p>
<p>
<img src="http://developers.sun.com/techtopics/mobility/allttips/mailers/2004/images/tt_0304_fig2.gif" border="0" alt="Advice from the Toolkit"><br>
Figure 2: Advice from the Toolkit
</p>
<p>
To fix this problem, have TimeMIDlet implement the Runnable interface and provide an implementation of the <code>run()</code> method as in Listing 2. Here, <code>run()</code> calls the <code>getTime()</code> method, which performs all the networking in this example. In addition, instead of calling <code>getTime()</code> directly, <code>commandAction()</code> creates a thread and invokes its <code>start()</code> method, which in turn calls the <code>run()</code> method. All changes are highlighted in bold.
</p>
<p>
<b>Listing 2. TimeMIDlet.java</b>
</p>
<pre>
import javax.microedition.midlet.*;
import javax.microedition.io.*;
import javax.microedition.lcdui.*;
import java.io.*;
public class TimeMIDlet extends MIDlet implements CommandListener, Runnable {
private static Display display;
private Form f;
private boolean isPaused;
private StringItem si;
private Command exitCommand = new Command("Exit", Command.EXIT, 1);
private Command startCommand = new Command("GetTime", Command.ITEM, 1);
public TimeMIDlet() {
 display = Display.getDisplay(this);
 f = new Form("Time Demo");
 si = new StringItem("Select GetTime to get the current Time! ", " ");
 f.append(si);
 f.addCommand(exitCommand);
 f.addCommand(startCommand);
 f.setCommandListener(this);
 display.setCurrent(f);
} 
public void startApp() {
 isPaused = false;
}
public void pauseApp() {
 isPaused = true;
}
public void destroyApp(boolean unconditional) {
}
public void commandAction(Command c, Displayable s) {
 if (c == exitCommand) {
 destroyApp(true);
 notifyDestroyed();
 } else if (c == startCommand) {
 Thread t = new Thread(this);
 t.start();
 }
}
public void run() {
 getTime();
}
public void getTime() {
 SocketConnection sc = null;
 InputStream is = null;
 Form f = new Form("Time Client");
 StringItem si = new StringItem("Time:" , " ");
 f.append(si);
 display.setCurrent(f);
 try {
sc = (SocketConnection)
Connector.open("socket://"+"remoteTimeServer"+":13");
is = sc.openInputStream();
StringBuffer sb = new StringBuffer();
int c = 0;
while (((c = is.read()) != '\n') && (c != -1)) {
sb.append((char) c);
}
si.setText(sb.toString()); 
 } catch(IOException e) {
 Alert a = new Alert
("TimeClient", "Cannot connect to server. Ping the server to 
 make sure it is running...", null, AlertType.ERROR);
 a.setTimeout(Alert.FOREVER);
 display.setCurrent(a);
 } finally {
 try {
if(is != null) {
 is.close();
}
if(sc != null) {
 sc.close();
}
 } catch(IOException e) {
e.printStackTrace();
 }
 }
 } 
}
</pre>
<p>
For more complex applications, you may want to implement networking and other blocking operations in a separate class that implements the Runnable interface, as explained in "<a href="http://enews.sun.com/CTServlet?id=56036723-1346146009:1080012083981">J2ME Low-Level Network Programming in MIDP 2.0</a>."
</p>
<p>
<b>For more information</b>
</p>
<p>
- <a href="http://enews.sun.com/CTServlet?id=56036723-1346146009:1080012083994">Download the J2ME Wireless Toolkit 2.0</a><br>
- "<a href="http://enews.sun.com/CTServlet?id=56036723-1346146009:1080012084005">Using Threads in J2ME Applications</a>"<br>
- "<a href="http://enews.sun.com/CTServlet?id=56036723-1346146009:1080012084031">Networking, User Experience, and Threads</a>"<br>
</p>
<p>
<b>Acknowledgments</b>
</p>
<p>
Special thanks to Gary Adams of Sun Microsystems, whose feedback helped improve the article.
</p>
<table width="100%" border="0" cellspacing="0" cellpadding="0" align="center">
<tr>
<td>
<div align="right">
<a href="#top">back to top<img src="http://developer.java.sun.com/images/back_to_top.gif" border="0" alt="pixel"></a>
</div>
</td></tr>
<tr><td bgcolor="#ffffff" height="2"><img src="http://developers.sun.com/techtopics/mobility/images/pixel.gif" width="1" 
height="1" ALT="Pixel" border="0"></td></tr>
<!-- Grey Horizontal Line Begins Here -->
<tr>
<td bgcolor="#cccccc" height="1"><img src="http://developers.sun.com/techtopics/mobility/images/pixel.gif" width="1" 
height="1" ALT="Pixel" border="0"></td>
</tr>
</table> 
<!-- Grey Horizontal Line ends Here -->
<a name="2"></a>
<h3>Text Wrapping in MIDP</h3>
<p>
by <a href="#author">Qusay H. Mahmoud</a><br>
<i>February 2004</i><br>
</p>
<p>
When long pieces of text are displayed on the small screens of cell phones and other small devices, they often "wrap to the next line," and this behavior can reduce the usability of wireless Java applications. Differences in screen size and wrapping behavior can cause handheld devices to break text in different places, creating unpredictable fragmentation of text.
</p>
<p>
This variability can cause problems. The user may not be able to tell whether the lines are parts of the same element, or two independent elements. The uncertainty is confusing in itself - and can lead to worse problems. If the application treats each line of text as a separate element, but the user assumes that the split is merely an artifact of text wrapping, subsequent behavior may be mystifying. For example, suppose the application splits the email address qmahmoud@javacourses.com into two lines, qmahmoud@javacours and es.com. If the application doesn't preserve the original string, it has an invalid email address. The flaw is not obvious, and may cause a problem only much later, when the user tries to send mail to the bad address.
</p>
<p>
Version 2.0 of the Mobile Information Device Profile (MIDP) enhances text wrapping in several ways. This tech tip provides some hints and guidelines on handling text wrapping in MIDP.
</p>
<p>
<b>Recognizable Item Boundaries</b>
</p>
<p>
MIDP provides several user-interface components, some of which wrap text automatically. For example, multiple-choice items include a checkbox at left and wrap text neatly, with a hanging indent. Implicit action items wrap and indent text the same way, with an arrow button in place of a checkbox. The List component, however, is not as helpful. Consider the following fragment of code, which uses a List to create a menu of choices:
</p>
<pre>
List choices = new List("Method of Payment", Choice.IMPLICIT);
choices.append("Choice Number One", null);
choices.append("This is a really long long long long long choice", null);
choices.append("Choice Number Three", null);
choices.append("Choice Number Four", null);
</pre>
<p>
As Figure 1 shows, on a typical device the second choice is likely to span two lines:
</p>
<p>
<img src="http://developers.sun.com/techtopics/mobility/allttips/mailers/2004/images/tt_0304_2-fig1.gif" border="0" alt="How Many Choices?"><br>
Figure 1. How Many Choices?
 </p>
<p>
If the user selects the second choice, the text wrapping becomes clear, as Figure 2 shows:
</p>
<p>
<img src="http://developers.sun.com/techtopics/mobility/allttips/mailers/2004/images/tt_0304_2-fig2.gif" border="0" alt="Implicit Selection"><br>
Figure 2. Implicit Selection
</p>
<p>
Note this implication, however: To be sure which lines belong to which choices, and thus to be clear about the choices available, the user would need to move up and down the list. Not exactly friendly interface.
</p>
<p>
If a string of text is likely to wrap to multiple lines, you should make it clear that the second and subsequent lines are parts of the same element, and do not represent new items. If you are providing the user with a set of items, some of which may wrap to multiple lines, be sure the user can see the start of each item. One way is to add a graphic to the left of the item, and indent any wrapped text - which, conveniently, the <code>Choice.EXPLICIT</code> list type does for you, as Figure 3 shows:
</p>
<p>
<img src="http://developers.sun.com/techtopics/mobility/allttips/mailers/2004/images/tt_0304_2-fig3.gif " border="0" alt="Explicit Selection"><br>
Figure 3. Explicit Selection
 </p>
<p>
<b>Item Layout in Forms </b>
</p>
<p>
Enhancements introduced in MIDP 2.0 offer developers more control over the appearance of their applications. MIDP now provides a more formal layout policy for arranging components within a Form. You can request that components be left-aligned, right-aligned, or centered. The Choice interface now has better text-wrapping behavior. The developer can hint to the application how to handle text that exceeds the screen width by invoking the method <code>setFitPolicy(int fitPolicy)</code>, where <code>fitPolicy</code> can be one of the following values:
</p>
<p>
<code>TEXT_WRAP_DEFAULT</code>: No preference as to how text is displayed; the implementation will exhibit its default behavior.
</p>
<p>
<code>TEXT_WRAP_ON</code>: Text will extend over multiple lines if necessary.
</p>
<p>
<code>TEXT_WRAP_OFF</code>: No wrapping or truncation; long lines of text will be clipped.
</p>
<p>
<b>Controlling Item Sizing</b>
</p>
<p>
In addition, several minor changes have been made to the Item class. For example, each Item has a preferred and minimum size that's based on its contents, label, and layout policy. The minimum size includes just the essentials to display the Item; the preferred size eliminates any clipping, and word-wrapping is kept to a minimum. Some of the new methods to help you work with Item sizes include:
</p>
<pre>
setPreferredSize(int width, int height)
getPreferredHeight()
getPreferredWidth()
getMinimumWidth()
getMinimumHeight()
</pre>
<p>
The <code>setPreferredSize()</code> is an interesting method, as it allows you to lock the width of an Item, or its height, or both. For example, you can choose to keep one dimension at a particular size by passing that number of pixels, and have the application compute the other dimension by passing <code>-1</code>, which is used to unlock the width or height.
</p>
<p>
Finally, here are some guidelines to keep in mind regarding text wrapping:
</p>
<p>
Remember that your applications will be running on devices from different vendors that have different display sizes.
</p>
<p>
Make text easier to read by starting new lines at familiar line breaks, or on word boundaries.
</p>
<p>
When working with items that are long strings, ensure that the user will find it easy to see the start of each item.
</p>
<p>
Use the enhanced APIs of MIDP 2.0 where you can, but keep your applications backward-compatible with MIDP 1.0.
</p>
<p>
<b>For more information</b>
</p>
<p>
- <a href="http://enews.sun.com/CTServlet?id=56036723-1346146009:1080012084041">JSR 118: MIDP 2.0</a><br>
- <a href="http://enews.sun.com/CTServlet?id=56036723-1346146009:1080012084053">Wireless BluePrints</a>
</p>
<table width="100%" border="0" cellspacing="0" cellpadding="0" align="center">
<tr>
<td>
<div align="right">
<a href="#top">back to top<img src="http://developer.java.sun.com/images/back_to_top.gif" border="0" alt="pixel"></a>
</div>
</td></tr>
<tr><td bgcolor="#ffffff" height="2"><img src="http://developers.sun.com/techtopics/mobility/images/pixel.gif" width="1" 
height="1" ALT="Pixel" border="0"></td></tr>
<!-- Grey Horizontal Line Begins Here -->
<tr>
<td bgcolor="#cccccc" height="1"><img src="http://developers.sun.com/techtopics/mobility/images/pixel.gif" width="1" 
height="1" ALT="Pixel" border="0"></td>
</tr>
</table> 
<!-- Grey Horizontal Line ends Here -->
<a name="author"></a>
<p>
<b>About the author</b>
</p>
<p>
Qusay H. Mahmoud provides Java consulting and training services. He has published dozens of articles on Java, and is the author of <i>Distributed Programming with Java</i> (Manning Publications, 1999) and <i>Learning Wireless Java</i> (O'Reilly, 2002).
</p>
<table width="100%" border="0" cellspacing="0" cellpadding="0" align="center">
<tr>
<td>
<div align="right">
<a href="#top">back to top<img src="http://developer.java.sun.com/images/back_to_top.gif" border="0" alt="pixel"></a>
</div>
</td></tr>
<tr><td bgcolor="#ffffff" height="2"><img src="http://developers.sun.com/techtopics/mobility/images/pixel.gif" width="1" 
height="1" ALT="Pixel" border="0"></td></tr>
<!-- Grey Horizontal Line Begins Here -->
<tr>
<td bgcolor="#cccccc" height="1"><img src="http://developers.sun.com/techtopics/mobility/images/pixel.gif" width="1" 
height="1" ALT="Pixel" border="0"></td>
</tr>
</table> 
<!-- Grey Horizontal Line ends Here -->
<br>
<!-- BEGIN RATE AND REVIEW -->
<script type="text/javascript">
<!-- Hide script from older browsers
// Popup window function
function onRateSubmitHandler()
{
var w = window.open("","foo","width=400,height=200,status=no,toolbar=no");
w.setTimeout("window.close();", 30000 );
return true;
}
// End of javascript 
-->
</script>
<form name="article_rating" method="post" action="http://survey.sun.com/ViewsFlash/servlet/viewsflash" onSubmit="return onRateSubmitHandler()" target="foo">
<table width="100%" cellspacing="0" cellpadding="1" border="0" class="white" style="margin-top:7px"><tr><td>
<table width="100%" cellspacing="0" cellpadding="4" border="0">
<tr><td class="dkgrey1"><b>Reader Feedback</b></td></tr>
<tr><td class="ltgrey"><b>
<a name="VFquality"></a>
<input type="radio" name="quality" value="Excellent"> Excellent  
<input type="radio" name="quality" value="Good"> Good  
<input type="radio" name="quality" value="Fair"> Fair  
<input type="radio" name="quality" value="Poor"> Poor  
</b></td></tr>
<tr><td class="ltgrey">
<p>
If you have other comments or ideas for future technical tips, please type them here: 
</p>
<a name="VFcomments"></a>
<b>Comments:</b><br><textarea name="comments" cols="50" rows="3" wrap="virtual"></textarea></td></tr>
<tr><td class="ltgrey">
<a name="VFEmail"></a>
<b>If you would like a reply to your comment, please submit your email address:</b><br>
<input type="text" name="Email" value="" size="35" maxlength="60"> Note: We may not respond to all submitted comments.</td></tr>
<tr><td class="ltgrey">
<input type="submit" border="0" value=" Submit » ">
<a name="VFURL"></a>
<input type="hidden" name="URL" value="developers.sun.com/techtopics/mobility/allttips/mailers/2004/tt_0304.html">
<a name="VFArticleTitle"></a>
<input type="hidden" name="WirelessTTipsTitle" value="WirelessTTips">
<a name="VFArticleAuthor"></a>
<input type="hidden" name="WirelessTTipsAuthor" value="Qusay H. Mahmoud">
<input type="hidden" name="cmd" value="tally">
<input type="hidden" name="pollid" value="CNP!tGreene">
<input type="hidden" name="results" value="? http://developer.sun.com/ratereviewthankyou.html">
<input type="hidden" name="charset" value="ISO-8859-1">
<p> 
Have a question about Java programming? Use <a href="http://enews.sun.com/CTServlet?id=56036723-1346146009:1080012084072">Java Online Support</a>. 
</p>
</td></tr></table></td></tr>
</table></form>
<!-- END RATE AND REVIEW -->
<table width="100%" border="0" cellspacing="0" cellpadding="0" align="center">
<tr>
<td>
<div align="right">
<a href="#top">back to top<img src="http://developer.java.sun.com/images/back_to_top.gif" border="0" alt="pixel"></a>
</div>
</td></tr>
<tr><td bgcolor="#ffffff" height="2"><img src="http://developers.sun.com/techtopics/mobility/images/pixel.gif" width="1" 
height="1" ALT="Pixel" border="0"></td></tr>
<!-- Grey Horizontal Line Begins Here -->
<tr>
<td bgcolor="#cccccc" height="1"><img src="http://developers.sun.com/techtopics/mobility/images/pixel.gif" width="1" 
height="1" ALT="Pixel" border="0"></td>
</tr>
</table> 
<!-- Grey Horizontal Line ends Here -->
<br>
<span class="small">Important: Please read our Licensing, Terms of Use, and Privacy policies:<br>
<a href="http://enews.sun.com/CTServlet?id=56036723-1346146009:1080012083694"><span class="link">http://developer.java.sun.com/berkeley_license.html</span></a><br>
<a href="http://enews.sun.com/CTServlet?id=56036723-1346146009:1080012083804"><span class="link">http://www.sun.com/share/text/termsofuse.html</span></a><br>
<a href="http://enews.sun.com/CTServlet?id=56036723-1346146009:1080012083822"><span class="link">http://www.sun.com/privacy/</span></a>
<br><br>
Feedback: Submit your feedback on the Wireless Developer Newsletter to:<br>
<a href="http://enews.sun.com/CTServlet?id=56036723-1346146009:1080012083833"><span class="link">http://developers.sun.com/contact/feedback.jsp?category=sdn</span></a>
<br><br>
Subscribe/Unsubscribe: Subscribe to other Java technology newsletters:
<br><br>
- Java Technology Fundamentals Newsletter. Learn the basics of the Java programming language and keep up-to-date on additions to the New-to-Java Programming Center.<br>
- Core Java Technologies Newsletter. Learn about new products, tools, resources, and events of interest to developers working with core Java technologies.<br>
- Enterprise Java Technologies Newsletter. Learn about new products, tools, resources, and events of interest to developers working with enterprise Java technologies.
<br><br>
You can subscribe to these and other Sun Developer Network publications on the SDN Newsletters and Publications page
<br>
- To subscribe, visit the <a href="http://enews.sun.com/CTServlet?id=56036723-1346146009:1080012084083"><span class="link">SDN Newsletters and Publications page</span></a>, select the newsletters you want to subscribe to and click "Update".<br>
- To unsubscribe, go to the <a href="http://enews.sun.com/CTServlet?id=56036723-1346146009:1080012084083"><span class="link">subscriptions page</span></a>, uncheck the appropriate checkbox, and click "Update".
<br><br>
Archives: You'll find the Wireless Developer Tech Tips archives at:<br>
<a href="http://enews.sun.com/CTServlet?id=56036723-1346146009:1080012083844"><span class="link">http://developer.sun.com/techtopics/mobility/allttips/</span></a>
<br><br>
Copyright<br>
<a href="http://enews.sun.com/CTServlet?id=56036723-1346146009:1080012083858"><span class="link">Copyright</span></a> 2004 <a href="http://enews.sun.com/CTServlet?id=56036723-1346146009:1080012084095"><span class="link">Sun Microsystems, Inc.</span></a> All rights reserved. 4150 Network Circle, Santa Clara, CA 95054 USA<br>
This document is protected by copyright. For more information, see: <a href="http://enews.sun.com/CTServlet?id=56036723-1346146009:1080012083858"><span class="link">http://java.sun.com/jdc/copyright.html</span></a>
<br><br>
<!-- BEGIN Copyright info which changes each month -->
Trademark Information: <a href="http://enews.sun.com/CTServlet?id=56036723-1346146009:1080012083926"><span class="link">http://www.sun.com/suntrademarks/</span></a><br>
Java, J2EE, J2SE, J2ME, and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries.
<!-- END Copyright info which changes each month -->
</span><br><br>
<!-- ================ -->
<!-- End Main Content -->
<!-- ================ -->
<center>
<a href="http://enews.sun.com/CTServlet?id=56036723-1346146009:1080012084095"><img src="http://developer.java.sun.com/images/lgsun.gif" border="0" alt="Sun Microsystems, Inc."></a>
</center>
</td>
</tr>
</table>
</td></tr>
</table>
</td>
<td bgcolor="#cccccc" width="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" border="0" alt="pixel"></td>
</tr>
<tr>
<td colspan="3" bgcolor="#cccccc" width="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" border="0" alt="pixel"></td>
</tr>
</table>
<br><br><table bgcolor = "#efefef"><tr><td><a href="http://subscriptions.sun.com/unsubscribe?56036723-1346146009">Please unsubscribe me from this newsletter.</a></td></tr></table><br><br><img src="http://enews.sun.com/OTServlet?id=56036723-1346146009" width=1 height=1></body>
</html>
winzip iconDownload code

Note: Due to the size or complexity of this submission, the author has submitted it as a .zip file to shorten your download time. Afterdownloading it, you will need a program like Winzip to decompress it.Virus note:All files are scanned once-a-day by Planet Source Code for viruses, but new viruses come out every day, so no prevention program can catch 100% of them. For your own safety, please:
  1. Re-scan downloaded files using your personal virus checker before using it.
  2. NEVER, EVER run compiled files (.exe's, .ocx's, .dll's etc.)--only run source code.

If you don't have a virus scanner, you can get one at many places on the net including:McAfee.com

 
Terms of Agreement:   
By using this code, you agree to the following terms...   
  1. You may use this code in your own programs (and may compile it into a program and distribute it in compiled format for languages that allow it) freely and with no charge.
  2. You MAY NOT redistribute this code (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.   
  3. You may link to this code from another website, but ONLY if it is not wrapped in a frame. 
  4. You will abide by any additional copyright restrictions which the author may have placed in the code or code's description.


Other 1 submission(s) by this author

 


Report Bad Submission
Use this form to tell us if this entry should be deleted (i.e contains no code, is a virus, etc.).
This submission should be removed because:

Your Vote

What do you think of this code (in the Intermediate category)?
(The code with your highest vote will win this month's coding contest!)
Excellent  Good  Average  Below Average  Poor (See voting log ...)
 

Other User Comments

12/18/2004 1:02:00 AM

it non fun when it easy
(If this comment was disrespectful, please report it.)

 
3/1/2007 2:45:59 AMritesh

good
(If this comment was disrespectful, please report it.)

 
6/30/2009 4:13:59 AMyogesh

project
(If this comment was disrespectful, please report it.)

 

Add Your Feedback
Your feedback will be posted below and an email sent to the author. Please remember that the author was kind enough to share this with you, so any criticisms must be stated politely, or they will be deleted. (For feedback not related to this particular code, please click here instead.)
 

To post feedback, first please login.