Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

JVM Languages

PersonalJava & Information Appliances, Part II

Jaison Dolvane and Kumanan Yogaratnam

, February 01, 1999


Feb99: PersonalJava & Information Appliances, Part II

Jaison is president of Espial Group and can be contacted at [email protected]. Kumanan is the vice president of research and development for Espial Group and can be contacted at [email protected].


Information appliances are personal network-connected devices such as smart web phones, set-top boxes, personal digital assistants, hand-held computers, and game consoles. Recognizing the unique (and often low-resource) requirements for building these personal devices, Sun Microsystems released the PersonalJava API for building consumer devices with displays. In the first installment of this two-part article, we discussed what we learned about PersonalJava while developing our Kalos Espresso, a lightweight Java User Interface toolkit optimized for low-resource environments. We concluded that the emerging class of information appliances will make it possible for many consumers to easily and inexpensively get plugged in. Consequently, human-factor issues and user-interface design will be a key part of the consumer device software development cycle.

This month, we'll examine the hardware requirements for PersonalJava applications, discuss the embedded operating systems that support PersonalJava, and put PersonalJava and Kalos Expresso to work by developing a phone directory application for a web phone appliance. (The complete web phone application is available electronically; see "Resource Center," page 5.)

Embedded Systems and PersonalJava

Operating systems in the embedded world cater to both nonvisual (automobile braking systems, aeronautical processors, telephone switches, and the like) and visual applications (PDAs, set-top boxes, information appliances, and so on). However, some embedded operating systems lack the graphic capabilities required to support the Abstract Windowing Toolkit (AWT) package in PersonalJava. Implementing an AWT layer on top of the native graphical system is one of the most difficult and time-consuming stages in porting the Java VM and libraries to a new platform. Consequently, while many embedded operating systems might support an implementation of embedded Java, there are only a handful today that have complete PersonalJava support, including the AWT implementation.

Java lets you develop graphical applications and applets, without worrying about the low-level details of the hardware. The platform-dependent implementation of the Java VM (along with Java library support) abstract this technical layer, providing you with a platform-independent Java AWT API for developing graphical applications.

The AWT specification includes several heavyweight components -- buttons, checkboxes, text areas, and the like. With their native peers, these AWT components add overhead. Each heavyweight component has a peer, forcing the application to maintain two instances of a component. Also, every event that passes through the heavyweight component must be redirected through its peer. Since these memory and processing overheads are less than desirable in low-resource environments, it is important that you minimize the use of heavyweight components. With Kalos Espresso, our solution was to build a set of lightweight components that depend only on a subset of necessary AWT heavyweight system components (Frame, Graphics, Font, and the like). This has two advantages:

  • You cut down on memory requirements and do away with the overhead associated with the peer indirection of events.
  • You protect Java applications or applets from some of the bugs that might exist across different platform Java implementations of AWT heavyweight components.

It is obvious that the same code should behave in a similar manner across platforms, as long as the underlying Java implementations perform properly. The different Java implementations are primarily to blame for the differences in application behavior. Although it is not possible to remove the dependency from the underlying Java implementation, it is possible to minimize its usage -- and that's what we've done with Kalos Espresso. It only requires a subset of the AWT to function, allowing us to maintain reliability across platforms.

Several embedded operating-system vendors are working to provide support for PersonalJava. Microware's OS-9, Wind River's VxWorks, and Sun's ChorusOS and JavaOS all ship with complete PersonalJava support. Future releases of others, such as Lucent's Inferno, Microtec's VRTX, and Geoworks's GEOS-SC, will also support PersonalJava. The different processor/OS combinations supported are beyond the scope of this article, but such information should be readily available from individual operating-system vendors.

To cope with the lack of available resources, the PersonalJava VM implements several optimization features. In fact, Sun claims that the PersonalJava VM implementation is approximately 30 times faster than the JDK 1.1 VM. Recently, several manufacturers have announced their intentions to manufacture processors that will improve the execution of the Java VM. Most of these chips are slated for market in 1999.

Java is an interpreted language and performance is a big issue. However, its advantages as a secure, scalable, and reliable development platform make it an excellent choice for next-generation information appliance software. Being aware of some basic issues, along with careful and intelligent programming, make it possible to develop applications that are well-suited for consumer device environments.

The PersonalJava AddressBook Application

Developing embedded applications with Java provides you with the advantage of not having to learn any system specifics. A Java application developed in a desktop environment should function in the same manner on a consumer device. For the purpose of illustration, we'll implement a sample application that runs on Intel's StrongArm SA11 processor, running Microware's OS-9 operating system with full PersonalJava support. Our goal is for the application to run well on processors with speeds as low as 60 MHz. Our target is to have something that works within 4 MB of memory. If the PersonalJava VM resides in ROM and requires 2 MB of memory to load, that leaves only 2 MB of memory to work with.

Our available platform has support for a variety of input devices -- mouse, keyboard, touch screen, and so on. Microware OS-9 supports all of these and provides appropriate drivers. If you are using another embedded operating system, refer to its documentation to determine the available input-device support. Here, we will develop the application assuming we have a limited keyboard available and a stylus for touch input. As for the display, we have available a full-color 5×4-inch screen with a maximum resolution of 320×240 pixels.

Recall that last month, we examined the issues with respect to developing for the PersonalJava platform. The following points illustrate the implementation of those ideas.

  • Double buffering. PersonalJava has a mechanism in place where we can check whether the PersonalJava platform natively supports double buffering to reduce screen flicker. In the event that the system does not support double buffering, we have to provide our own functionality. This is available in the espial.awt.DoubleBufferPanel class, which takes care of the necessary double buffering when placed as close to the UI root as possible (for example, as the immediate and only child of a Frame or Applet and the parent of the rest of the UI tree). If the system already supports double buffering, espial.awt.DoubleBufferPanel does nothing more than act as a container in the UI tree.
  • Touch sensitivity. Many PersonalJava devices support input via various pointing mechanisms, the most common being through touch-sensitive screens. All components in Kalos Espresso are positional-input ready and can respond to touch input.
  • Colors. The platform assumption we make here ensures that we do not have to worry too much about color restrictions because the platform supports multiple colors. This may not be true for all platforms and, in the interest of general applicability, we choose to use specific colors that are visible on most devices.
  • File systems. Another benefit of the platform we have chosen is that a local file system is supported via flash cards. In a more general application, we would take into account the possibility of the absence of a local file system. To this end, we would draw a distinct line between the part of the application that uses data and the part that stores data, allowing us to later port the application where the same assumptions cannot be made.

An Application Launcher

To start our web phone application, we first develop an application launcher. This program supports three applications: an e-mailer, phone directory, and scratch pad. Of the three, we will only implement the phone directory. This is sufficient to demonstrate how we use Kalos Espresso to develop PersonalJava application user interfaces.

Figure 1 shows the application launcher on the full-screen display of the web phone. To separate the launcher from each of the applications it launches, we've built it on a distinct colored background. Each icon uses an EToolStickyButton, which provides a two-state button. Like most components in Kalos Espresso, the sticky button is transparent, allowing the background color to show through. This is advantageous if the background is textured with an image.

Because each sticky button is a Boolean component (a two-state button as defined in the BooleanDef class), we are able to use the EBooleanGroup class to group the sticky buttons. This class allows only one of its members to be True (much as java.awt .CheckboxGroup can be used with java .awt.Checkbox) at any given time.

Listing One (which is excerpted from PhoneApp.java) illustrates the core of the application toolbar functionality. The highlighted lines show how the Boolean grouping was used to achieve the selection mechanism for the application icon buttons.

When users select any of the icons, the appropriate application is launched. In this case, we use a java.awt.CardLayout to flip between the applications that are loaded and initialized at startup. In a commercially available web phone, the actual launching mechanism would be more involved -- no application would be loaded until explicitly asked for by users. The application would also be kept open until explicitly closed. In our example, we simply flip to the right card as users select an application. Since only the phone directory is implemented, selecting other applications flips to a blank card.

The Phone Directory Application

One of the most important aspects of an application for a consumer device is that it cannot be based on a look-and-feel, such as Windows or Motif. All vendors try to brand the UI with their own well-researched look-and-feel, which will identify a product with the manufacturer. This was a consideration with our own applications and one of the primary mandates during the design and development of Kalos Espresso. As you can see in Figure 2, even though there is nothing Windows-like or Motif-like about the UI, we haven't given up on usability or intuition.

To enhance usability, the application screen is divided into two regions. We've chosen green as the application color, and various shades are used to provide different hints to users. For example, the upper region uses a different shade from the lower region to separate the overall view of the phone directory from the specific view of a single record. The third shade of green (darker) is used to indicate a region that is used to view data (lists, uneditable fields, and so on). As Figure 3 shows, when fields become editable, we use a white background because the association of white with editability is well established on most UIs.

There is, of course, still room for improvement. Entire departments in companies are dedicated to the research and design of user interfaces. Also, not all devices can/will support a full-color display. We are all familiar with the spinach green of the Windows CE and Gameboy handhelds, where only two colors are available -- black and not-black. While our application uses specific colors and targets the full-color display supported by the system running OS-9, our toolkit was developed to be extensible both visually and functionally without the overhead of most highly generic architectures.

One of the features that we used extensively is the Border object. Every container (derived from EContainer) in Kalos Espresso supports borders. These are special decorative objects that can be given to a container to provide flexible borders and background painting without building specific containers. All the regional separators and boxes were created at the container level because none of our components draw any borders or backgrounds. We call this the separation of look-and-feel from core UI functionality, by which we mean that in the case of a text-editing field, the basic editing and visual feedback of such editing is separated from the decorative aspects of the component. Our text fields provide regions where you can edit text, but that do not draw borders around themselves or look opaque. Such features are best achieved by an application developer who has a better idea of the corporate look-and-feel than would a third-party vendor.

Listing Two (excerpted from PhoneDirApp.java, also available electronically) illustrates the use of border objects in the construction of the phone directory list. Note the highlighted lines where the beveled border with particular background colors is set up. There are two ways to provide a specific look-and-feel:

  • Using borders and simple layouts to create the desired look-and-feel.
  • Extending the components and embedding the look-and-feel into them so that you don't have to worry about the details of drawing the right box around the edit field.

Even when taking the second approach, there is still some UI work that requires using the first approach. There is no way to avoid using borders and layouts, but it is possible to avoid directly extending the components. While the layouts provided by the JDK is limited, it is still sufficient for about 85 percent of UI development, without ever using the infamous (and unnecessarily tedious) java.awt.GridBagLayout.

Note that in this application UI, we designed the telephone button to dial a user-selected phone number. However, we have not provided the implementation to perform the actual dialing.

Device Storage

The biggest problem with applications for consumer devices is storage. When tackling this problem, you have some options:

  • Local flash-disk storage (usually with a file system mapped onto it).
  • Remote disk storage via some network with a file system mapped on top (NFS based, for example).
  • No file-mapped storage at all, but a network connection available for remote data transfers.

While the first and second options use identical storage systems (due to the file mapping), the third option can leave you stranded. Every application has to be developed for a specific storage platform, or there must be a distinct separation between the storage and management of the data from the application itself.

Obviously, separation is the most efficient route to pursue, but most separation scenarios can result in very strange and convoluted means of data access on the part of the application that has to use the data. To help avoid making such a mess, Kalos Espresso provides reader/writer-based mechanisms known as "DataSource" objects.

Figure 4 illustrates the concepts behind a data source. The data source masks the actual details of the storage, thus two users of the data source are happily oblivious of the storage mechanism's device dependencies. Using the basic concepts of reading, writing, and listening (with the help of the reader/writer-based synchronization mechanism), data source users can manipulate the desired data without worrying about side effects and dependencies.

The listbox merely listens for changes and, when necessary, reads data. When the phone directory application makes changes to the data source (by adding, deleting, or editing), then the listbox is notified.

There is more than just data-storage abstraction occurring here; the separation of the manipulation of the data from the component that displays the data is just as crucial. The application is not bound by, or distracted by, the limitations of the component. Everyone deals with the data directly and derives their respective responses.

For the phone directory, we have extended one of the ListDataSource (see Listing Three) implementations to store the PhoneDirRecord objects in memory (see PhoneDirRecord.java, also available electronically). In a more practical implementation, we would take into account the requirements of the device and implement a different data source for each storage mechanism.

Conclusion

If you look at the web phone's source code, you'll see that there is really no system-specific code. This application is written completely in Java using the 100 percent pure Java Kalos Espresso GUI toolkit, which is built to suit the requirements of minimal resource environments.

From our experience, Java has proven to be a feasible language for the embedded world and, as more embedded operating systems begin to support PersonalJava, the demand for applications to enable these devices is going to increase exponentially.

While the market for consumer devices is much larger than that of the personal computer, system resources are much lower than traditional PCs and user demographics are extremely diverse. For this reason, we would again like to reemphasize the importance of human factors and intelligent programming.

DDJ

Listing One

EBooleanGroup bg = new EBooleanGroup ();// setting up Sticky Button
m_email = new EToolStickyButton ();
m_email.setBooleanGroup (bg);
m_email.setState (true);
m_email.setImagePosition (EToolStickyButton.TOP);
m_email.setImageBundle (ImageUtils.getImageBundledResource 
                                             (getClass(), "email.gif"));
// ending setup of m_email
container_1.add (m_email);
// setting up Sticky Button
m_directory = new EToolStickyButton ();
m_directory.setBooleanGroup (bg);
m_directory.setState (false);
m_directory.setImagePosition (EToolStickyButton.TOP);
m_directory.setImageBundle (ImageUtils.getImageBundledResource 
                                            (getClass(), "directory.gif"));
// ending setup of m_directory
container_1.add (m_directory);
// setting up Sticky Button
m_scratch = new EToolStickyButton ();
m_scratch.setBooleanGroup (bg);
m_scratch.setState (false);
m_scratch.setImagePosition (EToolStickyButton.TOP);
m_scratch.setImageBundle (ImageUtils.getImageBundledResource 
                                            (getClass(), "scratchpad.gif"));
// ending setup of m_scratch
container_1.add (m_scratch);

Back to Article

Listing Two

// setting up Listm_phoneDirData = new PhoneDirListDataSource ();
m_dirList = new EListBox (m_phoneDirData);
// setting up wrapper for EList
EPanel tmp_0 = new EPanel ();
BaseBorder tmp_1;
tmp_0.setLayout (new BorderLayout ());
EScrollPanel sp_0 = new EScrollPanel (m_dirList);
tmp_0.add (sp_0, BorderLayout.CENTER);
tmp_0.setBorder (tmp_1 = new BevelBorder (new Color (89,165,118), false));
EScrollbar tmp_2 = new EScrollbar (EScrollbar.VERTICAL);
tmp_0.add (tmp_2, BorderLayout.EAST);
sp_0.setVerticalScrollbar (tmp_2);

Back to Article

Listing Three

package espial.demo.phoneapp;

</p>
import espial.awt.item.*;
import espial.util.*;
import espial.image.*;


</p>
import espial.datasource.list.*;


</p>
import java.awt.*;


</p>
/** A specialized data source which stored PhoneDirRecord entries. This 
 * implementation stores the list in memory and as a result the data is 
 * non-persistent. The idea here is that by re-implementing this class it is 
 * possible to modify the backend data source for the phone directory without 
 * the directory being any wiser.
 * We rely on the DefaultListDataSource object to manage the data in memory.
 */
public class PhoneDirListDataSource extends DefaultListDataSource {
    ImageBundle m_icon;
    public PhoneDirListDataSource (ImageBundle icon) {
        m_icon = icon;
    }
    /** Get an instance of espial.awt.item.Item that can render the data
     * at a specific index.
     * Developers note: By subclassing this method and setting the 
     *    m_renderer member before calling the superclass method allows the 
     *    subclass to override the Item that is used. Be careful though that 
     *    the Item the assigns is compatible with the one used by the 
     *    superclass unless you're completely overriding this method.
     *    @return an instance of Item. This method does not validate index, 
     *    so it always returns an instance, even though it may draw nothing.
     */
    public Item getDataRenderer (int ix) {
        if (m_renderer == null) {
            ImageItem it;
            m_renderer = (it = new ImageItem (m_icon.getImage ()));
            it.setImagePosition (ImageItem.LEFT);
        }
        Object data = getData (ix);
        if (data instanceof PhoneDirRecord) {
            m_renderer.setName (((PhoneDirRecord) data).name);
        }
        else {
           m_renderer.setName ("** Bad Record **");
        }
        return m_renderer;
    }
}

Back to Article


Copyright © 1999, Dr. Dobb's Journal

Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.