What on earth can Java do on a Palm Pilot? A lot more than you might think.
Introduction
Realizing that one size does not fit the entire range of computing devices from the PDA (Personal Digital Assistant) to the enterprise server, Sun defined three different editions of Java 2 corresponding to different-sized platforms. These editions are:
- J2EE (Java 2 Enterprise Edition) for enterprise-level applications running on enterprise servers
- J2SE (Java 2 Standard Edition) for desktop client applications
- J2ME (Java 2 Micro Edition) for small devices such as PDAs, cell phones, and set-top boxes
In this article, I present an overview of J2ME, indicate how to get started with J2ME development, and finally present a J2ME-based web cam application for the PalmOS.
J2ME
The range of devices supported by J2ME offers a variety of memory, display, and connectivity capabilities. For instance, a set-top box can have several megabytes of memory and be permanently connected to the Internet via cable modem, while a PDA will typically have several hundred kilobytes of memory and be infrequently connected to the Internet, if at all. To cope with this variety of platforms that fall under the "small device" umbrella, the J2ME designers introduced the concepts of Configuration and Profile. A Configuration defines a Java virtual machine and a set of core APIs. There are currently two configurations being defined under the JCP (Java Community Process). These are the CDC (Connected Device Configuration) and CLDC (Connected Limited Device Configuration). The CLDC is aimed at devices that have between 160 KB and 512 KB of memory, such as PDAs, cellphones, and pagers. It uses Sun's KVM (K Virtual machine), a small footprint Java virtual machine designed for small portable devices. The CDC is for 32-bit devices with more than 512 KB of memory. A Profile is related to the application or usage of a device. A Profile defines a Configuration and a set of APIs. Current Profiles being defined under the JCP include a PDA profile and a MIDP profile (Mobile Information Device) for cell phones and pagers. Both of these reference the CLDC.
JCP
The JCP is an open process for defining new additions to Java under industry and public scrutiny. Briefly the steps involved in defining a new addition are as follows:
- A JSR (Java Submission Request) defining the addition is submitted to a JCP Executive committee, which is comprised of elected industry representatives. The committee decides to accept or reject the JSR.
- If accepted, a CAFE (Call for Experts) is made to create an expert committee to fully define the JSR.
- A draft specification is submitted for public review by the expert committee.
- After review, the first public specification is made available along with a reference implementation.
J2ME Development for the PalmOS
Java developers targeting the PalmOS platform will eventually use the PDA Profile. As stated previously, the PDA profile is based on the CLDC. At the time of this writing, the PDA profile has not yet reached the implementation stage; however a reference implementation of the CLDC is available. The CLDC contains the following packages:
- java.lang a subset of the J2SE core package; one limitation of this package is a lack of floating-point support.
- java.util a subset of the J2SE package
- java.io contains stream classes for data input and output
- javax.microedition.io a CLDC-specific package containing connection classes; supported connection types on the Palm include UDP (User Datagram Protocol) and TCP (Transmission Control Protocol) sockets and HTTP connections.
A notable absentee from these packages is a GUI API. The PDA profile will include GUI functionality, but until it is available, the Palm port of the CLDC contains a set of Palm-specific GUI classes for development and test of CLDC applications. These classes are in the com.sun.kjava package.
Getting Started
The CLDC can be downloaded from Sun's website, java.sun.com. Be sure to download the Palm port of the CLDC and overlay it on the main CLDC implementation as per the download instructions. The CLDC contains the CLDC specification, Java Documentation for the CLDC classes, the KVM in Palm database form, and tools to convert Java class files into application resource files suitable for upload to the Palm. Programmers without a Palm device can also write and test KVM programs by using the POSE (PalmOS Emulator). POSE is freely available from www.palm.com, although you must enter into a licensing agreement with Palm Computing to obtain a necessary ROM (read-only memory) image. If you do possess a PalmOS device, you can transfer the device's ROM image to your PC and use it to boot POSE. POSE offers stricter error checking than PalmOS itself and also includes a random input event generator called Gremlins, which is a useful automated testing facility. Loading new application resource files is also faster and simpler than HotSyncing your Palm, as all development and testing can be done from the PC.
The com.sun.kjava Package
The com.sun.kjava package provides a simple collection of 17 UI classes. It was originally delivered as part of an early access version of the KVM on the PalmOS. This UI is much simpler than the Swing or AWT toolkits, only supports monochrome screens, and has no layout managers. The constant 160x160 screen size obviates the requirement for layout managers, since layout managers adapt UIs to different screen sizes. While this simplifies the package, it does mean that programmers have to position components manually. The main UI class is com.sun.kjava.Spotlet. Spotlet provides an execution environment and event handling for Palm programs, and all Palm programs extend Spotlet. Spotlet provides methods for handling key and pen events. The following "Hello World" program illustrates the use of Spotlet.
Anatomy of a Spotlet Program
Listing 1 shows the listing for a HelloWorld program. This program displays a button with the label "Hello World" and waits for the user to terminate it. The user can terminate the program in three ways
- by pressing the button with the Palm stylus
- by entering the character "q" via Palm's Graffiti script or the soft keyboard
- by pressing the Agenda key
The Spotlet Class
Like every KVM program, HelloWorld extends the Spotlet class:
public class HelloWorld extends Spotlet {Explicit Positioning
Since there are no layout managers in the KVM, the button must be centered manually:
String hello = "Hello World"; int stringWidth = g.getWidth(hello); // get string dimensions int stringHeight = g.getHeight(hello); // Create a centered button. button = new Button(hello, (SCREEN_WIDTH-stringWidth)/2, (SCREEN_HEIGHT-stringHeight)/2);Explicit Painting
Updating the screen is entirely the responsibility of the programmer, as there is no window manager helping with the job. When a program starts up, the Graphics clearScreen method must be called to erase the KVM startup screen, and all components must be explicitly painted by a call to their paint method. There is a single graphics context in com.sun.kjava, which is returned by the static method Graphics.getGraphics.
g.clearScreen(); // erase screen contents button.paint(); // draw the button on the screenEvent Handlers
The Spotlet class provides several event-handling methods that must be overridden by any program wishing to perform custom event processing. In HelloWorld, the penDown and keyDown methods are overridden to catch various quit events. The keycode argument to the keyDown method contains the code indicating the key that was pressed. This keycode is either the integer value representing the entered character or a constant representing one of the Hard or Soft (silkscreen) keys.
public void keyDown(int keycode) { if ((keycode == Spotlet.KEY_HARD1) || // Agenda key (keycode == 'q')) // letter 'q' System.exit(0); }Pen events on the main Palm screen are handled by the penDown method. The HelloWorld penDown method tests to see if the pen's x and y coordinates are in the button by calling the Button pressed method. pressed has a dual role in addition to returning a Boolean indicating the button containing the pen, it also causes the button to invert, providing button-pressed feedback.
public void penDown(int x,int y) { // test if pen in button and show button feedback if (button.pressed(x,y)) { System.exit(0); } }In order to receive any events, the application must register itself. Registering also implicitly unregisters any currently registered Spotlet. (Applications can contain multiple Spotlets, although only one receives events at any one time). The register method takes a single argument that indicates whether the application wants to receive hard-key events. If the Spotlet does not register for system events, these keys provide their normal functions (e.g., displaying the address book application and consequently terminating the application). It is therefore advisable to always register for system keys, even if the application does not need to process them:
spotlet.register(Spotlet.WANT_SYSTEM_KEYS);Building and Running the Application
Building and running a CLDC Palm application is a four-step process. The following explanation presumes the CLDC is installed on a Windows machine in the C:\java\j2me_cldc directory.
1. Set up the classpath to include the CLDC and Palm UI classes and compile the Java source using the standard JDK javac compiler.
set KVM_HOME=c:\java\j2me_cldc\bin set CLASSPATH=%KVM_HOME%\..\tools\palm\ classes.zip;%KVM_HOME%\api\classes;. mkdir tmpdir javac HelloWorld.java -d tmpdirThe -d option is supplied to javac to force the output class files to be placed in a separate directory. This is in preparation for Step 2.
2. Perform the preverification process. Verification is performed at run time by the Java virtual machine for J2SE and J2EE applications. It is not feasible to perform all of this memory- and compute-intensive operation on a small device, so the majority is done during a preverification process at compile time. The preverification process creates class files in a format that supports rapid final verification at run time on the device.
%KVM_HOME%\preverify -d . tmpdirpreverify takes all class files in tmpdir and writes the preverified version of each to the current directory.
3. Next the Java class files must be converted to a Palm Resource Specification using the MakePalmApp tool included with the CLDC. This tool is used as follows [line broken to fit column layout]:
java palm.database.MakePalmApp -v -icon kjava.bmp -bootclasspath %CLASSPATH% -classpath . -name Hello -o HelloWorld.prc HelloWorldIts arguments include the icon used to represent your application in the Palm Applications screen, the bootclasspath used to find the MakePalmApp class, the classpath to be used to locate your Palm application's class files, and the name of your application class. The above command produces a HelloWorld.prc file, which can be loaded on to the Palm.
4. Loading the prc file is achieved by using the Palm App Install tool, which adds HelloWorld.prc to the list of applications to be loaded on to the Palm during the next HotSync operation, or by the POSE Install Application/Database command.
When the application is loaded, its icon appears on the Applications screen. Note that if the Applications screen is displayed before you load your application, you may need to switch to another application and then back to the Applications screen before the new application's icon appears.
A J2ME Web Cam
The Palm is best known for its preloaded personal organizer applications, but its TCP/IP support can be leveraged to turn the Palm into a thin-client for Internet applications. The remainder of the article describes a CLDC web camera, developed as part of an ongoing collaboration between LOOX Software and members of Sun's Jini evangelist group. This collaboration focuses on a web-based monitoring and control system for a Jini-enabled house. The current user interface for the system, shown in Figure 1, is a J2SE application developed using Java Foundation Classes/Swing and JLOOX graphics components. The interface has three main areas of functionality:
- Control via an interactive schematic drawing of the house, the user can activate various Jini-enabled devices, including the TV, fan, lights, and aquarium pumps.
- Monitoring the system displays a continuously updating set of temperature and humidity readings from sensors placed inside and outside the house.
- Camera the user interface can display an image from one of several cameras placed throughout the house, allowing the user to really see what's happening from anywhere in the world.
The Camera interface is the first area of functionality ported to the CLDC. The J2SE version of the Camera interface allows the user to select one of a number of preset camera views or to manually select pan/zoom/tilt settings for a camera. The parameters of the camera view are encoded as a URL, which is passed to the JLOOX LxImage object constructor, for example:
http://.../halfsize.jpg?camera=5&pan=0&tilt=2&zoom=1The LxImage object retrieves the image from the URL and displays it in a Swing component.
This two-tier architecture is extended to three tiers for the KVM web cam, as illustrated in Figure 2. The steps involved in displaying a camera image on the Palm are as follows:
- The user selects a preset camera view from a list of choices, and the client sends the associated URL string over a newly established socket connection to a Camera Server.
- The Camera Server creates a URL object from the URL string and calls the Swing Toolkit.createImage(URL) method to retrieve the image from the web server controlling the actual camera in the Jini house.
- The color image is sent to the Camera Server by the web server, dithered, and converted to an array of bytes. This byte array is in a format used by the com.sun.kjava.Bitmap class constructor. Figure 3 illustrates the color-to-grayscale-to-monochrome dithering process used by the Camera Server.
- The monochrome image is sent back to the Camera Client and used to construct a Bitmap object, which is then painted to the Palm screen. See Figure 4.
The Camera Client code consists of three classes: CameraClient, CameraSelector, and ImageViewer. The code for these classes is shown in Listings 2, 3, and 4 respectively.
CameraClient initializes itself, creates an instance of CameraSelector, and passes control to it. Thereafter CameraClient acts as a dispatcher, passing data between and scheduling instantiation and cleanup of the CameraSelector and ImageViewer classes.
CameraSelector displays a list of preset camera views in a kjava SelectScrolledTextBox instance. When the user clicks on a preset view, the corresponding URL string is passed back to the CameraClient's handleImageRequest method. handleImageRequest resets the reference to CameraSelector, runs the garbage collector, creates an ImageViewer instance, and passes the URL string to the ImageViewer retrieveImage method. The retrieveImage method stores the image description and URL string, registers for system events, and starts up a thread to manage communication with the Camera Server.
The image thread creates a socket connection to the Camera Server and sends it the URL string. The thread then does a blocking read on the socket and waits for a six-byte reply from the Camera Server. This reply contains the magic string "Imag" and the width and height of the image. If the width and height are valid, the image thread sends the command "Ack" to the Camera Server, allocates space for the image data, and sets up a loop to read the data from the socket. As data arrives, it is stored in the imageBuffer array. Once the complete image is received, the socket is closed and a Bitmap object is constructed from the imageBuffer data. The bitmap is then painted to the screen.
The user returns to the CameraSelector view by pressing the Agenda key. The handleKeyDown method calls the CameraClient handleViewerDone method, which resets the reference to the ImageViewer object, runs the garbage collector, and creates a new CameraSelector instance.
Conclusion
Java will be an important development language for embedded and portable applications. Although crucial specifications such as the PDA Profile are not yet complete, the participation of industry giants, such as Ericsson, Motorola, Nokia, and Palm Inc., in the specification of J2ME technologies indicates the importance attached to Java in this space.
Acknowledgements
Thanks to my friends John Wetherill and Doug Sutherland of Sun Microsystems builders of the Jini House for the opportunity to participate in their inspirational project.
Resources
For further information please see:
- Java Community Process, http://java.sun.com/aboutJava/communityprocess/jcp2.html.
- Java 2 Micro Edition, http://java.sun.com/j2me.
- Connected Limited Device Connection, http://java.sun.com/aboutJava/communityprocess/jsr/jsr_030_j2melc.html.
- The Los Gatos Project, http://java.sun.com/features/2000/06/jeniuses.html.
Peter Meehan is President of LOOX Software Inc. in Los Altos, CA, where he is heavily involved with the LOOX range of dynamic graphics development tools. His interests include user interfaces, graphics and distributed computing, and the application of these technologies to supervision and control applications. He holds a B.A.I. in Computer Science and Electronic Engineering and an M.Sc. in Computer Science from Trinity College Dublin, Ireland. He can be contacted at meehanp@home.com.