Skinning the MicroEmulator
Part 1 - the Applet Emulator
Author: Bertil Gralvik
Date: 2004-03-08
Introduction
The MicroEmulator is a versatile and expandable CLDC/MIDP 1.0 mobile device emulator. It can be used as a standalone application on any Java enabled workstation. It uses AWT or JFC ( Swing ) as a presentation layer, and a Java WebStart ( jnlp ) version is also planned. The emulator can run as an Applet for demonstrating J2ME applications ( MIDlets ) over the web. MicroEmulator is developed by Bartek Teodorczyk and coworkers Julian L. Hunter and Markus Heberling.
Update 2006-12-01. A new force, Vlad Skarzhevskyy, has entered the project, and has sent me more optimized images for the T610 skin. Thanks Vlad!
It is a
sourceforge project usable under the GNU LESSER GENERAL PUBLIC LICENSE.
The MicroEmulator may be extended by adding platform specific look and feel,
aka skinning, as well as behaviors to mimic that of a specific J2ME
platform. The distribution comes with libraries for the different
presentation layers, a default generic device and an example device called
MinimumDevice.
Extensions for the Nokia 3410 and a Siemens device are also included. Anyone
who wants to take a shot at it, can create images and tune the emulator for
the new skin. You may also implement classes that mimic the specific
behaviors to your device.
In this tutorial I will describe, to the best of my knowledge, how to skin the MicroEmulator to look like my favorite mobile platform, the SonyEricsson T610, using the Applet presentation layer . Later, when I've got my boots strapped on, I may even get back to you about extending functionality. For now it's just skinning.
When you are done you may want to go on to Skinning the MicroEmulator, Part 2
First we'll take a look at what ..
ToDo
- Get a good image of the phone.
- Create versions of the image for the "mouse over" and "clicked" states.
- Measure the positions and extent of the display and the keys using an image editor.
- Check the functionality of the keys on the real platform and in what
order ( priority ) the
programmable keys map to MIDlet Command's. - Write a device descriptor XML file to decribe the new skin.
- Write a class that extends the AppletDevice class to initiate the emulator with our new device.
- Deploy the MicroEmulator with it's new skin and a demo MIDlet to run
As you can see, there is some work to do, but its fun. We'll start with the images, and from now on it's mostly about the T610 emulator skin, but I'm sure you can use most of the information for your own device.( If you are a bit curious, you may want to have a look at the final result before we get started )
The images
All images must be in PNG ( Portable Network Graphics ) format for the emulator to use it.
There are three basic images making up the skin, one for the "normal" untouched device and two for giving feedback to the user at mouse over and click gestures. If there already exists a PC emulator you should be able to extract the images. Take care though to read the license agreement for the emulator.
For the SonyEricsson SDK it states that all material is copyrighted, and may not be redistributed. So to be a good guy, I looked up a suitable image in the SonyEricsson press kit, and decided to use that for my skin.
The original is a TIF image and far too big, so I had to scale it down
and convert it to PNG. I used PaintShop Pro, as it offers good tools for
resizing and for the measurements we'll have to do later. The scale is
calculated from the screen size of the real machine. For T610 the screen is
127 by 160 pixels and preferably we'll make the image full size. We call the
image "normal.png"
The normal image.
Now we'll have to do two more images much like this one, so we'll make two copies and call them "over.png" for mouse over and pressed.png" for user clicks. Before we continue, lets discuss how the emulator uses the images.
In the untouched state the emulator projects the normal image. When the user hovers with the mouse over a button, that button is clipped from the "over" image and pasted on top of the normal image. The same thing happens when the user clicks a button, only this time the clip is taken from the "pressed" image. To be honest, we are not really forced to use the feedback images, but I strongly recommend that you do. If we are using only the normal image, the user will experience a dead interface. Visible clues are fine.
The only thing we have to change in the feedback images are the clickable buttons, and we do this by slightly changing the button color, one color for the "over" and one for the "pressed" image.
The over and the pressed
images
You may have noticed that there are arrows in the two images, and if you look carefully at the normal image, there are shadowy arrows too. They are there to make the T610 joystick visible and usable.
Tip: The arrows and the colored buttons should be in exactly the
same positions in all images.
To accomplish this, I used the selection tool in PaintShop Pro to select all
the buttons at once . I then named and saved the selection to disk. I could
color all the buttons in one go. For the "pressed" image I just loaded the
selection and got all buttons selected in exactly the same way. Nice feature
that other paint programs may have as well!
Icons
The MicroEmulator by default supports two sets of icons for giving state information to the user. One set flags the input state as being upper case, lower case or numbers only. The other hints the user if there is more information available by scrolling. The T610 have other icons, that are not directly supported on the MicroEmulator. They seem to require extending one ore more of the emulator device classes and falls outside the scope of this tutorial.
For the state icons you could use the ones that come with the MicroEmulator, or borrow from the corresponding emulator for your MIDlet development kit. Here I'm using the icons for the SonyEricssson SDK, as I don't think this violates the license agreement. After all the skin is a freebee ad for the SonyEricsson excellent platform.
Note: Remember that all icons must be in PNG format!
Icon | Used for |
---|---|
Input mode - Upper case only | |
Input mode - Lower case only | |
Input mode - Numbers only | |
Scroll mode - More information available by scrolling up | |
Scroll mode - More information available by scrolling down | |
T610 specific icons | |
Signal level from the net | |
Java is run - It always is for MIDlets | |
Battery level - Always optimistic |
Other icons are available for the T610 for flagging different languages, but we will leave them out here. The input mode icons are rotated to take up less space horizontally. If you dont like it that way, you can replace them by the MicroEmulator icons, found in the net\barteo\me\appletdevice\minimum directory.
Describing The Device
Now that the images are crafted, we have to make the MicroEmulator aware
of the new skin, and how to use it. We'll describe the physical features of
the skin and how the emulator it should react to key activation.
This description is done in a Device Descriptor XML document. For the
emulator to pick up this document we'll write a kind of proxy class,
extending the AppletDevice class. More on this later.
If you want to brush up on XML, a good starting point would be W3Scools tutorial on XML. If don't know anything about XML and don't want to know much - don't worry. The document structure is really simple and I cannot keep you from taking this...
Express course in XML
XML stands for Extensible Markup Language.
First a strange but important statement:
XML is not a markup language!
- That's right! XML is a set of rigid rules for how to construct a markup language.
- Markup languages, or document types are said to be instances of XML if the obey these rules.
- The rigidity of the rules makes it possible to programmatically verify ( to some extent ) that the information is correct.
- A well formed document follow the basic rules for markup, and a valid document follows an exact structure as given by a control document, a Document Type Definition ( DTD ) or an XML Schema.
- Examples of XML languages are XHTML, WML and SVG, to name a few.
- XML can be regarded be as a ( possibly infinitive ) class of markup languages.
- Normally an XML document has markup ( tags ) that conveys some kind of meaning of its content:
<device> <make>SonyEricsson</make> <model>T610</model> </device>
The basic rules are simple:
- The markup of an element ( e.g. device ) must have a start tag and an end tag: <device></device>
- Between the start and end tags is the content, the actual information ( e.g. SonyEricsson ).
- If an element has no content it is called an empty tag, e.g. <void></void>. For empty elements, an allowed short form is defined, with the start and end tags concatenated: <void/>
- An element may contain other elements ( child elements ), as can be seen from the <device> example above.
- An element can have attributes: <image width="120" height="45" src="panorama.png"/>, where the image element is empty and data is found as values of the attributes.
- Attribute values are always quoted.
- Special characters must be given by their entities, & for '&', < for '<', &rt; etc.
- The default character encoding is UTF8.
Many more rules apply, but this will do for now.
Was that a crash course for you! :-)
Metrics and descriptions
Now that we know all there is know about XML, let's have a look at the
the structure and some descriptions in the device descriptor document
"device.txt". it should really have the file extension .xml, but it seems
that some versions of the Netscape Navigator doesn't understand what to do
with this file type.
The device descriptor must be well formed for the XML parser/interpreter to
accept it, but it doesn't have to be valid - i.e. we don't need a DTD.
Normally the first line in an XML document start with an XML declaration but
for our special purpose, we may leave it out.
<device> <!-- The three basic images go here --> <display> <!-- display position and features go here --> </display> <keyboard> <!-- key positions and features go here --> </keyboard> </device>
The root element <device> is the container of all descriptions and contains three main parts: The three images, the <display> element describing the display screen and the icons and the <keyboard> element describing the keys ( buttons ) and how they map to the PC keyboard and MIDlet Commands.
We'll be modifying the device descriptor for the MinimumDevice that comes
with the MicroEmulator.
It is found in the
net\barteo\me\appletdevice\minimum directory.
This is how the display screen is described for the MinimumDevice.
<display> <numcolors>4</numcolors> <iscolor>false</iscolor> <foreground>000000</foreground> <background>c3cbb6</background> <rectangle> <x>28</x> <y>33</y> <width>96</width> <height>120</height> </rectangle> <paintable> <x>0</x> <y>10</y> <width>96</width> <height>96</height> </paintable> <!-- Icon descriptions go here --> </display>
The markup is descriptive, which makes it fairly easy to understand. What it says is that the device supports 4 , the foreground and background colors are given as hexadecimal numbers in the form "RRGGBB" for red, green and blue respectively. The <rectangle> element gives the position and extent of the screen, and the <paintable> element gives the position and extent of the area within the screen that a MIDlet can access.
Note that we are working with two coordinate systems here. The image, or device, coordinate system has its origin [x,y] = [0, 0] in the upper left corner of the device image. This system is used to describe the positions of the screen and buttons.
The screen coordinate system has its origin in the upper, left corner of the screen and is used to positions of icons, softbuttons and the area accessible by a MIDlet.
The image coordinate system ( blue )
and the screen coordinate system ( red )
Where to find information
We will start with the device descriptor for the MinimumDevice and change the information to fit our own device. But where do we find the necessary information? Well, it may come from a variety of sources.
If you have access to an emulator for the device and it is built on top of the SUN WTK, you can find the information in the Xxx-device.properties file. For the SonyEricsson T610, this is the SonyEricsson_T610.properties. You may also want to consult SUN's Basic Customization Guide for the WTK 1.0.4.
For information on positions, widths and heigths to be useful, our skin must have the same size, screen and button positions as the emulator image in the SDK.
In my development for the T610, the phone size is the same, but the SDK image is bigger, as the phone image is surrounded by a beautifying background image. By translating the values to the new image coordinates, I could still use the position and size information. The sizes of screen and buttons were the same.
If you don't have access to any emulator, you have to measure everything in the image. I did a lot of measuring in PaintShop Pro, a tool with some very nice features. It has rulers, that aren't very readable, but you can also drag guides from the rulers to exact pixel positions. You can then require that the rectangular selection tool should snap the guides. That way it is possible to make measurements exact to the pixel. These are the values you need.
Let's get started at last!
But first!
The Device Descriptor
We need other pieces of information than the physical constraints, but let us discuss these as we write the descriptor file. We can use any editor producing clean ASCII or UTF8 character encoding. So let's start from the top of the device descriptor file and work our way down.
The images
<device> <img name="normal" src="/devices/sonyericsson/t610/normal.png"/> <img name="over" src="/devices/sonyericsson/t610/over.png"/> <img name="pressed" src="/devices/sonyericsson/t610/pressed.png"/>
The three skin images are in the devices/sonyericsson/t610/ directory relative to a root directory. All other images and our Device class will be placed here. It will in fact become a package, later archived in a JAR-file. The package name, or namespace is chosen to be "world unique". We could sharpen it up a bit by calling the package com.myfirm.devices/se/t610. That way we would be able to discriminate between myfirm's T610 skin and yourfirm's skin for the same platform. ( oh, am I talking - lets go on! )
The display
The screen is capable of displaying 65536 colors which means that the <iscolor> element should be set to "true". We can set the foreground and background colors to our hearts content.
<display> <numcolors>65536</numcolors> <iscolor>true</iscolor> <foreground>000000</foreground> <background>ffffff</background>
The left upper corner of the screen is at [ 38, 86 ] and the size is 127 by 160 pixels.
<rectangle> <x>38</x> <y>86</y> <width>127</width> <height>160</height> </rectangle>
The screen is divided vertically with the topmost 16 pixels reserved for the icon bar and at the bottom 16 pixels for the button bar. The remaining 128 pixels is the drawing area for the MIDlet, which adds nicely up to the 160 pixel screen height. The <paintable> element uses screen coordinates.
<paintable> <x>0</x> <y>16</y> <width>127</width> <height>128</height> </paintable>
Next we describe the state icons.
<img name="up" src="/devices/sonyericsson/t610/up.png"> <paintable> <x>60</x> <y>145</y> <width>8</width> <height>8</height> </paintable> </img> <!-- down icon goes here -->
The icons are marked up as <img> elements with name and src attributes and a <paintable> element for position and extent. The name attribute is used by the emulator to identify the image, and the src to find and load it. The up arrow is shown on the button bar, whenever there is information available by scrolling up.
We describe the other icons in the same manner. The "down" arrow is shifted some pixels to the right, so that both arrows can be shown at the same time.
The input mode icons are all shown at the same position, as we can only have one current input mode.
<img name="mode" type="ABC"src="/devices/sonyericsson/t610/abc_upper.png"> <paintable> <x>64</x> <y>150</y> <width>14</width> <height>7</height> </paintable> </img> <!-- Two more input mode icon go here -->
As these icons are exclusive, they have the same name and are discriminated by a type attribute.
The specific icons for the T610, for battery level, signal level and java logo requires some changes or extensions to the MicroEmulator code, and are left out for now. So this ends the <display> element.
</display>
The keyboard
Next we describe the keys, or buttons, on the device. As these are the tools by which the user controls the device, we have to tell the emulator in what ways to react on key activation. We will describe not only the position and extent of each button, but what J2ME Command it should be mapped to. The user may also want to use the workstation keyboard, so we'll map the emulator keys to the PC keyboard keys. There are different types of keys on the device: standard numeric keys, standard special keys, joystick and device specific keys, and they are treated a little bit different as we will see.
The activation area for a key is a rectangle surrounding it. We don't have to measure the positions and extent of that area exactly, but we have to ensure that the areas for any two keys don't overlap. Otherwise there might be confusion on what key is actually activated.
All keys are described in child elements of the <keyboard> element.
We start with the description of the programmable keys. Two areas are
described - the activation area around the key itself, and the soft button
area on the screen showing the Command label.
<keyboard> <softbutton name="" key="VK_F1" alignment="LEFT"> <rectangle> <x>15</x> <y>264</y> <width>57</width> <height>29</height> </rectangle> <paintable> <x>1</x> <y>145</y> <width>58</width> <height>13</height> </paintable> <command>BACK</command> <command>EXIT</command> <command>CANCEL</command> <command>STOP</command> </softbutton> <!-- The right softbutton goes here -->
The name attribute here is an empty string. The key attribute maps the
key to the corresponding key on the PC keyboard. Her the key is mapped to
the F1 function key.
The <rectangle> element defines the activation area for the left
programmable key ( USER 1 ) in image coordinates, and the <paintable>
element defines the soft button area in screen coordinates.
Finally we have a list of J2ME Command types, mapping the key to a set of Command types in the order of priority. The right programmable key ( USER 2 ) is treated the same manner.
If you look for information on keys in the WTK emulator properties file, you will find it under different sections. In the properties file the key attribute values are found in the section "Assign PC keys", the key positions in "key mappings" and the position of the soft keys in the "Soft button regions" section. The MIDlet Command mappings for the keys are defined in the "Command types in J2ME" section. In the device descriptor, they are neatly summarized in the softbutton element.
Next we define the device special keys BACK and CLEAR right beneath the programmable keys. The BACK button is used in the T610 to go one step back in a menu, close an Alert and to force an exit from a MIDlet, even if it has no exit Command available. The CLEAR button is used as a backspace button in input mode. The functionality is not fully implemented here, but we'll define them anyway.
<!-- back and clear buttons on T610 --> <button name="end" key="VK_HOME"> <rectangle> <x>15</x> <y>295</y> <width>57</width> <height>21</height> </rectangle> <command>BACK</command> <command>EXIT</command> </button> <button name="" key="VK_BACK_SPACE"> <rectangle> <x>131</x> <y>294</y> <width>57</width> <height>22</height> </rectangle> </button>
The mapping of the BACK key to VK_HOME doesn't seem to work, so further study is needed.
Next are the definitions for the joystick. It is used for gaming actions in low level programming, but also serves as keys for for scrolling, menu selection and text cursor positioning.
<button name="l" key="VK_LEFT"> <rectangle> <x>73</x> <y>277</y> <width>20</width> <height>24</height> </rectangle> </button> <!-- The remaining joystick definitions go here -->
The names of the joystick buttons are "l", "r", "u" and "d" for left, right, up and down tilting directions. You can also press the the center of the joystick ( which is easier on the emulator than on the real thing : -) The button for this is named "sel" for selection. All joystick buttons are defined the same way and the key attributes map to the arrow keys and the Enter key on the PC keyboard.
The standard numeric keys are described in <button> elements. They are named after the their key number. As they are used for input of multiple characters in alphanumeric mode, we have to tell the emulator what characters and in what order they are generated ( This information is not found in the properties file of the WTK emulator, where it is implicit ). The numeric keys are mapped to the keypad ( Num locked ) on the PC keyboard.
<button name="0" key="VK_0"> <chars> <char>+</char> <char>0</char> </chars> <rectangle> <x>77</x> <y>417</y> <width>50</width> <height>25</height> </rectangle> </button> <!-- Remaining numeric keys go here -->
We have two standard special keys, the "asterisk" and "pound" keys. As special keys, they are implemented differently on different platforms, and the mappings may not work exactly as we hope.
<!-- "*" and "#" - no obvious mappings! --> <button name="*" key="VK_MODECHANGE"> <rectangle> <x>20</x> <y>414</y> <width>50</width> <height>27</height> </rectangle> </button> <button name="#" key="VK_MULTIPLY"> <chars> <char> </char> <!--<char></char> new line --> </chars> <rectangle> <x>133</x> <y>414</y> <width>50</width> <height>27</height> </rectangle> </button>
In the MinimumDevice example, the pound key is used to change the input mode and the asterisk key generates the ' * ' and '+' characters. On the T610 the mode change is done with the asterisk key, and the pound key generates space and new line characters. I've tried to match this behavior as closely as possible without rewriting code. Mapping the asterisk key to VK_MODECHANGE makes the toggling of input modes work. The pound key delivers the space character as it should, but not the new line ( commented out here ). The no sense mapping of the pound key to VK_MULTIPLY has no effect. It is automagically mapped to the space bar on the PC keyboard.
With a few flaws left, this concludes the <keyboard> element and the device descriptor as a whole.
</keyboard>
</device>
We've earned it!
The Device class
To tell the emulator to use our device, we will write a Device class extending the com.barteo.emulator.device.applet.AppletDevice class.
If you like to code a lot, you may be disappointed because this class is really simple.
package devices.sonyericsson.t610; public class T610Device extends com.barteo.emulator.device.applet.AppletDevice { public T610Device() { } public void init( com.barteo.emulator.EmulatorContext context ) { init( context, "/devices/sonyericsson/t610/device.txt" ); } }
The T610Device class should be in a package corresponding to the directory where we placed the images and the device descriptor document. The class has only one method init() which takes an EmulatorContext instance as argument and simply calls it's parents init() method, passing the context along with the path of our device descriptor. This initiates the AppletDevice and makes the emulator use our device. If this class is missing, the AppletDevice will use the default device.
Packing the device
To use our new device we have to pack it in a Java Archive.
First we make sure that everything is in place. The directory
"/devices.sonyericsson.t610/" should contain all the images and icons, the
device descriptor "device.txt" and the compiled T610device.class file. It
should also contain a directory META-INF with a manifest file.
devices sonyericsson 610 normal.png over.png pressed.png up.png down.png abc_lower.png abc_upper.png 123.png signal.png java_logo.png battery.png device.txt T610Device.class META-INF manifest.mf
The manifest file is a simple text file advising the emulator of the name
of the main class for the device.
You write the following lines in any text editor and save it as
"manifest.mf"
Device-Name: T610 Device
Device-Class: devices.sonyericsson.T610
To create the JAR file you could use the JAR tool that comes with the J2SE SDK, or if you are on a Windows workstation, you may use WinZip. Lazy as I am, I used the latter approach and zipped the "devices" and "META-INF" directories. I then renamed the zip file to t610devices.jar.
Testing the device
To test the device in the applet version of the MicroEmulator, we'll
create an HTML document with an applet tag. If you haven't done so already,
you should read the MicroEmulator README file now.
It is refreshingly short!
This is the minimum html we need:
<html> <head> <title>A T610 MicroEmulator skin</title> </head> <body>
<applet code="com.barteo.emulator.applet.Main" width="204" height="474" archive="me-applet.jar,t610devices.jar,simpledemo.jar"> <param name="midlet" value="com.barteo.midp.examples.simpledemo.SimpleDemo"> <param name="device" value="devices.sonyericsson.t610.T610Device"> </applet>
</body> </html>
The code attribute of the applet element refers to the emulator Main class found in the me-applet.jar archive. The width and height attributes should reflect the size of the device image. The archive attribute lists the archives to search for code and resources. The "device" parameter tells the emulator about our device class and the "midlet" parameter tells it what MIDlet to load.
We place this HTML document together with the JAR files in a deployment directory and open it in our favorite web browser, and if all went well - Vioila! The beauty of a good days work delight us.
Again ?
Deployment
Happy as we are with our shining device, we want to share it with the world. After all this was the intent all along - to present our brilliant MIDlets in a variety of devices. This should be the easy part.
Provided you have a web server at your disposal, it is as easy as copying the deployment directory to a suitable directory under the web servers document root.
Comments
Although this skin still has a few flaws, it works fairly well. It would be nice though to get the special keys work as intended. A good thing would also be to make the emulator show the T610 specific icons. However they are really just cosmetic, and a simple work around would be to incorporate them in the device normal image.
What is left out completely from this tutorial, is the possibility to extend the MicroEmulator device classes, to mimic specific L&F and behavior for a certain device. MIDlet screens and items, such as Alert's and DateField's have special appearances and behaviors on different devices.
As I get better acquainted with the inner workings of the MicroEmulator, I might come back to these programming aspects.
That's it folks!
Disclaimer: All current and future disclaimers apply, INCLUDING but NOT LIMITED to this one.
Comments, corrections and the like are appreciated!
You can reach me at petit[at]petitpub[dot]com
Errata and adjustments
The following errata and modifications were introduced 2006-02-16 and have been incorporated into the text above.
In the device descriptor the clear button was erroneously mapped to VK_BACKSPACE on the PC keyboard. No such key constant exists, and the mapping has been changed to to read:
<button name="" key="VK_BACK_SPACE">
This also made the CLEAR key work in input mode.
The PC key constants are defined in java.awt.event.KeyEvent.
The first version of the device descriptor placed the soft buttons on the bottom edge of the screen. In the MicroEmulator the text labels are positioned at the last pixel raw of the soft button. To get a small margin under the label, the height of the soft buttons is changed from 15 to 13 pixels and the right soft button horizontal position is shifted one pixel to the right.
Before and after adjustments
You may want to continue Skinning the MicroEmulator, Part 2 for applying the skin to the stand alone J2SE version of the MicroEmulator.
Recourses
Here is the MicroEmulator
home page and the
SourceForge project.
You may download the Java Archive for the
Sony Ericsson T610 Applet device here.
Brush up your XML with
W3Scools tutorial on XML
Here is SUN's
Basic Customization Guide for the WTK 1.0.4 ( later versions exist )