<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Don&#039;s Java ME Blog</title>
	<atom:link href="http://www.dbarnes.com/midlet/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dbarnes.com/midlet</link>
	<description>Java ME Games and Development Resources</description>
	<lastBuildDate>Tue, 16 Apr 2013 01:49:19 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Some Simple Text Effects in Java ME</title>
		<link>http://www.dbarnes.com/midlet/java-me-text-effects/</link>
		<comments>http://www.dbarnes.com/midlet/java-me-text-effects/#comments</comments>
		<pubDate>Sat, 12 Jan 2008 18:26:02 +0000</pubDate>
		<dc:creator>Don Barnes</dc:creator>
				<category><![CDATA[Java ME Development]]></category>

		<guid isPermaLink="false">http://www.dbarnes.com/midlet/java-me-text-effects/</guid>
		<description><![CDATA[The Graphics.drawString() method in MIDP is pretty limited. You can specify a position, anchor point, and with the help of Graphics.setColor() and Graphics.setFont(), a color and a font, but that&#8217;s about it. However, its possible to do some simple text effects that are a bit more interesting by combining multiple calls to drawString(). First, lets [...]]]></description>
				<content:encoded><![CDATA[<p>The <code>Graphics.drawString()</code> method in MIDP is pretty limited.  You can specify a position, anchor point, and with the help of <code>Graphics.setColor()</code> and <code>Graphics.setFont()</code>, a color and a font, but that&#8217;s about it.  However, its possible to do some simple text effects that are a bit more interesting by combining multiple calls to <code>drawString()</code>.</p>
<p><span id="more-40"></span>First, lets take a quick look at the APIs involved.  The <code>drawString()</code> method is pretty straightforward:</p>
<p><code>public void drawString(String str, int x, int y, int anchor);</code></p>
<p>The purposes of the <code>str</code>, <code>x</code>, and <code>y</code> parameters should be obvious.  The <code>anchor</code> parameter defines how the text should be positioned in relation to the specified x and y coordinates.  The accepted values are <code>LEFT</code>, <code>HCENTER</code>, <code>RIGHT</code> for the horizontal positioning, and <code>TOP</code>, <code>BASELINE</code>, and <code>BOTTOM</code> for the vertical positioning.  These constants can be combined using the logical OR operator, e.g.:</p>
<p><pre><code>g.drawString(&quot;Hello World&quot;, 100, 100,
Graphics.TOP | Graphics.HCENTER);</code></pre></p>
<p>For our first effect, we will draw a string in a specified color with a black outline with the method below.</p>
<p><pre><pre>
public void drawStringThick(
&nbsp;&nbsp;Graphics g, String str, int x, int y,
&nbsp;&nbsp;int anchor, int fillColor
) {

&nbsp;&nbsp;g.setColor(0x000000);
&nbsp;&nbsp;g.drawString(str, x + 1, y + 1, anchor);
&nbsp;&nbsp;g.drawString(str, x + 1, y - 1, anchor);
&nbsp;&nbsp;g.drawString(str, x - 1, y + 1, anchor);
&nbsp;&nbsp;g.drawString(str, x - 1, y - 1, anchor);

&nbsp;&nbsp;g.drawString(str, x + 2, y + 2, anchor);
&nbsp;&nbsp;g.drawString(str, x + 2, y - 2, anchor);
&nbsp;&nbsp;g.drawString(str, x - 2, y + 2, anchor);
&nbsp;&nbsp;g.drawString(str, x - 2, y - 2, anchor);

&nbsp;&nbsp;g.setColor(fillColor);
&nbsp;&nbsp;g.drawString(str, x, y, anchor);

}
</pre></pre>
<p>The next method will draw a string with a pseudo-3D rainbow effect.</p>
<p><pre><pre>
public void drawCrazyString(
&nbsp;&nbsp;int x, int y, Graphics g,
&nbsp;&nbsp;String msg, int anchor
) {
&nbsp;&nbsp;Font font = Font.getFont(
&nbsp;&nbsp;&nbsp;&nbsp;Font.FACE_PROPORTIONAL,
&nbsp;&nbsp;&nbsp;&nbsp;Font.STYLE_BOLD,
&nbsp;&nbsp;&nbsp;&nbsp;Font.SIZE_LARGE
&nbsp;&nbsp;);
&nbsp;&nbsp;g.setFont(font);
&nbsp;&nbsp;g.setColor(0x0000FF);
&nbsp;&nbsp;g.drawString(msg, x + 10, y + 10, anchor);
&nbsp;&nbsp;g.setColor(0x00FF00);
&nbsp;&nbsp;g.drawString(msg, x + 8, y + 8, anchor);
&nbsp;&nbsp;g.setColor(0xFFFF00);
&nbsp;&nbsp;g.drawString(msg, x + 6, y + 6, anchor);
&nbsp;&nbsp;g.setColor(0xFF7700);
&nbsp;&nbsp;g.drawString(msg, x + 4, y + 4, anchor);
&nbsp;&nbsp;g.setColor(0xFF0000);
&nbsp;&nbsp;g.drawString(msg, x + 2, y + 2, anchor);
&nbsp;&nbsp;g.setColor(0xFFFFFF);
&nbsp;&nbsp;g.drawString(msg, x, y, anchor);
}
</pre></pre>
<p>With some creativity, you should be able to come up with other combinations of these method calls that will produce some interesting results.  Happy coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbarnes.com/midlet/java-me-text-effects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Filtering and Ordering Records with RMS</title>
		<link>http://www.dbarnes.com/midlet/filtering-and-ordering-records-with-rms/</link>
		<comments>http://www.dbarnes.com/midlet/filtering-and-ordering-records-with-rms/#comments</comments>
		<pubDate>Sat, 13 Oct 2007 15:21:37 +0000</pubDate>
		<dc:creator>Don Barnes</dc:creator>
				<category><![CDATA[Java ME Development]]></category>

		<guid isPermaLink="false">http://www.dbarnes.com/midlet/filtering-and-ordering-records-with-rms/</guid>
		<description><![CDATA[If you&#8217;ve ever used the Record Management System mechanism in MIDP, you already know how useful the RecordStore class can be for storing persistent data. In a previous tutorial, Using RMS to Store Persistent Data, we used the RecordStore.getRecord(int) method to retrieve a record by its ID. However, sometimes you may have more complex retrieval [...]]]></description>
				<content:encoded><![CDATA[<p>If you&#8217;ve ever used the Record Management System mechanism in MIDP, you already know how useful the <code>RecordStore</code> class can be for storing persistent data.  In a previous tutorial, <a href="http://www.dbarnes.com/midlet/midp-rms/">Using RMS to Store Persistent Data</a>, we used the <code>RecordStore.getRecord(int)</code> method to retrieve a record by its ID.  However, sometimes you may have more complex retrieval criteria than simply the record ID.  That&#8217;s where the <code>enumerateRecords()</code> method comes in handy.  In this article we will discuss how to filter and order a subset of records in a <code>RecordStore</code> object using <code>enumerateRecords()</code></p>
<p><span id="more-39"></span>The complete signature of the <code>enumerateRecords()</code> method looks like this:</p>
<p><pre><code>public RecordEnumeration enumerateRecords(
RecordFilter, RecordComparator, boolean)
throws RecordStoreNotOpenException</code></pre></p>
<p>This method returns an object that enumerates a set of records from the <code>RecordStore</code>.  The <code>RecordFilter</code> argument allows the application to specify criteria that will used to return a subset of records.  Similarly, the <code>RecordComparator</code> argument allows the application to define logic that will determine the order of the records that are returned.</p>
<p>For example, lets say we have an application with a record store containing ZIP codes.</p>
<p><pre><pre>
/**
 * Initializes record store with some ZIP codes.
 */
public RecordStore initRecordStore() {
try {
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;// Open or create RecordStore
&nbsp;&nbsp;&nbsp;&nbsp;RecordStore recordStore
&nbsp;&nbsp;&nbsp;&nbsp;= RecordStore.openRecordStore(&quot;zipCodes&quot;, true);

&nbsp;&nbsp;&nbsp;&nbsp;// Add records if this record store hasn&#039;t yet 
&nbsp;&nbsp;&nbsp;&nbsp;// been initialized
&nbsp;&nbsp;&nbsp;&nbsp;if(recordStore.getNumRecords() == 0) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;recordStore.addRecord(&quot;49120&quot;.getBytes(), 0, 5);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;recordStore.addRecord(&quot;90210&quot;.getBytes(), 0, 5);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;recordStore.addRecord(&quot;56921&quot;.getBytes(), 0, 5);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;recordStore.addRecord(&quot;10210&quot;.getBytes(), 0, 5);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;recordStore.addRecord(&quot;32010&quot;.getBytes(), 0, 5);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;return recordStore;

} catch(RecordStoreException e) {

&nbsp;&nbsp;&nbsp;&nbsp;System.err.println(&quot;Could not initialize record store&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;return null;

}
}
</pre></pre></p>
<p>Now, let&#8217;s say we want to be able to return only ZIP codes that appear in a specific range, and we want them returned in lexicographical order.  First we will create a class that implements <code>RecordFilter</code> to specify the filtering.  The start and end of the range will be data members of this class.</p>
<p><pre><pre>
import javax.microedition.rms.*;

public class RangeRecordFilter implements RecordFilter {

/**
 * Creates a new instance of RangeRecordFilter
 */
public RangeRecordFilter(String start, String end) {
&nbsp;&nbsp;&nbsp;&nbsp;setStart(start);
&nbsp;&nbsp;&nbsp;&nbsp;setEnd(end);
}

/**
 * Determines if candidate is in specified range.
 */
public boolean matches(byte[] candidate) {
&nbsp;&nbsp;&nbsp;&nbsp;String candidateString = new String(candidate);

&nbsp;&nbsp;&nbsp;&nbsp;return (getStart().compareTo(candidateString) &lt;= 0
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp; getEnd().compareTo(candidateString) &gt;= 0);
}

public String getStart() {
&nbsp;&nbsp;&nbsp;&nbsp;return start;
}

public void setStart(String start) {
&nbsp;&nbsp;&nbsp;&nbsp;this.start = start;
}

public String getEnd() {
&nbsp;&nbsp;&nbsp;&nbsp;return end;
}

public void setEnd(String end) {
&nbsp;&nbsp;&nbsp;&nbsp;this.end = end;
}

private String start;
private String end;
&nbsp;&nbsp;&nbsp;&nbsp;
}
</pre></pre></p>
<p>Next, we will create a class that implements <code>RecordComparator</code> to specify the ordering.</p>
<p><pre><pre>
import javax.microedition.rms.*;

public class StringRecordComparator implements RecordComparator {

public int compare(byte[] rec1, byte[] rec2) {
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;// Convert to String objects
&nbsp;&nbsp;&nbsp;&nbsp;String rec1String = new String(rec1);
&nbsp;&nbsp;&nbsp;&nbsp;String rec2String = new String(rec2);

&nbsp;&nbsp;&nbsp;&nbsp;// Do a string comparison
&nbsp;&nbsp;&nbsp;&nbsp;int comparison = rec1String.compareTo(rec2String);
&nbsp;&nbsp;&nbsp;&nbsp;if(comparison &lt; 0) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return RecordComparator.PRECEDES;
&nbsp;&nbsp;&nbsp;&nbsp;} else if(comparison == 0) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return RecordComparator.EQUIVALENT;
&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return RecordComparator.FOLLOWS;
&nbsp;&nbsp;&nbsp;&nbsp;}

}

}
</pre></pre></p>
<p>Now we can use these classes to return an ordered subset of ZIP codes in a specified range from our record store.  For example:</p>
<p><pre><pre>
RecordStore recordStore = initRecordStore();
if(recordStore != null) {

&nbsp;&nbsp;&nbsp;&nbsp;// Create filter and comparator
&nbsp;&nbsp;&nbsp;&nbsp;RangeRecordFilter filter =
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new RangeRecordFilter(&quot;40000&quot;, &quot;60000&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;StringRecordComparator comparator
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= new StringRecordComparator();

&nbsp;&nbsp;&nbsp;&nbsp;// Enumerate matching records
&nbsp;&nbsp;&nbsp;&nbsp;RecordEnumeration records;
&nbsp;&nbsp;&nbsp;&nbsp;try {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;records = recordStore.enumerateRecords(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filter, comparator, false);
&nbsp;&nbsp;&nbsp;&nbsp;} catch(RecordStoreNotOpenException e) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.err.println(&quot;Could not enumerate&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;// Output the results
&nbsp;&nbsp;&nbsp;&nbsp;while(records.hasNextElement()) {
&nbsp;&nbsp;&nbsp;&nbsp;byte[] rec;
&nbsp;&nbsp;&nbsp;&nbsp;try {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rec = records.nextRecord();
&nbsp;&nbsp;&nbsp;&nbsp;} catch(Exception e) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.err.println(&quot;Could not get record&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(new String(rec));
}
</pre></pre></p>
<p>For more information about record stores, be sure to read the <a href="http://java.sun.com/javame/reference/apis/jsr118/javax/microedition/rms/package-summary.html">javax.microedition.rms Package Documentation</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbarnes.com/midlet/filtering-and-ordering-records-with-rms/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using the Mobile Media API to Play Video</title>
		<link>http://www.dbarnes.com/midlet/video-mmapi/</link>
		<comments>http://www.dbarnes.com/midlet/video-mmapi/#comments</comments>
		<pubDate>Mon, 13 Aug 2007 11:36:41 +0000</pubDate>
		<dc:creator>Don Barnes</dc:creator>
				<category><![CDATA[Java ME Development]]></category>

		<guid isPermaLink="false">http://www.dbarnes.com/midlet/video-mmapi/</guid>
		<description><![CDATA[The Mobile Media API (JSR-135) specification enables advanced audio and video support on Java ME devices. While MIDP 2.0 supports a subset of the MMAPI, this subset does not include the video or graphics components of the specification. In this article, we will look at a simple example of how to play video on a [...]]]></description>
				<content:encoded><![CDATA[<p>The Mobile Media API (JSR-135) specification enables advanced audio and video support on Java ME devices. While MIDP 2.0 supports a subset of the MMAPI, this subset does not include the video or graphics components of the specification. In this article, we will look at a simple example of how to play video on a MMAPI enabled device.</p>
<p><span id="more-38"></span>From a developer perspective, there are three major components you will need to worry about when working with the MMAPI. <code>Player</code> objects are used to process content and rendered it to the user. <code>Manager</code> objects are factories that create <code>Player</code> objects. Lastly, you will need an object to provide the input for the content itself. This can either be a <code>DataSource</code> or an <code>InputStream</code> object.</p>
<p><a href="/midlet/images/video-mmapi.png"><img src="/midlet/images/video-mmapi-tn.png" alt="Video MMAPI Demo" style="clear: right; padding-left: 5px; float: right; padding-bottom: 5px" title="Video MMAPI Demo" /></a>I&#8217;ve contructed a very simple MIDlet that demonstrates how to play a video, which I will be referring to below. The full source code for this MIDlet can be found here: <a href="/midlet/tutorial-files/VideoDemo.zip">MMAPI Video Demo Source Code</a>. An example MPEG file is included in this file. If you are using NetBeans Mobility Pack, make sure you have enabled the optional package &#8220;Mobile Media API&#8221; in your project configuration.</p>
<p>In this example, I&#8217;ve created a class called <code>VideoForm</code> that encapsulates all of the required logic for initializing and playing the video. A <code>StringItem</code> object is used to inform the user of the current status. The block of code below is used to create the player object. Note that <code>getMediaFileName()</code> and <code>getContentType()</code> are simply accessor methods in my <code>VideoForm</code> class. For this simple example, the video will be a resource stored in the JAR file, and the application will aquire an <code>InputStream</code> for it using the <code>getResourceAsStream()</code> method.<br />
<pre><pre>
// Create the Player object from an InputStream
InputStream inputStream = 
&nbsp;&nbsp;&nbsp;&nbsp;getClass().getResourceAsStream(getMediaFileName()); 

Player player = Manager.createPlayer( 
&nbsp;&nbsp;&nbsp;&nbsp;inputStream, 
&nbsp;&nbsp;&nbsp;&nbsp;getContentType() 
);
</pre></pre><br />
Once the <code>Player</code> is created, the code below sets the loop count and allows the <code>Player</code> to initialize itself. Note that the <code>realize()</code> method can be particularly slow, so appropriate feedback should relayed to the user.<br />
<pre><pre>
// Set the loop count 
player.setLoopCount(getLoopCount()); 

// Realize (contruct player) 
getStatusItem().setText(&quot;Realizing...&quot;); 
player.realize(); 
getStatusItem().setText(&quot;Realized.&quot;); 

// Prefetch (aquire resources) 
getStatusItem().setText(&quot;Prefetching...&quot;); 
player.prefetch(); 
getStatusItem().setText(&quot;Prefetched.&quot;);
</pre></pre></p>
<p>Now we can get a <code>VideoControl</code> object which can be added to our form. As you may have noticed, <code>VideoControl</code> is not part of MIDP 2.0, therefore the device must support MMAPI in order for this to work. Alternatively, if you were using a <code>Canvas</code> instead of a <code>Form</code> as your displayable object, you could take advantage of the <code>VideoControl.USE_DIRECT_VIDEO</code> option to write directly to the Canvas.</p>
<p><pre><pre>
// Add VideoControl to form 
VideoControl videoControl = 
&nbsp;&nbsp;&nbsp;&nbsp;(VideoControl)player.getControl(&quot;VideoControl&quot;); 

if(videoControl != null) { 
&nbsp;&nbsp;&nbsp;&nbsp;Item videoItem = 
&nbsp;&nbsp;&nbsp;&nbsp;(Item)videoControl.initDisplayMode( 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VideoControl.USE_GUI_PRIMITIVE, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;null); 
&nbsp;&nbsp;&nbsp;&nbsp;append(videoItem); 
}
</pre></pre><br />
Lastly, in our MIDlet class, we will do something similar to the following to set up the VideoForm and start the video.<br />
<pre><pre>
VideoForm form = new VideoForm(&quot;Video Test&quot;); 
form.setContentType(&quot;video/mpeg&quot;); 
form.setMediaFileName(&quot;/video.mpg&quot;); 
... 
// Start the video 
form.play();
</pre></pre><br />
For more information about MMAPI, check out the following links:</p>
<p><a href="http://java.sun.com/products/mmapi/">MMAPI Home Page</a><br />
<a href="http://java.sun.com/javame/reference/apis/jsr135/">MMAPI JavaDoc</a><br />
<a href="http://today.java.net/pub/a/today/2005/09/27/j2me4.html?page=1">J2ME Tutorial, Part 4: Multimedia and MIDP 2.0</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbarnes.com/midlet/video-mmapi/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Text Messaging and the Wireless Messaging API</title>
		<link>http://www.dbarnes.com/midlet/text-messaging-wma/</link>
		<comments>http://www.dbarnes.com/midlet/text-messaging-wma/#comments</comments>
		<pubDate>Mon, 16 Jul 2007 13:42:37 +0000</pubDate>
		<dc:creator>Don Barnes</dc:creator>
				<category><![CDATA[Java ME Development]]></category>

		<guid isPermaLink="false">http://www.dbarnes.com/midlet/text-messaging-wma/</guid>
		<description><![CDATA[Short Message Service (SMS), commonly referred to as Text Messaging, allows cell phone users to send short, plain-text messages to each other. The Wireless Messaging API (WMA) is an optional Java ME package that provides programmatic support for messaging technologies such as SMS. In this article we will look at how to use WMA to [...]]]></description>
				<content:encoded><![CDATA[<p>Short Message Service (SMS), commonly referred to as Text Messaging, allows cell phone users to send short, plain-text messages to each other.  The <a href="http://java.sun.com/products/wma/index.jsp">Wireless Messaging API (WMA)</a> is an optional Java ME package that provides programmatic support for messaging technologies such as SMS.  In this article we will look at how to use WMA to send SMS messages.</p>
<p><span id="more-37"></span>The Wireless Messaging API can be found in the <code>javax.wireless.messaging</code> package.  Sending of messages is handled by the <code>MessageConnection</code> class.  <code>MessageConnection</code> objects are obtained by calling the <code>open()</code> method of the <code>javax.microedition.io.Connector</code> class with a URL string in the format:</p>
<p><code>protocol://address:port</code></p>
<p>For example:</p>
<p><code>sms://+12125551212:5000</code></p>
<p>For SMS, the address part represents the <a href="http://en.wikipedia.org/wiki/Mobile_Station_Integrated_Services_Digital_Network">MSISDN</a> of the destination; typically this is a telephone number with country code.  The port number is application specific.  If you want the default messaging application of the destination device to open the message, simply leave off the port number.</p>
<p>Below is sample code for sending a text message.  Note that in a production application, you may want to spawn a new thread for running this code, as it involves a network call that could potentially block the user interface.  Also, exception handling has been ommitted from this example for clarity.</p>
<p><pre><pre>
import javax.wireless.messaging.MessageConnection;
import javax.wireless.messaging.TextMessage;
import javax.microedition.io.Connector;
import java.io.IOException;

public class SMSUtility {

public static void sendMessage(String msisdn, String text)
&nbsp;&nbsp;&nbsp;&nbsp;throws IOException {

&nbsp;&nbsp;&nbsp;&nbsp;// Open connection
&nbsp;&nbsp;&nbsp;&nbsp;MessageConnection con = (MessageConnection)
&nbsp;&nbsp;&nbsp;&nbsp;Connector.open(&quot;sms://+&quot; + msisdn);

&nbsp;&nbsp;&nbsp;&nbsp;// Create new message
&nbsp;&nbsp;&nbsp;&nbsp;TextMessage message = (TextMessage)
&nbsp;&nbsp;&nbsp;&nbsp;con.newMessage(MessageConnection.TEXT_MESSAGE);

&nbsp;&nbsp;&nbsp;&nbsp;// Set text
&nbsp;&nbsp;&nbsp;&nbsp;message.setPayloadText(text);

&nbsp;&nbsp;&nbsp;&nbsp;// Send message
&nbsp;&nbsp;&nbsp;&nbsp;con.send(message);

&nbsp;&nbsp;&nbsp;&nbsp;// Close connection
&nbsp;&nbsp;&nbsp;&nbsp;con.close();

}

}
</pre></pre></p>
<p>For more information about WMA, including other uses such as opening server connections, check out the following links:</p>
<p><a href="http://java.sun.com/products/wma/index.jsp">Wireless Messaging API (WMA); JSR 120, JSR 205</a><br />
<a href="http://java.sun.com/products/sjwtoolkit/wtk2.5.1/docs/UserGuide-html/wma.html">Sun Java Wireless Toolkit: Using the Wireless Messaging API</a><br />
<a href="http://developers.sun.com/mobility/allarticles/#wma">Java ME Technical Articles: WMA</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbarnes.com/midlet/text-messaging-wma/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using MIDP Localization to Support Multiple Languages</title>
		<link>http://www.dbarnes.com/midlet/midp-localization/</link>
		<comments>http://www.dbarnes.com/midlet/midp-localization/#comments</comments>
		<pubDate>Mon, 04 Jun 2007 12:05:05 +0000</pubDate>
		<dc:creator>Don Barnes</dc:creator>
				<category><![CDATA[Java ME Development]]></category>

		<guid isPermaLink="false">http://www.dbarnes.com/midlet/midp-localization/</guid>
		<description><![CDATA[In today&#8217;s global economy, it is now more important than ever for software to be written with localization in mind, and mobile applications are no exception. Thankfully, NetBeans Mobility Pack makes the task easier with built-in support for MIDP localization. In this article we will take a look at MIDP localization, and how NetBeans helps [...]]]></description>
				<content:encoded><![CDATA[<p>In today&#8217;s global economy, it is now more important than ever for software to be written with <a href="http://en.wikipedia.org/wiki/Software_localization">localization</a> in mind, and mobile applications are no exception.  Thankfully, NetBeans Mobility Pack makes the task easier with built-in support for MIDP localization.  In this article we will take a look at MIDP localization, and how NetBeans helps us implement localized applications.</p>
<p><span id="more-36"></span>A localized application has the ability to display text for the correct language based on the locale of the device.  This includes text for labels, alerts, commands, buttons, etc.  A localized application should be able to support new languages without making modifications to the application logic.  In Java ME, this is achieved through MIDP localization.</p>
<p>The current locale of the device can be determined by querying the <code>microedition.locale</code> system property.  For example:<br />
<pre><code>
String curLocale = System.getProperty(&quot;microedition.locale&quot;);
</code></pre><br />
The locale string contains an ISO standard <a href="http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt">language code</a> and <a href="http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html">country code</a> (e.g. &#8220;en_US&#8221;).</p>
<p>One approach to localization involves the creation of property bundle files containing name-value pairs which represent all the various pieces of text to be displayed in the application.  NetBeans Mobility Pack provides an MIDP localization wizard to facilitate the maintenance and use of such property bundle files.</p>
<p><a href="/midlet/images/midp-localization-1-support-class.png" target="_blank"><img src="/midlet/images/midp-localization-1-support-class_tn.png" alt="MIDP Localization" title="MIDP Localization" style="float: right; clear:right; padding: 5px 5px 5px 15px;" /></a><a href="/midlet/images/midp-localization-2-support-class.png" target="_blank" ><img src="/midlet/images/midp-localization-2-support-class_tn.png" alt="MIDP Localization" title="MIDP Localization" style="float: right; clear:right; padding: 5px 5px 5px 15px;" /></a>To start, right-click on the node for your MIDP project, select &#8220;New File/Folder&#8230;&#8221;, and then select &#8220;MIDP&#8221; > &#8220;Localization Support Class.&#8221;  On the next dialog, simply accept the default values by clicking &#8220;Finish.&#8221;</p>
<p><a href="/midlet/images/midp-localization-3-messages.png" target="_blank"><img src="/midlet/images/midp-localization-3-messages_tn.png" alt="MIDP Localization" title="MIDP Localization" style="float: right; clear:right; padding: 5px 5px 5px 15px;" /></a>You should now see a new class in the project tree named LocalizationSupport, as well as a messages.properties file.  Open the messages.properties file by double-clicking on its node, and add the following line to define a localization key and value:<br />
<pre><code>
Title = Hello World
</code></pre></p>
<p><a href="/midlet/images/midp-localization-4-new-locale.png" target="_blank"><img src="/midlet/images/midp-localization-4-new-locale_tn.png" alt="MIDP Localization" title="MIDP Localization" style="float: right; clear:right; padding: 5px 5px 5px 15px;" /></a>Now, let&#8217;s add a new locale.  Right-click on the messages.properties node in the project tree, and select &#8220;Add Locale&#8230;&#8221;  Choose a locale from the list; for this example, I selected &#8220;es_MX&#8221;.  Now expand the messages.properties node, and you will see a new sub-node titled &#8220;es_MX &#8211; Spanish (Mexico)&#8221; beneath the &#8220;default language&#8221; node.  Double-click the &#8220;es_MX&#8221; node to open the localized file.  You should see that the &#8220;Title&#8221; property has been copied from the default language file.  Change the value &#8220;Hello World&#8221; to &#8220;Hola Mundo&#8221;, and save the file.</p>
<p>Within your application, you can now do the following to retrieve the localized string:<br />
<pre><code>
String title = LocalizationSupport.getMessage(&quot;Title&quot;);
</code></pre><br />
Use this API to retreive localized strings whenever you initialize or change the text for your UI components.</p>
<p>Last but not least, you may want to test your application for different locales.  Luckily, it is possible to emulate a user-specified locale in the WTK emulator.  Search for a file called &#8220;ktools.properties&#8221; in your wireless toolkit folder.  By adding the line below to this file, the emulator will emulate the specified locale.<br />
<pre><code>
microedition.locale=es-MX
</code></pre><br />
Replace &#8220;es-MX&#8221; with the locale you wish to emulate.</p>
<p>For more information about localization in Java ME, check out the resource below.  Also, be sure to read the page titled &#8220;Adding Localization Support to a MIDP Application&#8221; in the NetBeans IDE Help.</p>
<ul>
<li><a href="http://developers.sun.com/techtopics/mobility/reference/techart/design_guidelines/localization.html">How to create a localized application</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.dbarnes.com/midlet/midp-localization/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Asynchronous Processing in Java ME: The Push Registry</title>
		<link>http://www.dbarnes.com/midlet/push-registry/</link>
		<comments>http://www.dbarnes.com/midlet/push-registry/#comments</comments>
		<pubDate>Mon, 14 May 2007 19:51:55 +0000</pubDate>
		<dc:creator>Don Barnes</dc:creator>
				<category><![CDATA[Java ME Development]]></category>

		<guid isPermaLink="false">http://www.dbarnes.com/midlet/push-registry/</guid>
		<description><![CDATA[When writing mobile applications, you may encounter situations where you need to execute logic independently of user interaction. For example, your application may need to do something in response to an outside event, such as an e-mail message being received. You could put a loop in your application that periodically checks to see if the [...]]]></description>
				<content:encoded><![CDATA[<p>When writing mobile applications, you may encounter situations where you need to execute logic independently of user interaction.  For example, your application may need to do something in response to an outside event, such as an e-mail message being received.  You could put a loop in your application that periodically checks to see if the conditions for performing the task have been met.  However, even if it were supported by the device, this approach could consume valuable resources.  A better solution is to use the push registry API, which was added in MIDP 2.0.  In this article we will take a look at the features and limitations of the push registry.</p>
<p><span id="more-35"></span>The push registry allows your application to request that the device launch a MIDlet asynchronously.  This ability can be incredibly useful for many types integration.  There are two types of push events: push connections and push alarms.  A push connection is triggered in response to an inbound network connection.  A push alarm, on the other hand, is triggered by a timer and can be used run some code on a regular interval, for example.</p>
<p>There are two ways to register a push event.  Push connections and push alarms can be registered using the PushRegistry API, found in the <a href="http://java.sun.com/javame/reference/apis/jsr118/javax/microedition/io/PushRegistry.html"><code>javax.microedition.io.PushRegistry</code></a> class.  In addition, push connections can be defined in the JAD file or JAR manifest.</p>
<p>The PushRegistry API has a number of limits.  First, when using connection events, only one application can be registered on a given port at a time.  This means that your application should probably be designed to handle conflicts at port-level.  Second, both push and network operations are considered restricted operations in MIDP 2.0.  This means that your application must explicitly request push and network permissions in the JAD file or JAR manifest.  In addition, your code will probably need to be signed in order for it to be granted those permissions on most devices.</p>
<p>For more detailed information about the PushRegistry, be sure to check out the following links:</p>
<ul>
<li><a href="http://java.sun.com/javame/reference/apis/jsr118/javax/microedition/io/PushRegistry.html">PushRegistry API JavaDoc</a></li>
<li><a href="http://developers.sun.com/techtopics/mobility/midp/articles/pushreg/">The MIDP 2.0 Push Registry</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.dbarnes.com/midlet/push-registry/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Working with the TiledLayer Class</title>
		<link>http://www.dbarnes.com/midlet/tiledlayer/</link>
		<comments>http://www.dbarnes.com/midlet/tiledlayer/#comments</comments>
		<pubDate>Mon, 07 May 2007 02:58:50 +0000</pubDate>
		<dc:creator>Don Barnes</dc:creator>
				<category><![CDATA[Java ME Development]]></category>

		<guid isPermaLink="false">http://www.dbarnes.com/midlet/tiledlayer/</guid>
		<description><![CDATA[A common technique used in video games is to have a large scrolling background formed by a grid of smaller, reusable images. In MIDP 1.0, such a feature would need to be implemented from scratch or with a third-party library. However, MIDP 2.0 provides the convenient TiledLayer class to address this specific need. In this [...]]]></description>
				<content:encoded><![CDATA[<p>A common technique used in video games is to have a large scrolling background formed by a grid of smaller, reusable images.  In MIDP 1.0, such a feature would need to be implemented from scratch or with a third-party library.  However, MIDP 2.0 provides the convenient TiledLayer class to address this specific need.  In this article we will look at a simple example of how to use the TiledLayer class in a Java ME application.</p>
<p><span id="more-33"></span>TiledLayer is part of the <code>javax.microedition.lcdui.game</code> package that was introduced with MIDP 2.0.  The constructor for the TiledLayer class accepts five parameters: the number of columns and rows in the grid, an Image object containing the tiles, and the width and height in pixels of each tile.</p>
<p><code>TiledLayer(int columns, int rows, Image image, int tileWidth, int tileHeight)</code></p>
<p>The image can have multiple rows of tiles.  The tileWidth and tileHeight properties are used to break up the image into individual tiles.  The tiles are numbered starting with 1 and incrementing in <a href="http://en.wikipedia.org/wiki/Row-major_order">row-major order</a>.  Index 0 is reserved for transparency; TiledLayer won&#8217;t draw anything for cells with index 0.</p>
<p><img src="/midlet/images/tiledlayer-tiles.png" alt="Example TiledLayer Tiles" /></p>
<p>For our example application, we&#8217;ll start by creating a class that extends GameCanvas.  Extending GameCanvas will allow us to take advantage of the off-screen buffer that this class provides.<br />
<pre><pre>
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
public class DemoCanvas extends GameCanvas {
</pre></pre>
</p>
<p>Next, we&#8217;ll add an instance variable for our TiledLayer object, along with the customary setter and getter methods.<br />
<pre><pre>
public TiledLayer getTiledLayer() {
&nbsp;&nbsp;&nbsp;&nbsp;return tiledLayer;
}
public void setTiledLayer(TiledLayer tiledLayer) {
&nbsp;&nbsp;&nbsp;&nbsp;this.tiledLayer = tiledLayer;
}
// Instance variables
private TiledLayer tiledLayer;&nbsp;&nbsp;// The TiledLayer object
</pre></pre>
</p>
<p>We will also add some constants to store the size of our tiles in pixels, and the background color.  Remember that the 0 index tiles are transparent, so we will be responsible for clearing the background ourselves.<br />
<pre><pre>
// Constants
public static final int TILE_WIDTH = 16;
public static final int TILE_HEIGHT = 16;
public static final int BACKGROUND_COLOR = 0x00000000;
</pre></pre></p>
<p>We will need to provide some data for the grid.  For the purposes of this example, we can hard code some data into a two-dimensional array.  In a real-life application, you would probably read this data from a resource, generated from some sort of <a href="http://www.dbarnes.com/game-map-editor/">map editor</a> software.<br />
<pre><pre>
public byte[][] getGridData() {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Create and populate a two-dimensional
&nbsp;&nbsp;&nbsp;&nbsp;// array with sample grid data
&nbsp;&nbsp;&nbsp;&nbsp;byte gridData[][] = {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{0,0,0,1,2,2,2,3,0,0,0,0,10,10,0,0},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{0,0,0,10,10,0,0,0,1,2,2,3,0,0,0,0},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{0,0,1,2,2,3,0,0,0,0,0,4,5,6,0,0},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9}
&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;return gridData;
}
</pre></pre>
</p>
<p>Now, we will add a method to create and initialize our TiledLayer object.  To initialize the cells, we will simply iterate through the byte array we created above and call the TiledLayer.setCell() for each value.<br />
<pre><pre>
public void initTiledLayer() {

&nbsp;&nbsp;&nbsp;&nbsp;// Get the grid data
&nbsp;&nbsp;&nbsp;&nbsp;byte[][] gridData = getGridData();

&nbsp;&nbsp;&nbsp;&nbsp;// Derive number of columns and rows
&nbsp;&nbsp;&nbsp;&nbsp;// from grid data array sizes
&nbsp;&nbsp;&nbsp;&nbsp;int rows = gridData.length;
&nbsp;&nbsp;&nbsp;&nbsp;int columns = gridData[0].length;

&nbsp;&nbsp;&nbsp;&nbsp;// Get the tile Image object
&nbsp;&nbsp;&nbsp;&nbsp;Image tileImage;
&nbsp;&nbsp;&nbsp;&nbsp;try {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tileImage =
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Image.createImage(&quot;/tiledlayer-tiles.png&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;} catch(java.io.IOException e) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.err.println(&quot;Unable to create image&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;// Create a TiledLayer object
&nbsp;&nbsp;&nbsp;&nbsp;TiledLayer tiledLayer = new TiledLayer(
&nbsp;&nbsp;&nbsp;&nbsp;columns, rows, tileImage,
&nbsp;&nbsp;&nbsp;&nbsp;TILE_WIDTH, TILE_HEIGHT);

&nbsp;&nbsp;&nbsp;&nbsp;// Transfer grid data to TiledLayer object
&nbsp;&nbsp;&nbsp;&nbsp;for(int y = 0;&nbsp;&nbsp;y &lt; rows; y++) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(int x = 0; x &lt; columns; x++) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int tileIndex = gridData[y][x];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(tileIndex &gt; 0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiledLayer.setCell(x, y, tileIndex);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;// Set the TiledLayer instance variable
&nbsp;&nbsp;&nbsp;&nbsp;setTiledLayer(tiledLayer);

}
</pre></pre>
</p>
<p>Next, we need a method to draw the background.  In addition to rendering the TiledLayer object, it will also need to clear the background.  Note that since GameCanvas provides an off-screen buffer, there is no need to override the paint() method; GameCanvas already provides an adequate implementation.<br />
<pre><pre>
public void drawBackground() {
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;// Get off-screen buffer
&nbsp;&nbsp;&nbsp;&nbsp;Graphics g = getGraphics();

&nbsp;&nbsp;&nbsp;&nbsp;// Clear the background
&nbsp;&nbsp;&nbsp;&nbsp;g.setColor(BACKGROUND_COLOR);
&nbsp;&nbsp;&nbsp;&nbsp;g.fillRect(0, 0, getWidth(), getHeight());

&nbsp;&nbsp;&nbsp;&nbsp;// Paint the tiled layer
&nbsp;&nbsp;&nbsp;&nbsp;TiledLayer tiledLayer = getTiledLayer();
&nbsp;&nbsp;&nbsp;&nbsp;if(tiledLayer != null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiledLayer.paint(g);
&nbsp;&nbsp;&nbsp;&nbsp;}

}
</pre></pre></p>
<p>Now we&#8217;ll add a custom constructor to call our initialization method, and to perform the initial drawing of the off-screen buffer.  Since we&#8217;ll be overriding the keyPressed() method in the next step, we will pass false for the suppressKeyEvents parameter of the GameCanvas constructor.<br />
<pre><pre>
protected DemoCanvas() {

&nbsp;&nbsp;&nbsp;&nbsp;// We will be overriding keyPressed,
&nbsp;&nbsp;&nbsp;&nbsp;// so do not suppress key events
&nbsp;&nbsp;&nbsp;&nbsp;super(false);

&nbsp;&nbsp;&nbsp;&nbsp;// Initialize the TiledLayer
&nbsp;&nbsp;&nbsp;&nbsp;initTiledLayer();

&nbsp;&nbsp;&nbsp;&nbsp;// Draw to the off-screen buffer
&nbsp;&nbsp;&nbsp;&nbsp;drawBackground();

}
</pre></pre></p>
<p>Lastly, we&#8217;ll implement an extremely simple keyPressed() method that will scroll the background when the direction keys are pressed using the convenient TiledLayer.move() method.  It will also force a repaint of the off-screen buffer and flush it to the display.<br />
<pre><pre>
protected void keyPressed(int keyCode) {

&nbsp;&nbsp;&nbsp;&nbsp;// Handle scrolling in response to key presses
&nbsp;&nbsp;&nbsp;&nbsp;TiledLayer tiledLayer = getTiledLayer();
&nbsp;&nbsp;&nbsp;&nbsp;if(tiledLayer != null) {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Get game action from key code
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int gameAction = getGameAction(keyCode);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch(gameAction) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case UP:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiledLayer.move(0, -16);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case DOWN:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiledLayer.move(0, 16);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case LEFT:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiledLayer.move(-16, 0);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case RIGHT:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiledLayer.move(16, 0);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Repaint the off-screen buffer
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;paintBackground(getGraphics());

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Flush the off-screen buffer to the display
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flushGraphics();

&nbsp;&nbsp;&nbsp;&nbsp;}

}
</pre></pre><br />
<a href="/midlet/images/tiledlayer-example.png" target="_blank"><img src="/midlet/images/tiledlayer-example-thumb.png" alt="TiledLayer Example" style="float:right; padding: 0 10px 0 10px;" /></a></p>
<p>There you have it.  The source code for the completed example is available here: <a href="/midlet/tutorial-files/tiledlayer-demo.zip">TiledLayer Example Source Code</a></p>
<div style="clear: both;"></div>
]]></content:encoded>
			<wfw:commentRss>http://www.dbarnes.com/midlet/tiledlayer/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using Preprocessor Directives to Port Java ME Applications</title>
		<link>http://www.dbarnes.com/midlet/preprocessor-directives/</link>
		<comments>http://www.dbarnes.com/midlet/preprocessor-directives/#comments</comments>
		<pubDate>Sun, 01 Apr 2007 21:42:15 +0000</pubDate>
		<dc:creator>Don Barnes</dc:creator>
				<category><![CDATA[Java ME Development]]></category>

		<guid isPermaLink="false">http://www.dbarnes.com/midlet/preprocessor-directives/</guid>
		<description><![CDATA[There may be times when you want to take advantage of device-specific features, yet support as wide a selection of devices as possible. For example, perhaps you want to play sound in your application, but you also want to target several different platforms, each with different APIs for playing sounds. You could manually create a [...]]]></description>
				<content:encoded><![CDATA[<p>There may be times when you want to take advantage of device-specific features, yet support as wide a selection of devices as possible.  For example, perhaps you want to play sound in your application, but you also want to target several different platforms, each with different APIs for playing sounds.  You could manually create a new project for each device you wish to support, but that could quickly turn into a nightmare as you try to keep common code in sync.  That&#8217;s where preprocessor directives come in.  This handy feature allows you to insert conditional logic into your source files that will include or exclude blocks of code before it gets to the Java compiler.</p>
<p><span id="more-31"></span>For the purposes of this article, we will be focusing on the NetBeans implementation of preprocessor directives.  First, you will need to create a configuration for each platform you wish to support.  To do this, open the project properties dialog (available from the &#8220;File&#8221; menu), and click &#8220;Manage Configurations&#8221; in the upper right hand corner of the dialog.  Click &#8220;Add&#8230;&#8221; to add a new configuration.  Choose the template that corresponds to the platform you are developing for, then enter a meaningful name for the configuration, and click OK.  Note that if you are targeting a platform that utilizes a third-party API, you may need to download the corresponding development kit from the <a href="http://www.dbarnes.com/midlet/links/#third-party-development">vendor&#8217;s website</a> in order to enable the proper templates.</p>
<p>Next, define any variables you wish to reference from the preprocessor directives in the Abilities table.  You can do this from the &#8220;Abilities&#8221; tree node in the project properties dialog.  A number of useful variables are already predefined by NetBeans, and you can add others as necessary.</p>
<p>Now you are ready to put preprocessor directives to work.  Revisiting our previous tutorial on <a href="http://www.dbarnes.com/midlet/using-sprint-midp-extensions/">Sprint MIDP 1.0 Extensions</a>, here are some snippets of code that could be used to play a sound, in both the MIDP 2.0 and Sprint PCS MIDP 1.0 platforms.</p>
<p><pre><code>
//#if MIDP==&quot;2.0&quot;
import javax.microedition.media.*;
//#elif vendor==&quot;SprintPCS&quot;
import com.sprintpcs.media.*;
//#endif
</code></pre></p>
<p><pre><pre>
public void playSound(String uri) throws Exception {
//#if MIDP==&quot;2.0&quot;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;// Play sound
&nbsp;&nbsp;&nbsp;&nbsp;Player p = Manager.createPlayer(uri);
&nbsp;&nbsp;&nbsp;&nbsp;p.start();

//#elif vendor==&quot;SprintPCS&quot;

&nbsp;&nbsp;&nbsp;&nbsp; // Create a new clip object
&nbsp;&nbsp;&nbsp;&nbsp;Clip clip = new Clip(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uri,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;audio/vnd.qcelp&quot;,&nbsp;&nbsp;// MIME type
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1,&nbsp;&nbsp;// Priority
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp; // Seconds of vibration
&nbsp;&nbsp;&nbsp;&nbsp;);

&nbsp;&nbsp;&nbsp;&nbsp; // Play sound
&nbsp;&nbsp;&nbsp;&nbsp;Player.playBackground(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clip, // Clip object
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp; // Do not repeat
&nbsp;&nbsp;&nbsp;&nbsp;);

//#endif

}
</pre></pre></p>
<p>For a more in depth look at the NetBeans preprocessor directive syntax, check out the following article: <a href="http://www.netbeans.org/kb/50/preprocessor-syntax.html">Defining and Using Preprocessor Directives in the Mobility Pack</a>.  You may also want to take a look at another preprocessing solution offered by <a href="http://www.j2mepolish.org/docs/preprocessing.html">J2ME Polish</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbarnes.com/midlet/preprocessor-directives/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Floating Point Support in Java ME</title>
		<link>http://www.dbarnes.com/midlet/floating-point-support-in-java-me/</link>
		<comments>http://www.dbarnes.com/midlet/floating-point-support-in-java-me/#comments</comments>
		<pubDate>Sun, 18 Mar 2007 03:08:42 +0000</pubDate>
		<dc:creator>Don Barnes</dc:creator>
				<category><![CDATA[Java ME Development]]></category>

		<guid isPermaLink="false">http://www.dbarnes.com/midlet/floating-point-support-in-java-me/</guid>
		<description><![CDATA[Anyone who has been writing Java ME (J2ME) applications for a while has probably run into one of the more frustrating limitations of the platform, lack of support for the floating point primitive types: float and double. More accurately, there is no floating point support in CLDC 1.0. If you can, use CLDC 1.1, which [...]]]></description>
				<content:encoded><![CDATA[<p>Anyone who has been writing Java ME (J2ME) applications for a while has probably run into one of the more frustrating limitations of the platform, lack of support for the floating point primitive types: float and double.  More accurately, there is no floating point support in <em>CLDC 1.0</em>.  If you can, use <a href="http://java.sun.com/products/cldc/">CLDC 1.1</a>, which does have floating point support.  If that&#8217;s not a viable option, another possibility is to use one of the fixed point math libraries that are freely available, or to roll your own solution.</p>
<p><span id="more-30"></span>One popular third-party library is <a href="http://mywebpages.comcast.net/ohommes/MathFP/">MathFP</a>, which according to the author is free for non-commercial use.  Note, however, that every operation is a method call; that can turn into a lot of overhead.  If you are writing an application where performance is a major concern (i.e. video games), your best bet is to roll your own fixed point math code, and implement it inline rather than through method calls.</p>
<p>The following article provides some good examples of using inline fixed point arithmetic in a Java application: <a href="http://www.devx.com/Java/Article/21850/0/page/2">Optimizing Fixed Point (FP) Math with J2ME</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbarnes.com/midlet/floating-point-support-in-java-me/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Sinfah&#8217;s Lair Reaches 20,000 Downloads</title>
		<link>http://www.dbarnes.com/midlet/sinfahs-lair-20000-downloads/</link>
		<comments>http://www.dbarnes.com/midlet/sinfahs-lair-20000-downloads/#comments</comments>
		<pubDate>Fri, 16 Mar 2007 14:13:53 +0000</pubDate>
		<dc:creator>Don Barnes</dc:creator>
				<category><![CDATA[Announcements]]></category>

		<guid isPermaLink="false">http://www.dbarnes.com/midlet/sinfahs-lair-reaches-20000-downloads/</guid>
		<description><![CDATA[Sinfah&#8217;s Lair reached the 20,000 download mark today on GetJar. Many thanks to everyone who has played and provided feedback!]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.dbarnes.com/midlet/games/sinfahs-lair/"><br />
<img style="clear: right; padding-left: 5px; float: right; padding-bottom: 5px" alt="Sinfah's Lair for Java Enabled Cell Phones" title="Sinfah's Lair for Java Enabled Cell Phones" src="http://www.dbarnes.com/midlet/images/sinfahs_lair_02.png" /><br />
</a></p>
<p><a href="http://www.dbarnes.com/midlet/games/sinfahs-lair/">Sinfah&#8217;s Lair</a> reached the 20,000 download mark today on <a href="http://www.getjar.com/mobile/5656/Sinfahs-Lair">GetJar</a>.  Many thanks to everyone who has played and provided feedback!</p>
<div style="clear: both;"></div>
]]></content:encoded>
			<wfw:commentRss>http://www.dbarnes.com/midlet/sinfahs-lair-20000-downloads/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
