Archive for the ‘ant’ Category

Do-it-yourself custom GUI for a range of MIDP devices

Suppose you’re writing a game or application, and you’d like it to have an attractive, professional-looking GUI (with your theme, brand, or skin), and you’d like it to run on as many Java ME MIDP devices as possible.  There’s some work to be done, but it’s not that hard.  I wrote about how to do it in the last chapter of my book, and it was the topic of my Jazoon talk.  Plus I wrote a library of utilities to simplify the task (the Frog-Parrot UI Library), but — looking over my blog the other day — it hit me that I never really posted a technical explanation of how to use this library.

Here’s the general idea:

If you want a mature product for MIDP customization — one that will teach you how MIDP customization works as you’re using it — J2ME Polish is a good place to start, as I explained here.  But in practice, I found that I wanted 100% control over the look-and-feel of the GUI, which I couldn’t get from J2ME Polish.

Essentially, handsets have a list of standard screen sizes, and many of them are so small that I need to have pixel-by-pixel control over where everything is placed.  Having the device place the widgets, etc., for you — guessing where you want them based on layout algorithms — isn’t nearly as useful on a small screen as it is on, say, a big browser window on a P.C.  So I wrote a library that would allow me to bundle the screen information into resource files, selecting the right image files for each screen size and passing along the data for how big widgets and images are and where they should be placed.

The annoying thing about making a custom GUI for MIDP is that you have to start from scratch, drawing your GUI onto a blank canvas.  That means re-inventing the wheel on some very standard functionality: widget navigation, navigating back and forth through a stack of screens, scrolling, and even cutting up a paragraph of text in the right places so it won’t disappear off the edge of the page.  That’s the functionality I’ve written for you in the FPUIL (which you can use however you like, as long as you don’t imagine it comes with a warranty. 😉 ).

In this brand-new version (which I just re-worked today on a Windows machine, download here), I’ve included some build files to build the project with Ant and Antenna. Look at the build.xml and build_all.xml files to see some examples and explanation of how to build a MIDlet for different target devices.

That should be enough to get started, and if I find some time, I’ll try to write more explanation…

Advertisements

Converting files to UTF-8

Here’s a common problem you often face as a Java ME programmer:

You’re internationalizing your game or application, so you send all of your files full of texts and labels to the translators, and you get back a bunch of files that are saved in some standard character encoding scheme, but not utf-8. You can’t bundle these files directly into the resource directory of your game’s jar file because some devices won’t be able to read them. Ideally, the solution is to tell the translating service that you need the files in utf-8 format, but often it isn’t the developer who is in charge of this, and sometimes such information gets lost in the shuffle. So your product manager hands you a pile of files and leaves you to figure out how to make them work.

Many standard text editing programs (emacs, for example) are capable of reading in a text file in one encoding and saving it in another. But if you’re a professional software engineer, you don’t want to waste your time opening up fifty files one by one, changing the encoding, and resaving them — especially if you’re likely to get more files and updates later.

What to do?

Some operating systems have built-in commands (such as native2ascii) to change the character encoding of a file. But looking at my options, I’d say the simplest and most portable solution is to just write a trivial little Java SE file converter, like this:

/**
* A utility to convert text files to utf-8.
*/
public class FileEncoder {

/**
* args[0] is the input file name and args[1] is the output file name.
*/
public static void main(String[] args) {
try {
FileInputStream fis = new FileInputStream(args[0]);
byte[] contents = new byte[fis.available()];
fis.read(contents, 0, contents.length);
String asString = new String(contents, “ISO8859_1”);
byte[] newBytes = asString.getBytes(“UTF8”);
FileOutputStream fos = new FileOutputStream(args[1]);
fos.write(newBytes);
fos.close();
} catch(Exception e) {
e.printStackTrace();
}
}

}

Because it’s written in Java, you can call this directly from your Ant build script (see this post for an example of calling an arbitrary Java program from an Ant script). That way you can actually leave the originals as they are and create the corrected files on the fly while building the rest of the resources for each target device.

In the above example, I’ve hard-coded “ISO8859_1” as the encoding of the source file. That’s ISO Latin-1, a character encoding I see a lot of here in France. For a list of other encodings supported by java (and their names for use in Java) look here. Note that the names of the encodings are a little different in Java SE (formerly J2SE) than they are in Java ME (J2ME). So in the above Java SE program, I write the output file in “UTF8” but once I’ve read the resource file into a byte array in the Java ME program on the device, I convert it to a String as follows:

String contentsOfMyDataFile = new String(dataFileByteArray, 0, dataFileByteArray.length, “utf-8”);

Now if you want to hard-code a string with non-ascii characters directly into your Java ME application, what you do is completely different from what you do when reading resource files from the jar. In the code, you use escape characters. “\u” is the signal that what follows is a unicode character code. A standard example is printing a price in euros: to put the euro symbol in a String in your code, you would write “\u20ac”

For a list of character code charts, look here.

Localized resource building with JSR 238: a simple custom ant task example

For today’s programming adventure, let’s tackle resource building!!!

Creating a series of jar files containing different sets of specialized resources is one of the basic reasons for setting up a build process with a tool such as Ant rather than just building with ktoolbar (as I discussed the other day). To put this in concrete terms, let’s look at a practical example that illustrates both how to write a simple Ant task and how to create resource files for the Mobile Internationalization API (JSR 238).

The Mobile Internationalization API provides a standard way to customize resources such as label strings and images and pack them efficiently into the jar file. As long as the resources are organized correctly, the API consults the platform behind the scenes to determine which set of resources should be used at any given moment. The trick is building the resource files and the correct resource directories. JSR 238 defines a special file format (.res) that allows you to pack a set of different resources together in a single, efficient binary file. As you might imagine, that means there’s a little work to be done to create the resource files — you can’t just create them by hand in a text editor as you might with a properties file.

Nokia has been kind enough to provide a reference implementation for this JSR that you can download here. The Nokia reference implementation provides both the tools to create the resource files and an emulator that allows you to test a MIDlet that uses JSR 238. All of these tools were written with the assumption that you’re using Windows — and the emulator won’t run on any other operating system — but the tools to build and test the resource files are pure Java, so you can use them on any system.

The Nokia reference implementation provides some complete sample programs as well to demonstrate how to call the resource building tools from within an Ant build file. You can see from looking at the MoonDemo that in fact that ResourceMaker tool can be integrated into an ant build as it is. Here’s the relevant snippet from the build.xml file:

<target name=”makeres” depends=”preverify”>
<java classname=”com.nokia.phone.ri.global.tools.ResourceMaker”
classpath=”${ri.home}/tools” >
<arg line=”src/res.xml src res MoonPhases en fi-FI da-DK hu-HU” />
</java>
</target>
Any java class can be called from within an Ant build file by using the “java” element (the “java” ant task) as seen here.

However, I wanted to get a better idea of how to write a custom Ant task, and this seemed like as good an application as any since the argument line is a little complicated and not terribly intuitive. So as an exercise, I wrote an Ant task that makes exactly the same call to the nokia ResourceMaker tool, but does it from a custom Ant task as follows:

<?xml version=”1.0″ encoding=”ISO-8859-1″?>

<!– A simple example ant task –>
<project name=”ResourceAntTask” default=”resources” basedir=”.”>

<!– define the task by binding it to the corresponding java code –>
<taskdef name=”buildres” classname=”net.frog_parrot.ant.BuildResources” classpath=”/home/carol/myAntTask/bin:/home/carol/JSR_238_RI_1_0/tools/ResourceMaker/bin/”/>
<!– define a custom type that is used by the task –>
<typedef name=”locale” classname=”net.frog_parrot.ant.StringElement” classpath=”/home/carol/myAntTask/bin”/>

<!– This build file’s one target calls the custom task –>
<target name=”resources”>
<buildres descriptor=”/home/carol/JSR_238_RI_1_0/demos/MoonDemo/src/res.xml” source=”/home/carol/JSR_238_RI_1_0/demos/MoonDemo/src/” destination=”.” name=”MoonPhases”>
<locale name=”en”/>
<locale name=”hu-HU”/>
</buildres>
</target>

</project>
The above is a complete build file, which would normally be named build.xml.

To create the ant task, I need to write the class BuildResources.java which extends org.apache.tools.ant.Task (see the Apache Ant JavaDoc for details on the various classes available).Here’s the code:

Continue reading

Building a J2ME project with Ant

For a basic MIDlet, the Wireless Toolkit’s ktoolbar application is pretty convenient. When you run it and click on “new project” it provides a GUI where you can enter the information that goes into the Jad and manifest files, then it creates the Jad and manifest files for you as well as creating directories where you can place the source code and the resources. Then all you need to do is select project > package > create package, and it builds the MIDlet for you including a Jar file and a Jad file that you can run on the emulator or run on an actual device. It will even create an obfuscated version for you — all you have to do is download proguard.jar and drop it into the WTK’s bin directory for the project > package > create obfuscated package to work.

However, as soon as you want to do anything fancy with your build at all (such as add extra steps for style checking, preprocesing, custom resource building, etc.) it’s a good idea to set up your build process to use Ant.

The nice thing about Ant is that it’s easy to use and it’s easy to extend it to do essentially anything you want. The build process is controlled through XML files which group sets of commands as “targets.” The commands themselves (ant tasks) are just calls to Java classes, so if there’s no existing command to perform some task that you’d like to have in your build process, you can write your own ant task to do it.

A MIDP project has some standard steps (compile, preverify, build the Jad file, write the corresponding Jar), and as you might imagine, other people have already written Ant tasks for all of this. So after installing Ant, the next step for a MIDP project is to download and install Antenna.

All you really need to do to install antenna is to download the jar file and drop it into your ant lib directory. Then the Antenna Home overview page gives you all the details about what ant tasks are available and what are all of the corresponding properties and attributes to set. Personally I like to start with at least one working demo or sample, so I downloaded the zip file containing the sources and samples, and decided to try the “games” example.

The “games” example copies the source files from one of the standard WTK demos (the “Games” demo) and builds it in a separate directory using Antenna. To run it, you just go into the games sample directory and type “ant”. If you look at the build.xml file, you’ll see pretty quickly that if you change the value of the “midlet.name” property from “Games” to the name of any other project (subdirectory of your WTK/apps directory), you can use this same build file to build another project.

There were a couple of minor changes needed to get it to work. As indicated on the Antenna home page, I had to set my wtk.home property to the actual path of my WTK directory (in my case it was “/home/carol/jme/WTK2.2″). Plus I added a line to tell ant where to find all of the antenna tasks, again as explained on the antenna home page:

<taskdef resource=”antenna.properties” classpath=”full path to antenna jar”/>

There was one strange glitch though. On my first try, it gave me this cryptic error message:

[wtkbuild] Compiling 8 source files to /home/carol/jme/ant/build/classes
[wtkbuild] javac: target release 1.1 conflicts with default source release 1.5

BUILD FAILED
/home/carol/jme/ant/build/build.xml:39: Compile failed; see the compiler error output for details.

This message is annoying because it’s clear there’s some sort of version number conflict regarding the compilation step “javac”. But version of what? I thought maybe my JAVA_HOME variable was messed up again or maybe there was a problem with the classpath or some other environment variable, but since my J2ME Polish project compiled okay (using javac and Ant) I figured it must be something antenna-specific. So like any good troubleshooter at a loss for leads, I googled the error message. Perhaps googling this same error message led you here. 😉 If so, you’re in luck because I tracked it down.

Google yielded a page that mentioned that this error appears when you use Ant’s Javac task and set the target without setting the source. I’m still not entirely sure what these version numbers relate to, but I did recall that the Antenna home page mentioned that the Antenna WtkBuild task extends the Javac task and sets the target to 1.1. In fact, if you look in the WtkBuild.java source code that you’ve downloaded from Antenna, it’s pretty easy to find the line where it does it. It looks like this: setTarget(“1.1”);

Now, you can add a call to setSource in the code and then rebuild and rejar the Antenna code, but — as you might guess — you can also just set this value in the build.xml file in the command where you call the “wtkbuild” task. I’m not sure what the optimal values for source and target are in this case, but through a little trial and error I found some that worked:

<wtkbuild srcdir=”${midlet.home}/src” destdir=”classes” preverify=”false” source=”1.3″ target=”1.1″/>

or

<wtkbuild srcdir=”${midlet.home}/src” destdir=”classes” preverify=”false” source=”1.5″ target=”1.5″/>

Some other values I tested yielded other amusing error messages such as the following:

[wtkbuild] javac: invalid source release: 1.1

For my next adventure I will write my own Ant task!!! Stay tuned!!! 😀