Wireless Programming With J2ME
Wireless Programming With J2ME
5,7 cod
ines of so +l 00 on CD-R u e
e rc ! M O
Dreamtech Software Team
Best-Selling Books Digital Downloads e-Books Answer Networks e-Newsletters Branded Web Sites e-Learning New York, NY Cleveland, OH Indianapolis, IN
Wireless Programming with J2ME: Cracking the Code Published by Hungry Minds, Inc. 909 Third Avenue New York, NY 10022 www.hungryminds.com Copyright 2002 Hungry Minds, Inc. All rights reserved. No part of this book, including interior design, cover design, and icons, may be reproduced or transmitted in any form, by any means (electronic, photocopying, recording, or otherwise) without the prior written permission of the publisher. Library of Congress Control Number: 2001093843 ISBN: 0-7645-4885-9 Printed in the United States of America 10 9 8 7 6 5 4 3 2 1 1B/QR/QS/QS/IN Distributed in the United States by Hungry Minds, Inc. Distributed by CDG Books Canada Inc. for Canada; by Transworld Publishers Limited in the United Kingdom; by IDG Norge Books for Norway; by IDG Sweden Books for Sweden; by IDG Books Australia Publishing Corporation Pty. Ltd. for Australia and New Zealand; by TransQuest Publishers Pte Ltd. for Singapore, Malaysia, Thailand, Indonesia, and Hong Kong; by Gotop Information Inc. for Taiwan; by ICG Muse, Inc. for Japan; by Intersoft for South Africa; by Eyrolles for France; by International Thomson Publishing for Germany, Austria, and Switzerland; by Distribuidora Cuspide for Argentina; by LR International for Brazil; by Galileo Libros for Chile; by Ediciones ZETA S.C.R. Ltda. for Peru; by WS Computer Publishing Corporation, Inc., for the Philippines; by Contemporanea de Ediciones for Venezuela; by Express Computer Distributors for the Caribbean and West Indies; by Micronesia Media Distributor, Inc. for Micronesia; by Chips Computadoras S.A. de C.V. for Mexico; by Editorial Norma de Panama S.A. for Panama; by American Bookshops for Finland. For general information on Hungry Minds products and services please contact our Customer Care department within the U.S. at 800-762-2974, outside the U.S. at 317-572-3993 or fax 317-572-4002. For sales inquiries and reseller information, including discounts, premium and bulk quantity sales, and foreign-language translations, please contact our Customer Care department at 800-434-3422, fax 317-572-4002 or write to Hungry Minds, Inc., Attn: Customer Care Department, 10475 Crosspoint Boulevard, Indianapolis, IN 46256. For information on licensing foreign or domestic rights, please contact our Sub-Rights Customer Care department at 212-8845000. For information on using Hungry Minds products and services in the classroom or for ordering examination copies, please contact our Educational Sales department at 800-434-2086 or fax 317-572-4005. For press review copies, author interviews, or other publicity information, please contact our Public Relations department at 317-572-3168 or fax 317-572-4168. For authorization to photocopy items for corporate, personal, or educational use, please contact Copyright Clearance Center, 222 Rosewood Drive, Danvers, MA 01923, or fax 978-750-4470. LIMIT OF LIABILITY/DISCLAIMER OF WARRANTY: THE PUBLISHER AND AUTHOR HAVE USED THEIR BEST EFFORTS IN PREPARING THIS BOOK. THE PUBLISHER AND AUTHOR MAKE NO REPRESENTATIONS OR WARRANTIES WITH RESPECT TO THE ACCURACY OR COMPLETENESS OF THE CONTENTS OF THIS BOOK AND SPECIFICALLY DISCLAIM ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. THERE ARE NO WARRANTIES WHICH EXTEND BEYOND THE DESCRIPTIONS CONTAINED IN THIS PARAGRAPH. NO WARRANTY MAY BE CREATED OR EXTENDED BY SALES REPRESENTATIVES OR WRITTEN SALES MATERIALS. THE ACCURACY AND COMPLETENESS OF THE INFORMATION PROVIDED HEREIN AND THE OPINIONS STATED HEREIN ARE NOT GUARANTEED OR WARRANTED TO PRODUCE ANY PARTICULAR RESULTS, AND THE ADVICE AND STRATEGIES CONTAINED HEREIN MAY NOT BE SUITABLE FOR EVERY INDIVIDUAL. NEITHER THE PUBLISHER NOR AUTHOR SHALL BE LIABLE FOR ANY LOSS OF PROFIT OR ANY OTHER COMMERCIAL DAMAGES, INCLUDING BUT NOT LIMITED TO SPECIAL, INCIDENTAL, CONSEQUENTIAL, OR OTHER DAMAGES. Trademarks: Hungry Minds, the Hungry Minds logo, and Cracking the Code are trademarks or registered trademarks of Hungry Minds, Inc. in the United States and other countries and may not be used without written permission. Java, Forte, NetBeans and all trademarks and logos based on Java, Forte, and NetBeans are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All other trademarks are the property of their respective owners. Hungry Minds, Inc., is not associated with any product or vendor mentioned in this book.
Credits
Acquisitions Editor Chris Webb Project Editor Chandani Thapa Technical Editor Dr. K.V.K.K. Prasad Media Development Specialist Angela Denny Permissions Editor Laura Moss Media Development Manager Laura Carpenter VanWinkle Project Coordinator Nancee Reeves Cover Design Anthony Bunyan Proofreader Anne Owen Indexer Johnna VanHoose Dinse Cover Vault door image used courtesy of
Dreamtech Software India, Inc., is a leading provider of corporate software solutions. Based in New Delhi, India, the company is a successful pioneer of innovative solutions in e-learning technologies. Dreamtechs developers have more than 50 years of combined software-engineering experience in areas such as Java, wireless applications, XML, voice-based solutions, .NET, COM/COM+ technologies, distributed computing, DirectX, Windows Media technologies, and security solutions.
Other Contributors
Pankaj Kumar, Deepak Sharma, Gaurav Malhotra, Anil Kumar Singh, Bill Ray, a team of programmers of Dreamtech Software India, Inc. They contributed to the development of software in this book.
Acknowledgments
We acknowledge the contributions of the following people for their support in making this book possible: John Kilcullen for sharing his dream and providing the vision for making this project a reality. Mike Violano and Joe Wikert for believing in us. V.K. Rajan and Priti for their immense help in coordinating various activities throughout this project.
To our parents and family and beloved country, India, for providing an excellent environment for nurturing and creating world-class IT talent.
Preface
Wireless devices are new entrants in the information technology arena. As wireless devices are compact and easy to handle, the focus of Information technology is rapidly shifting from PCs to PDAs, cellular phones, and pagers. The market for these devices has undergone a tremendous growth over the past few years. These devices are becoming increasingly sophisticated in response to the demand for using them to access the Net as well as computing devices. Moreover, these devices are paving the way for new business strategies. Sun Microsystems fulfilled the aspirations of the Java Community by launching J2ME (Java 2 Micro Edition), which gave Java an edge over other programming tools in its performance on wireless devices. It was first introduced at the Java One Conference in 1999. The J2ME has two design centers. Thus, this platform has two configurations and these are CLDC (Connected Limited Device Configuration) and CDC (Connected Device Configuration). This has to be kept in mind while talking about J2ME. With an approach that is based on configurations and profiles, J2ME offers flexibility to the developer, which is of great significance for extremely diverse handheld and wireless devices. This approach makes it possible to provide as much functionality as the device has the potential to support. Added to this are the usual benefits of Java, such as portability across platforms, security, and the objectoriented character. This is why Java is predicted to be the most preferred language for the modern computing devices. It may well be said that J2ME is still in the early stages of development. Two configurations have become available, but only a few of the proposed profiles are available as of now. This situation is bound to change as soon as the Micro Edition platform becomes more mature. Consequently, its use is also expected to increase considerably. Many leading companies have started releasing Java-enabled devices. This means that you can download Java applications even on your mobile phones and run them offline.
Preface
The book, as mentioned in the preceding section, consists of 12 chapters. The first five chapters dwell on theory, followed by six projects. The book ends with a chapter on the conversion of existing Java applications to their J2ME versions. The first chapter provides a short overview of the Micro Edition platform. It introduces the basic building blocks of the platform, such as the CLDC, CDC, Foundation Profile, and MIDP. The J2ME virtual machines are also dealt with here. Significant features of J2ME, as compared to the Standard Edition, are pointed out. Related Java technologies such as Java Card, PersonalJava, and EmbeddedJava are mentioned in passing. The second chapter discusses the programming techniques required for writing applications for small wireless devices. These devices may be severely constrained in terms of resources such as memory and processing power. This is why a new general approach has to be adopted, in addition to specific methods to take care of device-specific problems. This may be an important chapter for you if you are new to programming for small and wireless devices. The third chapter is about a configuration namely, CLDC. Configurations are the base on which profiles may be added. They provide the basic functionality common to devices of a particular category. You will find the following in this chapter: Introduction to the important classes that make up CLDC Procedure for installing CLDC (nothing much to explain there) Compiling, preverifying and running application written using J2ME CLDC Several case studies to illustrate the use of CLDC APIs The fourth chapter explains the Mobile Information Devices Profile, or MIDP. The format of this chapter is the same as that of the previous chapter. You get an introduction to classes and the procedures of installing, compiling, preverifying, and running. Case studies are also presented to help you understand the APIs fully. The fifth chapter is on J2ME and contains what is relevant to programming with J2ME. It deals with XML parsing. XML parsing is used in almost all the projects in the book. After the introduction, the reader is told about one of several available parser packages, namely kXML. Needless to say, this example of XML parsing is provided in the form of functioning code. With the sixth chapter begins a series of projects. Chapter 6 is based on a project, or application if you please, called Online Testing Engine. It allows you to attempt tests online, using devices such as mobile phones. The application is a simple one, but it serves to illustrate the basic concept behind such applications. The project chapters follow the following format: Introducing the application Explaining the user interface Explaining the working of the application Complete source code with heavy commenting and line-by-line explanation The seventh chapter is on a project called Online Ordering System. This project is an Ordering System for devices such as cell phones and pagers. You can check the stock available and place an order accordingly. The price of the order to be placed will also be calculated and displayed to you. This can be considered an m-commerce application that uses existing J2EE applications hosted on a server. The eighth chapter is about a remote-control MP3 player application and is based on PersonalJava and can be used with devices such as Pocket PC. Though this application is written using PersonalJava, it can easily run on a CDC-based platform. It should be noted that, at the time of writing this application,
Preface
Personal Profile was not available, but it is known that PersonalJava will merge into J2ME as the Personal Profile. Therefore, this application can be considered a CDC-based application that uses Personal Profile. It also uses the Java Media Framework. Chapter 9 is on a project called Peer-to-Peer Search Application. This application is a peer-to-peer searching tool for Palm devices. It allows you to search for files on particular system and displays the listing of the available files, somewhat like Napster. You can read a complete peer-to-peer application developed using J2SE and C# in the book Peer-to-Peer Application Development Cracking the Code series, author Dreamtech Software Team.
xi
Chapter 10 contains a project called Mobile Web Services. It is meant to provide services to the user that can be accessed from mobile devices. The project targets devices such as cell phones and similar services. The services the user gets are weather details, movie ticket booking, and news. This project uses XML very extensively. Chapter 11 is devoted to writing a simple game for Palm devices. The game involves a stationary gun and a moving target. The user has to fire a limited number of bullets to hit the target. Points are awarded accordingly. Chapter 12 deals with converting applications in which a great deal of effort has been put in by developers all around the world in developing Java applications. It is natural that some of these can be converted to work with handheld devices. The final chapter of the book explains how and to what extent this can be done. Some general guidelines to handle this process are provided. As this is a code-heavy book with an introduction to the theory, we hope that it will help Java developers in adapting to the Micro Edition platform. Since entry-level material has been left out of the book, making the book smaller in size, you will find it easier to go through it even if you are short on time.
Contents
Preface.........................................................................................................viii Chapter 1: An Overview of J2ME .................................................................1
Introduction ............................................................................................................................................. 1 What J2ME is about......................................................................................................................... 1 What J2ME offers............................................................................................................................ 2 J2ME Virtual Machines .......................................................................................................................... 3 The K Virtual Machine (KVM) ...................................................................................................... 3 The C Virtual Machine (CVM)....................................................................................................... 4 Configurations ......................................................................................................................................... 5 CLDC ............................................................................................................................................... 5 CDC.................................................................................................................................................. 7 Profiles..................................................................................................................................................... 8 Mobile Information Device Profile (MIDP)................................................................................... 8 Foundation Profile ........................................................................................................................... 9 Other profiles ................................................................................................................................... 9 Getting Set to Program with J2ME....................................................................................................... 10 Our First J2ME Application.................................................................................................................. 10 RelatedJava Technologies..................................................................................................................... 12 PersonalJava................................................................................................................................... 12 Java Card........................................................................................................................................ 13 Summary................................................................................................................................................ 15
xiv
Contents
Use GUI classes optimally and creatively.....................................................................................25 Use the servers functionality ........................................................................................................25 Use low-level UI APIs in MIDP....................................................................................................25 Use SyncML for data synchronization ..........................................................................................26 Summary ................................................................................................................................................26
.................................. 27
Core Packages ........................................................................................................................................27 java.lang package ...........................................................................................................................27 java.io package ...............................................................................................................................27 java.util package .............................................................................................................................28 Brief introduction to commonly used packages............................................................................28 Generic Connection Framework ...........................................................................................................31 Kjava API...............................................................................................................................................33 Brief introduction to commonly used classes .......................................................................................36 Spotlet .............................................................................................................................................36 Graphics..........................................................................................................................................37 Button..............................................................................................................................................37 TextField.........................................................................................................................................38 RadioButton and RadioGroup........................................................................................................38 HelpDisplay ....................................................................................................................................39 ScrollTextBox.................................................................................................................................39 Database..........................................................................................................................................40 TextBox ..........................................................................................................................................41 Installation of CLDC .............................................................................................................................41 Compiling, preverifying, and running applications ......................................................................42 Case Studies ...........................................................................................................................................43 TextField_Spotlet ...........................................................................................................................43 ScrollTextBox_Spotlet...................................................................................................................45 HelpDisplay_Spotlet ......................................................................................................................47 CheckRadio_Spotlet.......................................................................................................................49 HttpCheck_Spotlet .........................................................................................................................52 Server ..............................................................................................................................................55 Socket_Check .................................................................................................................................55 Summary ................................................................................................................................................62
Contents
xv
Graphics Class ............................................................................................................................... 73 Class List........................................................................................................................................ 75 Class StringItem............................................................................................................................. 76 Class TextField .............................................................................................................................. 76 Class TextBox................................................................................................................................ 77 Class Ticker.................................................................................................................................... 78 Persistence Package............................................................................................................................... 78 Class RecordStore.......................................................................................................................... 79 Exceptions in Persistance Package................................................................................................ 82 Installation of MIDP and Running Applications ................................................................................. 82 run.bat............................................................................................................................................. 83 sample.bat....................................................................................................................................... 84 example.jad .................................................................................................................................... 85 J2ME Wireless Toolkit ......................................................................................................................... 85 MIDP for Palm ...................................................................................................................................... 86 Case Studies........................................................................................................................................... 91 TextFieldCheck.............................................................................................................................. 91 LabelUI .......................................................................................................................................... 93 ChoiceGroupUI.............................................................................................................................. 95 TickerUI ......................................................................................................................................... 98 MenuCheck .................................................................................................................................... 99 AddressBook................................................................................................................................ 101 TestHTTP..................................................................................................................................... 109 Summary.............................................................................................................................................. 111
xvi
Contents
TestFile.asp ..........................................................................................................................................161 Summary ..............................................................................................................................................163
Contents xvii
Differences in the hardware......................................................................................................... 356 Problems due to device variety ................................................................................................... 356 Differences in the application models......................................................................................... 357 Differences in APIs...................................................................................................................... 357 What Conversion Entails .................................................................................................................... 358 Modifying the application design, if necessary .......................................................................... 358 Reducing the GUI ........................................................................................................................ 358 Removing unnecessary or impossible functionality................................................................... 359 Optimizing the use of resources .................................................................................................. 359 Using JavaCheck ................................................................................................................................. 359 An Example of Conversion................................................................................................................. 361 Analyzing the design ................................................................................................................... 361 Reducing the GUI ........................................................................................................................ 362 Is some functionality unnecessary or impossible? ..................................................................... 363 Listing the items consuming resources ....................................................................................... 364 Testing the application................................................................................................................. 365 Summary.............................................................................................................................................. 365
Index ...........................................................................................................369 End User License Agreement ...................................................................377 Sun Microsystems, Inc. Binary Code License Agreement.....................379 License Agreement: Forte for Java, Release 2.0 Community Edition for All Platforms ......................................................................................382
Chapter 1
An Overview of J2ME
This chapter presents the basics of J2ME and serves to enlighten the reader on the steps involved in programming with J2ME. It also provides the groundwork necessary for developing applications. J2ME has been compared with J2SE, and so some background is provided on J2ME virtual machines. We also mention, albeit not in detail, Java technologies of a similar nature.
Introduction
Java came to the limelight with the release of HotJava browser, which demonstrated the suitability of Java for the Internet. It established that dynamic and interactive Web pages could be created with Java. The craze for applets also caught up with its release. Subsequently, Netscape 2 for Windows became the first commercial browser to support Java 1.0. Java was at its maximum hype at this time, because it seemed to offer capabilities on the Web that werent otherwise possible. The promise of cross-platform applications also added to Javas reputation. Since then, Java has come a long way. Its acceptance is so widespread that you can find APIs for carrying out most of the things that can be done in other programming languages. From applets to RMI and from Servlets to speech APIs, you find everything under the Java umbrella. Perhaps this accumulation of tools providing all kinds of functionalities contributed to Sun Microsystems decision to organize the Java family better. Another reason for this could be the boom of nonconventional computing devices. These devices had actually started emerging before the birth of Java. In fact, the Java language itself was initially aimed at providing programming solutions for such devices. Computing was no longer restricted to servers or PCs. And the world of small devices spread far beyond organizers possessing 16K memory and toy processors. Newer devices not only had increased memory and processor power, but also were proliferating in shapes, sizes, display types and areas, input and output methods, and networking. Sun Microsystems came up with the idea of dividing the Java universe into three separate platforms for different purposes. The domain of the three platforms was to be determined by the sizes for which they were meant. Thus the platform for conventional computing was called the Java 2 Standard Edition (J2SE) and that for enterprise applications and distributed computing became the Java 2 Enterprise Edition (J2EE). The third platform was meant for the nonconventional consumer devices. These devices are characterized by some typical features, such as mobility, limited memory and processing power, incapability to access power from the mains (being battery powered), small display areas, and limitations and variety with respect to input and output methods. Of course, not all these features must be present on one device. One thing common to most of these devices is that they are all connected to some network, even if not always. The Java platform meant for these devices was called the Java 2 Micro Edition (J2ME). And this platform is what we focus on in this book.
Configuration) and CDC (Connected Device Configuration). You need to keep this fact in mind while talking about J2ME. Whenever youre programming for a mobile phone, you are as much within the fold of the J2ME as you are if youre programming for a set-top box with almost as much computing power as a desktop system. But it is true that J2ME is more associated with small devices that have modest amounts of power and memory. Yet, when you program for devices such as set-top boxes, the difference between J2ME and J2SE narrows, and people whove been writing code for the standard edition feel quite at ease with J2ME. It is while writing code for devices such as mobile phones that the peculiarities of J2ME become relevant. We try to cover both design centers in this book, as far as possible. The micro edition platform was conceived and designed in the form of layers (Figure 1-1). Each layer adds some functionality. The primary requirement is, of course, a virtual machine for running Java applications. These, together with the virtual machine, form part of the configuration. On top of this configuration resides a profile. The exact profile that can be added is dictated by the device and also by the configuration that is being used. But youre not restricted to one profile. You can add another profile on top of the first one. This cannot, however, be done arbitrarily you cannot add any profile on top of profile.
For the time being, we dont have many profiles to choose from: the profile released till recently was Mobile Information Device Profile. The newer Foundation Profile doesnt really match the concept of a profile because it has no libraries for providing user interface. Even after that day comes that we do have more choices, J2ME is not limited to Configurations and profiles, and we can also add optional packages over and above configurations and profiles. Thus we may consider a platform as parts joined together to form a whole that suits the devices for which our applications are meant. Thus we find a great deal of flexibility in regard to implementing the programming model. Device manufacturers as well as independent vendors can provide their own versions of virtual machines if they follow the Java Virtual Machine Specification. If so, their virtual machines would be no less capable than those provided by Sun. Devices can be sold in Java-enabled condition, or they can be Java enabled later on by the user. Similarly, applications may be loaded onto the devices before the devices are sold, or the user may download them from the Web.
application that invokes a servlet residing on a server, you can run the same on a mobile phone or a settop box. This is because the server side remains the same you need to regard only the restrictions of the device. These applications can be games, navigation aids, applications interacting with databases, or anything permitted by the resources on the device. The idea of ubiquitous computing can be realized with this platform (Figure 1-2).
capabilities to run on low-power processors, to enable partitioning of the VM, and to fulfill the Java assurance of portability. This last issue could have been a big problem, considering the diversity of small devices. There is actually no full portability, but porting is not very difficult because the KVM was implemented in C language. Just as applets are written using the APIs available in the standard edition, these applications (spotlets, MIDlets, and more to come) are written using Java APIs available in CLDC, CDC, MIDP, Foundation Profile, and so on. And just as applets are run using the conventional JVM, these applications are run using the KVM. We should note here that, when we talk of KVM, we mean the reference implementation of KVM provided by Sun. However, J2ME can use any VM that is written according to the Sun's Java Virtual Machine Specifications (JVMS) and can handle as much work as the K virtual machine. The K Virtual Machine can theoretically run several profiles, but it cannot run quite perfectly all the profiles and APIs that arent specifically designed for it, just as it cannot be used to run the CDC. It is basically meant for CLDC and, at present, for only one profile: MIDP. This means that applications written for the conventional JVM or even for CVM most probably cannot run on the KVM without some changes. But the converse is not true applications written for KVM can easily run on the CVM or the normal JVM. A more recent version of KVM (version 1.02) has some improved capabilities, such as a better garbage collector, debugging support with KDWP, a better preverifier, and so on. KDWP is a Debug Proxy (Debug Agent) tool. Debug proxy is tool that is interposed between a Java IDE (Integrated Development Environment) such as Forte and the KVM for debugging purposes. This version includes an implementation for Linux, too. Certain other bugs have been removed and the performance of the interpreter has been improved.
Configurations
As already mentioned, configurations form the base of the J2ME platform. They provide the basic minimum functionality for a particular category of devices. This functionality is to be common to all devices in that category, irrespective of other factors. The very reason for dividing the platform into configurations and profiles is to serve this purpose. The devices targeted by J2ME, even those in the same category, are so diverse in terms of their capabilities that it would have been difficult, if not impossible, to implement the J2SE kind of model for them. The whole platform had to be conceived in the form of layers, operating one on top of another. The base is formed by one configuration, over which you add one or more profiles. A configuration includes the virtual machine and the required basic minimum libraries. Because the devices can be broadly divided into two categories, two configurations were needed. These are the Connected Limited Device Configuration (CLDC) and the Connected Device Configuration (CDC). Their domains may overlap in some cases, because there isnt any definite border between the two. With some devices, it would be difficult to decide whether CLDC or CDC is the more suitable configuration. For example, some screen phones may have more resources which can be best explored by CDC-based applications where as some may not have enough resources to run the heavier CDC-based applications. Configurations define the horizontal limits of the platform for a category or family of devices. They specify what parts of the Java language, what features of the Java virtual machine, and what core libraries are supported. As mentioned previously, you may sometimes have the option of using either of the two configurations, but you cannot use both simultaneously. You must choose one before you start running Java applications on the device. In fact, the manufacturer may have decided this for the user.
CLDC
The Connected Limited Device Configuration, or CLDC, has been designed for severely resourceconstrained devices such as todays cell phones, PDAs, and so on. Therefore, it has everything optimized to a great extent. The virtual machine (KVM or any other similar implementation adhering to the specification) is small, and some of the Java language features are not supported. But the real difference is that the libraries available are very few in number. What this means is that you dont need to learn the basics again what you learned about the standard edition suffices for the most part but the libraries must be used with great care (Figure 1-3).
Some of the main features of CLDC are as follows: Data types long and float are not supported. All the methods of J2SE inherited classes that use these data types have been removed. Several runtime exceptions are present, but the number of runtime errors has been reduced significantly for the classes inculded in CLDC. In fact, only the following three errors are available: java.lang.Error java.lang.OutOfMemoryError java.lang.VirtualMachineError Other errors are handled in an implementation-specific manner. To make garbage collection simple, support for finalization is not provided. There is no finalize method in the java.lang.Object class. Java Native Interface (JNI) is not supported in CLDC. The purpose to eliminate-dependence such that the applications can be ported to any platform containing the virtual machine. You can use threads, but not thread groups or daemon threads. In the standard edition, you can mark objects for possible garbage collection. This cannot be done with CLDC. In other words, there is no support for weak references. Verification of classes to check whether the code is well-formed is done off-device that is, on the desktop system on which the applications are developed. This is done by a tool called preverifier. You must do preverification explicitly after you compile your code. A different security model is used in CLDC, which is somewhat similar to the one used in browsers for downloaded applets. The reason is that the model used in the standard edition is too heavy for small devices, and the security needs of the connected devices are similar to those of the browsers. There are only four packages available in CLDC. Most of the J2SE packages such as java.lang.awt, java.lang.beans, and so on have been dropped. CLDC contains only the following packages: java.io: Stripped-down version of the J2SE java.io package. It contains the classes required for data input and output using streams. java.lang: Stripped-down version of the J2SE java.lang package. It contains the classes that are basic to the Java language such as the wrapper classes for data types.
java.util: Stripped-down version of the J2SE java.util package. It contains classes such as Calender, Date, Vector, and Random. javax.microedition.io: A newly introduced CLDC-specific class that defines the Generic Connection Framework. It contains the classes for handling all types of connections by using the same framework.
CDC
The Connected Device Configuration is designed for the devices of the second category. These devices, as we saw, are not as constrained as the CLDC targeted devices. CDC targets devices with 32-bit processor and 2MB+ memory. Consequently, this configuration can afford to provide many more features of the standard edition, both with respect to the Java language support and virtual machine support. In fact, it has full Java language and virtual machine support. And, more important, the number of APIs included in CDC is significantly higher than in CLDC. This means that you can have much more functionality in your application if you use CDC. You can do this, of course, only if the device permits (Figure 1-4).
CDC gives you better networking support and a more flexible security mechanism. It does not contain the deprecated APIs of the standard edition. CDC must be used together with a profile called Foundation Profile, which we briefly introduce later in this chapter. On its own it cannot do much useful work. Some of the important features of this configuration are as follows: Full Java language and virtual machine support, according to the Java Language Specification and the Java Virtual Machine Specification. The interfaces between parts of the runtime environment, such the garbage collector, interpreter, and so on, are clearly defined so that it is easy to add new features to the virtual machine. Cleanup and shutdown of the virtual machine is efficient, freeing up all memory and stopping threads without any leaks. Some other features have already been considered while discussing CVM. CDC contains the following packages, which are almost similar to those of the same names in the standard edition: java.io java.lang java.lang.ref
Profiles
Configurations provide very little functionality they just prepare the ground on which to add whatever you need. It is the profiles that give functionality, such as the graphical user interface. For example, if you have just CLDC installed on a device such as a PDA, you cannot create any user interface objects. No GUI is possible in your applications. For that, you need a profile. This is why Sun added a package called KJava with CLDC to enable testing and development, even if KJava is to be abandoned later. As a matter of fact, Sun Microsystems has provided tools for Palm development with its new wireless toolkit version 1.0.2 and the kit is based on CLDC and MIDP; there is no KJava now. A profile may add other kinds of functionality, such as better networking support, database management, distributed computing, and so on. Like configurations, profiles may also be device-category specific. Some profiles may be useful for small devices, while others may be suitable for less-constrained devices. For example, MIDP and PDA Profile are used for mobile phones and PDA-like devices, respectively, on top of CLDC. On the other hand, Personal Profile is used for devices such as set-top boxes, on top of CDC.
javax.microedition.lcdui: This is the package responsible for providing the user interface. It includes classes such as those for creating user-interface elements (buttons, text fields, choice groups, gauges, images, and so on) and for handling events (listeners). This is basically a gameoriented user interface package, but can be used for other UI purposes. javax.microedition.rms: This package provides the capability to make data persistent. For this purpose, the main class thats included is the RecordStore class. In addition, there are interfaces for comparison, enumeration, filtering, and listening.
Foundation Profile
This profile is, in a way, just an extension of CDC. CDC APIs on the whole don't provide the functionality available in Java Standard Edition, therefore, to get the same functionality as the Java Standard Edition one has to use the APIs of Foundation Profile on top of CDC. Foundation profile acts as an extension to CDC to achieve Java 2 Standard Edition functionality. Profiles are normally supposed to add GUI functionality to the configurations, but Foundation Profile does not do this. There is no GUI package in this profile. Another peculiarity about this profile is that it is mandatory. You must use it along with CDC to prepare the ground for adding another profile. CDC, if combined with the Foundation Profile, adds up to complete the basic Java API set, as available in the standard edition. Refer to Figure 15 (Foundation Profile) to know in which layer the foundation profile comes. The only exception is the user interface that is, there is no java.awt package. The classes it contains, in addition to those provided by the CDC, are as follows:
java.security.acl java.security.interfaces java.security.spec
Other profiles
Apart from MIDP and Foundation Profile, no other profiles are formally available at the time of writing this chapter. But there has been something called PersonalJava, as you may well be aware. Because it uses a subset of the J2SE, it is comparable to the CDC-based segment of the J2ME platform. In fact, if you take care of certain things mentioned in the CDC-Foundation Profile porting guide, you can easily write applications that run on both the PersonalJava runtime environment and the CDC-based runtime environment. In other words, you can consider PersonalJava to be just another profile for CDC. This is why some people refer to it as the PersonalJava Profile. They are further justified in considering that its soon to be formally merged with J2ME as the Personal Profile.
10
The profiles that are under development at present and may soon be available are as follows:
12
RelatedJava Technologies
Javas association with limited devices is older than its J2ME initiative. For more than the last couple years, Java has been venturing into the realm of devices, which includes not only mobile phones and connected organizers, but smart cards as well. Even before J2ME became a platform and its constituents, such as CLDC and MIDP, made their appearance, technologies have propagated for more or less the same purpose for which J2ME is meant. These technologies also came forth from the Sun stable and were Java based. The more prominent ones among them are PersonalJava, EmbeddedJava, and JavaCard. PicoJava is a microprocessor dedicated to executing Java-based bytecodes without the need of an interpreter or Just-in-time compiler. PicoJava directly executes the Java virtual machine instruction set. As a result, Java software applications are up to three times smaller in code size and up to five times faster thus reducing memory requirements and are 20 times faster than Java interpreters running on standard CPUs. Knowledge of these technologies is not mandatory for a J2ME programmer, but it serves to clarify the role of J2ME in the world of wireless programming. And because some of these technologies may be absorbed (in a modified form) into the J2ME fold in the future, many programmers working with them may choose to shift to the micro edition. Besides, there is the fact that many of the concepts used in J2ME are the same as those used in PersonalJava or EmbeddedJava. We find an analogy in that EJB existed before J2EE came into being, but now it is a part of the enterprise edition. One more point to note here is that PersonalJava and EmbeddedJava have many things in common. Many tools are common to the two. Some tools work for both of them, such as javac, JavaCheck (a tool that checks whether applications and applets are compatible with a particular specification), JavaCodeCompact (a tool used to convert Java class files to C language source files so that they can be compiled into ROM format), and JavaDataCompact (a tool thats similar to JavaCodeCompact, except that, with JavaDataCompact, you can include HTML files, images, and sounds in the device ROM). This is one more reason why Java technologies dealing with connected and/or limited devices (other than PCs and servers, of course) should be brought under a common platform.
PersonalJava
PersonalJava has been in use for quite some time. It was meant to provide solutions for the same category of devices to which CDC-based J2ME is targeted that is, devices such as Web phones, set-top boxes, and so on. You can use the same JDK for developing PersonalJava applications; the only thing to remember is that APIs not supported by it are to be avoided. Unlike the CDC-Foundation Profile, it has user-interface APIs in the form of AWT. This AWT is the java.awt package, which is inherited from J2SE. To address the special needs of consumer devices, another method for adding GUI is provided. It comes as the Truffle Graphical Toolkit. Unlike AWT, which is meant for desktop display, this toolkit can be used to provide a customizable look and feel to targeted devices. You can test your application on the PersonalJava emulation environment. The JDK-based APIs included in PersonalJava are as follows:
java.applet java.awt java.awt.datatransfer java.awt.event java.awt.image java.awt.peer java.beans
Some other APIs specific to PersonalJava are as follows: Double buffering Specifying component input behavior in mouseless environments Unsupported optional features Timer API
Java Card
Java Card technology has fewer chances of becoming part of the J2ME platform than the preceding two technologies. This technology, too, aims at providing programming tools for small devices with embedded processors. The devices it is concerned with are mostly smart cards, but other similar embedded devices can also avail this technology. The applications made using this technology are also called applets. You can call them Java Card applets or just card applets to differentiate them from normal applets. Although there are a number of differences between the standard edition and the Java Card technology, most of the basics remain the same. Because we are talking about small cards the size of a business card (so that they can be carried in pockets), it is quite understandable that they are even shorter on resources than the small devices targeted by J2ME CLDC. Besides, this technology must deal with an even more varied diversity than J2ME does, because the number and varieties of smart cards used in the world is much more than the number of cell phones or pagers. This is why it was developed as a separate platform and is difficult to merge with J2ME. Perhaps the difference that first strikes a Java programmer who is a newcomer to this technology is that the file system used is not the same as in the other Java technologies. Java Card does not use the class file format it uses a new format called the CAP (Converted APplet) file format. The Java Card system is made up of the following constituents:
14
The process involved in developing a card applet is as follows: First you write the applet on your desktop system, just as you write a normal applet or a MIDlet. After compiling it, you must test it by using a smart-card simulator. This step is similar to testing MIDlets on a cell-phone emulator. After you test and debug the applet, you are ready to install it on the device. For this, you first must create an export file that contains information about files being used by the applet. This is somewhat similar to creating jad files for MIDlets or MIDlet suites. The next step is to convert the class and export files to CAP files. This is done by the converter mentioned in the preceding list. The converter may also automatically create export files. Then you copy these files to a card terminal say, a PC to which a card reader is attached. The CAP files are loaded by an installation tool on the terminal, which then transfers the files to the device. Another installation tool on the device reads these files and brings them to a condition from which they can be run by the virtual machine. In other words, the virtual machine has lesser workload there is division of labor between the installer and the VM. This division of labor reduces the size of both and adds modularity to the system. For clear view of the process, refer to Figure 1-7.
Some other distinguishing features of the Java Card technology are as follows: Because smart cards almost always need some kind of authentication mechanism, very strong security is a must for this technology. This is partially achieved in Java by the verifier. Other methods may be used to further enhance security, but the Java Card specification leaves it to developers and users to enable flexibilty. There is also the provision of runtime environment security by techniques such as applet firewall. It basically isolates applets from one another. There is no support for dynamic class loading. To run applets on the card, you must mask them into the card during manufacturing or install them later as described previously. There is no security manager class in the Java Card API. Garbage collection and finalization are not possible in Java Card, nor are they required. Threads and cloning are also not supported. Access control is available, but some of the cases are not supported. The data types not supported are char, double, float, and long. The only numeric types supported are byte and short. The type int may be available in some implementations. Most of the Java core classes are not available in Java Card.
Summary
In this chapter, you are acquainted with J2ME and related technologies. We have tried to cover almost all related J2ME technologies available as of printing. J2ME is targeted for devices which are resource constrained; therefore, programming for these devices is also different from the programming done for desktop computers. Chapter 2 discusses the programming techniques involved for J2ME.
Chapter 2
18
capability to be always on the network, whether through a wire or without it. Generally, the throughput of an occasionally connected device is more than that of an always-available device. This is because the speed of basic serial connection is more than that of wireless communication. Speeds of both are, of course, increasing. Newer cradles that support Universal Serial Bus (USB) standard are faster, and the wireless communication is also becoming faster with the advent of Bluetooth and 3G. The bandwidth of the network to which these devices are connected is normally limited. This limits the communication speed, and applications running consume more resources. The latency rate is also high which affects the performance of the application running on these devices. Also associated with this is the issue of cost of communication, especially of the wireless kind. The networking hardware also contributes to the cost of the device and the load on the power source that is, the battery.
Input methods
Handheld devices may or may not have a full keyboard and may or may not have a pointing/selection device. As an example, the data-ready mobile phone has only the following (see Figures 2-1 and 2-2): The usual keys found on a telephone, such as the digits 0-9, #, *, with alphabets marked on 2-9 Arrow keys, may be just for up and down or left and right Some dedicated function keys or system keys One or more keys with programmable labels
In the future, work will be done to make voice recognition feasible on small devices. Still, voice recognition needs a lot of processing power and is available on some devices but only for voice dialing. Voice inputs are very limited in these devices and cant be a used as input devices. For this option to be used as a satisfactory input device, it needs a fare level of development and is in the processing stages. In the future, it may become the preferred input method for devices that cannot afford full keyboards.
Output methods
For most devices, the usual output method is a display screen (see Figure 2-3). It is nowhere near that of a PC in size. A typical display of a mobile device is capable of displaying 4-10 lines of text 12-20 characters wide and may be graphical (bitmapped) or text-only. At most, a small device (for example, a PDA) may have a screen that can display 20 lines of text. Apart from the size of the screen, these devices cannot display many fonts. Even simple bitmapped graphics cannot be taken for granted. Similar is the case with color support. A typical pager or a mobile rarely has color support. Even some PDAs do not have this capability (color support is given in Palm VII). This situation is set to change in a few years, and color capability will perhaps become the rule rather than the exception.
20
Some other simple output methods may also be used for denoting specific events or purposes. Indicator lights may alert the user about some hardware events such as network activity and power usage or software events such as message availability. These indicator lights can be programmed and can be controlled by an application. Similarly, audio signals such as beeps and rings can indicate various hardware and software events. If the device has the capability, messages or music can be played back and voices can be synthesized. The vibrating battery of a mobile phone is also an output method. Infrared ports are also one way of communication between these devices where the communication takes place through infrared rays. For example, as soon as a device comes near another device, it may communicate with the second device by using infrared rays. The communication involves both input and output.
The importance of form factor is not limited to the characteristics it refers to. It also influences the choice of input and output methods. Input methods such as keyboards and output methods such as display screens are dependent on the form factor. The type, size, and location of batteries also depend on the form factor. A device that needs to be thin and light may have to be designed with rechargeable batteries. Hardware needed for various purposes such as wireless communication may affect the form factor. So, before starting to write applications for a small device, it is useful to consider how this factor affects your application.
Symbian/EPOC
In mid 1998, Nokia, Ericsson, Motorola and Psion Software teamed up to form Symbian for developing the software and hardware standards for the next generation of wireless smart phones and terminals. The
22
operating system for Symbian is EPOC, which has already been developed and incorporated into palmtop computers such as the Psion Series 5. Industry leaders such as Sony, Sun, Philips and NTT DoCoMo have joined the Symbian alliance and licensed EPOC.
Palm OS
Palm holds about three quarters of the global handheld computing market. Major Palm partners include IBM which developed WorkPad PC. Other Palm OS (Operating System) licensees include Handspring, OmniSky, and Nokia. You can develop J2ME applications for Palm using CLDC and Kjava APIs. Refer to Chapter 3 wherein we develop some case studies for Palm OS.
Make your applications small: Besides conserving runtime memory, you have to keep the size of your application in accordance with the storage available. To achieve this, you can package your application in the form of a JAR archive. Other tools that remove unnecessary information from a file may also be used to cut down the size of the application. Use of scalar types: Whenever you declare an object, it is allocated space on the runtime heap. To reduce consumption of runtime memory, try to declare as few objects as possible. This can be achieved by using scalar types such as int, short, and so on in place of object declaration. Do not hold on to resources when not needed: Resources such as files, network connections, and so on should not be kept up when they are not in use. Perform necessary cleanup operations yourself (such as assigning null value to objects when they are no longer needed) rather than depending on the garbage collector or the host environment. Recycle objects: Once an object has been declared, it occupies some space on the runtime memory. Thus, if you can recycle some of your objects, you save on this space. Allocate objects as and when needed: This can reduce the load on memory. To use this technique, you have to check whether the object reference is null or not. Avoid creating objects inside loops: If you create objects inside a loop, a new object will be created for every iteration of the loop, and it will have memory reserved for it. This will thus cause wastage of memory space for limited memory devices, since most of these objects are not going to be used later and will be out of scope. Moreover, the garbage collector will spend time and resources in dealing with these objects. To avoid these, you can first create an array and then loop through the indices of this array. In fact, this technique can be used for other kinds of optimizations, too. For example, you can try to avoid calling a method inside a loop. Check the memory usage: Before concluding that everything possible has been done to conserve memory, it would definitely help if there were a way to find out how much total memory is being actually used and how much of it is being used by a particular object. There is a procedure for this. The class java.lang.Runtime has methods freeMemory and totalMemory. The method freeMemory can be used to find out how much memory is presently free. The memory is measured in bytes. The method totalMemory, as you can guess, returns the amount of total memory available. To find the memory used by an object, you can use the freeMemory method before and after the object is instantiated. Then you just have to find the difference between the two values returned. One more method of use in this regard is the currentTimeMillis in java.lang.System class that gives you the time taken to execute a method. Like the
24
called. Catch the OutMemoryError: If after all of the previous, the system runs out of memory, you should ensure that your application has an exit route available if the problem cannot be solved. You might be able to resolve such a crisis by releasing resources, but if you cant, at least show the user a message and allow the application to be closed. Manage this yourself instead of leaving it to the operating system.
26
color is supported by the device. The color model used in these classes is a 24-bit model. There are 8 bits each for colors red, green, and blue. Of course, not every device can render such variety of colors on the display. This means that mapping of requested colors to available colors will occur, that is, if an application uses colors that a device doesnt support, the device will map to those colors that are supported by the device. You can display fairly good-looking images on small devices by using the low-level APIs. This can be done by using the drawImage method of the Graphics class. It has the following signature:
public void drawImage(Image img, int x, int y, int anchor);
The last parameter refers to anchor points used in several of the GUI classes. These are used to ensure that the processing needed to position an object properly on the display is reduced. Another feature in these APIs that can be of much help in improving the look of your application is the Font class. The letters used on small devices are usually displayed with the same font. You certainly dont get the variety you can have on a desktop, but at least you can select one out of a few choices. The number may increase in the future. You can also specify the style and size of the font, in addition to its face name. A Font object is created in the following way:
Font myFont = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_ITALIC, FONT.SIZESMALL);
The three parameters are the face, style, and size, respectively.
Summary
After completing this chapter, the reader should be acquainted with the techniques involved in programming for J2ME. These considerations in this chapter are important and should be taken into account while programming for J2ME to develop a quality software for resource constrained devices. In Chapter 3, we will start programming in CLDC and Kjava used for Palm application development. We will discuss the APIs and implement them with some case studies.
Although this chapter is on CLDC, we also take up the Kjava API, which is used to enable CLDC on a Palm device. The Kjava API has some extra functionality for adding user interface components to J2ME applications. This API may be absent in future releases of CLDC. It is a temporary arrangement by Sun Microsystems to allow development and testing of CLDC applications. CLDC specification 1.0 lays down the guidelines to which any implementation of CLDC has to adhere. Sun has developed its own reference implementation of this configuration, but vendors are free to provide their own. In this chapter, we take up only Suns implementation. It can be downloaded for free from www.sun.com/software/communitysource/j2me/. Version 1.0 of the reference implementation provided by Sun can be run as is here on Windows and Solaris platforms. You can also run it on Palm devices, but for that you will have to download a Palm overlay and unzip it into the directory in which CLDC is installed. A newer version of CLDC, numbered 1.0.2, is available for Linux as well, in addition to Windows and Solaris. The CLDC API consists of only four packages: java.io, java.lang, java.util, and javax.microedition.io. The first three are subsets of similar packages in J2SE and are covered very briefly. The fourth package is new and is unique to the micro edition.
Core Packages
The three core packages in the CLDC implementation are discussed in this section.
java.lang package
This package has the classes that are fundamental to the Java language. These classes define the data types, basic exceptions, and so on. Many classes that are not required in J2ME are absent. Two interfaces Cloneable and Comparable are not included. Some classes, such as those for Float and Double data types, are absent. There is no ClassLoader. Several exceptions present in J2SE, such as NoSuchFieldException, are not there in CLDC. The interfaces, classes, and exceptions that are part of the CLDC and thus define the Java language in Java 2 Micro Edition platform are listed in the section, Brief introduction to commonly used packages.
java.io package
This package for providing data input and output through data streams has two interfaces (DataInput and DataOutput) and several input and output stream as well as reader and writer classes, similar to the Java 2 Standard Edition. In addition, there are several I/O exceptions. Because of the limited input/output capabilities of the mobile devices, this package provides limited functionality as compared to the java.io package in Java Standard Edition. Most of the classes are absent in this package. For data input and output, you dont have the option of using serialization or file systems. Whatever is present is used in almost the same way as in the standard edition.
28
java.util package
This package contains the utility classes for such things as generating random numbers, creating time zone objects, implementing growable array of objects, enumeration, and so on. As compared to the Java 2 Standard Edition, J2ME has only seven classes and one interface left.
30
The syntax for using these classes is the same as in J2SE, but since some of the constructors are absent, they cant be used. For example, you will still use the StringBuffer class as:
StringBuffer sb = new StringBuffer(5); // Declares a StringBuffer with // no characters and an initial capacitiy of 5 characters.
32
Class Connector
Class connector is the only class in the package and is used to open a connection with the open method. The parameter string describing the target conforms to the URL format as described in RFC 2396. This takes the general form:
{scheme}:[{target}][{params}]
Where {scheme} is the name of a protocol such as http, {target} is the name of the target device to which the connection is to be made. Similarly, {param} are the parameters required to establish the connection. The methods available are listed below:
open openDataInputStream openDataOutputStream openInputStream openOutputStream
The following code block shows how this class and its methods can be used:
InputStream input; Input = Connector.openInputStream(testhttp://www.s-cop.com/userlist.asp);
This code block opens a socket connection to a URL named 127.0.0.1 at a port 7070. Read/write access is provided to the client. Input/output streams are also obtained from the connection using the methods of the interface StreamConnection (openInputStream and openOutputStream). These methods return streams which are used for communication.
Kjava API
This API, which is composed of the com.sun.kjava package, is officially not part of the CLDC but has been included with the reference implementation release of CLDC to allow development and testing of CLDC applications. CLDC doesnt have any user interface classes. This is where Kjava comes in. It has the GUI classes such as Bitmap, TextField, and so on, which make development of interactive applications possible (to view all the classes with the hierarchy structure refer to Figure 3-6 and Figure 37). But it should be noted that this is only a stopgap arrangement. It may change in future releases or may be absent altogether. Remember that adding GUI components is something that is supposed to be done with a profile, at least in case of CLDC. When you want to actually deploy your applications, you may have to substitute the Kjava GUI components with those of a profile, such as the PDA profile when it is available (it is under development at present).
34
Very recently, Sun Microsystems has come up with MIDP for Palm. This means that if you want to use CLDC on Palm, you can do so by using MIDP for Palm. In that case, Kjava will no longer be needed. If we are still including Kjava in this chapter, it is because it is included in the CLDC release. Moreover, MIDP has some extra functionality in addition to having the GUI classes. The GUI classes, too, are more advanced than in Kjava. Therefore, in our opinion, if you want to get an idea of how CLDC works, first try your hand on CLDC with Kjava. When you have explored it enough, you can move on to MIDP. In this section, we briefly explain the GUI classes provided in the Kjava package. Kjava includes the following classes:
Spotlet Graphics HelpDisplay TextBox TextField Button
36
Spotlet
All applications made using CLDC and Kjava have to extend this class. This is the only way you can make an executable application unless you decide to use MIDP. The application you write can consist of more than one spotlet, but only one spotlet can be activated at one time. This class is used for event handling callbacks, registering the application, and so on. Registering means giving focus to the spotlet. And only the spotlet with focus will have callbacks.
public class First extends Spotlet { First() { register(NO_EVENT_OPTIONS); } public void penDown(int x, int y) { // Handling the pen strokes } public void keyDown(int x, int y) { // Handling the key pressed } }
In the preceding code block, the application named First is declared. It is inherited from the class Spotlet, so, therefore, it has to extend this class. It is registered with NO_EVENT_OPTION, which means the spotlet is made current and will not be unregistered on pressing normal keys. However, if the system keys (five keys for Palm devices) are pressed, then the spotlet is unregistered. The system keys are the five keys through which the Palm device is being operated. The five keys are used to invoke different applications in the Palm device and there are two additional keys for up and
Graphics
This is the basic class used to draw objects on the display, almost in the same way as in the standard edition. For drawing the object, it uses the following methods:
getGraphics drawLine drawRectangle drawBorder borderType drawString setDrawRegion resetDrawRegion copyRegion copyOffScreenRegion clearScreen drawBitmap playSound
Use of some of these methods is shown below with code examples. First, we look at initialization of a variable of the Graphics class and at clearing the drawing region by calling the appropriate functions of the Graphics class, namely resetDrawRegion() and clearScreen():
graphics = Graphics.getGraphics(); graphics.resetDrawRegion(); graphics.clearScreen();
If you want to display a String (the title of the graphic) at a specified position, you can use the drawString method of the Graphics class:
graphics.drawString("Target Practice",35,10);
And to draw a circle, you can use the same method with the corner radius parameter equal to half the squares width:
graphics.drawRectangle(initial_position_bullet,72,4,4,Graphics.GRAY,2);
Button
No need to explain this class. Just have a look at the following code:
// Declaring button variables. private Button play; ...
38
/* * Initializing the button object play, placing it on the screen * at the appropriate position and then painting (drawing it). */ play = new Button("Play Now",10,140); play.paint();
For event handling of this button, the code will look like this:
public void penDown(int x, int y) { if(play.pressed(x,y)) { // Write your code here. } }
TextField
Now we consider how the class TextField can be used. It, too, is similar in use to the TextField class in J2SE:
// Declaration of a TextField named choicefield private TextField choicefield;
After declaring the TextField, we initialize it with proper parameters. These parameters specify the String label for the TextField, its position in terms of coordinates, and its width and height. To allow the text to be entered in only the uppercase, we have to call the setUpperCase method with the parameter true. Next we give it the focus by calling the setFocus method:
choicefield = new TextField("Option:",10,145,50,10); choicefield.setUpperCase(true); choicefield.setFocus();
To make the TextField visible on the screen, we use the paint method, as in J2SE:
choicefield.paint();
Now we determine whether the TextField has the focus or not. If it has, we call the handleKeyDown method, which in turn calls spotlets keyDown method:
if(choicefield.hasFocus()) { choicefield.handleKeyDown(x); }
Finally, after the user has completed entering text, we remove the focus from the TextField the loseFocus method. We also remove the caret by using the killCaret method:
choicefield.loseFocus(); choicefield.killCaret();
by calling
Now we initialize the RadioButton objects simple and difficult, placing them on the screen at the appropriate positions and then drawing them:
simple = new RadioButton(85,45,"Simple"); // Initially this button is to be kept selected. Therefore, a method // setState is called, which is passed a parameter true, which will take //care of this. simple.setState(true); simple.paint(); /** * Initializing the RadioButton object Difficult, placing it * on the screen at the appropriate position and then drawing it. */ difficult = new RadioButton(85,60,"Difficult"); difficult.paint();
The radio buttons have to be added to the RadioButton group, so that only one of the buttons will be selected at a particular instant of time:
level.add(simple); level.add(difficult);
If a radio button is selected, the appropriate variable associated with that radio button is assigned that value. For example, if the radio button of the label Simple is selected, then the variable label_information is given the value simple. This is done by calling the method handlePenDown:
else if (simple.pressed(x,y)) { level_information = "simple"; simple.handlePenDown(x,y); } else if (difficult.pressed(x,y)) { level_information = "difficult"; difficult.handlePenDown(x,y); }
HelpDisplay
The class HelpDisplay is provided in Kjava to give the user some information about how to use the application or to display simple text for whatever purpose the developer thinks this class can be used. The following code initializes a HelpDisplay object with parameters being the text to be shown, the class to be called, and event options:
// Call to the class HelpDisplay to display the help text. (new HelpDisplay(helpText,"TargetPractice", NO_EVENT_OPTIONS)).register(NO_EVENT_OPTIONS);
ScrollTextBox
If the text that the user enters does not fit in the display area, you will have to use the ScrollTextBox. We show here an example of declaring and then initializing a ScrollTextBox named first. The
40
parameters supplied are the initial text, the position in terms of coordinates, and the size (width and height):
private ScrollTextBox first; // initializing the ScrollText Box.. first = new ScrollTextBox(textx,0,0,150,140); first.paint();
Now we define handling for the event that occurs when the user places the pen on the display. It is similar to clicking the mouse on a PC. The difference is that we are using the penDown method:
public void penDown(int x, int y) { if (first.contains(x,y)) first.handlePenMove(x,y); }
Similarly, we define event handling for movement of the stylus, just as we do for movement of mouse. We will be using the penMove method here:
public void penMove(int x, int y) { if (first.contains(x,y)) first.handlePenMove(x,y); }
Database
If you want to develop any nontrivial application, you cant avoid using some form of database. The problem is that CLDC had to have a very small footprint and the devices also dont have much space for databases. So, some optimal method of using very limited functionality databases has to be used. This is why Kjava has a class called Database that just acts as an interface with the database manager on the Palm OS. We show here the way to use this class:
// Declaration Database dbg; // Initializing the Database by creating the name of the // Database, the creator id(cid) and the table id(tid).. String nameing = "data_base"; int cid = 0x4B415754; int tid = 0x44425370; dbg = new Database (tid,cid,Database.READWRITE); // Creating the Database... Database.create(0,nameing,cid,tid,false); } // end Constructor..
As you can see, a Database object is first declared and then initialized with table id (tid), creator id (cid) and the mode as the parameters. The mode is set to READWRITE so as to allow both reading from and writing to the database. The database is actually created by calling the create method. This method takes the following parameters: int cardNo: the card number java.lang.String name: name of the database int cID: creator ID int tID: table ID boolean resDB To set the content of the database, we use the method setRecord:
And to read a database record into a byte array, we use the getRecord method:
byte[] data = dbg.getRecord(1);
The method for adding a record to the database is, predictably, addRecord.
TextBox
This class serves a similar purpose as the TextField class, but you will prefer it when you want the text in it to look graceful even when the width of the text is more than the display area. This is because a TextBox will not break words. The text will not be wrapped to the following lines. Following is a code block showing the use of this class:
TextBox Text; Text = new TextBox(Text To be Displayed,10,10,120,120); Text.paint();
Installation of CLDC
When you download the CLDC reference implementation from Suns site, you get a ZIP archive that can run on Windows, Solaris, and Linux. To install it, you just have to unzip the archive into any directory of your choice. There is no setup program. But you should have JDK installed on your computer before you try to run CLDC applications. Version 1.0 of CLDC was available in one archive, which also has non-CLDC classes in the com.sun.kjava package. With this, you could develop and test applications on your desktop system. But if you needed to run these applications on a Palm device, you had to install a Palm overlay that was available in a separate archive. In the new 1.02 version, the Kjava API has been taken out of the CLDC archive and is added to the Palm overlay. In other words, now you have to download both CLDC and the Palm overlay, even if you have to run applications only on the desktop system. For installing version 1.02, you first unzip the CLDC in any directory and then unzip the Kjava overlay in the j2me_cldc directory that was created while you were unzipping the CLDC archive. Note that you have to unzip with the overwrite option selected. The CLDC archive and the Kjava overlay include the following: Compiled CLDC and non-CLDC (Kjava) classes in the bin\api directory. KVM interpreter and preverification tool (in the bin directory) and their complete source code (in the tools\preverifier directories). Complete documentation for all the classes (both CLDC and non-CLDC) in HTML format as well as PDF format. The release notes and the CLDC 1.02 specification are also included. Source code for Java Application Manager (JAM) and JavaCodeCompact (JCC) tool. A sample implementation of the application management software is included. The source code of the KDWP Debug Proxy (also known as Debug Agent) implementation in the tools\kdp directory. It is a tool that can be interposed between a Java development environment (such as Forte) and the KVM. Sample applications in the samples and bin\samples directories. This reference implementation of the CLDC is meant for device manufacturers, developers, or those who want to port the KVM to a platform other than Windows, Solaris, Palm, or Linux. It includes all that is needed to build the complete reference implementation on Windows, Solaris, Palm, or Linux. Some parts
42
of the KVM are optional, and if you are ambitious enough, you can compile your own KVM to experiment with various optional features.
Compiling
On Windows platform, the command used to compile an application is:
javac g:none bootclasspath %cldc_root%\bin\common\api\classes -classpath %cldc_classpath% -d %classfile_dir% %1%.java
The options used in the preceding command are: -g:none: For no debugging information. If you want debugging information, you can use just g or g:{lines,vars,source}. -bootclasspath: For overriding the location of bootstrap class files. %cldc_root%\bin\api\classes: The directory where CLDC class libraries are located. If you use %cldc_root%, you will have to give a command line argument for this directory. You may avoid this by giving the full path where you unzipped the CLDC libraries. -classpath: For giving the path to the user class files. %cldc_classpath%: The location of the user class files. Again, you may avoid giving the command line argument by giving the full path. If you want to use files from more than one directory, they can be specified by separating them with semicolons. -d: For specifying the directory where you want to store your compiled class files. %classfile_dir%: The location of the compiled class files. You may give the full path or use command line argument. %1%.java: The file(s) you want to compile.
Preverifying
After compiling, you can preverify the compiled class files by using the following command:
%cldc_root%\bin\win32\preverify d %preverified_dir% -classpath %cldc_classpath%;%cldc_root%\bin\common\api\classes %classfile_dir%
Needless to say, this and the other commands that follow have to each be entered as a single line on the console. The options used in this command are explained here: %cldc_root%\bin\win32\preverify: This is the command for the preverify tool, along with the directory in which it is located. Instead of using command line argument, as here, you can give the absolute path. -d: The option to use if you want the preverified files to be stored in a particular directory. %preverified_dir%: The directory in which preverified class files are to stored. It is recommended that you make it the same as that for compiled files. %classfile_dir%: The directory where the compiled class files are located.
Explanations of the options are given here: %cldc_root%\bin\win32\kvm: The command to run the KVM along with the path where KVM is located. -classpath: The option for specifying the location of preverified files. %1%: The main class file that you want to run.
Note that all these commands are for CLDC version 1.0. For version 1.02, you will have to add to the classpath the directory where Kjava libraries are stored.
Case Studies
Now that we have become familiar with the CLDC API and the new classes, and so on, in it, we can try our hands at programming with this basic constituent of the J2ME platform. In this section, we are going to practically use some of the important CLDC classes to do some routine tasks such as building parts of the user interface. Since CLDC by itself doesnt have much functionality, we will use it along with the Palm overlay that is, the Kjava API to demonstrate how CLDC can be used. This will be done with the help of some case studies. Each of these case studies is aimed at performing some common programming task. These case studies are in the form of spotlets, which can be compiled and run to see the results. The concept of spotlet is introduced in the com.sun.kjava package, of which the former is a class.
TextField_Spotlet
In any interactive application, one of the most basic requirements is that the user should be able to enter text. This can be met by providing a text box in which the user clicks and starts typing. We provide such a text box in this case study. After entering the text, the user clicks the button labeled OK and is shown the text entered. Of course, typing and clicking may not really be the actions an actual user will perform, because PDAs dont usually have a mouse and a keyboard. But whatever the pointing and text entering mechanism, the logic remains the same.
44
Since we are using the Palm overlay, we have to import the com.sun.kjava package. A text field is declared using the TextField class of Kjava. As you can see, the drawing part is similar to an applet everything is finally put on the screen using the paint method. Note the use of register method of the spotlet class, which makes the spotlet the focus of event handling. Other methods from the Kjava API are penDown and keyDown, which are for clicking and typing, respectively. They belong to the spotlet class. Methods like setFocus, setUpperCase, pressed, and so on, belong to the TextField class. To see the output, refer to Figure 3-8.
24) 25) 26) 27) } 28) 29) public void penDown(int x, int y) { // Handling events... 30) if(ok_button.pressed(x,y)) { 31) gr.drawString("User Entered..",30,130); 32) gr.drawString(tf_textfield.getText() + " ", 95,130); 33) } 34) } 35) 36) public void keyDown(int x) { 37) if(tf_textfield.hasFocus()){ 38) tf_textfield.handleKeyDown(x); 39) } 40) } 41) 42) public static void main(String args[]) { 43)// Call to the main function... 44) new TextField_Spotlet(); 45) } 46)}
ScrollTextBox_Spotlet
The next spotlet shows a list of items, which are too numerous to fit within the display screen. We provide a scroll bar to allow the user to see all the items. When the user presses the OK button, the application is closed. This is done by using the ScrollTextBox class of the Kjava API. Note that the penDown method is still there, but instead of keyDown, we have to use the penMove method. We have used here the pressed, handlePenDown, and handlePenMove methods of the ScrollTextBox class. To see the output, refer to Figure 3-9.
46
HelpDisplay_Spotlet
Users who get your applications may not be sure how to use them. Even simple applications have to provide some sort of help for new users. In the case of fast-evolving small devices, which run fasterevolving applications, providing a Help feature is even more relevant. This spotlet illustrates how you can add instructions for using your application. For this, you simply use the HelpDisplay class. The user is shown some Help text, and when he presses the Done button, he is returned to the screen from which he asked for help. To see the output, refer to Figure 3-10 and Figure 3-11.
48
CheckRadio_Spotlet
The capability of the user to make choices from a given list is another part of an interactive application. Two ways of doing this are through radio buttons (for selecting only one element) and check boxes (for making more than one choice). This spotlet shows how this can be done with CLDC and Kjava. The user is shown four radio buttons, out of which he has to choose one. Two check boxes are also shown, out of which one or both can be selected. On pressing the OK button, the choices made by the user are displayed. Note the use of the if statement for controlling event handling. To see the output, refer to Figure 3-12.
50
52
99) } 100) 101 public static void main(String args[]){ 102) new CheckRadio_Spotlet(); 103) } 104)}
HttpCheck_Spotlet
Any device that is to be connected to a network should be able to access files from another system on that network. The most common way of doing this is presently through an HTTP connection. Any J2ME application you make for a PDA may have to use files placed on a Web server. In CLDC, this is done by using the Connector class. This is the class that holds the methods used to create all connection objects. Here we first create a text file called check1.txt and place it on a server. The user is shown a scroll text box and a button labeled Fetch. When the user presses this button, the contents of the file are displayed in the scroll text box. The file on the server is fetched with the help of OpenDataInputStream method of the Connector class. It takes the URL of the file to be fetched as the argument. Since the connection framework of CLDC is still in the development stage, you have to use test as the prefix before the actual URL of the file. To see the output, refer to Figures 3-13 and 3-14.
54
24) public httpcheck_spotlet(){ 25) register(NO_EVENT_OPTIONS); 26) gr.clearScreen(); 27) gr.drawString("Http Check.....",30,10); 28) bt.paint(); 29) fetch.paint(); 30) gr.drawRectangle(0,30,160,80,0,1); 31) String temp = "Here the result of Http Connection will 32) be Displayed..."; 33) 34)// Initailizing the scroll text box with string temp... 35) stb = new ScrollTextBox(temp,1,30,130,100); 36) stb.paint(); 37) try { 38) dos = 39)Connector.openDataInputStream("testhttp:// 40) 127.0.0.1/check1.txt"); 41) } 42) catch (IOException e) { 43) } 44) } 45) 46) public void penDown(int x, int y) { // Handling the events... 47) if(bt.pressed(x,y)) { 48) try { 49) dos.close(); 50) } 51) catch (IOException e) { 52) System.out.println( e ); 53) } 54) System.exit(0); 55) } 56) 57) if (fetch.pressed(x,y)) { 58) int count; 59) int total = 0; 60) try { 61) while ((count = dos.read(b,0,32)) > 0) { 62) for (int i = 0;i<count;i++) { 63) c[total] = b[i]; 64) total++; 65) } 66) } 67) } 68) catch (IOException e) { 69) } 70) 71) String str = new String(c, 0 ,total); 72) stb = new ScrollTextBox(str,1,30,130,100); 73) stb.paint(); 74) } 75) 76) if (stb.contains(x,y)) 77) stb.handlePenDown(x,y);
Server
The data on a device such as a PDA needs to be frequently synchronized with the data on a desktop or server system. For this, you need a listener on the desktop or server system, which will respond to the request from the client that is, the PDA. This is not a J2ME application, but we have used it because, without it, the next spotlet cant be run. You can see that the java.net package has been imported, which is a part of the standard edition.
Socket_Check
Another way of transferring data from one device to another is through socket connections. In this case study, we give an example of how this can be done. The user is given a text field in which he enters some text. On pressing the OK button, the contents of the text field are transferred via the socket connection to a server socket. The server reads the text and responds to the client socket. A message is shown
56
indicating that the connection has been established. Whatever the user types in the text field is redirected to the client and is shown on the screen. We open the socket connection by using the StreamConnection interface of the javax.microedition.io package. You can also see the use of many other CLDC classes and methods in this spotlet. To run this spotlet, first make sure that your Server.class class file is not in the folder in which you have the Socket_Check.class file (because when you preverify the application you will get an error as the Server.class is a Java Standard Edition program). You then have to start the server by typing java server at the command prompt. On pressing the Exit button, both the spotlet and the server are closed. To see the output, refer to Figures 3-15 and 3-16.
58
28) Graphics gr = Graphics.getGraphics(); 29) 30) public socket_check(){ 31) register(NO_EVENT_OPTIONS); 32) gr.clearScreen(); 33) gr.drawString("Socket Check...",30,10); 34) bt.paint(); 35) bt1.paint(); 36) gr.drawRectangle(0,20,160,80,0,1); 37) tf.setUpperCase(true); 38) tf.setFocus(); 39) tf.paint(); 40) 41)// Initializing the socket connections 42) try { 43) socket = (StreamConnection)Connector.open( 44) "socket://127.0.0.1:5555", 45) Connector.READ_WRITE, true); 46) if (socket != null) { 47) System.out.println("Connection is established to 49) localhost on port 5555..."); 50) } 51) 52)// Opening the input and output streams... 53) is = socket.openInputStream(); 54) os = socket.openOutputStream(); 55) } 56) catch(IOException ae) { 57) System.out.println("Couldn't open socket 58) to 59) 127.0.0.1 :5555... Either server is not 60) started 61) (start it from ../serverforsocket/ 62) using the 63) command java server ) or port is 64) already in 65) use.... " ); 66) System.exit(0); 67) } 68) } 69) 70) public void penDown(int x, int y) { 71) if(bt.pressed(x,y)) { 72) try { 73) os.write((tf.getText()+"\n").getBytes()); 74) StringBuffer sb = new StringBuffer(); 75) 76) int b; 77) while ((b=is.read()) != 13) { 78) sb.append((char)b); 79) } 80) 81) 82) 83) 84) 85) 86) gr.drawString(sb.toString(), 55,50); sb.delete(0,sb.capacity()); } catch (IOException aer) { System.out.println(aer); } }
No practical interactive application can avoid using databases. This final spotlet of the chapter shows how databases can be created and accessed by using CLDC. Strictly speaking, we are adding database functionality by using not just CLDC, but the Kjava API. This is because CLDC in itself doesnt have database functionality. This spotlet faces a problem. Although a database is being created and accessed successfully, when you try to add a new record to the database, it overwrites the existing record, even when you use the addRecord method of the Database class. We find a way around this problem in the project on CLDC later in the book in Chapter 6.To see the output, refer to Figures 3-17 and 3-18.
60
40) 41) 42) 43) tf_textfield.paint(); 44) tf1_textfield.paint(); 45) 46)// Database initialization..... 47) String name = "check"; 48) int cid = 0x4B415754; 49) int tid = 0x44425370; 50) 51) dbg = new Database 52) 52) (tid,cid,Database.READWRITE); 53) 54) if (dbg.isOpen()){ 55) Database.create(0,name,cid,tid,false); 56) } 57) else { 58) Database.create(0,name,cid,tid,false); 59) } 60) } 61) 62) public void penDown(int x, int y) { 63) 64)// Handling events... 65) if(ok_button.pressed(x,y)) { 66) byte[] data = 67) (tf_textfield.getText()+"?").getBytes(); 68) dbg.addRecord(data); 69) } 70) if(get_button.pressed(x,y)) { 71) byte[] data = dbg.getRecord(65535); 72) String temp = new String(data); 73) temp = 74) temp.substring(0,temp.indexOf("?")); 75) tf1_textfield.setText(temp); 76) } 77) } 78) 79) public void keyDown(int x) { 80) if(tf_textfield.hasFocus()){ 81) tf_textfield.handleKeyDown(x); 82) } 83) } 84) 85) public static void main(String args[]){
62
Summary
This chapter gives you a feel for programming mobile devices and the restrictions in terms of resources for mobile devices. This chapter is groundwork for the next chapter in the book as we have six unique projects in this book. One should be well conversant with the APIs before going on to these chapters. Chapter 4 concentrates on MIDP. Its an important chapter as we have two MIDP-based projects in this chapter.
Chapter 4
64
To solve these problems, MIDP uses an application model based on MIDlets. These MIDlets are somewhat similar to applets. Every MIDP application is a MIDlet, and every MIDlet extends the class javax.microedition.midlet.MIDlet. Also, like an applet, it has to necessarily implement some methods. These methods are startApp, pauseApp, and destroyApp. As you can guess from their names, they are meant to allow the application management software to manage the lifecycle of the MIDlet. A MIDlet, during its lifecycle, can be in any of the following states (usually in the same order): Loaded: Occurs when the MIDlet has been created using the new keyword. This state can occur only once per instance of a MIDlet. In case of an exception, the MIDlet is destroyed. Paused: Occurs when the MIDlet has been initialized but is not holding any shared resources. Active: Occurs after it has been initialized and is functioning normally. This state is entered into after the paused state. Destroyed: Occurs when the MIDlet is destroyed and all the resources are released.
MIDlet Suites
Just as J2SE classes can be packaged together into a single JAR file, so, too, can MIDlets. When this is done, the JAR file is called a MIDlet suite. A MIDlet suite is created if the MIDlets need to share code or data. The MIDlets in the suite can share the resources in the JAR file, i.e., it can call another MIDlet in the JAR file. Moreover, MIDlets in different suites cannot interact directly. This provides security around the MIDlet suite instead of around each MIDlet. The name, version, and creator of the MIDlet suite are all identified by entries in the manifest. These entries also describe the minimum configuration and profile versions required. The following are the MIDlet manifest attributes: MicroEdition-Configuration: The name and version of the J2ME configuration required to run the MIDlet suite. (Optional) MicroEdition-Profile: The name and version of the J2ME profile required to run the MIDlet suite. (Compulsory) MIDlets: The name, icon, and main class of each MIDlet in the suite. (Compulsory) MIDlet-Data-Size: The minimum number of bytes of persistent storage that the MIDlet requires to run. The default is zero. (Optional) MIDlet-Description: A description of the MIDlet suite. (Optional) MIDlet-Icon: The path of PNG file within the JAR file, used by the application management software to identify the MIDlet suite. (Optional) MIDlet-Info-URL: A URL describing the MIDlet suite in detail. (Optional) MIDlet-Name: The name of the MIDlet suite. (Compulsory) MIDlet-Vendor: The vendor of the suite. (Compulsory) MIDlet-Version: The version number of the suite in the format XX.YY or XX.YY.ZZ. (Compulsory)
MIDP API
The MIDP API consists of the following packages: Core packages (java.io, java.lang, java.util): These form the base on which CLDC and MIDP stand. javax.microedition.lcdui: A User Interface API for Mobile Information Devices such as cell phones.
To get a better idea of the use of this class and its methods, look at the following code that represents a skeleton MIDP application:
import javax.microedition.midlet.*; import javax.microedition.lcdui.*; /** * Skeleton Application illustrating the use of MIDlet Class.. */ public class first extends MIDlet implements CommandListener { private Command quit; // The Quit button private Display ourDisplay; // Declaring the display // Initialize the Display and place system controls in the Constructor..
66
public first() { ourDisplay = Display.getDisplay(this); quit = new Command("Quit", Command.SCREEN, 2); } /** * Initialize all the classes to be used in the program here (startApp()).. */ public void startApp() { ... ... }
// If the Application needs to be paused temporarily. public void pauseApp() { ... ... } // Clean up when the application is destroyed.. public void destroyApp(boolean unconditional) { ... ... } // Event handling routine.. public void commandAction(Command c, Displayable s) { if (c == quit) // If Quit button is pressed.. { notifyDestroyed(); // Call the destroyApp method.. } } }
We will be explaining the more commonly used among these in this section.
Interface CommandListener
In MIDP, event handling is based on the listener model. Every Displayable object needs one (and only one) listener. CommandListener is a listener for high-level events. Like other listeners, it is registered using the method Displayable.setCommandListener. It has only one method called commandAction, which we have used in the following code block:
68
// Implementing the interface... public class TextFieldCheck extends MIDlet implements CommandListener { // Declaring Buttons and initializing them to null... Command ok = null; Command quit = null; // Handling the event. public void commandAction(Command c, Displayable d) { // Event handling for the Button if ( c == ok ) { // Code for tasks to be done on OK button press... } if ( c == quit ) { // Code for tasks to be done on Quit button press... } }
Alert Class
This class is used to show a message, warning, or other information to the user for a specified period of time or until the user cancels it. It can contain strings, images, etc., and can also handle events, like any other screen. The methods available for this class are:
getDefaultTimeout getTimeout setTimeout appendString appendImage appendItem insertItem deleteItem
Following is a code block showing the use of Alert class and some of its methods:
// // // // // // Popping an Alert... Parameters.. 1. Title of the Alert.. 2. Text of Alert. 3. Image if required. 4 Type of Alert (INFO, WARNING,ERROR, CONFIRMATION, ALARM).
Alert alert = new Alert (Warning, You have entered Wrong serial number, null, AlertType.WARNING); // Making this alert a Modal alert.. alert.setTimeout(Alert.FOREVER); // or else... // Making this alert disappear after certain milliseconds.. alert.setTimeout(10);
ChoiceGroup Class
This class provides us a way of adding UI components that may be selected by the user. It is possible to create components that can be selected, either one or more at a time. In other words, both radio buttons and check boxes can be created using this class. Which one will be created depends on the value of the choiceType parameter. If it is EXCLUSIVE, we will get check boxes, and if it is MULTIPLE, we will have radio buttons. The methods provided for this class are implementations of methods in the interface Choice:
appendElement(String stringElement, Image imageElement) deleteElement(int index) getImage(int i) getSelectedFlags(boolean[] selectedArray_return) getSelectedIndex() getSize() getString(int i) insertElement(int index, String stringElement, Image imageElement) isSelected(int index) setElement(int index, String stringElement, Image imageElement) setSelectedFlags(boolean[] selectedArray) setSelectedIndex(int index, boolean selected)
Let us look at the use of this class for creating radio buttons:
// Declaring Form and ChoiceGroup objects and initializing them to null... Form ui_holder = null; ChoiceGroup radiobutton_type = null; String[] name = {"a","b","c"}; Image[] img = null; // // // // // Initialize the ChoiceGroup.. Parameter 1 --Title Parameter 2 --Type of ChoiceGroup (Exclusive for RadioButtons) Parameter 3 --Label of the radio buttons displayed Parameter 4 --Images for the radio button label if required
radiobutton_type = new ChoiceGroup("Choices..",ChoiceGroup.EXCLUSIVE,name,img); // Adding the ChoiceGroup to the Form... ui_holder.append(radiobutton_type); // Event Handling.. // To get the String of the selected radio button... radiobutton_type.getString(radiobutton_type.getSelectedIndex());
Now we create a group of check boxes with the same class, just changing the choiceType parameter:
// Declaring Form and ChoiceGroup objects and initializing them to null... Form ui_holder = null; ChoiceGroup checkbox_type = null;
70
String[] name1 = {"d","e","f"}; Image[] img = null; checkbox_type = new ChoiceGroup("Choices..",ChoiceGroup.MULTIPLE,name1,img); ui_holder.append(checkbox_type); checkbox_type.isSelected(i)
Command Class
MIDP has no Button class. Instead, a class called Command is used to create UI objects that behave almost like buttons. Only the label, that is, the name of the command, priority of the command, and so on, are contained in a Command. What the Command object will actually do is specified in the CommandListener attached to the screen on which the object is placed. The parameters required to be passed while instantiating a Command object are: Label for the Command button. Position of Command button. Priority of the command over other commands. The third parameter (if it is used as the number of the accelerator key) works as follows: If the user presses the central button (hot key) of the cell phone, all the commands listed will be shown; the user can then scroll to the label of the button he or she wishes to use, or the user can press the serial number of the button to choose that particular button. There is only one method available for this class. This method is toString, which returns a string representation of the object. See the following code to see how button-like objects can be created using this class:
Form ui_holder = null; // Declaring Command objects and initializing them to null... Command ok = null; Command quit = null; // Instantiating the Form... ui_holder = new Form("User Interface - TextField"); ... ok = new Command("Ok",Command.SCREEN,3); quit = new Command("Quit",Command.SCREEN,2); // Adding Command Button to the Form ui_holder.addCommand(ok); u i_holder.addCommand(quit); ... // Invoking Action Listener ui_holder.setCommandListener(this); public void commandAction(Command c, Displayable d) { // Event handling for the Button if ( c == ok ) { ... } if ( c == quit ) {
Display Class
This class represents the display of the device. To show a user interface object on the device, you first have to declare the display, get it, and then make it current with the object supplied as the parameter to the setCurrent method. The methods specific to this class are enlisted:
getDisplay isColor numColors getCurrent setCurrent
Let us see the use of this class in the following code block:
// Declaring Form object and initialzing it to null... Form ui_holder = null; // Declaring variable for Display class and initializing as null... private Display display = null; // Getting the Display unique to this MIDlet... display = Display.getDisplay(this); /* * Making the Display Current so that it can show * the Form. */ display.setCurrent(ui_holder);
Form Class
LCDUI package contains a Form class. A Form is a kind of Screen on which other UI objects can be added. You can instantiate a Form object with either just a string title or a string title and an array containing the Items to be added to Form. The methods available are:
appendItem appendString appendImage insertItem deleteItem setItem getItemAt getSize setItemStateListener
In the following code snippet, we create a Form and initialize it to null. This Form is given a string title. Then we add a TextField to this Form by calling the append method:
72
// Declaring the form... Form myform = null; ... // Declaring the Display and initializing it as null... private Display show = null; ... // Getting the Display unique to this MIDlet... show = Display.getDisplay(this); // Initializing the form with a string title... myform = new Form("User Interface - TextField"); // Declaring and initializing a TextField... tx = new TextField("MyField","Type here...",70,0); // Adding the TextField to the form... myform.append(tx); // Showing the form, which is a Displayable object, on the screen... show.setCurrent(myform);
Gauge Class
Sometimes you want to use a bar graph indicating progress of some process or for use in a game. The class Gauge serves this purpose. It can be both interactive and noninteractive, depending on the need of the application. What determines this fact is the Boolean value of the second parameter taken by the constructor of this class. The methods for this class are:
setValue getValue setMaxValue getMaxValue
In the following code block, we create a Form and add to it a Gauge with the interactive parameter specified as true. In other words, the bar graph created will be of interactive type:
private Display display = null; Form ui_holder = null; ... // Declaring variable for the Gauge class... Gauge gaugeUI; ... display = Display.getDisplay(this); ... ui_holder = new Form("User Interface - Gauge "); gaugeUI = new Gauge("Values..",true,10,0); ui_holder.append(gaugeUI); ... display.setCurrent(ui_holder); ... // Event handling for the OK button.. if ( c == ok ) { int i = gaugeUI.getValue(); display.setCurrent(ui_holder); } ...
Graphics Class
The Graphics class in MIDP is somewhat like the class of the same name in the standard edition. It provides fairly good functionality for displaying 2-D graphics on constrained devices. Many of the methods of this class are similar to those of the Graphics class in J2SE. (However, as expected, some methods have been dropped since they are not relevant here. Some new methods have also been introduced, keeping in mind the characteristics of mobile devices. We briefly describe those methods that are present and point out the differences from their J2SE versions: translate: To translate the origin of the graphics context to the point (x, y) relative to the current coordinate system. getTranslateX: A new method to get the X coordinate of the translated origin of this graphics context. getTranslateY: Also a new method to get the Y coordinate of the translated origin of this graphics context. getColor: To determine the current color. It returns an integer in the form 0x00RRGGBB. getRedComponent: Another new method to determine the red component of the current color. It returns an integer value in the range 0-255. getGreenComponent: A similar method to find out the green component of the current color. getBlueComponent: To find out the blue component of the current color. getGrayScale: This one is also a new method, like the preceding three. It can be used to determine the current grayscale being used for all subsequent rendering operations. For color values, this returns the brightness of the color. setColor: A variation of the J2SE method, with two constructors instead of just one. It can be used to specify the current color in RGB values. All subsequent rendering operations will use this specified color. In one constructor, the red, green, and blue values are passed as three parameters (with values in the range 0-255). In the second constructor, only one parameter is used to specify RGB values in the format 0x00RRGGBB. setGrayScale: Like getGrayScale, it is a new method. It specifies the current grayscale to be used for all subsequent rendering operations. For color displays, this method sets the color for all subsequent drawing operations to be of gray color equivalent to the value passed in this method. This value is in the range 0-255. getFont: To get the current system font. setFont: To specify the font for all subsequent text-rendering operations. getClipX: A variation of the getClip method of J2SE. It returns the X offset of the current clipping area, relative to the point from which the coordinate system starts for this graphics context. Separating the getClip operation into two methods returning integers is more performance- and memory-efficient than one getClip() call returning an object. getClipY: Same as the preceding, but for returning the Y offset of the current clipping area. getClipWidth: This method is a variation of getClipBounds method. It returns the width of the current clipping area. getClipHeight: This returns the height of the current clipping area. clipRect: This method is the same as in J2SE, being used with the following constructor:
clipRect(int x, int y, int width, int height)
setClip: To set the current clip to the rectangle specified by the given coordinates. Rendering operations have no effect outside the clipping area. Only one constructor is available, with the following signature:
74
drawLine: Same as in J2SE. Draws a line between the coordinates (x1,y1) and (x2,y2) using the current color. Its signature is:
drawLine(int x1, int y1, int x2, int y2)
fillRect: Same as in J2SE. It fills the specified rectangle with the current color. The signature is:
fillRect(int x, int y, int width, int height)
drawRect: Same as in J2SE. It draws the outline of the specified rectangle using the current color. The resulting rectangle will cover an area of width + 1 pixels by height + 1 pixels. The width and height have to be nonnegative. The signature is:
drawRect(int x, int y, int width, int height)
drawRoundRect: Same as in J2SE. It draws the outline of the specified rounded corner rectangle using the current color. The signature is:
drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)
fillRoundRect: Same as in J2SE. Fills the specified rounded corner rectangle with the current color. The signature is of the form:
fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)
fillArc: Same as in J2SE. Fills a circular or elliptical arc covering the specified rectangle. The signature is:
fillArc(int x, int y, int width, int height, int startAngle, int arcAngle)
drawArc: Same as in J2SE. Draws the outline of a circular or elliptical arc covering the specified rectangle.
drawArc(int x, int y, int width, int height, int startAngle, int arcAngle)
drawString: Slightly different from the J2SE version. It draws the specified String using the current font and color. There is an additional parameter for the anchor point for positioning the text. The String to be drawn should be at least one character long. The (x,y) position is the position of the anchor point. The signature is:
drawString(String str, int x, int y, int anchor)
drawSubstring: A new method that draws a part of the specified String using the current font and color. The (x,y) position is the position of the anchor point. The parameters to be passed are: the String to be drawn zero-based index of first character in the substring length of the substring the x coordinate of the anchor point the y coordinate of the anchor point the anchor point for positioning the text The method can throw java.lang.ArrayIndexOutOfBoundException.
drawImage: A simplified version of drawImage methods in J2SE. Only one constructor is available. It draws the specified image by using the anchor point. The image can be drawn in different positions relative to the anchor point by passing the appropriate position constants. The signature of this method is:
drawImage(Image img, int x, int y, int anchor)
Class List
This class is used to add selectable objects to the UI of your application. It is quite similar in nature and behavior to the ChoiceGroup class in J2SE. One of the differences is that the choiceType parameter can have an additional value IMPLICIT, which allows handling of events generated by the user selecting a choice. The methods used with this class are also just the implementations of the methods in the interface Choice:
getSize getString getImage appendElement insertElement deleteElement setElement isSelected getSelectedIndex getSelectedFlags setSelectedIndex setSelectedFlags
We use the List class here to create menu of choices. Just as action is taken when you select an item in the menu, selecting a choice item in the List will notify the application:
// Declaring a variable of the type List.. List menu = null; // Initializing the variable ... // Parameter 1 --- Label of the List. // Parameter 2 --- List Type IMPLICIT. (Selection by scrolling) menu = new List("Various Options..",List.IMPLICIT); // Adding the List Items.. // Parameter 1 --- Label. // Parameter 2 --- Image if required. menu.append("TextField",null);
76
// Adding action Listener to the List.. menu.setCommandListener(this); // Making it the current Display. display.setCurrent(menu); // Handling the events on the List. public void commandAction(Command c, Displayable d) { List down = (List)display.getCurrent(); switch(down.getSelectedIndex()) { case 0: System.out.println ("Text Field..."); break; case 1: System.out.println ("Ticker..."); break; case 2: System.out.println("Alert..."); break; }
Class StringItem
This class can be used to add Strings to a Form, just as ImageItem could be used to add Images. You have to specify the label of the item and the text to be added:
getText setText
Class TextField
This is a class to represent a standard text field so that the user can enter text into it. The parameters required are the label, the initial text, the maximum size, and the input constraints. The concept of input
Class TextBox
This class creates an object that is similar to a TextField object, but one difference is that a TextBox is not an Item that has to be added to a Form. Rather, it is a component that can be directly added to a Screen. The methods available are:
getString setString getChars
78
Following is some code that creates a TextBox object named ourBox, with some initial text:
String s = "Hello From J2ME"; ... private Display ourDisplay; // Declaring the display private Form ourForm = null; ... ourDisplay = Display.getDisplay(this); ... ourForm = new Form("Our First"); TextBox ourBox = new TextBox("J2ME Application", s, 256, 0); ourForm.append(ourBox); ... ourForm.setListener(this); ourDisplay.setCurrent(ourForm);
Class Ticker
The class Ticker provides a way to show some horizontally scrolling text on the display, somewhat like a marquee in HTML. The text String is passed as parameter. Its methods are:
setString getString
It is not very difficult to use this class, as you can see from the following code:
// Initializing the Ticker. // Parameter 1 .. Text For the Ticker. ui_ticker = new Ticker("..This is an Example of a Ticker User Interface.."); // Adding Ticker to the Form. ui_holder.setTicker(ui_ticker);
Persistence Package
The Mobile Information Device Profile gives you a mechanism to persistently store data and later retrieve it. This persistent storage mechanism is modeled after a simple record-oriented database and is called the Record Management System. The package it is contained in is named javax.microedition.rms. The only class in this package is the RecordStore class. In addition, there are four interfaces. These interfaces and their methods are listed as follows: RecordComparator: To compare and sort record in the RecordStore. It has only one method: Compare.
RecordListener: This is the interface that can be used for listening to events generated when records are changed, added, or deleted. The methods it has are:
recordAdded recordChanged recordDeleted
Class RecordStore
The only class of this package it is used to represent a collection of records in a device database. These records remain persistent even when another MIDlet is started or even when the device is rebooted or the battery is changed. Following are some points to note when dealing with record stores using MIDP: You can manipulate only the MIDlet suite's own record stores. There is no way to share records between MIDlets in different suites. In accordance with the Java convention, record store names are case sensitive and may consist of any combination of up to 32 unicode characters. They have to be unique in a given MIDlet suite. If you use more than one thread in a MIDlet, you have to coordinate this access yourself. Records are uniquely identified within a given record store by their recordId, which is an integer value and is used as the primary key. The recordId of the first record created in a record store will be 1. The record store keeps track of an integer representing a version. This version number is incremented for each operation that changes the contents of the record store. The methods available with this class are:
openRecordStore closeRecordStore listRecordStores deleteRecordStore getName
80
In the following code block, we define a method called read_record, which reads the contents of an XML file and then adds the parsed values to a RecordStore. For this, it calls another method record_add defined after the read_record. This method is used in our Mobile Web Services project in Chapter 10. Most of the code here is to handle the reading and parsing of the XML file contents, but it may help you in getting an idea about the practical use of RecordStore class. You will be able to understand the following code if you also refer to Chapter 10 briefly. The RecordStore class gives you many methods for managing the device database. We have used only a few of these, but once you are able to use these, it may be easier to use others. For an even better illustration of the use of this class, see the case study named AddressBook later in this chapter.
void read_record() { int k, id; String state = "", data = ""; boolean founditem = false, foundstate = false; try { /* Opens RecordStore for insertion of records */ recordStore = RecordStore.openRecordStore("addresses", true); } catch(RecordStoreException rse) { rse.printStackTrace(); } // Start of XML handling part... do { try { /* Events generated by the parser while parsing XML file */ event = parser.read (); /* Type of event generated while parsing XML File */ if(event.getType()==Xml.START_TAG)
82
} }
The method record_add defined next is meant to add records to a store, as the name suggests:
/* Function for record addition...*/ int record_add(String data) { int i = 0; try { byte b[] = data.getBytes(); i = recordStore.addRecord(b,0, b.length); } catch (RecordStoreException rse) { rse.printStackTrace(); } return i ; }
run.bat
@echo off rem This file runs the example.jad/jar file in the emulator. set CLASSPATH=lib\midp.jar;lib\examples.jar; src\example\sokoban\sokoban.zip bin\midp -descriptor run.jad
When you write your own applications, you can change the classpath according to the directory where you store your source files. For compiling and preverifying, you can add commands to the batch file listed in the preceding code. The commands will be similar to those used in CLDC; you just have to use relevant classpaths. Note that the MIDP APIs are available in the JAR archive midp.jar. You can extract these if you like. In order to give you a better idea about the whole process of compiling, preverifying, jarring, jadding (jadding is creating an application descriptor which is required by the midp.exe to execute the application), and running MIDlets and MIDlet suites, we are giving in the following section the code for a longer sample batch file. This file takes a command line argument called %name% that signifies the name of your application, in this case, the sample MIDlets. We have used the same name for the directory in which the source files, the manifest (example.mf), the application descriptor (example.jad), and the JAR archive (example.jar) are placed. If you want different names for these files and directories, you can use more command line arguments, but a single name is more convenient if you are careful about the directories and the classpath. The benefit of using such a batch file is that it gives you the option of executing or skipping each command. This way, you can try to fix things in one of the commands by just skipping the rest. Obviously, the name of the batch file and also its content except the Java files are not case sensitive. Also, the indented lines are a continuation of the preceding lines that is, if you type them on the console, you have to type them without pressing the Enter key. Before being able to run applications, you have to prepare the manifest and the application descriptor, describing the MIDlet. The contents of these will include attributes mentioned MIDlet Suites section earlier in this chapter. Some other things should be noted with respect to the commands used in the batch file. Unlike previous files, we are compiling, verifying, jarring, and jadding the source files given in the src directory. Earlier, we had just used the JAR archive provided with the release. This seems to create a problem in the preverifying tool (preverify.exe) in Windows 98 (which was tried) in that it is unable to do its job on specifying midp.jar in the classpath. One workaround tried was to unjar the MIDP API and specify the name of the directory in the classpath only for preverification, because there is no problem in compiling or running with the JAR file. Also, the preverifying tool in the MIDP release was replaced with the one that came with the J2ME Wireless Toolkit. It worked as far as preverifying goes, but the emulator crashed sometimes while running the sample MIDlets.
84
sample.bat
Code for sample.bat is described here:
@echo off rem This file compiles, preverifies, and runs the sample applications in the emulator. set name=%1 shift if "%name%"=="" goto :abort echo Creating directories... mkdir tmpclasses mkdir classes mkdir res choice /c:ync /t:n,10 Do you want to compile? if errorlevel 2 goto skipcompile echo Compiling source files... rem Replace or change classpaths according to the locations on your disk... javac -bootclasspath lib\midp.jar -d tmpclasses -classpath tmpclasses src\%name%\*.java javac -bootclasspath lib\midp.jar -d tmpclasses -classpath tmpclasses src\%name%\lcdui\*.java javac -bootclasspath lib\midp.jar -d tmpclasses -classpath tmpclasses src\%name%\manyballs\*.java javac -bootclasspath lib\midp.jar -d tmpclasses -classpath tmpclasses src\%name%\sokoban\*.java javac -bootclasspath lib\midp.jar -d tmpclasses -classpath tmpclasses src\%name%\stock\*.java javac -bootclasspath lib\midp.jar -d tmpclasses -classpath tmpclasses src\%name%\tiles\*.java :skipcompile choice /c:ync /t:n,10 Do you want to preverify? if errorlevel 2 goto skippreverify echo Verifying class files... bin\preverify -classpath lib;tmpclasses -d classes tmpclasses :skippreverify choice /c:ync /t:n,10 Do you want to do jarring? if errorlevel 2 goto skipjarring echo Jarring verified class files... jar cmf %name%.mf %name%.jar -C classes . echo Jarring resource files... jar umf %name%.mf %name%.jar -C res . :skipjarring choice /c:ync /t:n,10 Do you want to run the applications?
example.jad
Code for example.bat is described here:
MIDlet-Name: SunSamples MIDlet-Version: 1.0 MIDlet-Vendor: Sun Microsystems, Inc. MIDlet-Description: Sample suite from MIDP early access workspace. MicroEdition-Profile: MIDP-1.0 MicroEdition-Configuration: CLDC-1.0 MIDlet-1: Sokoban, /icons/Sokoban.gif, example.sokoban.Sokoban MIDlet-2: Tickets, /icons/Auction.gif, TicketAuction MIDlet-3: Colors, /icons/ColorChooser.gif, example.Color MIDlet-4: Stock, /icons/Stock.gif, example.stock.StockMIDlet MIDlet-5: Tiles, /icons/Tiles.gif, example.tiles.Tiles MIDlet-6: ManyBalls, /icons/ManyBalls.gif, example.ManyBalls MIDlet-7: Sampler, /icons/App.gif, Sampler MIDlet-8: Properties, /icons/App.gif, example.PropExample MIDlet-9: HttpTest, /icons/App.gif, example.HttpTest
You can also run MIDlet suites from a browser by configuring them to recognize the MIME type. For example, you can add the following types to Netscape Communicator. Then, if you open the application descriptor say, example.jad the browser will run it for you. At least this is what Suns documentation says. When this was tried on Windows 98 with Netscape, either there was no response or the system halted. With IE, the system did not halt but the browser did nothing.
Description: MIDP app descriptor MIME Type: text/vnd.sun.j2me.app-descriptor Extension: jad Application: D:\DTP\J2ME\Download\j2me_midp-1_0-ea1-win\midpea1\bin\midp.exe -transient file://%1
86
Note that this toolkit is meant for MIDP only and not for other profiles not so far, at least. You download the J2ME Wireless Toolkit from Suns product page just as you can download CLDC and MIDP implementations. You will, of course, need JDK before you can use it. If you want to use it with Forte, you will also need to download Forte for Java from Suns site from the URL http://www.sun.com/forte/ffj/ce. A newer version of this toolkit, numbered 1.0.1, is now available. As far as an ordinary user will be able to make out, it just has the design of its emulated devices changed. J2ME Wireless Toolkit includes everything you need to develop applications. It includes the preverifier, the MIDP libraries, MIDP documentation, an emulator to run MIDlets, and even the sample applications that are available with MIDP release. Moreover, to perform build and run operations from command line, batch files are provided. There are in fact several emulators included with the toolkit. The emulator gives you the choice to test your applications on a default gray phone, default color phone, minimum phone, and even a pager. The emulator also supplies runtime logging of various events, including method tracing, garbage collection, class loading and exceptions thrown. Thus you can trace the execution of an application. The limitations of the emulator are that it does not emulate the application management and speed of execution. The latter means that the application may execute at a different speed on the actual device for which it is meant. Operation of the KToolbar is quite simple. It can be started from the Start button on Windows. You have to first create a new project and give it a name, as well as specify the MIDlet class name. After this, a directory will be created with the same name as the one you give for the project. It will contain three subdirectories (bin, res, and src). You then have to put the source code you wrote in the src directory. When you hit the Build button, the application will be compiled and preverified. To run it, you have to just hit the Run button. Before running the application, you can choose the device on which you want to see it run. There are four choices, as mentioned previously. For more information about this toolkit, you can read the user guide included in the download.
88
90
Case Studies
This section is on case studies developed using MIDP APIs. The case studies covers important GUI classes and also makes use of HTTP connection.
TextFieldCheck
Our first example of an MIDP application is a simple MIDlet to demonstrate the use of a TextField. You can use it in several classes and methods that are required in most MIDlets. These include, especially, the class MIDlet (which has to be used in every MIDlet) and the methods of this class for managing the life cycle of a MIDlet (such as startApp, pauseApp, and destroyApp). You can run this application in J2ME Wireless Toolkit as explained previously. On starting the MIDlet, the user sees a screen displaying the name of the MIDlet. On selecting it, the user is shown a TextField in which he can enter any text. After he has done this, he can press the OK button. Upon this, a message is displayed that the user has successfully entered whatever was required refer to Figure 4-9 to view the Output. Of course, the button is just a label above the actual button of the mobile phone. The top-right button is used as an OK button, and the top-left button is used as an Exit button.
To add the UI component TextField, we first create a Form in this MIDlet and then add the component to it. In addition to the TextField, there are buttons on this form to allow the user to indicate that he has finished typing in the TextField and to allow him to quit. These buttons are created by implementing the class Command. For event handling, CommandListener is used. We have to implement this interface to define what will be the behavior of the application when the user presses the button. This is done by using a simple if block. Note that in using the pauseApp and destroyApp methods, all items have to be assigned null values.
public class TextFieldCheck extends MIDlet implements CommandListener { // Declaring variable for Display class. private Display display = null;
92
// Declaring variable for Form class. Form ui_holder = null; // Declaring variables for Buttons in the UI. Command ok = null; Command quit = null; // Declaring variable for the TextField. TextField textcheck = null; public TextFieldCheck() { // Initializing the Display display = Display.getDisplay(this); // Initializing the Buttons ok = new Command("Ok",Command.SCREEN,3); quit = new Command("Quit",Command.SCREEN,2); } public void startApp(){ ui_holder = new Form("User Interface - TextField"); // Initializing the Form textcheck = new TextField("Enter the Text Here..","",50,0); string_item = new StringItem("User Entered ..", ""); // Adding TextField to the form (place holder) ui_holder.append(textcheck); // Adding Stringitem to the form (place holder) ui_holder.append(string_item); // Adding Command Button to the Form ui_holder.addCommand(ok); // Adding Command Button to the Form ui_holder.addCommand(quit); // Invoking Action Listener ui_holder.setCommandListener(this); /* * Making the Display Current so that it can show * the Form. */ display.setCurrent(ui_holder); } public void pauseApp() { string_item = null; ui_holder = null; textcheck = null;
LabelUI
The next MIDlet is about putting some text on the screen to serve as a label. This is done here in two ways. First, a string User Interface Label is passed as parameter to a Form named ui_holder. Then another string A simple Label is added to the Form by calling the append method. The first string can be considered the title and the second can be the description as shown in Figure 4-10.
In the second way of doing a similar thing, two strings are passed as parameters to a StringItem, the first of which serves as a label for the second. Then this StringItem is added to the Form, again by calling the append method. There is an OK command so that the user can indicate that he has completed viewing the text. Again note that all items have to be assigned null values in pauseApp and destroyApp methods.
94
public class LabelUI extends MIDlet implements CommandListener { // Declaring variables for Display class. private Display display = null; // Declaring variables for StringItem class. StringItem string_item = null; // Declaring variables for Form class. Form ui_holder = null; // Declaring variables for Buttons. Command ok = null; public LabelUI() { // Initializing the Display display = Display.getDisplay(this); ok = new Command("Ok",Command.SCREEN,3); } public void startApp() { // Initializing the Form. ui_holder = new Form("User Interface - Label"); // Adding a simple label to the Form. ui_holder.append("A simple Label..."); string_item = new StringItem("Example of a String Item....", "Hello World Label"); // Adding StringItem to the form (place holder). ui_holder.append(string_item); // Adding Command Button to the Form. ui_holder.addCommand(ok); // Invoking Action Listener.. ui_holder.setCommandListener(this); /* Making the Display Current so that it can show * the Form. */ display.setCurrent(ui_holder); } public void pauseApp() { string_item = null; ui_holder = null; } public void destroyApp(boolean condition) { string_item = null; ui_holder = null; // Destroy the form.
ChoiceGroupUI
This MIDP application shows how you can put the equivalent of radio buttons and check boxes on the UI of a MIDlet. The class responsible for both these in MIDP is ChoiceGroup. It is only the value of the parameter choiceType that determines whether the ChoiceGroup elements will act as radio buttons or check boxes. The three types of ChoiceGroups are EXCLUSIVE, MULTIPLE, or IMPLICIT. The label for the whole ChoiceGroup is set by passing the value of the label parameter as Choices. Text labels for the elements of a ChoiceGroup are added by passing the stringElements parameter with a value equal to a string array containing the labels. Since in this case we wanted no images, we have set the value of the imageElements as null. All the elements are added to the Form by calling the append method as before.
When the user makes his choices and presses the OK button, the commandAction is used for event handling. For this event handler, if blocks and a for loop are used. As a result of this, the user is shown a message reporting the choices made by him as shown in Figure 4-11 and Figure 4-12. He can get out of the application by pressing the Quit button.
96
/** A program to demostrate how a ChoiceGroup works on a * handheld device. */ public class ChoiceGroupUI extends MIDlet implements CommandListener { // Declaring variable for the Display class. private Display display = null; // Declaring variables for the ChoiceGroup. ChoiceGroup radiobutton_type = null; ChoiceGroup checkbox_type = null; // Declaring variables for the StringItem class. StringItem string_item1 = null; StringItem string_item2 = null; // Declaring variables for the Form class. Form ui_holder = null; // Declaring variables for Buttons. Command ok = null; Command quit = null; String[] name = {"a","b","c"}; String[] name1 = {"d","e","f"}; Image[] img = null; boolean[] values = null; public ChoiceGroupUI() { // Initializing the Display. display = Display.getDisplay(this); // Initializing the Button. ok = new Command("Ok",Command.SCREEN,3); quit = new Command("Quit",Command.SCREEN,2); } public void startApp() { // Initializing the Form. ui_holder = new Form("User Interface - ChoiceGroups"); // Initializing the Choice groups. radiobutton_type = new ChoiceGroup("Choices..", ChoiceGroup.EXCLUSIVE,name,img); string_item1 = new StringItem("User Clicked ",""); checkbox_type = new ChoiceGroup("Choices..", ChoiceGroup.MULTIPLE,name1,img); // Getting the values the user clicked. string_item2 = new StringItem("User Clicked
","");
98
TickerUI
This is a simple MIDlet, showing the use of the Ticker class. It basically shows the user some scrolling text somewhat like a marquee in HTML. The Ticker has to be passed some string as the parameter. This string will be shown scrolling horizontally on the screen as in Figure 4-13. But before it happens, you have to call the setTicker method and pass the name of the Ticker object as an argument to this method. Note that we are not using the append method as we did in previous examples. There is an OK button for the user to indicate that the user has had enough of the Ticker.
MenuCheck
Now we present a more advanced application. This is a very useful MIDlet, since it shows how a menu can be created with MIDP. The class used for this is List. Just as in the case of ChoiceGroup, there can be three types of Lists: IMPLICIT, EXCLUSIVE, and MULTIPLE. We use the first variety here, as this will perhaps be the most used in applications. For this variety, we dont have to attach applicationdefined commands it is enough to register CommandListener that is called when the user makes a selection.
We begin building a menu by adding elements to a List by calling the append method. The other important thing to do is to implement the commandAction method of the CommandListener class. We do this by using the switch block to determine what the user will get when he selects an entry on the menu. In our case, the user sees a message (as in Figure 4-15) describing the selection he made. Needless to say, there is a Quit button here as well, since we dont want to lock in the user.
Listing 4- 5: MenuCheck.java
import javax.microedition.midlet.*; import javax.microedition.io.*; import javax.microedition.lcdui.*; /** A program to check how a Menu works on a handheld. * The program gives a taste of how a Menu works by adding * various Alerts and TextFields on to it. */
public class MenuCheck extends MIDlet implements CommandListener { private Display display = null; Command ok = null; Command quit = null; List menu = null; Form ui_form = null; StringItem si = null; public MenuCheck() { // Initializing the Display display = Display.getDisplay(this); quit = new Command("Quit",Command.SCREEN,2); } public void startApp() { menu = new List("Various Options..",List.IMPLICIT);
AddressBook
This is perhaps the most advanced application in this chapter. In a way, this MIDlet is an extension of the MenuCheck MIDlet. It doesnt just show some message when the user makes a selection. Rather, it goes on to add some real functionality by allowing the user to add records to an address book, search them, delete them, and moreover, to quit the application.
The menu is created in the same way as previously by using the List class and adding elements to it by calling the append method see Figure 4-16. This List is again of IMPLICIT type. For adding entries to an address book (or for searching for and deleting them), you need to use database capability. This is where MIPDs persistence package and its RecordStore class are relevant. A RecordStore is opened by calling its openRecordStore method. Records are added to it by calling the addRecord method. When the user selects Add Address on the menu, he gets two TextFields in which he can type his name and telephone number, respectively as shown in Figure 4-17. The getString method is used on these TextFields to get the text user types. You can also see the use of ByteArrayOuputStream, DataOutputStream, and the writeUTF method.
For searching records, enumerateRecords method is used (Figure 4-19 shows how to search the record and Figure 4-20 displays the search results), along with while and if blocks. For deleting records(refer to Figures 4-21 and 4-22), deleteRecord method is used, in addition to the
Finally, calling the closeRecordStore method of the RecordStore class closes the database. But before proceeding to the next MIDlet, take note of the exceptions and trycatch blocks, as well as the switch block that is used for event handling in case of the main menu.
Listing 4- 6: AddressBook.java
import import import import import import import javax.microedition.midlet.*; javax.microedition.io.*; javax.microedition.lcdui.*; javax.microedition.rms.*; java.util.Enumeration; java.util.Vector; java.io.*;
/** A program to demonstrate how databases work on a handheld device * by creating an address book where you can add, search and * delete number/addresses. */ public class AddressBook extends MIDlet implements CommandListener {
// Declaring a Menu(List) List menu = null; Form ui_form = null; StringItem si = null; // TextField for storing the name... TextField name = null; TextField phone = null; // Declaring a RecordStore (Database)... RecordStore recordStore = null; public AddressBook() { display = Display.getDisplay(this); quit = new Command("Quit",Command.SCREEN,3); search = new Command("Search",Command.SCREEN,2); delete = new Command("Delete",Command.SCREEN,2); addnow = new Command("Add",Command.SCREEN,2); mainmenu = new Command("Main",Command.SCREEN,2); // Initializing the Record Store try { recordStore = RecordStore.openRecordStore( "addresses", true); } catch(RecordStoreException rse) { rse.printStackTrace(); } } public void startApp() { menu = new List("Address Book...",List.IMPLICIT); menu.append("1. Search Address",null); menu.append("2. Add Address",null); menu.append("3. Delete Address",null); menu.append("4. Quit",null); menu.setCommandListener(this); display.setCurrent(menu); } // GUI for the Search Screen... void searchScreen() { ui_form = new Form("Search An Address"); name = new TextField("Name to Search..","",50,0); ui_form.append(name); ui_form.addCommand(search);
TestHTTP
We end the chapter by showing how connectivity can be established with a MIDlet. It is done by using the HttpConnection interface and Connector class of javax.io package. We first open an HTTP connection by using the open(url) method and then calling the openInputStream method on this connection in order to allow reading data from it by using the read(data) method. The file to be read is passed as a URL to the connection. Both the connection and the input stream are closed by calling the close method. This final part is done inside a finally block to release all the resources. It is a simple MIDlet, but a useful one. To see the output refer to Figure 4-23.
Summary
This chapter gives you a feel for programming mobile devices and a sense of the restrictions in terms of resources for mobile devices. This chapter is groundwork for the six unique projects in this book. You should be well conversant with the APIs before going on to these chapters. Chapter 5 concentrates on XML parsing using kxml parser for J2ME. This is an important chapter as we have four project chapters that have extensive use of XML.
Chapter 5
Structure of XML
An XML document is just like an HTML document, having the new tags defined in the Schema, or the DTD. The first line is used for declaring the version of the XML; and the second line indicates the name of the DTD to be used by the document. These constitute the XML Prolog. The XML Prolog is written as:
<?xml version="1.0"?> <!DOCTYPE shop SYSTEM "shopfile.dtd">
Further, the document will have the structure of the HTML body, in which tags will be used as per their structure, and nesting will be defined in the DTD:
<shoplist> <itemname> Computer </itemname> <price> $500 </price> <qty> 2 </qty> <memory> 1.2MB </memory> </shoplist>
The preceding declaration explains the functionality of the tags as follows: Line 1: The tag group shop contains the main container tag shoplist. The plus (+) indicates that a shoplist can occur several times in shop. Line 2: The shoplist tag contains itemname, price, qty, and memory. Line 3: The itemname tag contains character data. Line 4: The price tag contains character data. Line 5: The qty tag contains character data. Line 6: The memory tag contains character data and is mandatory. The preceding example declares an external DTD. The following example in Listing 5-2 illustrates an embedded DTD.
The other special symbols used to define tags are: #FIXED: Defines the fixed value of an element. #IMPLIED: Specification of default value. ID: Defining ID. ENTITY: Pointing to external data. |: OR (EITHER).
XML Schema
We have just seen that only ELEMENT is used to define the type of tag in DTD. To define further types for the tags for the validation of the datatypes inserted in between the tags, XML Schemas are used. The Schemas are written as an XML file so that the need for the processing software to read the XML declaration syntax is obviated. XML Schema is a complete language used to define and describe the classes for the XML document. It contains the type declarations such as byte, integer, date, sequence, and so on. It also allows derived data-type declarations from the basic data types available in the language. It is the function of the XML Schema to define the relationship between the XML document, namespaces, and DTDs. These Schemas are also used to check the validity of the XML document.
XML Parsing
XML parsing refers to the concept of translating the tag definition and executing the document with the new tags so that the user or the application development environment can understand the data stored in the document. The special software required for this is called a parser. A parser is software that parses an XML document on the basis of XML tags. The parser recognizes the XML tag on the basis of parameters passed to it and gets the text associated with the tag (refer to Listing 5-1). This is accomplished by interpreting and translating the definition of tags contained in a DTD. There are two categories of parsers: Validating parsers Nonvalidating parsers In order to understand these types, it is required to know the meaning of valid and well-formed documents. A valid XML document is a document that is compliant to the DTD which is associated with the XML document. The DTD can be written in the same XML document (embedded) or it can be specified as a link. A valid document has to be well-formed. While youre defining tags in a DTD, their inter-relationships are also defined. A well-formed document is one in which all the tags adhere to the relationships defined in the DTD. Some of the rules to be followed by well-formatted documents are: All the tags used in the document have to be balanced by including start and end tags. All the essential attributes defined in the DTD should be present. The attribute values have to be given within quotes. The container and containing tags must be strictly as per the DTD, or the Schema. Markup characters such as < or & cannot be present alone. If required, they have to be used as <, &, etc. All empty tags should end with />. It is the function of the parser to check for the preceding rules. Based on the XML documents we have discussed above, there are two types of XML parsers, one for parsing valid XML documents and the other one for non-valid XML documents.
kXML
This is the most important and popularly used XML parser for KVM. This is a combination of the pull parser and the XMLWriter, which is used for writing XML. It contains a WAP Binary XML (WBXML), which is used for transmitting XML documents over wireless communication channels. For this, it has support for Wireless Markup Language. It does contain a special kDOM, which is a Document Object Model replacement for kXML. It is simpler and manages the space more efficiently than Document Object Model. It compiles and works in the Mobile Information Device environment without any modifications. It is present in de.kxml.parser package. Its functionality is defined in the Parser class.
TinyXML
This is a nonvalidating push parser, which compiles the entire DOM tree into the memory and then parses the entire XML document in one go. It needs modifications to the source code to run on Mobile Information Device. The main feature of the TinyXML is that it follows only a few specific encoding types: ASCII, UTF-16, UTF-16BE, and UTF-8. The encoding type has to be specified in the XML Prolog. If the type specified in the XML Prolog is not of the encoding ASCII, UTF-16, UTF-16BE, and UTF-8,the TinyXML parser will not parse the XML document and will throw an exception.
NanoXML
This is another parser for KVM, which works on push-parsing technology. It has a specific feature for modifying a document and writing the modified document back onto the stream. Since this feature is not very useful for MID at present, this parser does not have any major use or popularity. However, once this feature is accepted in the MID specifications, it will be an important parser for wireless communication.
While parsing the preceding XML, when the parser comes across the <Hello> tag, it will generate a StartTag event. The getname( ) method of this class will return Hello, which is the name of the tag. For details of using this tag, refer to the case study in this chapter. TextEvent class: This class also extends ParseEvent class. The object of this class is generated when the parser finds some text associated with the tag. For example, in the preceding XML, when the parser comes across Hello How are you, it will generate a text event. The getText( ) method of this class will return Hello How are you, which is the text of the tag. EndTag class: This is a subclass of the ParseEvent class. The object of this class is generated when the parser finds the end of a tag. For example, in the XML given in the StartTag class, when the parser comes across the </Hello> tag, it will generate an EndTag event. The getName( ) method of this class will return Hello, the name of the end tag.
org.kxml.io package
This package contains classes for writing XML data. Let us discuss these classes one by one: AbstractXmlWriter: This class is a base class for XmlWriter class and provides functionality for the XmlWriter class. This class has methods which are used for writing XML documents; the methods like attribute(), endTag(), and startTag() are used to create XML documents.
LookAheadReader: This class is like a reader class, but there is a peek() function in this class that shows the next character; this class also doesnt throw IOException.
XmlWriter: This class gets its functionlity from AbstractXmlWriter class. This class has checkpending(), close(), and write(char c), other than the methods inherited from AbstractXmlWriter class.
Application
This application will illustrate XML parsing by defining subject ID and subjectname tags, parsing the data, displaying the parsed data on the screen, and reading the data.
Application description
The code listings for the two programs are given in Listings 5-3 and 5-4.
/** * Declaring the GUI components * */ 17. 18. private Button bt = new Button("Ok",70,145); // Gui Components (Button) private Button exit = new Button("Exit",35,145); // Gui Components (Button)
/** * main Class which calls the Class XmlCaseStudy. * */ 19. public static void main(String args[])throws Exception 20. { 21. XmlCaseStudy casestudy = new XmlCaseStudy(); 22. } 23. public XmlCaseStudy() 24. { /** * Getting the Graphics and redrawing the screen. * */ 25. 26. 27. /** Graphics graphics = Graphics.getGraphics(); graphics.resetDrawRegion(); graphics.clearScreen();
/** * Registering the Spotlet and painting the GUI components. * */ 30. 31. 32. 33. 34. 35. register(NO_EVENT_OPTIONS); bt.paint(); exit.paint(); } public void penDown(int x, int y) {
/** * When Ok is pressed unregister the spotlet, call the startReading * class to read the XML file then call the XML parser which will * parse the file and store the results in a string which is passed * as a parameter to another class which displays the result. */ 36. 37. 38. 39. 40. 41. 42. 43. if(bt.pressed(x,y)) { unregister(); startReading(); parseData(); new result_screen(result_string); } else
/** * Exit the program * */ 44. 45. 46. 47. 48. 49. 50. 51. { System.exit(0); } } public void startReading() { try {
/** * Read the file and pass to the XML parser.. * */ 52. 53. din = Connector.openDataInputStream("testhttp://pankaj/books.xml"); xmlparser = new XmlParser(new InputStreamReader(din));
/** * Start Tag is encountered.. and Appended to a string. * */ 67. 68. 69. 70. 71. 72. if(event.getType()==Xml.START_TAG) { StartTag stag = (StartTag)event; String name = stag.getName(); result_string = result_string + "Start "+name + "\n"; }
/** * text between tags is encountered and appended to the String. * */ 73. 74. 75. 76. 77. 78. 79. if(event.getType()== Xml.TEXT) { TextEvent tevent = (TextEvent)event; String name = tevent.getText(); name = name.trim(); result_string = result_string +"Value }
"+name + "\n";
/** * End Tag is encountered.. and Appended to a string. * */ 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. if(event.getType()== Xml.END_TAG) { EndTag end_tag = (EndTag)event; String name = end_tag.getName(); result_string = result_string + "End "+name + "\n"; } } catch(IOException ex) { System.out.println("Exception occured"); } }
Code description
Lines 1-7: Basic packages used by various classes. Lines 8-10: Packages used by the XML parser. Lines 11-12: Declaring a class XmlCaseStudy. This class is responsible for reading the file and parsing it. Then it displays a screen, which contains the parsed results. Lines 13-16: Variable declaration to be used within this code. Lines 17-18: Declaration of GUI components. Lines 19-22: Declaration of constructor of XmlCaseStudy class to run the Java application is encoded here. Lines 25-27: Getting the graphics and redrawing the screen. Lines 28-29: Painting the title on the screen. Lines 30-33: Registering the spotlet and painting the GUI components. Lines 36-42: When OK is pressed, this code unregisters the spotlet, calls the startReading class to read the XML file and then calls the XML parser, which will parse the file and store the results in a string that is passed as a parameter to another class, which will display the result. Lines 43-46: To exit from the program. Lines 48-66: For reading the file and passing it to the XML parser. The code block serves to open the file and catch the exception if the file is not found. Opens and displays the file on the screen if found. Lines 67-72: This if condition is true if the Start tag is encountered and the name of the tag is passed to the String variable called name. The name is appended in another String variable result_string. Lines 73-79: It reads the data as a string and trims it till the end tag is encountered. The string is appended to the String variable. Lines 80-95: Checks for the end tag in the loop and catches any exception encountered. It checks for the end of the document, and when this is done, the message is printed on the screen.
Output
Figures 5-1 and 5-2 give the user a sense of the look of DTD and XML files.
122 Chapter 5: Handling and Parsing XML in J2ME Listing 5-4: result_screen.java
2001 Dreamtech Software India, Inc. All Rights Reserved.
/** * Basic packages used by various classes.. * */ 1. import com.sun.kjava.*; /** * Decalaring a class result_screen which is responsible for * showing the results in the ScrollTextBox */ 2. public class result_screen extends Spotlet 3. { /** * Declaring the GUI components * */ 4. 5. 6. 7. Button exit = new Button("Exit", 80,145); ScrollTextBox result_box; result_screen(String result) {
/** * Getting the Graphics and redrawing the screen. * */ 8. 9. 10. /** * * */ 11. Graphics graphics = Graphics.getGraphics(); graphics.resetDrawRegion(); graphics.clearScreen(); Painting the title on the screen.,
graphics.drawString("Result of parsing",25,2);
/** * Registering the Spotlet and painting the GUI components. * */ 12. 13. 14. 15. 16. 17. 18. result_box = new ScrollTextBox(result,10,20,120,120); exit.paint(); result_box.paint(); register(NO_EVENT_OPTIONS); } public void penDown(int x, int y) {
Code description
Line 1: Basic packages used by various classes. Line 2: Declaring a class resultscreen that is responsible for showing the results in the ScrollTextBox. Lines 4-6: Declaration of the GUI components to display on the screen. Lines 8-10: Getting the graphics and redrawing the screen. Lines 12-18: Registering the spotlet and painting the GUI components. Lines 19-25: Exit the program. Lines 26-30: Declaration of penmove function.
Output
Figure 5-2 shows the output screen.
Summary
This chapter serves to give the reader an overview of the parsers available for XML to be used with J2ME. The XML parsers are small, since the memory and other resources are limited in the case of wireless devices. Some of the common XML browsers are: kXML NanoXML TinyXML WBXML More details of these browsers can be found at the following links:
kXML: http://kxml.enhydra.org/
NanoXML: http://nanoxml.sourceforge.net/
TinyXML: htttp://gibaradunn.srac.org/tiny/
WBXML: http://trantor.de/wbxml/ We have discussed the kXML parser and the main classes and methods for handling the wireless devices. Further details of these classes can be obtained from http://kxml.enhydra.org/. The example given in the application section of this chapter illustrates the usage of some of the classes discussed in the text. The application presented takes the data from the file, parses it, and displays the output on the screen.
Chapter 6
User Interface
The main class of TestManager is named, not surprisingly, TestManager. It contains the GUI components that the user sees on the screen, such as scroll text box, buttons, text fields, etc. When the application is started, the user sees a Welcome screen. He can proceed from here by pressing the OK button, or if he changes his mind, he can quit the application by pressing Exit. If he wants to go on and presses OK, he sees a scroll text box showing the topics on which he can test his knowledge. He enters the serial number of one of the topics and presses the OK button. He is presented with the first question on that topic, picked randomly from the database. There are three buttons on the screen labeled Next, Prev, and Review. He can decide on attempting a question by entering the serial number of the option he thinks is correct. Or he can leave the question unanswered and go to the next question by pressing Next. In the same way, he can tackle more questions. At any stage during the test, he can see the status of the test by pressing the Review button. If he does this, the number of questions attempted, number of correct and wrong answers, and the number of unattempted questions are displayed. On this Review screen, he can decide whether the test is too tough for him and quit the test by pressing Exit. Otherwise, he can get back to the test by pressing OK. Moreover, while answering the question, he can even go back to the previous question by pressing the Prev button. On completing the test, he can see the final result. Results are given in terms of how many questions were answered correctly, how many were unattempted, how many remain unanswered (that is, were read but not attempted), and how many were answered but were wrong. The test also has one history sheet, where the user can see a chronological summary of all the tests and the results.
Here it is assumed that the CLDC has been installed in the c:\j2mecldc directory and the TestManager project has been installed in the c:\testmanager directory. The complete source code for the project is given in the TestManager.java, MainScreen.java, QuestionParser.java, Books.asp, and TestFile.asp sections in the chapter. You can also copy it from the CD to run it. However, you should have Personal Web Server (or any other Web server) installed and running for testing this application. Moreover, you will have to copy the ASP files in the root directory of the server.
How It Works
The project includes the following files: TestManager.java: The main Java (CLDC) file. MainSreen.java file: Contains four inner classes named NextScreen, Results, ResultScreen, and TestHistory.
QuestionParser.java
MaintenanceSoft.mdb: MS Access database, where topics, questions, results, etc., are stored. The topics on which the user can test his knowledge, questions on these topics, options for these questions, and the answers are stored on the server in the MS Access file named MaintenanceSoft.mdb. The MaintenanceSoft.mdb file has three tables: MainData, QuestionData, and AnswerData. These tables store all the data related to the Test for table structure of the given tables refer to Figures 6-1, 6-2, and 6-3. The MainData table shown in Figure 6-1 contains the name of the subjects on which tests are available. The QuestionData table as shown in Figure 6-2 stores details related to the questions. The information like the QuestionId, the QuestionText, and the NoOfChoices for that Question are stored in this table. The AnswerData table as shown in Figure 6-3 stores details related to the answer of a particular question. The information like the QuestionId to which this answer is associated the ChoiceNo field stores the no of choices the AnswerText field stores the content of the answer, Correct field stores the correct option to this answer etc.
On starting the application (Figure 6-4), a request is sent to the ASP file kept on the server, to which the ASP responds by reading the database of topics and sending the list of the topics in XML format. The XML parser reads this list, and it is shown in a scroll text box to the user. It is stored on the Palm device in a Palm database. When the user selects a topic for the exam, the ASP file reads the database on questions, picks up questions at random on the selected topic, and returns these to the client in XML format. The XML parser again reads these and then shows them to the user.
The flow of the program is shown in the flow chart and is explained as follows: Executing the Java class file TestManager starts the application. It causes the ASP file http://host/books.asp to read the topics stored in the MS Access file and return them in XML format. The XML parser parses the XML and stores the result in a Palm database on the PDA. The class MainScreen is called, which creates the GUI components and displays the text parsed from XML (the list of topics) on the scroll text box as shown in Figure 6-5.
The user enters the serial number of the test he wants to attempt and presses OK. At this, class QuestionParser is called. The choice is passed as a parameter to an ASP file called TestFile.asp as a search string. A file of the same name is created. For example, if the user entered 1, a file 001.xml would be generated. The parser again parses the XML which contains data related to the test ie the questions their choices and the correct choice of the respective question are stored in a database. An inner class of MainScreen, named NextScreen, is now called. It creates the new GUI components and displays the first question as shown in Figure 6-6.
Now the user has the option to press one out of these three buttons: Next, Prev (Previous), or Review. If the user presses one of the first two buttons, a function critical is called, which displays either the next question or the previous one, depending on the users choice. When Next is pressed, the correct answer of the question is matched with the answer selected by the user and, accordingly, one out of these four options is stored: Correct, Wrong, Unanswered, and Unattempted. This goes on till all the questions are answered.
If the user presses the Exit button, the application is closed. If the user presses the OK button, a function named critical is called. This function moves back to the question where the user pressed the Review button. If the user decides to quit the test, he can press the Result button. At this, the class NextScreen is called, which tells the user the details of the test as shown in Figure 6-8. It presents the results in terms of the following:
Name of the test Date on which the test is being taken Questions asked Correct answers to the questions asked Score in the test
TestManager.java
This is the main class of the TestManager. It starts the TestManager with a welcome screen and when the user presses the "OK" button it calls an XML parser and stores the results provided by the parser in the palm Database. This class calls the QuestionParser class internally.
Code explanation
Lines 1-8: The code between these lines pertains to the inclusion of the basic packages used by various classes in the project, such as java.util.* for vectors and enumerations and java.io.* for input and output. Lines 9-11: The code between these lines pertains to the inclusion of the packages required by the various classes in the XML parser. Line 14: The code here pertains to declaring the main class of the online Testing Engine. It starts the TestManager with a welcome screen. Subsequently, when the user presses the OK button, it calls an XML parser and stores the results provided by the parser in the Palm database.
138 Chapter 6: Project 1: Online Testing Engine Lines 17-27: The code between these lines pertain to declaring the temporary variables used for
storing the results. Lines 29-32: Declares the variables for the XML parser and parse event (where the callbacks after the parsing will be stored). Lines 34-39: Declares the variables for the DataInputStream for reading the ASP, for buttons (OK and Exit), for textbox (message), etc. Lines 42-51: This is the main program that indicates the starting of the Online Testing Application by calling the class TestManager. Line 56: The code here pertains to making the spotlet the current spotlet. The system keys can cancel the spotlet any time. Lines 58-60: The code here pertains to painting the buttons and the textbox on to the screen. Lines 63-68: Initializing the database by creating the name of the database, the creator- idis cid and the table-id is tidand subsequently creating the database. Lines 73-84: The code between these lines pertains to the action taken when the user presses the OK button. 75: The spotlet is unregistered thereby making way for the next spotlet. 77: The code here pertains to calling a function start (), which is used to send a request to the server. 80: A function parseData() is called in which the results of parsing are stored.
83: After storing the results, a call is made to a user-defined class, main_screen, which
pertains to the main testing portion. Lines 85-88: The code between these lines is used when the user presses the button Exit. When the button is pressed, the application is closed, and control is returned to the OS. Lines 94-105: The code here pertains to sending an ASP request to the server to get a list of all the available tests. This request is made using the class Connector of the CLDCs javax.microedition.io package. The server returns an XML file. The XML stream is then directly passed on to the parser, which parses the XML file.
Lines 108-168: The code between these lines pertains to an important function parseData. This is
the function in which the XML parser sends the callbacks. The callbacks are identified accordingly by using the functions (whether the element obtained is the start tag or end tag, etc). 118-119: If the tag encountered is SubjectID, the corresponding flag that is, subject_id is made true. 121-122: If the tag encountered is SubjectName, the corresponding flag that is, subject_name is made true. 130-133: If the flags (subject_id and root_flag) are true, the text obtained between the nodes is stored in a string variable of the name name1, separated by a predetermined delimiter (ALT + 232). Similarly, if the flags (subject_name and root_flag) are true, the text obtained between the nodes is appended to the variable name1. 137-152: When the end of the XML document is obtained, all the flags are made false, and the data in the variable name is appended by a last delimiter (ALT+237) and then finally converted into a byte array and stored into the Palm database created earlier. 165-167: When the end of the XML document is reached, the total number of records are counted and stored in the first recording place of the Palm database.
MainScreen.java
This class pertains to the TestManagers screen. This class shows all the number of tests available at a particular instant of time. When the user presses a choice, then a request is made to the central server to generate that test based on the choice made. The test generated is in XML format and is sent to the parser, after which the first question is shown to the user.
68) 69) 70) 71) 72) 73) 74) 75) 76) 77) 78) 79)
154) 154) 155) 156) 157) 159) 160) 161) 162) 163) 164) 165) 166) 167) 168) 169) 170) 171) 172) 173) 174) 175) 176) 177) 178) 179) 180) 181) 182)
Code explanation
Lines 1-5: The code contained in these lines pertains to the inclusion of the basic packages used by various classes in the project, such as java.util.* for vectors and enumerations and java.io.* for input and output. Line 8: The most important class of the online Testing Engine MainScreen is declared here. A list of all the tests available at a particular instant of time is shown. When the user makes a choice, a request is made to the central server to generate the XML file for that test, send it to the parser, and then show the first question to the user. Lines 12-18: The declarations of the static data variables, which are used by all the inner classes of the MainScreen, are encoded in these lines. These include examination code (exam_code), examination name (exam_name), and total number of questions in a test (total_number). Lines 21-39: The static function entry is declared here. This function is used to maintain a history of the tests taken by the user. 25: The data is stored in a specific position on the database that is, record number 65535. 26: The earlier data is retrieved from the location. 32: The old data is deleted from the location. 36: The new entry is added to the database location. Lines 45-47: The button variables bt and exit are initialized and a Textfield variable choicefield is declared. Line 60: The code here pertains to making the spotlet the current spotlet. The system keys can cancel the spotlet at any time. Lines 63-65: These lines initializes the TextField and put the cursor onto the focus. Line 69: A call to an important function is made known as reading(). This function reads the database created and puts the results in a proper format onto the ScrollTextBox and also stores the result in a 2-D array. It returns a String, which is put onto the ScrollTextBox. Lines 71-78: These are for initializing the ScrollTextBox variable of the name first and painting the buttons and the ScrollTextBox onto the screen. Lines 81-86: These are for initializing the database by creating the name of the database, the cid (creator id), and the tid(table id). This database is used to maintain the history of the tests undertaken by the user.
QuestionParser.java
When the user, after seeing all the available tests, selects a test to give, a request is made to the server to generate that test by calling an ASP of the name test.asp and passing it a parameter bookid = choice selected. The ASP then generates an XML file of the same name; the XML file is then passed on to the XML parser, which parses the XML; and the callbacks generated by the XML parser are stored in the Database.
Code explanation
Lines 1-8: The code here pertains to the inclusion of the basic packages used by various classes in the project, such as java.util.* for vectors and enumerations and java.io.* for input and output. Lines 9-11: These encode the packages required by the various classes in the XML parser. Line 12: This signifies declaring another important class of the online Testing Engine (QuestionParser). It sends a request to the server to generate a test on the basis of the test number of the test passed to it as a parameter. It then parses the XML response sent by the server and stores the result of the parsing in a Palm database. Lines 15-20: Various Boolean flags used in parsing are initialized to false.
Lines 116-139: When the end tag (question) is encountered, the respective flags are reset and the name (variable ) is stored on the database. Lines 147-149: When the end of the XML document is reached , the total number of records are counted and stored in the first recording place of the Palm database.
Books.asp
This asp file is requested for the list of topics available on which the test can be given. The asp file sends query to the database and generates XML data to be sent as response to the client.
Code explanation
Line 5: Variables are declared here. Lines 6-9: An ADODB connection object with name conn is created here, which is used to establish the connection with MaintenanceSoft database on the MS-Access. A connection object represents an open connection to a data source. Here ADODB connection object is used to establish a connection with MS-Access. A connection object is needed to acces data using data environment and will represent a connection to a database residing on server that is used as a data source. Lines 10-13: The new instances of the ADODB recordset are created here and have names objrs,objrs1 and set their CursorType as adopenstatic . A cursor type is way to cache data on the client machine and to provide local scrolling, filtering and sorting capabilities. Adopenstatic is a static copy of a set of records and can be used to find data or generate reports, in this changes by other users are not visible). Lines 14-16: A SQL query is defined in the variable tsql which is selecting distinct subjectID from the QuestionData table. Then selected record will be opened in the objrs recordset. Lines 17-23: Function changequote is defined here. This function stores the passed parameters value in the tmpstring variable. Then this function calls the REPLACE function to replace the escape sequeces like <, >, &, into <, >, &, " respectively in the tmpstring and then returns the resulted string. Lines 24-40: An XML is generated on the base of the records selected in the objrs recordset. A SQL query is defined in the variable sql1 which is selecting SubjectName from the MainData table
TestFile.asp
This asp file is requested for the test questions on the basis of topics given as parameter given to this asp. The asp file sends a query to the database and generates a set of questions with choices and answers in XML data to be sent as responses to the client.
Summary
This chapter was the first full-blown application developed using J2ME for Palm devices; there are five more such applications described in the coming chapters which will make the reader conversant with J2ME technology. We have another application based on CLDC and Kjava APIs in Chapter 11. You can go to Chapter 11 directly if you are interested in developing a game for Palm devices, as Chapter 11 is based on developing a game using CLDC and Kjava APIs. In Chapter 7, we will develop an application using MIDP APIs.
Chapter 7
User Interface
The main class of the project is named OrderManager. It contains the GUI components and displays the list of items and the stock available. It receives the quantity being ordered, calculates the total amount of the order as well as the cost, and updates the database by calling a JSP script. It has an inner class named GetData, which opens a URL and reads XML data on the fly. This class calls a JSP script, which queries the database and generates XML data about the item, quantity available, and the cost. It uses a Java-based XML parser to parse XML data. On starting the application, the user sees a screen displaying the items and their available quantities. He can select an item by pressing Enter. On this, a text field appears in which the quantity to order can be entered. He can press the Save button so that the quantity is saved. Or he can go back to the list of items by pressing the Back button. He can order as many items as he wants and can even change the quantity of an item previously selected. At the end, he can quit by pressing the Exit button.
How It Works
The project includes the following files: OrderManager.java: The main file, which also includes an inner class called GetData. sql_xml.jsp: The JSP script that returns data from the database. sql_order_mon.jsp: The JSP script, which updates the database according to the order placed. A third-party XML parser.
OrderManager demonstrates the way in which a J2ME application can be used in concert with an existing J2SE or J2EE application. The supplier may already have a J2SE or J2EE application for receiving orders from customers sitting in front of their PCs. This means there is already an application running for receiving requests and sending response. In the present case, this is done by using Java Server Pages. The items and their quantities available are stored in a database on the server. Lets go through the database table structure which stores the data on the server. There are three tables in the database, namely stock_mast table,Order Table, and Status Table.
The table stored in Figure 7-1 is stock_mast table. The field item_code stores information related to the code of the item, field quantity stores information about the quantity of item available, and the field unit_price stores information about the per unit price of the item.
The table shown in Figure 7-2 is the order table that stores information related to the order placed. This field order_id stores information related to the order id, field order_date stores information about the date on which the order was placed, field item_code stores information about the item ordered, field quantity stores information about the quantity ordered and the field rate stores information about the amount or the total price of order.
There are two JSP scripts one reads the database and displays the list of items and their quantities, and the other saves the values of quantities ordered by the customer to the database. The J2ME application does the rest. The control flow of the project is explained in the following paragraphs and is also shown in the flow chart: The application is started (Figure 7-4) by executing the Java classfile OrderManager.
The inner class GetData is called, which in turn calls a JSP script named sql_xml.jsp. This JSP reads the database, where items and their quantities are stored, and returns the item code, quantity available, and the unit price of the item in XML format. The XML data is parsed in the parseData method of the GetData class by using a third-party XML parser. It is simultaneously stored in vectors. After the data has been completely parsed, the values of the items stored (quantity and price) are returned. At this point, the list of items is displayed, showing quantity and item codes in Figure 7-5.
The user can either press the Total button or select an item (see Figure 7-5). If he selects an item, the next screen is displayed with a text field in which the quantity to order can be entered as shown in Figure 7-6. After entering the quantity, the user can press either the Back button or the Save button as shown in Figure 7-7. If the former, he is returned to the list of items. If the latter, the quantity entered is saved. The user presses the Back button to go back to the list, which will display the screen shown in Figure 7-5.
If the user presses the Total button shown in Figure 7-5, a new screen appears that displays the total amount ordered per item and the total order shown in Figure 7-8. The user can press either the Back button or the OK button. If he presses the former, he is returned to the list shown in Figure 7-5. If he presses the OK button, a JSP script, sql_order_mon.jsp, is called, values is passed as parameters, and the database is updated to store the ordered values.
Now the user can press the Exit button to quit the application. This button is present on earlier screens, too, so the user could have quit at any stage, even without ordering anything. If the user presses the OK button without entering anything, an error screen is displayed for some amount of seconds (in our case, 5000 milliseconds see Figure 7-9).
Code explanation
Lines 1-30: This includes the basic packages required by the different classes during the program. These statements import various GUI components such as TextField, List, and StringItem; Collection classes such as Vector and HashTable; HTTP Connection classes such as HttpConnection and Connector; classes for XML parsing; and classes for Communication such as InputStream and InputStreamReader. Line 39: This declares the class OrderManager. Lines 42-78: The declaration of objects. The objects declared are Vector objects for storing XML data; the GetData object, which is an inner class for the OrderManager class; objects for User Interface classes such as List, Form, and several Command objects. Lines 81-95: This represents the constructor for the class OrderManager. These lines initialize List, HashTable, and different Command objects. The commands are generated when the user presses any button on the device, and these commands are recognized using the Command objects. Line 98: The declaration of the startApp() method, which is called when the MIDlet starts. Lines 101-116: These lines initialize the GetData class. This class reads XML data from an HttpConnection and parses the XML data. The parseData() method of the GetData class parses the XML data and stores the required data in three different Vectors: the methods returnItem(), returnStock(), and returnPrice(), containing the item, the quantity, and the price of the item, respectively. Lines 120-125: The code is a for Loop to get the items and the quantity from the Vectors and append them to the list that will be displayed to the user. Lines 127-147: Displays the list and the two commands added to the list: the Exit command and the Total command. It also initializes two forms: the entryform with the backcommand added to it and the displayform with goback and okcommand added to it. Line 154: Declares the commandAction method, which performs the action when the user presses a button. Lines 160-182: An if condition that is executed when the user selects an item in the List. The String representation of the selected item is stored in a String object str. The object item code is extracted from that String. A TextField object is initialized. The if condition next to this will
Code explanation
Line 6: Initialize and load the JDBC-ODBC driver. Line 8: To get the database connection. The JDBC url should contain a data source name (DSN), UserID, and the password for the ODBC data source. Line 10: To create statement object to execute the SQL Statement. Line 11: Declaring variable for storing the resultset of the statement. Line 13: Writing an SQL String, passing it to the DBMS and executing the statement. The SQL statement selects the item code, Quantity and unit price from the stock_mast table for displaying it. Line 14: While loop for checking the next record in the recordset. Line 15: Inserting the value of "item code" from the recordset rs in String variable name. Line 16: Inserting the value of "quantity" from the recordset rs in integer variable aId. Line 17: Inserting the value of "unit_price" from the recordset rs in integer variable uPrice. Line 19: Displaying the item code, quantity, unit price in the item code, quantity, unit price tags. Line 21: Closing the while loop Line 23: Closing the recordset rs.
%>
Code explanation
Line 1: Initializing and loading the JDBC-ODBC driver. Line 2: To get the database connection. The JDBC url should contain a data source name (DSN), UserID and the password for the ODBC data source. Lines 5-7: To create statement objects to execute the SQL Statements. Line 9: Declaring variable for storing the resultset of the statement. Lines 11-23: Declaring and intializing integer and string type variables. Line 25: Declaring and initializing the date type object now Line 27: Inserting the value of day in the variable day_date Line 28: Inserting the value of month in the variable mon_date Line 29: Inserting the value of year in the variable year_date Line 31: Inserting the parameter "value" int the string type variable parameters. Line 33: Writing an SQL String, passing it to the DBMS and executing the statement. The SQL statement enerates the next order no.from the status table which keeps the track of the current order no in process. Line 34: While loop for checking the next record in the recordset. Line 36: Inserting the value of "order_id" from the recordset in oId variable Line 37: Displaying the oId variable in the order_id tag. Line 39: Inserting the date object in the order_date tag and displaying the date in the date format (dd/mm/yyyy) Line 41: closing the while loop. Line 42: Closing the record set rs. Lines 44-45: Incrementing the value of order no and inserting the current order no in the status table. Line 48: Declaring the string tokenizer st Line 49: While loop for checking for more tokens in the string st. Line 51: Inserting the value of "item_code" from the String variable st by checking for more tokens. Line 52: Inserting the value of "quantity" from the String variable st by checking for more tokens. Line 53: Inserting the value of "unit_price" from the String variable st by checking for more tokens. Line 54: Writing an SQL String, passing it to the DBMS and executing the statement. The SQL statement inserts the order details (order_id, order_date, item_code, Quantity and rate) in the order table. Line 56: Closing the while loop Line 59: Closing the connection.
Summary
This chapter was a second full-blown application developed using MIDP for Mobile Phone. There are four more such applications to come in the following chapters. After going through this chapter, you
Chapter 8
By leaving the values for these environment variables blank, we actually remove them from the memory to avoid using other Java libraries we might have installed. We can now run any Java application in our pJava Emulation Environment:
C:\pjee3.1\bin\pjava myJavaApplication
The preceding command assumes the Environment has been installed in the default directory (pjee3.1), which you will need to change if you have installed it anywhere else. You can also alter your path to allow you to run the Environment directly:
set PATH=%PATH%;c:\pjee3.1\bin
Many applications will give errors when you try to run them using pJava. If any unsupported APIs are being used, such as Swing, the application will not run. Applications that don't make use of these APIs will work perfectly, and you may be surprised to see that they dont appear at all different from what they appear in Java 2 Standard Edition. Since the APIs not supported by pJava are normally the most recently developed ones, you will find that older Java applications should run perfectly without modification. If you are developing under Microsoft Windows or Solaris, it's worth doing all your development using the pJava Emulation Environment, as it is easy to forget the limitations of the APIs available.
JavaCheck
JavaCheck is an application, written in Java, which analyses Java source code to confirm that it contains only API calls available in pJava. The intention is that it will, eventually, be able to analyze applications intended for different deployment platforms (such as CDC and the KVM), but for the moment, it supports checking only pJava compatibility. While the pJava Emulation Environment will warn us if we try to use anything that isn't supported, it can be helpful to be able to run large amounts of code through a checking device, particularly if we are porting an existing application. It is also very useful if we don't have access to the pJava Emulation Environment (that is, if we are developing on a platform other than Microsoft Windows or Sun Solaris), where it provides the only method of checking our compatibility before deploying on the target device. There are four possible states for an API: It can be Supported, Unsupported, Modified, or Optional. Supported APIs are obvious, and Unsupported is pretty clear, too. Modified APIs are slightly more complex, though the modifications are rarely as important as they might first appear. A good example of a Modified API is the Frame class, which, in pJava, can exist only once in each application. Many classes are considered Optional, and this should be of concern to anyone developing applications for deployment on multiple platforms. However, at the time of writing, every pJava implementation implements every Optional class, making this much less of an issue. Future implementations may not have the Optional classes available, though this seems unlikely given the wide support already available. JavaCheck can be downloaded from http://java.sun.com/products/personaljava/javacheck.html. It is important to download not only the application itself, but also a specification file for the version of Java you wish to test against. As already mentioned in the first paragraph of this section, the only specification available is for pJava, but it still comes in a separate file and must be downloaded separately. JavaCheck can be run in two different modes: from the command line or with a graphical user interface. Using the GUI is simple and effective. The GUI of JavaCheck can be invoked by executing the command:
java JavaCheckV
The V at the end of the name denotes that you are running the Visual version (with its GUI). We might also want to specify the CLASSPATH where the application can be found, which will depend on where we decided to install it. In my case, it's in a directory called utils, so I would run the application as follows:
java cp /utils/JavaCheck/bin/JavaCheck.jar JavaCheckV
This will give us the following screen (Figure 8-3). Note the message at the top indicating that we have to load a specification file (see Figure 8-3); we select the specification file that we have already downloaded. Now we use the next Tab Classes as in Figure 8-4 to specify what files we want to check.
Now that we've selected the files, we can start the analysis, which takes only a few seconds to produce the following result as shown in Figure 8-5.
It should come as no surprise that these classes do not conform to the pJava specification, as the application was not intended to be used on a CDC device, but this shows the kind of result you could expect. (Though this particular result would show that a lot of work is necessary to get these classes ported!) Selecting a particular class listed in the bottom window will show you some information about what the problem might be and what you might be able to do about it. We can also invoke JavaCheck as a command-line application, though we have to specify everything on the same line:
C:\temp>java -cp /utils/JavaCheck/bin/JavaCheck.jar JavaCheck -v -i /utils/JavaC heck/specs/specs/pJava_1.1.0.spc -classpath .
The parameter -v specifies that we want a Verbose response (with all the details), and -i specifies the specification file we want to use, while the -classpath points to where the files to be analyzed are located. The current directory is specified for the classpath, with the use of a ., so I'll run this
The only thing we really have to worry about are the Unsupported and Unresolved classes; in this case, there are no Unsupported classes, so if we wanted to port this to a pJava platform we would need to look at the Unresolved classes, that is, the classes which the Java Check was not able to resolve.
How It Works
The first task is to define the protocol we are going to use for our communication. While there are many standard protocols available to choose from, we will be defining our own. Conforming to standards is often very useful, but any standard protocol will lead to gains in flexibility being offset by costs in efficiency. Depending on your application, you may wish to use HTTP or a similar protocol for the convenience of passing through firewalls, etc., though this will add considerably to the processing load imposed by the networking, which is something we want to keep to a minimum.
Note that the listing is terminated with a single full stop alone on a line. This is a standard way of terminating a list of unknown length. (This list will be as long as the number of tracks loaded by the server.) This will cause a problem only if we ever have a track called ., which is not only unlikely, but as the track names are based on the file names, it is actually impossible on most personal computer systems. We will also add a command, status, which simply responds with the currently playing track; this will enable the client to display the currently playing track on request. We also have to decide on the case of the commands and responses. This is important, as it can cause hard-to-find problems later unless properly specified. In common with many modern protocols, we're going to define ours to be case-insensitive; any mix of case upper- and lowercase characters can be used. This will add some processing overhead but will prevent later problems. Once we have defined our format, it's worth going through a dry run, working through typical clientserver communications with a paper and pen to be certain we understand what's going to happen and to give us some examples to work from when we are testing the application. We will use a directory full of MP3 files and go through how the client and server communicate. See Table 8-1.
Open Connection +OK Next +Playing Track Babylon Zoo Spaceman Close Connection
Open Connection +OK Previous +Playing Track EMF You're Unbelievable Close Connection
Open Connection +OK Last +Playing Track Petula Clark Downtown Close Connection
Open Connection +OK First +Playing Track EMF You're Unbelievable Close Connection
Open Connection +OK Play 3 +Playing Track Men Without Hats Security Close Connection
Open Connection +OK Resume +Playing Track Men Without Hats Security Close Connection
This table shows us all the possible commands and the responses. We could go on to define the various error messages which could be returned and how we might cope with them, though we might want to start development to see the kind of problems that crop up. As this system simply allows a server to be controlled by a client through discrete transaction-based communications (one connection for each command), any error will be dealt with by shutting down the network connection and starting again. Our server will not accept more than one command per connection, each transaction can perform only one action, and it's worth looking at why we have made this limitation and when it would be inappropriate. Our application is designed to give control of a function operating on a server to a client application and is strictly a "control" relationship. Having each command as a separate connection does add considerable overhead but makes for a much simpler client and server and makes error recovery easier. Because each transaction is independent, any individual transaction failure can be fixed just by repeating the transaction. While this model of operation may not be suitable in every circumstance, some applications may have continuous communications between client and server and save resources by holding a connection open; in many situations, the simplicity and robustness outweigh the cost in resources. It is worth noting that this is the model on which HTTP operates and so do all Web-driven interfaces. The next two figures display the flow of the application. Figure 8-6 displays the flow of server application and Figure 8-7 displays the flow of client application.
How to Run
To run the server you have to type the following command on the command prompt.
java MP3Player java MP3Player d:\mp3\
The actual process of installation the client will vary depending on the device being used. Since we are working with a Pocket PC device, we will be looking only at how to install the application onto that platform, which is very simple indeed. Other devices normally are similarly simple to use, but you will need to check the device documentation for details. In order to be able to execute PersonalJava applications, the device first has to have a Java Virtual Machine installed. Most of these are available from Sun, though some companies provide their own implementation (for example, Symbian for the EPOC JVM). At the time of writing, the Pocket PC JVM is at final beta stage and is available only to users registered with the Sun Developer Connection, which requires (free) registration: the following URL should be used to register:
http://developer.java.sun.com/developer/earlyAccess/personaljava/
Once the beta is completed, the final version should be available from:
http://www.javasoft.com/products/personaljava
The file is provided in the form of a Pocket PC CAB file, which should be copied onto the device and executed. Follow the on-screen prompts to install the JVM. Once the JVM is installed, it's just a matter of copying your class files onto the device and executing the file containing the main() method (MP3Client.class in our example). This application MP3Client , when run, will produce something that looks like Figure 8-9 (though the exact appearance will, of course, depend on the device in which it is run).
MP3Player.java
This class is part of Server for this application and caters to the request sent by the client. This class is the main class and is responsible for invoking the other three classes which are NetDeamon, GUI and Track.
Code explanation
Lines 1-6: These lines are the normal import statements you would expect to see in any Java network application. Lines 8-13: These lines contains our class variables. playList stores all the Track objects we will be listening to and forms our play list. myGUI will be our graphical user interface, allowing the application to be used in standalone mode. myDeamon is our networking object, which will handle all the client commands. The currentlyPlaying variable holds the track that is currently being played. Lines 14-23: Our main method is used to instantiate an instance of MP3Player, so we don't have to work with a static object. We want the application to be able to take a directory specified on the command line here in these lines we check to see if a directory has been specified and run the appropriate constructor. Lines 24-29: In these lines the constructor is used if a directory has been specified on the command line and creates the graphical user interface, network interface, and a new play list using the changeList() method. Note that NetDeamon is a threaded class and needs to be started here. We pass a reference to the GUI and network interfaces to allow them to call methods of our instance of MP3Player when commands come in (from the GUI or network). Lines 30-35: The second constructor in these lines is almost identical, but runs a method of the GUI object to allow the user to select a directory using a FileDialog. Lines 36-41: In these lines the method allows the selection of a particular track from the play list, which will be started. Note that the currentlyPlaying track must be stopped first, as the Java Media Framework is multithreaded and will happily play two tracks simultaneously, which makes for interesting effects, but not relaxing listening! We also have to tell the GUI that the track has been changed so it can update its display. If we wanted to have server-initiated contact to update
NetDeamon.java
This class is part of Server for this application. This extends thread and is used for receiving client connection and sending response to the client.
Code explanation
Lines 1-6: These lines are the normal import statements you would expect to see in any Java network application. Lines 8-11: This class declared is used to handle the networking aspects of the client, receiving client connections, and responding to the commands issued by the client. Lines 12-15: In these lines a reference to the MP3Player object that instantiates this class is kept to allow us to call methods of that object when we receive appropriate commands. This reference is stored in the class variable parent. Lines 16-40: This is our main loop of the networking daemon; it enters an infinite loop and waits for an incoming connection. Contact is responded to with +OK, and the incoming message is then sent to the processMessage() method in uppercase to maintain our requirement for caseinsensitivity. Since all communications consist of a single command and response, we shut down the network connection. Note the use of the flush() method after every network communication; this is very important, as otherwise communications can be lost when the connection is closed. Missing out the flush() method not only causes problems, but the problems are very hard to locate. Lines 41-96: Here in these lines we just have an if block that looks to find out what the incoming command is and carries out the appropriate action. Most of the commands are very simple, with only the "TRACK LISTING" command being complex, and that just requests an ArrayList of all the tracks from the parent object and outputs their names to the client. Almost all the commands respond with the name of the currently playing track, so we have a separate method just for that function: Lines 97-101: The method in these lines is used to send the currently playing track, with "+Playing" at the start, as specified in our protocol.
GUI.java
This class is part of Server for this application. This class creates and displays the Graphical User Interface for the application. It allows the user the same interaction as the client object but locally to the server. It would be possible to create this application without any interface at all, relying on the client to issue all the commands and specifying the directory on the command line when the server is run. However, having a local GUI makes testing a great deal easier and makes the application more useful. The ActionListener interface is used to catch menu events, allowing the user to change the directory to be used.
public class GUI implements MouseListener, ActionListener { Frame f; java.awt.List nameList; Panel extras; Panel buttons; Button first,previous,next,last; Label playing; MP3Player parent; public GUI(MP3Player MP3) { parent = MP3; f = new Frame("My MP3 Player"); nameList = new java.awt.List(); first = new Button("First"); previous = new Button("Previous"); next = new Button("Next"); last = new Button("Last"); first.addMouseListener(this); previous.addMouseListener(this); next.addMouseListener(this); last.addMouseListener(this); buttons = new Panel(new GridLayout(1,4)); buttons.add(first); buttons.add(previous); buttons.add(next); buttons.add(last); MenuBar myMenuBar = new MenuBar(); Menu myMenu = new Menu("Directory");
Code explanation
Lines 1-6: These lines are the normal import statements you would expect to see in any Java network application. Lines 8-16: These lines contain our class variables and should be familiar to any Java programmer. We aren't using Swing components for this application; the interface isn't complex enough to make it worth using. These are all AWT classes. Note the last variable, parent, which is used to maintain a reference to the MP3Player object, which instantiates this object. It means that we can call methods of that object when the user presses buttons, etc. Lines 18-55: The constructor in these lines is fairly typical of Graphical User Interface objects and shouldn't present any surprises. An anonymous adapter is used to close the application if the user
Track.java
This class is used to represent the actual files themselves and handles all the JMF functions. The JMF is not complex, at least for this level of functionality, and even if you're not familiar with this, you should have no problem following the example. The ControllerListener interface is used in the JMF to allow an object to respond to media events, as we shall see.
public class Track implements ControllerListener { File details; Player p; MP3Player parent; int number; public Track(MP3Player mp, String fname, int n) { number = n; parent = mp; try { details = new File(fname);
Code explanation
Lines 1-6: These lines are the normal import statements you would expect to see in any Java network application. Lines 8-13: These lines contains our class variables; we keep track of the file as well as creating a Player object (from the JMF) and a reference to the MP3Player object that instantiates this class. We also keep track of our position in the play list, so we know what track comes next! Lines 15-40: The constructor these lines creates all the class variables, including the Player object we'll be using to control the audio media. Note that the Player is created from the static Manager class, as specified in the JMF. We also use the realize() and prefetch() methods of Player, which causes the JMF to allocate resources to the Player object and gives us a very fast response when we start playing the audio. If we left out these two lines, the application would still work but would have a delay when we started playing every track. Lines 42-49: These two accessor methods declared in these lines just return details of the audio file being played. Lines 50-53: This method in these lines returns the control panel for the Player object. For audio files, this consists of a sliding bar and pause button. Lines 54-78: The method is required by the ControllerListener interface; it receives events relating to the audio file. Note that we actually ignore most events, becoming interested only when the track is finished and we want to move on to the next track. Lines 79-91: The methods in these lines pass on commands to the Player object. Note that the last method resets the position within the file to the start; without that, the object would remember where it was in the file and return to that position when play was requested next time.
MP3Client.java
This class is a part of client application a will run on the device. This class interacts with the server the communication between the client and the server is socket based. This class provides the GUI for the client running on the Device.
public class MP3Client implements MouseListener { Frame f = new Frame();; Button first, previous, next, last, pause,update; Label status = new Label();; List tracks; String server; public static void main(String args[]) { MP3Client myClient = new MP3Client(args); } MP3Client(String[] args) { if (args.length != 0) { go(args[0]); } else { ServerDialog getServer = new ServerDialog(f,this); } } public void returnServer(String s) { go(s); }
Code explanation
Lines 1-5: The import statements are very typical for any Java application intended to have a graphical interface and provide networking capability. Line 7-13: Here we define our class variables, including our graphical objects and a String that we will use to hold the name of our server (its IP address). Lines 15-18: Our main method in the preceding lines instantiates an instance of the MP3Client class . Lines 20-30: The constructor in these lines checks to see if a server has been defined on the command line or if the user should be presented with a dialog box asking the user to specify a server. While specifying on the command line may be preferable, it should be noted that not every device or operating system has a command line available to the user. Pocket PC devices, for example, do not offer the user any kind of command line, and while parameters for Java applications can be specified through the use of platform specific settings, it's much easier to just ask the user where the server is. Lines 32-35: The getServer object (an instance of the ServerDialog class) calls the returnServer method defined in these lines when the user gets connected to a server.
ServerDialog.java
This class is a part of client application a will run on the device. This class provides a Dialog box to the user for entering the server details.
class ServerDialog extends Dialog implements MouseListener { MP3Client parent; TextField t; ServerDialog(Frame f, MP3Client mp3) {
Code explanation
Lines 1-5: The import statements are very typical for any Java application intended to have a graphical interface and provide networking capability. Line 7-10: This class simply presents a dialog box to the user to enter the name, or IP address, of the server to connect to. Lines 12-25: The user interface for this dialog box is very simple, consisting of only a Button, a Label, and a TextArea. Lines 26-30: When the OK button is pressed, the dialog box calls the returnServer()method of the object that instantiated this dialog box and makes itself invisible. Note that no attempt is made to establish if the server exists or is a valid server, though this functionality could be added without significant work. Lines 31-35: These methods in the preceding lines are required by the MouseListener interface.
Summary
This application shows a typical use of a PersonalJava compatible device being used to provide a mobile user interface to a server-managed operation. It is this capability to take applications with you that has made mobile devices so popular, and by using applications of standard socket communications, the application should be able to operate worldwide without difficulty. While it is possible to generate much more complex client-side applications, it is important to consider the limitations of the device. If large amounts of processing are being done on the client, something is wrong, and the application design should be looked at to see if more work couldn't be shifted to the server to reduce the load on the client. Mobile devices should be considered to be extensions of the desktop; while laptop devices provide much of the functionality of their desk-top equivalents, handheld devices never will, and it's important to remember that. By allowing users to take their interfaces with them, you can provide all the functionality of a desktop application without the processor load associated with it.
Chapter 9
User Interface
When you start the application, the starting screen shows just two buttons: Start and Exit. Press the Start button and the next screen shows a scrollable list of users currently connected to the same server using this application. Being connected means that they have logged on to the Net with this application. Files can be searched in two ways: One is the server-level search, and the other is the user-level search. Serverlevel search is useful when the user knows what files he wants or at least some characters in the name of that file so that he can then use wildcards for conducting the search. For example, if he knows that the name of the song he wants has the word rock in it, he can use this information as the search criterion and
How It Works
This application consists of five class files namely, peer_application, userlist_screen, serversearch, searchfiles, and showfiles. In addition, it uses an external XML parser available in org.kxml.parser package. The application is started by executing the first class file that is, peer_application. This class performs the following tasks: Importing the packages required, including those for handling and parsing XML (org.kxml.*, org.kxml.io.*, org.kxml.parser). Declaring variables for the XML parser, parse event, IP address, user list, and the text to be displayed in ScrollTextBox. Using the Graphics class to clear the screen and display the text welcoming the user, through clearScreen and drawString methods, respectively. Putting Start and Exit buttons on the screen by using the paint method. Defining event handling for the buttons via the penDown method. If the Start button is pressed, the current spotlet is unregistered and the method startReading is called. The Callbacks generated by the XML parser in the method parseData() are stored in three variables namely, ip_address, users_connected, and text_for_display. Calling a method named startReading, which is responsible for sending a request to the server for the list of users connected at any time. Instantiating and calling the class userlist_screen, which displays the list of users. It takes its parameters as the three variables previously mentioned. Closing the application in case the user does not want to go further and presses the Exit button. Defining the method startReading. This method instantiates the preceding three variables and opens an InputStream on the ASP file named userlist.asp. It also shows an error if an IOException occurs. Defining the method parseData. It uses the XML parser previously mentioned and finds the userinfo tag with the help of a dowhile loop and an if block. The attributes of this tag are obtained by using the getValue method and are then added to their appropriate positions. The vector ip_address is then returned to the calling class.
Declaring variables for buttons, ScrollTextBox, TextField, StreamConnection, XML parser and parse event, String variables folder_data, file_data, vectors for the previously mentioned variables, and two more variables (folder_vector and record_of_users). Defining the constructor of the class to take text, ip_address, users_connected, viewfile_flag, and record_of_users as the parameters. The parameters are then initialized by the variables earlier defined. Using the Graphics class to display the user interface elements. Defining event handling via the keyDown and penDown methods. The former handles the input if the TextField is in use, and the latter handles the event of buttons being pressed. If necessary, control is transferred to a relevent class. For details of this method, you can refer to the line-by-line explanation after listing userlist_screen.java. Defining the method appropriatelength, which is called to make the application compatible with C# listeners. It is required because the C# listener cannot read more than 1,024 bytes at a time. This method takes an array called file_bytes and an integer called file_size as parameters and returns a byte array. The class showfiles is called when a user is selected whose files/folders he wants to view and has pressed the Browse button as shown in Figure 9-2. It performs the following tasks:
Creating the user interface for the screen showing shared files and folders as shown in Figure 9-3.
The class serversearch is called when the user wants to search on all users as shown in Figure 9-4. It takes care of the following tasks:
Declaring variables, buttons, TextField, DataInputStream, Vector, ip_address, and users_connected. Displaying the user-interface elements by using the Graphics class. Defining event handling through the keyDown method. It serves the purpose of shifting focus when the Tab key is pressed. Defining event handling through the penDown method. This method handles the events generated by pressing the buttons. If the Search button is pressed, the results satisfying the search criterion are displayed as shown in Figure 9-5. For details of this method, refer to the line-by-line explanation after Listing 9-5, serversearch.java. Defining the method parseData that holds the callbacks generated when XML parsing is done.
The class searchfiles is called when the user has browsed to another user and wants to conduct a search as shown in Figure 9-6. It performs the following tasks:
Declaring buttons, TextField, Strings (parent_information, text_for_display, folder_data, file_data, and host_address), XML parser and parse event, Vector folder_vector, StreamConnection, InputStream, and OutputStream. Defining the constructor to take address and parent_information as the parameters. The parameters are initialized with the variables already declared. Drawing the user-interface elements, including buttons and TextField. Defining event handling through penDown and keyDown. The former simply calls the latter if an option has the focus. The penDown method responds to events generated by pressing the button. The method appropriatelength is called to provide compatibility with C# listeners. The basic flow of the program is shown in the flow chart (see Figures 9-7 and 9-8).
Source Code
Source code for peer_application.java, java userlist_screen.java showfiles. serversearch.java, searchfiles.java is given in Listings 9-1, 9-2, 9-3, 9-4, and 9-5, respectively.
Declaring three important variables ,IP_addresses of vector type to store the IP_addresses, a vector type variable users_connected which consists of list of users connected and a String variable of the type text_for_display which consists of the text to be displayed on the ScrollTextBox. Vector ip_addresses; Vector users_connected; String text_for_display; int counter = 1;
/** * This is the main method which indicates the starting of the peer * to peer application by calling the class peer_application. */ 27. public static void main(String args[])throws Exception 28. { 29. peer_application peer_to_peer = new peer_application(); 30. } 31. // Constructor for the class peer_application. 32. public peer_application() 33. { // To make the spotlet as the current spotlet.. 34. register(NO_EVENT_OPTIONS); 35. Graphics graphics = Graphics.getGraphics(); 36. /** * Initializing the variable of the graphics class and clearing * the drawing region by calling the appropriate functions of * the Graphics class namely (resetDrawRegion() and clearScreen()). */ 37. graphics.resetDrawRegion(); 38. graphics.clearScreen(); /** * Displaying a string (Title) at a specified position by using * the member function of the Graphics class */ 39. graphics.drawString("Peer to Peer System..",25,10); 40. /** * Initializing the button object Start, placing it on the screen * at the appropriate position and then painting(drawing it). */ 41. start = new Button("Start",30,145); 42. start.paint(); 43. /** * Initializing the button object exit, placing it on the screen * at the appropriate position and then painting(drawing it). */ 44. exit = new Button("Exit",70,145);
// Using the Connector class of CLDC an InputStream is opened on // the ASP 73. din = Connector.openDataInputStream("testhttp://www.scop.com/userlist.asp"); 74. // The InputStream opened on the URL is passed on to the XmlParser. 75. xmlparser = new XmlParser(new InputStreamReader(din)); 76. } 77. catch(IOException e) 78. { 79. System.out.println("Exception Occured while reading the XML from asp or while passing it to the XML parser"); 80. } 81. } // End of the method Startreading().. 82. // Function parseData (it will hold the callbacks generated by the // XMLParsing. 83. Vector parseData() 84. { // Move in infinite loop till the XML document ends.. 85. do 86. { 87. try 88. { 89. event = xmlparser.read (); 90. 91. if(event.getType()==Xml.START_TAG) 92. { // The StartTag is identified. 93. StartTag stag = (StartTag)event; 94. 95. String name = stag.getName(); 96. // If the Tag encountered is userinfo then the Attributes of the // tag are taken using the function getValue() and are added at // their appropriate positions. 97. if (name.equals("userinfo")) 98. { 99. 100. text_for_display = text_for_display +counter + ". " +stag.getValue("username")+"\n"; 101. ip_addresses.addElement((Object)stag.getValue("ip")); 102. users_connected.addElement((Object)stag.getValue("username")); 103. counter++; 104. } 105. 106. } 107. 108. } 109. catch(IOException ex)
118. return (ip_addresses); 119. } 120. // A function to return the TextforDisplay to the calling program 121. String returnTextForDisplay() 122. { 123. return (text_for_display); 124. } 125. // A function to return the vector usersConnected to the calling program 126. Vector returnUsersConnected() 127. { 128. return (users_connected); 129. } 130. } // End of class
Code explanation
Lines 1-8: Details the basic packages used by various classes in the project, such as java.util.* for vectors and enumerations and java.io.* for input and output, etc. Lines 9-11: Details the inclusion of the packages required by the various classes in the XML parser. Line 13: Declaration of a class peer_application. This is the first class of the Peer-to-Peer application project, which welcomes the user to the application, and on pressing the Start button, the user can go on to the actual task of the application. Lines 16-17: Declaring variables for the XML parser and parseEvent (where the Callbacks after the parsing will be stored). Lines 19-22: Declaring the variable for the DataInputStream for reading the ASP, for buttons (Start and Exit), for TextBox (message), etc. Lines 23-26: Declaring three important variables, ip_addresses of vector type to store the ip_addresses; the vector-type variable users_connected, which, as the name suggests, contains the list of users connected; and a String variable of the type text_for_display, which contains the text to be displayed on the ScrollTextBox. Lines 27-30: This is the main method that indicates the starting of the Peer-to-Peer application by calling the class peer_application. Lines 34-38: The code between these lines pertains to making the spotlet the current spotlet, initializing the variable of the Graphics class, and clearing the drawing region by calling the appropriate functions of the Graphics class namely, resetDrawRegion() and clearScreen(). Line 39: Displaying a string (Title) at a specified position by using the member function of the Graphics class.
12. private Button refresh; 13. private Button search; 14. private Button viewfiles; 15. private Button browse_user; 16. private Button exit; // Declaring ScrollTextBox and textField variables. 17. private ScrollTextBox userlist; 18. private TextField option; 19. Vector ip_address; // Declaring StreamConnection variable used for Sockets.. 20. StreamConnection socket = null; // Declaring InputStreams and OutputStreams used by the socket // connections. 21. InputStream socket_inputstream; 22. OutputStream socket_outputstream; /** * Declaraing variables for the xmlparser and parse event(Where * the callbacks after the parsing will be stored. */ 23. AbstractXmlParser xmlparser; 24. ParseEvent event; /** * Declaring variables for storing the parameters passed on to * the class. */ 25. Vector folder_vector; 26. Vector users_connected; 27. String text_for_display; /** * Declaring variables to folder_data where the folder information * is stored, similarly the variable file_data where the file * information is stored. */ 28. String folder_data; 29. String file_data; 30. int counter; 31. String address; 32. String user_data; 33. Vector record_of_users; 34. // Constructor of the class userlist_screen is called.. 35. userlist_screen(String text, Vector ip_addresses,Vector users_connected, boolean viewfile_flag ,Vector record_of_users) 36. { // The current graphics is obtained... 37. Graphics graphics = Graphics.getGraphics(); /** * Initializing the variable of the graphics class and clearing * the drawing region by calling the appropriate functions of * the Graphics class namely (resetDrawRegion() and clearScreen()). */ 38. graphics.resetDrawRegion();
/** * Initializing the button object "Refresh", placing it on the screen * at the appropriate position and then painting(drawing it). */ 48. 49. refresh = new Button("Refresh",10,20); refresh.paint();
/** * Initializing the button object "Search", placing it on the screen * at the appropriate position and then painting it. */ 50. 51. /** * * * * */ 52. 53. 54. 55. 56. search = new Button("Search",60,20); search.paint();
Initializing the button object "ViewFiles", placing it on the screen at the appropriate position, the painting of the "ViewFiles" button will be decided by checking the view_file flag. If the flag is true then the button will be painted on the screen else not.
/** * Initializing the ScrollTextBox object userlist, placing it on * the screen at the appropriate position and then painting(drawing it). */ 57. 58. userlist = new ScrollTextBox(text,10,40,130,100); userlist.paint();
// Event Handling function. (KeyDown).. 69. public void keyDown(int x) 70. { // Handle the input if the TextField is in focus. 71. if(option.hasFocus()) 72. { 73. option.handleKeyDown(x); 74. } 75. } // End KeyDowm 76. 77. // Event Handling function. (penDown).. 78. 79. // 80. 81. // // 82. 83. // 84. // // 85. 86. public void penDown(int x, int y) { If refresh Button is pressed.. if(refresh.pressed(x,y)) { Remove the focus from the TextField and kill the TextField blinking caret. option.loseFocus(); option.killCaret(); To show a new class first unregister all the controls of the // existing class unregister(); Create an object of the class peer_application and call the function startReading() to send a request to the server peer_application refresh_application = new peer_application(); refresh_application.startReading();
"+filename+"\n";
// The folders are also stored in a vector variable of the // name folder_vector. 287. folder_vector.addElement((Object)filename); 288. counter++; 289. } 290. 291. 292. } 293. 294. } 295. 296. 297. } 298. catch(IOException ex) 299. { 300. System.out.println("Exception occured"); 301. } 302. } 303. while (!(event instanceof EndDocument)); 304. 305. System.out.println("**** END OF DOCUMENT ****"); // end of document // Socket Connection and Input and OutputStreams are // closed... 306. try 307. { 308. socket.close(); 309. socket_inputstream.close(); 310. socket_outputstream.close(); 311. } 312. catch(IOException e) 313. { 314. System.out.println("user list"+ e); 315. 316. }
Code explanation
Lines 1-5: Details the inclusion of the basic packages used by various classes in the project, such as java.util.* for vectors and enumerations and java.io.* for input and output. Lines 6-8: Details the inclusion of the packages required by the various classes in the XML parser. Line 10: Declares a class userlist_screen. This class displays to the user a list of the various listeners connected to the server at a particular instant of time. Along with this information, it also provides the user certain buttons for various uses, such as the Browse button, which the user presses after keying in a particular serial number. On pressing this button, the user is shown a screen that consists of all the files/folders shared by a particular listener. A Search button is also provided that the user can use to search for a file or a range of files for a single user or a range of users connected at a particular instant of time, etc. Lines 12-18: Declares the Button, ScrollTextBox, and the TextField variables, which are used as the GUI of this screen. Lines 20-22: A StreamConnection-type variable (socket) is also declared, which is used to create a socket connection with the listener. Apart from this, an inputstream and an outputstream variables are also declared, which are used for communication between the socket on the users machine and the socket on the listeners machine. Lines 23-24: Declares variables for the XML parser and parse event (where the callbacks after the parsing will be stored). Lines 25-27: Declares variables for storing the parameters passed on to the class. Lines 28-33: Declares variable folder_data, where the folder information is stored, and the variable file_data, where the file information is stored. Lines 37-39: Pertains to making the spotlet the current spotlet and initializing the variable of the Graphics class and clearing the drawing region by calling the appropriate functions of the Graphics class namely, resetDrawRegion() and clearScreen(). Line 41: Displays a string (Title) at a specified position by using the member function of the Graphics class. Lines 43-46: Pertains to the assigning of the variables defined earlier in Lines 20-27 with the parameters passed on to the class. Line 47: Pertains to making the spotlet the current spotlet. The system keys can cancel the spotlet at any time. Lines 48-66: Pertains to initializing the Button objects Refresh, Search, Exit, and Browse, placing them on the screen at the appropriate positions and then painting (drawing) them. The button object ViewFiles is also initialized. However, the button is painted only when the flag view_file is true. Lines 80-95: Pertains to the action taken when the user presses the Refresh button. 82-84: The caret on the TextField is killed, and the spotlet is unregistered, thereby making way for the next spotlet.
12. private Button browse_directory; 13. private Button search; 14. private Button close; // Declaring ScrollTextBox and textField variables. 15. private ScrollTextBox filelist; 16. private TextField option; 17. 18. 19. 20. /** * Vector information_vector; String parent_information; String text_for_display; Declaring variables to folder_data where the folder information * is stored, similarly the variable file_data where the file * information is stored. */ String folder_data; String file_data; int counter; String host_address; Declaring StreamConnection variable used for Sockets.. StreamConnection socket = null; Declaring InputStreams and OutputStreams used by the socket connections. InputStream socket_inputstream; OutputStream socket_outputstream;
30. Vector folder_vector; /** * Declaraing variables for the xmlparser and parse event(Where * the call backs after the parsing will be stored. */ 31. AbstractXmlParser xmlparser; 32. ParseEvent event; 33. // Constructor for the class showfiles.. 34. showfiles(String text_for_display, Vector folder_vector, String address, String parent_information,boolean viewfiles_flag) 35. { // initializing the parameters with the varaiables declared // earlier. 36. host_address = address; 37. information_vector = folder_vector; 38. this.parent_information = parent_information; // The current graphics is obtained... 39. Graphics graphics = Graphics.getGraphics(); /** * Initializing the variable of the graphics class and clearing * the drawing region by calling the appropriate functions of * the Graphics class namely (resetDrawRegion() and clearScreen()). */
83. // 84. 85. 86. 87. // If Browse button is pressed then call the // method browse_directory() with parameter 1. 88. if(browse_directory.pressed(x,y)) 89. { 90. 91. browseDirectory(1); 92. } 93. 94. // If close button is pressed. 95. if(close.pressed(x,y)) 96. { // If the parent_information is root then.. 97. if (parent_information.equals("ROOT")) 98. { // Remove the focus from the TextField and kill the TextField // blinking caret. 99. option.loseFocus(); 100. option.killCaret(); // To show a new class, first unregister all the controls of the // existing class 101. unregister(); // Create an object of the class peer_application and call the // function startReading() to send a request to the server 102. peer_application refresh_application = new peer_application(); 103. refresh_application.startReading(); // Then call the parser function, it will return a vector. 104. Vector ip_addresses = refresh_application.parseData(); 105. String text_for_display = refresh_application.returnTextForDisplay(); 106. Vector users_connected = refresh_application.returnUsersConnected(); 107.
228. socket_inputstream = socket.openInputStream(); 229. socket_outputstream = socket.openOutputStream(); 230. } 231. catch(IOException ae) 232. { 233. System.out.println("Couldn't open socket:"); 234. } // An XMLRequest which is to be sent to the Listener is formed.. 235. 236. String xmlRequest = "<?xml version='1.0' encoding='utf-8'?><p2p_lng> <request type=\"SHOWFILES\"> </request></p2p_lng>"; 237. // It is converted to byte array 238. byte [] byteXmlRequest = xmlRequest.getBytes();
// The length of the byte array is taken out. 239. int byteXmlRequest_length = byteXmlRequest.length;
/** * A function appropriate length is called which will make * this request equal to 1024 bytes in length. This is done in * order to make compatibility with the C# listeners. */ 240. byteXmlRequest = appropriatelength(byteXmlRequest,byteXmlRequest_length); 241. 242. 243. try 244. { // The xmlrequest is sent via socket connection to the Listener // machine.. 245. socket_outputstream.write(byteXmlRequest); // The stream of response by the server is then passed on to // the xmlparser for parsing.. 246. xmlparser = new XmlParser(new InputStreamReader(socket_inputstream)); 247. 248. } 249. catch(IOException e) 250. { 251. } 252. // Function used for parsing is called... 253. parseData(); 254. // Remove the focus from the TextField and kill the TextField // blinking caret 255. option.loseFocus();
Code explanation
Lines 1-5: Includes the basic packages used by various classes in the project, such as java.util.* for vectors and enumerations and java.io.* for input and output. Lines 6-8: Includes the packages required by the various classes in the XML parser. Line 10: Declares a class showfiles. This class displays the list of the various files/folders shared by a particular listener, which the user decides to browse at a particular instant of time. It also provides certain buttons for various uses, such as the Browse button, which the user presses after keying in a particular serial number of the directory. On pressing this button, the user is shown a screen that consists of all the files/folders that are included in that particular directory. A Search button is also provided, which the user can use to search for a file or a range of files in the files shown. Lines 12-17: Declares the Button, ScrollTextBox, and TextField variables, which are used as the GUI of this screen. Lines 18-20: Declares variables for storing the parameters passed on to the class. Lines 21-22: Declares variables to folder_data, where the folder information is stored, and the variable file_data, where the file information is stored. Lines 27-29: A StreamConnection-type variable (socket) is also declared, which is used to create a socket connection with the listener. Apart from this, inputstream and outputstream
255-257: The caret on the TextField is killed and the spotlet is unregistered, thereby making
way for the next spotlet. A class showfiles is called, which contains the parameters constructed during the parsing activity. Lines 264-339: The code between these lines pertains to an important function, parseData. This is the function in which the XML parser sends the Callbacks. The callbacks are identified accordingly, using the functions (whether the element obtained is the start tag or end tag, etc.). 274: If the tag encountered is fileinfo, the attributes of the tag are taken using the function getValue() and are added at the appropriate positions. 281-289: A check is made here to see whether the filename generated is a folder or a file. If a file is found, it is appended onto the file_data; otherwise, it is appended onto the folder_data. 290: The folder_data is also added to a vector for later use. 304-314: When the parsing is complete, the socket connection and the socket streams both input and output are closed. 315-338: The code between these lines pertains to adding the numbers to the filenames generated. A variable text_for_display is assigned the values of the folder_data and the file_data.
128. xmlparser = new XmlParser(new InputStreamReader(din)); 129. } 130. catch(IOException e) 131. { 132. System.out.println("Server Search Exception: "+e); 133. 134. } // Function used for parsing is called... 135. parseData(); 136. 137. // An enumeration is generated from the vector users_connected.. 138. Enumeration enumeration = users_connected.elements(); // A loop is executed till enumeration has no more elements 139. while (enumeration.hasMoreElements()) 140. { 141. int increment = 0; 142. Object temp = enumeration.nextElement(); 143. 144. Enumeration enum = record_of_users.elements(); 145. while (enum.hasMoreElements()) 146. { 147. Object temp1 = enum.nextElement(); 148. // If match is found, then count is increased by 1. 149. if (temp1.equals(temp)) 150. { 151. increment++; 152. } 153. } 154. // The count is shown with the text_for_display. 155. text_for_display = text_for_display+number+". "+(String)temp+"("+increment+")"+"\n";
Code explanation
Lines 1-3: Details the inclusion of the packages required by the various classes in the XML parser. Lines 4-8: Details the inclusion of the basic packages used by various classes in the project, such as java.util.* for vectors and enumerations and java.io.* for input and output , etc. Line 10: The class serversearch is declared. This class is responsible for implementing the server-level search, wherein the browser can search for a particular file or a class of files on a particular computer or a set of computers. When the search is over, a list of users connected at a particular instant of time is displayed, along with the number of files (displayed in brackets) that satisfy a particular search criterion. Lines 13-14: Declares variables for the XML parser and parse event (where the callbacks after the parsing will be stored). Lines 18-21: Declares the various GUI components used in the class. These GUI components include two Buttons with the labels Search and Cancel and two TextFields. Lines 24-25: Two vector variables, users_connected and ip_addresses, are declared. These variables keep a record of the IP addresses of the users connected, along with the names of the users connected at a particular instant of time. Lines 31-32: Initializes the variable of the Graphics class and clears the drawing region by calling the appropriate functions of the Graphics class namely, resetDrawRegion() and clearScreen(). Line 33: Pertains to making the spotlet the current spotlet; however, the system keys can cancel the spotlet at any time. Line 35: Displaying a String (Title) at a specified position by using the member function of the Graphics class. Lines 36-40: Pertains to the painting of the various GUI components such as the two TextFields and the two buttons on the screen. Lines 42-43: Pertains to initializing the parameters with the variables declared earlier.
Lines 47-71: The code is executed when the user presses a key. If the Tab key is pressed from a
normal QWERTY keyboard, the current text fields caret is made to disappear and the caret is made to appear in the other TextField.
displayed in the ScrollTextBox), ip_addresses (IP addresses of the users connected at a particular instant of time), users_connected (names of the users connected at a particular instant of time), false (indicating that the View Files button is not to be shown), and record of users (names and IP addresses of the users connected at a particular instant of time).
Lines 197-256: The code pertains to an important function, parseData. This is the function in which the XML parser sends the Callbacks. The callbacks are identified accordingly, using the functions (whether the element obtained is the start tag or end tag, etc.). 211: If the Tag encountered is result, the attributes of the tag are taken using the function getValue() and are added at their appropriate positions. 221-237: A check is made here to see whether the filename generated is a folder or a file. If a file is found, a flag folder_identity is set to 0, and if a folder is found, the folder_identity is set to 1. 240-243: All this data generated by the parser is then added to a vector of the name record_of_users.
Code explanation
Lines 1-5: Details the inclusion of the basic packages used by various classes in the project, such as java.util.* for vectors and enumerations and java.io.* for input and output. Lines 6-8: Details the inclusion of the packages required by the various classes in the XML parser. Line 10: The code here pertains to the declaration of the class searchfiles. This class helps the user perform the client-level search that is searching the present contents of the spotlet for a filename or a subset of filenames. Lines 12-14: Declares the Button and TextField variables, which are used as the GUI of this screen.
Lines 171-251: The code pertains to an important function, parseData. This is the function in
which the XML parser sends the Callbacks. The callbacks are identified accordingly, using the functions (whether the element obtained is the start tag or end tag, etc.). 181: If the tag encountered is fileinfo, the attributes of the tag are taken using the function getValue() and are added to the appropriate positions. 188-196: A check is made here to see whether the filename generated is a folder or a file. If a file is found, it is appended onto the file_data; otherwise, it is appended onto the folder_data. 197: The folder_data is also added to a vector for later use. 215-225: When the parsing is complete, the socket connection and the socket streams both input and output are closed.
Summary
This chapter describes the fourth full-blown application we have developed using J2ME in this book. This application is developed for Palm devices. The application is Peer search and is a Peer-to-Peer based application. Although a brief summary of the Peer-to-Peer application is given in this chapter, we recommend you go through the book Peer-to-Peer Application Development for better understanding of the concept. Chapter 10 is on developing a small portal for mobile phones using MIDP.
Chapter 10
User Interface
The initial screen of the application is the application launch screen shown in Figure 10-1, and the next screen shows the user a list of the available services. These are, as mentioned in the preceding section, Weather, Movies, and News as shown in Figure 10-2. The user highlights the service he/she wants to avail and presses the Select button. To quit the application, he/she can press the EXIT button.
If the service selected is Movies, the user will see a list of cinema halls as shown in Figure 10-5. The screen will display a button labeled Back to return to the previous screen. On selecting a theater, the user is shown the name of the film running at that hall as in Figure 10-6. Every screen from here on will have a Back button. The user then can select the movies he/she wants to see. The dates on which that movie will play are shown in Figure 10-7, and the user can select a date.
The user is now presented with details about the movie, such as the show time, ticket rate, and so on, as in Figure 10-8. The screen will have two buttons, Back and Book. On pressing Book, he/she is prompted to enter his/her name as in Figure 10-9. Two buttons are available in Figure 10-9, Back and OK. Pressing Back will return the user to the previous screen, that is, Figure 10-8.
If the user presses OK, he/she is prompted to enter his/her e-mail ID as in Figure 10-10. Again, there are two buttons, Back and OK. The user now has to select the category, such as balcony, box, etc as shown in Figure 10-11. The last thing to enter is the number of tickets required as shown in Figure 10-12. As soon as the Book button is pressed, the tickets are booked.
If the user selects the News service, he/she will see the subjects on which news is available, such as the economy, politics, etc shown in Figure 10-13. This screen will have the buttons OK and Cancel. The user may scroll to a subject and press the OK button for the highlights on that subject as in Figure 10-14.
Two buttons, labeled Back and View, are present to let the user either go back to the list of subjects or to read the news in some detail as in Figure 10-15, respectively. On the screen showing the news in detail are two buttons, Previous and Start. Previous takes the user to the previous screen and Start to the initial screen.
How to Run
To run this application, you should have the J2ME Wireless Toolkit installed, as we explained in Chapter 4. The steps involved for running the application would be: 1. Start KToolbar of the J2ME Wireless Toolkit from the Start menu. 2. Begin a new project by clicking New Project. 3. Enter a name for the project say, MobileServices. 4. Enter the name of the main MIDlet class, which is also named Main. 5. Click Create Project. 6. Copy the source code for the project in the C:\J2MEWTK\apps\MobileServices directory. 7. Now come back to the KToolbar and click the Build button. Once the project is successfully compiled and preverified, click the Run button.
How It Works
Before getting into the details of the application, lets first examine the Database for this application. We have used SQLServer on the backend. Lets examine the Table structure of the Database. The table shown in Figure 10-16 is a Weather table which stores the weather details.
The table shown in Figure 10-21 is a news table which stores the news details. The table contains information regarding the news subjects there, headlines, heading ID, and the news description i.e., the detail news.
The application is started when the class MainClass is executed. This class displays the list of the services available. The three services, as we have seen, are Weather, Movies, and News. If the user decides to quit and presses the Exit button, the destroyApp method is called for the MIDlet MainClass, and the application closes. If, instead, the user decides to further explore and selects the Weather service, another class, Weather, is called. This class, in turn, calls the class DataParser, which parses the XML and throws the result. The data thrown is entered into the device database (RecordStore). Now, if the user presses the Cancel button, the MIDlet Weather is destroyed. At this stage, the user is shown a list of cities for which the weather report is available. If the user selects a city and presses the OK button, data is read from the devices database and displayed to the user. There are two buttons, labeled Back and Cancel. Pressing Cancel results in the MIDlet Weather being destroyed as before. Pressing Back takes the user to the previous screen. The second service is Movies. If the user selects this service, a class MoviesList is called. This class, in turn, calls the parseDataMovies method of the DataParser. As a result, the list of movie halls is
The Movies service of this application is handled by the class MoviesList. When this class is started by selecting the Movies service, the URL of an XML file, midlet_movies.xml (shown in Figure 1023) is passed as a parameter to the method sourceurl, which is called by a DataParser object. This class has a method, getAllData, that is passed a String and an integer counter as parameters. The value of the counter variable is used for checking the conditions in the if blocks, just as in the method parseDataMovies. If the value is 1, a new List object is created, and the URL of an XML file, midlet_status.xml (shown in Figure 10-24) is passed to the method sourceurl, which is called by the DataParser object parsemoviedata. Then this object calls the parseMovieData method with a parameter value of 2.
If the value of the counter variable is 2, the dates on which a particular movie will be screened are displayed. And if the value is 3, details of the show, such as the time of the show and ticket rates for different categories, are displayed. Event handling, defined in the method commandAction of the CommandListener class, takes care of the rest of the things, depending on the command generated when the user makes the choices.
The News service of this application is handled by the class News. When this class is started by selecting the News service, the URL of an XML file, midlet_news.xml (shown in Figure 10-25), is passed as a parameter to the method sourceurl, which is called by a DataParser object. The XML file is parsed and values stored in a Vector object vnews. The values in vnews object is News category which is displayed to the user. When the user selects a category the sourceurl method is passed the URL of an XML file, midlet_news_det.xml (shown in Figure 10-26) as argument. The XML file is parsed and the Headlines of News are displayed to the user. When the user selects a Headline again the sourceurl method is passed the URL of an XML file, midlet_news_description.xml (shown in Figure 1027) as argument. The XML file is parsed and the detail news is displayed to the user.
Lets examine the working of the complete application. The flow charts in Figures 10-28, 10-29, 10-30, 10-31 and 10-32 explain the complete flow of the application.
MainClass.java
This class launches the Mobile services. This is main class and calls the other three MIDlets of this application. The list of services is displayed to the user and on selecting a service, this class passes control to another MIDlet (Listing 10-1).
Code explanation
Lines 1-7: Import statements, which import the required classes to run this application. Line 11: Declaring MainClass. This class is a MIDlet, and this is the main class. This class calls the other three MIDlets in this application. Lines 14-26: The lines of code here declare different objects. Lines 28-34: Constructor declaration. The code in the constructor gets the Display object and initializes a command. This command is an exit command. Lines 36-50: The startApp() method is declared. This will initialize a List, which will display to the user the services provided. The user can see the weather details, book movie tickets, or read news. It will also register the list for event handling and adds a command to the list. Lines 52-55: The pauseApp() method is declared. Lines 57-64: The destroyApp() method is declared. All the objects declared are set to null. This will help in freeing resources. Line 66: The commandAction() method is declared. This method is called whenever a user event is generated on the GUI components. Lines 69-107: This if condition is true if the user selects an item in the list. The list contains three items: Weather, Movies, and News.
DataParser.java
This class is used for handling Http requests and reading and parsing XML data. This class caters to the request of the three MIDlets used in this application (Listing 10-2).
} void read_news() { int k, id; String news = "", data = "", head_id = "", head = ""; boolean foundnews = false, foundhead = false, foundhead_id = false; do { try { event = parser.read (); if(event.getType()==Xml.START_TAG) { StartTag stag = (StartTag)event; if(stag.getName().equals("news")) { foundnews = true; } if(stag.getName().equals("heading")) { foundhead = true; } if(stag.getName().equals("heading_id")) { foundhead_id = true; } } if(event.getType()== Xml.TEXT) { TextEvent tevent = (TextEvent)event; if(foundhead_id) {
Code explanation
Lines 1-16: Import statements, which will import the required classes to run this application. Line 17: Declaring DataParserclass. This class is an important class, as it is used to make the HTTP connection and XML parsing. Lines 19-32: The lines of code here declare different objects. Lines 35-43: Constructor declaration. The code here initializes Vector and Hashtable objects. Lines 46-61: The sourceurl() method is declared. This method takes a String value as a parameter, which is the address of the HTTP server. This method makes an HTTP connection with the specified URL and opens a stream from that connection to read data. This also initializes an XmlParser object. Lines 63-102: The read_category() method is declared. This method is called by the News MIDlet, and this method gets the news category from the database. 71-84: This will read the XML data and generate parser events. The if condition is true if the START_TAG event is generated. The tag name is compared, and if the tag name is category, foundnews is set to true. 85-94: This if condition is true if text is found while parsing. This will Throw a TEXT event, get the text, and store it in the Vector. Lines 104-183: The read_record() method is declared. This method is called by the Weather MIDlet, and this method gets the state name and the weather details. 109-113: A RecordStore object is created to add data to the devices database. 123-137: This will read the XML data and generate parser events. The if condition is true if the START_TAG event is generated. The tag name is compared, and if the tag name is weather, founditem is set to true; if the tag name is state, foundstate is also set to true. 138-151: This if condition is true if text is found while parsing. This will throw a TEXT event, get the text, and store it in a String variable with delimiter ?. 153-166: This if condition is true if an END_TAG event is generated. This will add the data in the devices database and store the state name and the record id in the Hashtable. 173-182: On the event of ENDDocument, the recordStore will be closed. Lines 186-199: The record_add() method is declared. This method will add a record to the database. This method is called by the read_record() method. Lines 202-213: The deleterecord() method is declared. This method will delete the record from the database. Lines 214-273: The read_news() method is declared. This method is called by the News MIDlet. This will read text related to tags such as news, heading, and heading_id. The data read is stored in Hashtable. Lines 274-309: The returndetails() method is declared. This method is called by the News MIDlet. This will read the description of the news when the tag description is found and stores the text in a String.
Weather.java
This class is used to provide the user with details on the weather. The class calls the DataParser class to send requests for weather details and get the response. This class first displays the names of the cities for which weather details are available and on selecting the city, the user is displayed the weather details of that city. Before this class is destroyed it passes the control to the Main class (Listing 10-3).
Code explanation
Lines 3-10: The inclusion of the basic packages used by various classes in the project, such as Hashtable and Enumerations (java.util.*), for input and output (java.io.*), etc. Line 14: The code here pertains to the declaration of the class Weather. This class is called when the user selects Weather in the menu containing services. Line 17: Declaration of the object getd of the GetData class. Lines 20-42: Declaring variables of List type for storing and displaying a list of cities and details of the weather, the variable of Display type for requesting that object to be displayed on the device, and the variable of Vector type for storing the list of cities and the list of labels; the command buttons variables Cancel, OK, Back, and Exit, for moving to the next field, to the previous field, and exiting from the Weather screen; the variable of Hashtable, for storing the list of cities available for weather details; and the Recordstore type for handling records in the database.
News.java
This class as the name says facilitates the user to read news. The class calls the DataParser class to send requests for News and get the response. This class first displays the subjects for which news is available and on selecting the subject the user is displayed the headlines of the news. The user has to select a headline. Before this class is destroyed, it passes the control to the Main class (Listing 10-4).
details.addCommand(startcommand); } /* if condition is associated with previous command button when the it */ if(c == previouscommand) { /* Registering the List object news for event Handling */ news.setCommandListener(this); /* displays List Object news on cellphone screen */ displaylist.setCurrent(news); /* To attach the Back Command Button with List Object news */ news.addCommand(backcommand); /* To attach the Add Command Button with List Object news */
Code explanation
Lines 3-9: The code between these lines pertains to the inclusion of the basic packages used by various classes in the project, such as Hashtable and Enumerations (java.util.*), for input and output ( java.io.*), etc. Line 12: The code here pertains to declaration of the class News. This class is called when the user selects News in the menu containing services. Line 15: Declaration of the object getd of the DataParser class. Lines 18-38: Declaring variables of Display type for requesting that object to be displayed on the device; List type for storing and displaying list of categories, news and news details; and Vector type for storing the list of Headlines and list of labels; declaring variables for command buttons and initializing them with null; the command buttons variables Cancel, OK, Back, Exit, Previous,
MoviesList.java
This class facilitates the user to book tickets for a movie. The class calls DataParser class to send requests for movie details and get the response. This class first displays to the user the list of theaters. On selecting the theater, the movies shown at the theater are displayed. The user has to select the movie and the date on which the movie shown is displayed. Upon selecting the date, the user is shown the details of the movie like the show time, no of tickets available on the basis of category. The user after viewing the details can book the tickets and has to give details like name, emailId, number of tickets, and so on. Before this class is destroyed it passes the control to the Main class (Listing 10-5).
Code explanation
Lines 1-14: These are import statements that will import the necessary classes for running this application. Line 16: Declaring MoviesList class. This class is a MIDlet and is used to book movie tickets. The user can also view the status of the movie. Lines 18-34: The code in these lines declare different objects. Lines 36-45: Constructor declaration. The constructor is passed two arguments: One is the Display object, and the other is the object of MainClass. This also initializes a list, which will
Summary
This chapter was a full-blown application developed using MIDP for Mobile Phone. After reading this chapter, the reader can manipulate the application provided in this chapter to add create a complete portal and can add more services. In Chapter 11 we will develop an application using CLDC and Kjava APIs and it is the last chapter containing a project.
Chapter 11
User Interface
On starting the game, the user sees a screen as shown in Figure 11-1 with two sets of radio buttons (of the class RadioButton) and three buttons (of the class Button). He can make his choice of the level at which he wants to play the game (simple or difficult) and about the number of shots he can use for target practice by selecting one radio button each. With the three buttons, he can start playing (Play Now), read instructions (Instructions), or exit the game if he wants to discontinue playing. There arent many instructions to read because this is a simple game. On pressing the Play Now button, the starting screen is shown as in Figure 11-2. This screen shows the target and the gun. There are two buttons (Start and Exit) to either begin shooting or to quit there should always be an escape option available. Press the Start button, and the target begins to move. A third button simultaneously appears as in Figure 11-3. This button (Shoot) is for shooting. The player can quit the game at any time as desired. Otherwise, he shoots for the number of times he selected in the initial screen (Figure 11-1). Once he has availed all the chances to hit the target, another screen shows his score as in Figure 11-4. Two buttons (Play Again and Exit) on this screen allow him to either have another try or to quit the game.
How It Works
You can run the application by using the batch file provided with the source code. Before clicking it, you will have to change the paths to match those on your machine, as usual. This will also take care of compilation and preverification. The class TargetPractice is the starting class of this application. When this class is executed, it shows the initial screen as described in the preceding section and shown in Figure 11-1. It is responsible for the following tasks: It provides the user interface for the initial class, which includes the RadioButtons for options and simple buttons. It stores the values for options in the variables level_information and shot_information. It provides the event handling for the radio buttons and the buttons. The penDown method is used for this. It calls the class MainClass for handling the game. The main class of the application is called simply MainClass. The important tasks performed in this class are as follows: Creating the user interface for the screen before the game starts and also retaining it for the time when it is being played. This is done with the help of the classes provided in KJava API. These include RadioButton and Button. The String class of java.lang package is used for creating Strings. All objects are drawn and redrawn on the screen, as before, by using the Graphics class of KJava. This class is used in a way that is similar to the Graphics class of J2SE (java.awt package).
A constructor that takes parameters for the level of game and the number of shots is defined. One of the tasks performed inside this constructor include registering the spotlet. Some variables, such as the score, are given their initial values. A Thread is declared, and its two possible times of sleep are given values. These sleep times determine the level of the game. Drawing operations on the user interface elements are performed inside the constructor.
A counter is used to keep track of the number of times the player has shot at the target. Its value is incremented after every shot by calling the reload() method. When the value of the counter becomes equal to the number of shots selected by the player in the beginning, the spotlet is unregistered, the screen is cleared, and the Result class is called with the score parameter. The thread is started in the method run(). Ifelse blocks are used to control the position of the target, as well as for drawing and redrawing it. The main thing is to make sure that, as the target goes out of the screen on one side, it is made to reappear from the other side for another shot. All the event handling for the game is defined in this class within the method keyDown(). It takes care of drawing and redrawing the barrrel and the bullet. The method is invoked when the user
Once the game is finished, the scores are shown by the class Result. It provides the UI and event handling for the result screen and calls the main class again if the player presses the Play Again button. Program flow is described as follows and shown in Figure 11-5: The game is started by executing the class TargetPractice. It performs the tasks described previously and shows the initial screen. If Exit is pressed, the application will end. On the users pressing the Play Now button, the class MainClass is called with the level and shot values as the parameters. This sets up the stage for the game and shows the next screen. The exit option is there, too. On the users pressing the Start button, a thread is activated, which allows the target to move up and down. A new button, labeled Shoot, appears in addition to the Start and Exit buttons. On the users pressing the Shoot button, the value of the Boolean variable shoot becomes true. As a result, the bullet and the target are shown moving by drawing and redrawing them in changing postions. This is done by using ifelse blocks in the methods run()and keyDown(). Checks are applied to see that they reappear on the screen as they go out of it. The method reload() is called to repeat the process of firing the bullet and moving the target. When the value of the counter becomes equal to the maximum shots chosen, the class MainClass is unregistered, and the class Result is called. If the Play Again button is pressed, the class TargetPractice is called again so that the game can be played again.
Source Code
Source code TargetPractice.java MainClass.java, and Result.java is given.
TargetPractice.java
This class acts as the first class of the program. It provides the user with various options (level and shots that the user can fire). Along with this, the class also provides a button to display the instructions to the user (Listing 11-1).
/** * Declaring button variables. * For starting the game -- Play. * Quit the game -- exit. * Instructions for playing the game -- Instructions. */ 9. private Button play; 10. private Button instr; 11. private Button exit; /** * Declaring and initializing the variables for level and number * of shots that user can fire. * level -level_information * shots -shot_information */ 12. 13. String level_information = "simple"; 14. int shot_information = 5; /** * Initializing a RadioGroup of the name level. All the RadioButtons * pertaining to level will be placed in this RadioGroup. * This way only one of the buttons can be checked at a time.
/** * Similarly, initializing a RadioGroup of the name "shots". * All the RadioButtons pertaining to shots will be placed in * this RadioGroup. This way only one of the buttons can be checked * at a time.The RadioButton with the label "5" is given the * variable name "five", the RadioButton with the label "10" is * given the variable name as "ten" and similarly the RadioButton * with the label "20" is given the variable name as "twenty". */ 18. 19. private RadioGroup shots = new RadioGroup(3); 20. private RadioButton five = null; 21. private RadioButton ten = null; 22. private RadioButton twenty = null; 23. // Declaring a variable of the class Graphics. This class is // responsible for showing all the graphics (labels etc.) on // the screen. 24. Graphics graphics; 25. 26. public TargetPractice() // Constructor TargetPractice 27. { 28. // To make the spotlet as the current spotlet... 29. register(NO_EVENT_OPTIONS); 30. /** * Initializing the variable of the graphics class and clearing * the drawing region by calling the appropriate functions of * the Graphics class, namely resetDrawRegion() and clearScreen(). */ 31. graphics = Graphics.getGraphics(); 32. graphics.resetDrawRegion(); 33. graphics.clearScreen(); 34. /** * Displaying a string (Title) at a specified position by using * the member function of the Graphics class. */ 35. graphics.drawString("Target Practice",35,10); 36. /** * Initializing the button object play, placing it on the screen * at the appropriate position and then painting (drawing it).
* Displaying a string Level at a specified position on the screen. * This acts as the label of group of radio buttons. */ 48. graphics.drawString("Level",15,45); 49. 50. /** * Initializing the RadioButton object simple, placing it * on the screen at the appropriate position and then drawing it. */ 51. simple = new RadioButton(85,45,"Simple"); // Initially this button is to be kept selected. Therefore, a function // setState is called, which is passed a parameter true, which will //care of this. 52. simple.setState(true); 53. simple.paint(); 54. /** * Initializing the RadioButton object difficult, placing it * on the screen at the appropriate position and then drawing it. */ 55. difficult = new RadioButton(85,60,"Difficult"); 56. difficult.paint(); 57. /** * Adding the RadioButtons to the RadioButton group, thereby ensuring * that only one of the buttons will be selected at a particular instant * of time. */ 58. level.add(simple);
// Initially this button is to be kept selected. Therefore, a function // setState is called which is passed a parameter true which will // do the same. 65. five.setState(true); 66. five.paint(); 67. /** * Initializing the RadioButton object five, placing it * on the screen at the appropriate position and then drawing it. */ 68. ten = new RadioButton(85,90,"10"); 69. ten.paint(); 70. /** * Initializing the RadioButton object five, placing it * on the screen at the appropriate position and then drawing it. */ 71. twenty = new RadioButton(85,105,"20"); 72. twenty.paint(); 73. /** * Adding the RadioButtons to the RadioButton group, thereby ensuring * that only one of the buttons will be selected at a particular instant * of time. */ 74. shots.add(five); 75. shots.add(ten); 76. shots.add(twenty); 77. 78. } // End of the constructor TargetPractice. 79. /** * The code below pertains to event handling. */
129. public static void main(String args[]) 130. { 131. new TargetPractice(); 132. } 133. // End of the class TargetPractice. 134. }
Code explanation
Lines 1-5: The code here pertains to the inclusion/importing of the various packages required by the various classes during the program. These include packages such as com.sun.kjava, which are used by the classes that help in creating the GUI, and the Graphics class, which is responsible for the creation of rectangles for the target, circles for the bullets, etc. Line 7: This is for declaring the class TargetPractice. This class acts as the first class of the program. It provides the user with various options (level and shots that the user can fire). It also provides a button to display the instructions to the user. Lines 9-11: Objects of the class Button are declared. These buttons are used for various purposes for example, Play (for starting the game), Exit (for quitting the game), and Instructions (for instructions on how to play the game). Lines 13-14: Used for declaring and initializing the two variables level_information and shot_information. These two variables store the information about the level of the game (difficult or simple) and the number of shots that can be fired (5, 10, or 20). Lines 15-22: For the declaration of various radio buttons and radio groups. The radio groups are declared to ensure that only one radio button can be selected at a time. There are two radio groups declared: level and shots. The radio buttons declared are Simple, Difficult, 5, 10, and 20. Line 29: The spotlet is made the current spotlet here. The system keys can cancel the spotlet at any time. Lines 31-33: These codes are for getting the Graphics object of the spotlet, resetting the drawing region, and clearing the spotlet screen. Line 35: Drawing and positioning a String at a specified position on the spotlet. This String acts as the title/heading of the game.
MainClass.java
As the name suggests, this is the main class of the project that is responsible for starting the game. This class implements a Runnable interface as well, which is used to include the thread capability in the class. The functionality this class provides is the movement of the gun, movement of bullet, and displaying the score to the user (Listing 11-2).
// Declaring a variable of the class Graphics this class is // responsible for showing all the graphics (lables etc.) on // the screen. 11. Graphics graphics;
/** * The code pertains to the declaration of the three of this class. These three variables are all * of integer type. Their use is as follows: * initial_position -- initial position of the target bar. * initial_position_bullet -- as the name suggests, this variable * describes the initial position of the * bullet. * initial_position_barrel -- Initial position of the gun. */ 12. 13. 14. int initial_position = 0; int initial_position_bullet = 0; int initial_barrel_position = 0;
// Another important variable is declared. This variable is of // boolean type and of the name shoot. When this variable is // true, the gun is fired, else the gun remains loaded and ready // to fire. 15. // 16. 17. boolean shoot = false; Declaring a thread Thread t; String level;
/** * Declaring the variables for number of shots, sleeptime(delay) * score, counter (used as number of shots), cont (continue the * game). */
22. boolean cont = true; 23. /** * Constructor of the MainClass. It takes two parameters, a string * parameter which denotes the level and an integer parameter * which indicates the number of shots. */ 24. public MainClass(String level, int shots) 25. { 26. // To make the spotlet the current spotlet... 27. register(NO_EVENT_OPTIONS);
/** * Initializing a variable of the graphics class and clearing * the drawing region by calling the appropriate functions of * the Graphics class namely resetDrawRegion() and clearScreen(). */ 29. graphics = Graphics.getGraphics(); 30. graphics.resetDrawRegion(); 31. graphics.clearScreen(); 32. /** * Initializing the variables level and shots with the parameters. * */ 33. this.level = level; 34. this.shots = shots; 35. /** * Adjusting the delay (sleeptime) according to the level. If the * level is simple, the dealy is more. Otherwise it is less. */ 36. if (level.equals("simple")) 37. { 38. sleeptime = 35; 39. } 40. else 41. { 42. sleeptime = 15; 43. } 44. 45. // Initializing the initial position of the bullet.
graphics.drawString(""+counter,30,2); graphics.drawString(""+score,105,2);
// Initial position of the Gun. 55. initial_barrel_position = 70; // Drawing the gun. using the Graphics class method drawRectangle(). 56. 57. 58. graphics.drawRectangle(2,70,25,10,Graphics.GRAY,0); graphics.drawRectangle(2,80,8,5,Graphics.GRAY,0); // Drawing the Bullet 59. 60. // Drawing the Target for target practice at an initial position 61. 62. 63. 64. 65. initial_position = 45; graphics.drawRectangle(127,initial_position+20,10,10,Graphics.GRAY,0); graphics.drawRectangle(137,initial_position+10,10,30,Graphics.GRAY,0); graphics.drawRectangle(initial_position_bullet,72,5,5,Graphics.GRAY,2); // Barral // Butt
graphics.drawRectangle(147,initial_position,10,50,Graphics.GRAY,0);
66. /** * Initializing the button object called Exit; placing it on the screen * at the appropriate position and then painting(drawing it). */ 67. exit = new Button("Exit",100,145);
/** * Initializing the button object called Start, placing it on the screen * at the appropriate position and then painting (drawing it). */ 68. /** start = new Button("Start",20,145);
Code explanation
Lines 1-5: These statements correspond to the inclusion/importing of the various packages required by the various classes during the tenure of this program. These include packages such as com.sun.kjava, and the Graphics class, which is responsible for the creation of rectangles for the target, circles for the bullets, etc. Line 7: The class MainClass is declared here. This class, as the name suggests, is the main class of the game program responsible for game play and scoring. This class implements a Runnable interface as well, which is used to include the Thread capability in the class. Line 10: This code is for declaring objects of the class button. These buttons are Play (for starting the game), Shoot (for firing the shots), and Exit (for quitting the game). Lines 12-14: The three most important variables of this class are declared here. These three variables are all of the integer type. Their use is as follows: initial_position: Describes initial position of the target bar. initial_position_bullet: Describes the initial position of the bullet. initial_position_barrel: Describes the initial position of the gun. Line 15: Declaration of the variable shoot. This variable is of the Boolean type. When this variable is true, the gun is fired; otherwise, the gun remains loaded and ready to fire. Lines 18-22: These statements declare the variables for the number of shots, sleeptime (delay), score, counter (used as number of shots), and cont (continue the game). Line 27: The spotlet is made the current spotlet by this code. However, the system keys can cancel the spotlet at any time. Lines 29-31: The process of getting the Graphics object of the spotlet, resetting the drawing region, and clearing the spotlet screen are encoded here. Lines 34-35: Initializing the variables level and shots with their parameters. Lines 36-43: Using the if else statements, the level variable is checked and, accordingly, the sleep time (delay) is adjusted. The sleep time is less for Difficult and more for Simple. Lines 48-52: Shots and score are displayed on the screen Lines 55-57: The gun is drawn at an initial position specified. Line 59: The bullet is also drawn at an initial position specified. Lines 61-65: The target is drawn. It consists of three rectangles, one on top of the other. Lines 67-72: Initializing the button objects declared earlier (play, shoot, and exit); placing them on the screen at an appropriate position and then drawing on the screen are achieved by these. Only the Shoot button is not drawn, as it will be drawn only when the user presses the Start button. Lines 78-80: Used for activating the Exit button. When the Button is pressed, the game is closed, and the control is returned to the OS. Lines 82-88: The code between these lines corresponds to the user pressing the Start button. When the Start button is pressed, the Boolean flag shoot is made false, indicating that the gun is loaded. The Shoot button is painted on the screen, and a new thread is generated to take care of the targets moving. Lines 89-92: The code between these lines is executed when the user presses the Shoot button. When this is done, the Boolean flag shoot is made true, indicating that the gun is fired. Lines 96 170: When the new thread is created in the code between lines 82-88, the control is transferred to this method.
Result.java
As the name suggests, this class is responsible for displaying the result of the game to the user and also for providing the user with a choice of repeat play by giving a button with the label Play Again (Listing 11-3).
1. import com.sun.kjava.*; 2. import java.lang.*; 3. import javax.microedition.io.*; 4. import java.io.*; 5. import java.util.*; 6. /** * The code below pertains to declaring a class Result.java. As * the name suggests, this class is responsible for displaying the * result of the game to the user and also for providing the * user with a choice of repeat play by giving a button with the * label Play Again.
// Declaring a variable of the class Graphics. This class is // responsible for showing all the graphics (lables etc.) on // the screen. 11. Graphics graphics; 12. // Constructor of the class. This takes as its argument an int // (the score), scored by the user in the game. 13. public Result(int score) 14. { 15. // To make the spotlet the current spotlet.. 16. register(NO_EVENT_OPTIONS); 17. /** * Initializing the variable of the graphics class and clearing * the drawing region by calling the appropriate functions of * the Graphics class, namely resetDrawRegion() and clearScreen(). */ 18. graphics = Graphics.getGraphics(); 19. graphics.resetDrawRegion(); 20. graphics.clearScreen(); 21. /** * Drawing the label at the specified position on the screen * and placing the score alongside the label. */ 22. graphics.drawString("Thanks for playing..",25,25); 23. graphics.drawString("Your Score is ",25,45); 24. graphics.drawString(""+score,85,45); 25. /** * Initializing the button object playagain, placing it on * the screen at the appropriate position and then drawing it. */ 26. playagain = new Button("Play Again",15,140); 27. playagain.paint(); 28. /** * Initializing the button object exit, placing it on the screen * at the appropriate position and then painting(drawing it). */
Code explanation
Lines 1-5: Inclusion/importing of the various packages required by the various classes during the program are being accomplished here. These include packages such as com.sun.kjava, which is used by the classes that help in creating the GUI, and the Graphics class, which is responsible for the creation of rectangles for the target, circles for the bullets, etc. Line 7: The code here pertains to declaring the class result. This class, as the name suggests, is responsible for displaying the results of the game to the user, along with providing the option to the user to play the game again. Lines 9-10: Declaring objects of the class button. These buttons are used for Play Again (restarting the game) and Exit (quitting the game). Line 16: The spotlet is made the current spotlet. However, the system keys can cancel the spotlet at any time. Lines 18-20: These are for getting the Graphics object of the spotlet, resetting the drawing region and clearing the spotlet screen. Lines 22-24: Used to display a message and the the users score while playing the game. Lines 26-30: Initializing the button objects declared earlier (playagain and exit); placing them on the screen at appropriate positions and then drawing them on the screen are encoded. Lines 36-38: The action involved when the user presses the Play Again button. The user is shown the main/starting screen of the game program by calling the constructor of the class TargetPractice.
Summary
This chapter was a Final full-blown application developed using CLDC and Kjava APIs for PDAs. This chapter follows on from Chapter 6. You can develop your own game or even modify this game as required. In Chapter 12 we will discuss a very important aspect of converting an existing J2SE application to J2ME. This chapter is a must read as it will provide guidelines for the conversions of applications.
Chapter 12
Differences in APIs
Due to the preceding differences between devices, it is quite natural that the APIs required will also be different. This is true not just for J2SE and J2ME, but also for CLDC and CDC. APIs being different means that one platform may have certain APIs that another platform may not have. Let us consider some examples: The combination of CLDC and MIDP, which are parts of J2ME, has only three of the packages in common with the J2SE core API: java.io, java.lang, and java.util. In case of CDC plus Foundation Profile, there are far fewer differences, because the Foundation Profile is based mainly on the J2SE 1.3 API. Moreover, the C Virtual Machine on which CDC and Foundation Profile run has full Java language support. There is, however, one difference: This combination has no GUI available not even the AWT API. This is because CDC, being a configuration, is not supposed to have GUI, and the Foundation Profile is also meant to be just what its name suggests the foundation on which other profiles can be added. Even though the Foundation Profile is based on the J2SE 1.3 API, it doesnt have many packages that are now commonly employed while writing applications using J2SE. Those it does have include, among others, the Swing packages. But it also means that those APIs that are common are not identical. For example, while comparing J2SE and J2ME, we observe the following differences: Package java.io is present in both J2SE and J2ME, but there are only two interfaces available in MIDP namely, DataInput and DataOutput. On the other hand, J2SE has as many as ten interfaces, including Externalizable and Serializable. The same is the case with the other classes of the same package. There are no buffered input/output streams available in MIDP, nor are there any of the various filter stream classes such as FilterReader and FilterWriter. Package java.math is present in both CDC plus Foundation Profile and J2SE, but the former does not have the BigDecimal class, which is used to represent immutable, signed numbers with arbitrary precision. These numbers allow the developer to completely control how his numbers will be rounded. Another difference is even more significant for us. This relates to the completely new APIs added with a platform (or configuration/profile). The varying needs of devices targeted by the platforms dictate that, at least in some cases, new APIs have to be introduced. This is because the existing model on which the present APIs are based is not applicable in the case of these devices. Here are a few examples:
CLDC API introduces a new Generic Connection Framework in the package javax.microedition.io. This framework is necessitated by the fact that different devices
have different levels of support for networking, in addition to other hardware limitations. This means that support for all kinds of connections cannot be added in a configuration meant for pagers and PDAs. For this reason, a single connector class with a hierarchy of interfaces is used to represent all kinds of connections. Actual implementation for any protocol is not provided in CLDC. For every protocol, there has to be at least one class. These classes are to be made available in profiles. For example, the MIDP has an HttpConnection class in the javax.microedition.io package. This class provides the support for HTTP connections. It is
provided so that the developers could add some form of user interface. For this reason, a package named javax.microedition.lcdui has been added. This API is based on the Screen model. In other words, every user interface element is either a kind of screen (in that it extends the Screen class) or it is added to a screen directly or as part of a Form. files in many devices. But some form of persistence is required for any effective application development. This need is fulfilled by the javax.microedition.rms package in the MIDP. This is done with a class called RecordStore.
Devices such as mobile phones have no secondary storage. Data cannot be stored in the form of
Using JavaCheck
Wouldnt it be wonderful if we had some tool to automatically find out which classes and methods are not supported by the platform or configuration/profile to which we want to port the application? There is, indeed, a way to do this. As we saw in Chapter 8, there is tool called JavaCheck that can check whether the classes and methods you use in your application are available on the platform to which you are shifting your application. But the trouble is that it requires a specification in the form of an SGMLcompliant, encoded text file, and presently, the only specification available in this form is for PersonalJava. In other words, you cannot use it for other platforms or configurations/profiles. Still, we have to be aware of its existence, because other specifications may become available. To find out how to run it and check dependencies, refer to Chapter 8 section JavaCheck.
An Example of Conversion
The process described previously is better explained through an example. The application we are going to convert was originally made in J2SE. It is a peer-to-peer application, somewhat like the famous Napster or Gnutella software. You can use it to share any of the files on your system with anyone, anywhere, whos connected to the Net at that moment. There is no need to remain permanently connected like a Web server. You just have to log on and see the list of other users connected to the Net. If they have any files that they want to share, you can download them. Similarly, you can make available your files to them. A search facility is, of course, provided. For more details about the J2SE version of this application, you may refer to the book Peer To Peer Application Development Cracking the Code Series, by Hungry Minds Publishing, Inc. Here we will detail the process through which this conversion passed. This process roughly follows the flow chart shown in Figure 12-1.
In the J2ME version, we will have to use the following statements instead:
import org.kxml.*; import org.kxml.io.*; import org.kxml.parser.*;
When we use the parser in the J2SE application, we use the following code:
try { XMLReader parser = new SAXParser();
// Generate an Object of the MyContentHandler Class it is in this class that // the xml parser generates the call backs... MyContentHandler contHandler = new MyContentHandler(); parser.setContentHandler(contHandler); parser.parse(uri); // call the parse function of the XMLParser class with the
It is when we come to the user interface that we have to make major changes. We will take these up in a later step. Component level design: This part involves analyzing the application at the code-block level. This will require modifications, since the two platforms are different in terms of APIs, Java language support, virtual machine, etc. The devices on which we want to run the converted application have different memory and storage capabilities, processing power, etc. This will necessitate changes at the component level also. Now we come to the question of whether the design of the J2SE application is suitable for conversion. As we discussed previously, the differences are not so much so as to make the design unsuitable for conversion. Thus the answer to this question is yes, and so we can consider the next question. The modifications are definitely possible. We are not going to use another language, just an optimized version of the J2SE platform. Moreover, in several areas, there are no differences at all. So we need not drop the idea of conversion and can go ahead.
We are using ScrollTextBox in the J2ME version, the code for which is:
userlist = new ScrollTextBox(text,10,40,130,100); userlist.paint();
Another factor is that, normally, there is no QWERTY keyboard on the Palm devices. These devices, as we know, use a stylus (or pen) to enter text, using some handwriting-recognition software. So we have to substitute the text-entry parts (such as entering the user number) with something equivalent. For example, we use the penDown method of the spotlet class for event handling. Since there is no mouse on these devices, we also have to use the pen to simulate mouse clicks. In the J2SE version, the event handling code is as follows:
public void actionPerformed(ActionEvent ae) { if (ae.getSource() == file_open )// When Open Button is pressed... { // Create a socket connection to the desired user and browse the shared files / folders on his / her machine. } }
// else form an XML request consisting of the file to be downloaded ... ... writer.requestFString("DOWNLOAD",information[row][0]); // requestFString... ... ... // Popping up a file Dialog, get the location where the file is to be stored. // File Dialog to place the file. ... ... str1 = file_final.getPath();// Get the path where the file is being saved.. ... ... BufferedOutputStream out_file = new BufferedOutputStream(new FileOutputStream(str1)); // Create an outputstream to that path... ... ... while ((y = br_socket.read(f,0,32))>0) // Read the socket and write on to the file... ... ... // Monitoring the progress of the progress monitor ... ... // Close the Streams and the Socket Connections. ... ... } // End Class Download_file...
This code is no longer needed, since we would not be adding the functionality to download or upload files. Another point is that we cannot have the ServerSocket class in J2ME. This presents no problem, since we cannot upload files anyway. The same listener (ServerSocket class) made in J2SE will be used at the server. There will be no listener on the Palm device. More information is available in the book Peer To Peer Application Development Cracking the Code series, by Hungry Minds Publishing, Inc.
Summary
After doing all the programming, one would be interested to learn whether the already developed Java applications using Java Standard Edition can be converted to Java 2 Micro Edition with minimum efforts. This chapter discusses this aspect and provides guidelines on converting the application. We have discussed how we converted an existing Java 2 Standard Edition application to Java 2 Micro Edition; this will be of great help to the reader.
Appendix A
System Requirements
Make sure that your computer meets the minimum system requirements listed in this section. If your computer does not conform to these requirements, you may have a problem using the contents of the CD. Your system must be equipped with the following: Microsoft Windows 9x or Windows 2000 A CD-ROM drive double-speed (2x) or faster
Whats on the CD
The CD-ROM contains source-code examples, applications, and an electronic version of the book. The following sections summarize the contents of the CD-ROM, arranged by category.
Source code
The source code of the projects discussed in this book is given in the Source Code folder. The Source Code folder contains different sub-folders containing the Source code of the case studies and the projects. The following list describes the folders in the Source Code folder: CLDC CaseStudies: This folder contains the Case Studies of the CLDC and Kjava APIs (Chapter 3). MIDP CaseStudies: This folder contains the Case Studies of the MIDP APIs (Chapter 4). XML Parsing CaseStudy: This folder contains the Case Studies of XML parsing using kXML parser (Chapter 5). Online Testing Engine: This folder contains the Source code for our first project, Online Testing Engine (Chapter 6).This project is built using CLDC and Kjava. Online Ordering Systems: This folder contains the Source code for our second project, Online Ordering Systems (Chapter 7). This project is built using MIDP. MP3 Player: This folder contains the Source code for our third project, MP3 Player for Pocket PC (Chapter 8). This project is built using PersonalJava. P2P search Application: This folder contains the Source code for our fourth project, Peer-to-Peer Search Application (Chapter 9). This project is built using CLDC and Kjava. Mobile Services: This folder contains the Source code for our fifth project, Mobile Web Services (Chapter 10). This project is built using MIDP. Target Game: This folder contains the Source code for our sixth project, Target Practice Game (Chapter 11).This project is built using CLDC and Kjava.
Applications
The following applications are on the CD-ROM: Java 2 Software Development Kit Standard Edition version 1.3 for Windows: Java 2 SDK 1.3 or later is a kit to develop a standard Java application. The compilation of the programs made for J2ME has been done using this kit, so you need to have JDK to compile your programs for J2ME.This kit can be downloaded from http://java.sun.com/j2se/1.3. Forte for Java, release 2.0 Community Edition for All Platforms: The Forte for Java release 2.0 software is an integrated development environment used for devloping Java applications. It is an IDE provided by Sun Microsystems. For more information, visit http://www.sun.com/forte/ffj/. Java 2 Platform, Micro Edition, Wireless Toolkit 1.01 (J2ME): This kit is released by Sun to develop MIDP applications. The development is very easy for the programmers since this kit has a GUI base. This comes with a cell phone emulator from Sun and Motorola and a two-way pager emulator from RIM and can also be integrated with the Palm OS 3.5, provided that you have the emulator on your system.This kit can be downloaded from http://java.sun.com/products/j2mewtoolkit kXML APIs: These are XML parsing APIs and come in a Zip file. We have used the minimum version of this parser.This parser is available at http://kxml.enhydra.org/. Tomcat: Tomcat is the Web server extension used to execute server-side Java components such as servlets and JSP. We have used JSP in our Online Ordering Systems project (Chapter 7).This can be downloaded from http://jakarta.apache.org/tomcat.
E-Book
Those readers who desire an electronic copy of the contents in the book can find one on the CD-ROM that accompanies this book. This CD-ROM contains the PDF files of all the chapters, as well as the appendix, in the book. These files can be viewed through the Acrobat Reader 5.0 software, which has been incorporated on the CD-ROM.
Troubleshooting
If you encounter difficulty installing or using the CD-ROM programs, try the following schedule: Turn off any antivirus software that you may have running: Installers sometimes mimic virus activity and can make your computer incorrectly believe that it is being infected by a virus. (Be sure to turn the antivirus software back on later.) Close all running programs: The more programs you are running, the less memory is available to other programs. Installers also typically update files and programs; if you keep other programs running, installation may not work correctly. If you still have trouble with the CD, please call the Hungry Minds Customer Service phone number: (800) 762-2974. Outside the United States, call (317) 572-3994. You can also contact Hungry Minds Customer Service by e-mail at [email protected]. Please note that Hungry Minds will provide technical support only for installation and other general quality-control items; for technical support on the applications themselves, consult the programs vendor or author.
Index
A
AbstractXml parser class,. kXML, 116 AbstractXmlWriter class, kXML, 117 Active state, MIDlets, 64 AddressBook MIDlet case study, 101109 Alert class javax.microedition.lcdui, 68 MIDP, 68 alphanumeric pagers, 19 APIs (application programming interfaces). See also KJava API J2SE conversion to J2ME, 357358 low-level, 2526 states, 189 applets, card applets, 13 application models, J2SE conversion to J2ME, 357 application planning, 25 applications CD with book, 367 compiling, CLDC and, 42 first J2ME application, 1011 Mobile Web Services, 275 running CLDC, 43 MIDP, 8285 XML parsing, 117123 Attribute class, kXML, 116 AWT (Abastract Windows Toolkit) peer objects, 186 pJava and, 185 ChoiceGroupUI MIDlet, 9598 HelpDisplay_Spotlet, 4749 HttpCheck_Spotlet, 5255 LabelUI MIDlet, 9395 MenuCheck MIDlet, 99101 ScrollTextBox_Spotlet, 4547 TestHTTP MIDlet, 109111 TextField_Spotlet, 4345 TextFieldCheck MIDlet, 9193 TickerUI MIDlet, 9899 CD with book, 366367 CDC (Connected Device Configuration), 2, 78, 185186 CheckRadio_Spotlet, 4952 ChoiceGroup class, javax.microedition.lcdui, 69 ChoiceGroupUI MIDlet case study, 9598 cHTML (Compact HTML), 2 cid (creator id), 40 circle drawing, 37 Class connector, 32 classes Button, 3738 ChoiceGroup, 69 Command, 70 Connector, 5255 Database, 4041 Display, 71 Form, 7172 Gauge, 72 Graphics, 37, 7375 HelpDisplay, 39 java.io, 3031 KJava, 3536 List, 7576 OrderManager class, 169180 peer_application, 220221 preverifying, CLDC, 42 RadioButton, 3839 RadioGroup, 3839 RecordStore, 7982 ScrollTextBox, 3940 searchfiles, 223 serversearch, 222 showfiles, 221 Spotlet, 36 StringItem, 76
B
bandwidth limitations, 1718 batch files, CLDC, 43 Books.asp file, TestManager, 159161 Button class, KJava, 37, 38
C
CAP (Converted Applet) format, 13 card applets, 13 case studies AddressBook MIDlet, 101109 CD with book, 366 CheckRadio_Spotlet, 4952
370 Index
TextBox, 41, 7778 TextField, 38, 7677 Ticker, 78 userlist_screen, 221 CLDC (Connected Limited Device Configuration), 2, 57 applications compiling, 42 running, 43 batch files, 43 data types, 29 installation, 4142 KJava overlay, 41 P2P file sharing and, 219 packages Generic Connection Framework, 3134 java.io, 2731 java.lang, 2730 java.util, 2831 Palm overlay, 41 Palm use, 35 preverifying classes, 42 TestManager, 125 CLDC API, 27 CLDC CaseStudies folder, CD with book, 366 clearScreen( ) function, 37 Collections APIs, pJava and, 185 Command class, javax.microedition.lcdui, 70 CommandListener, 6768 compiling applications, CLDC, 42 concatenation, string concatenation, 24 configurations, 5 CDC, 78 CLDC, 57 connections, socket connections, 5562 Connector class, 5255 conserving memory, 2224 constructors, java.lang, 2930 counters, Target Practice game, 331 CVM (C Virtual Machine), 45 destroyApp method, 64 Destroyed state, MIDlets, 64 Display class, javax.microedition.lcdui, 71 DOM (document object model), kDOM, 115 downloading JavaCheck, 189 drawing circles, 37 Graphics class, KJava, 37 rectangles, 37 drawString method, 37 DTD (Document Type Definition), 112 shopfile.dtd, 113 DTDLess code, 112
E
e-book on CD with book, 367 e-commerce, 164. See also m-commerce EmbeddedJava, 12 emulated environments, 186189 EndDocument class, kXML, 117 EndTag class, kXML, 116 EPOC, 185 event handlers CommandListener, 6768 javax.microedition.lcdui, 6768 example.jad file, MIDP installation, 85 exceptions, 24 javax.microedition.rms, 82 Persistence package, 82
F
first application, 1011 flow, TestManager, 131 Form class, javax.microedition.lcdui, 7172 Forte, JDK and, 86 Forte for Java, release 2.0 Community Edition for All Platforms, CD with book, 367 Foundation Profile, 2, 9
D
data types CLDC, 29 java.lang package, 27 Database class, KJava, 4041 Database_Check.java, 5962 DataInput interface, 27 DataOutput interface, 27 DataParser.java, Mobile Web Services, 294305 design centers, 1
G
garbage collector, 24 Gauge class, javax.microedition.lcdui, 72 Generic Connection Framework, 3134 GetData class, OrderManager, 164 Gnutella, 219 Graphics class, javax.microedition.lcdui, 7375 Graphics class, KJava, 37 GUI (graphical user interface) adding, 12 class use, 25
Index
classes KJava, 33 KJava package, 3536 J2SE conversion to J2ME, 358 GUI.java file, MP3 player, 207210
371
H
handheld devices changes in, 21 input methods, 1819 output methods, 1920 physical characteristics, 20 hardware, J2SE to J2ME conversion differences, 356 heavyweight process, 186 HelpDisplay class, KJava, 39 HelpDisplay_Spotlet, 4749 HTTP connections, 5255 HttpCheck_Spotlet, 5255
I
i-Mode, 2 initialization, TextField class, 38 input methods, 1819 input/output, J2SE conversion to J2ME, 356 installation CLDC, 4142 MIDP, 8285 interfaces AddressBook MIDlet, 101109 ChoiceGroup class, 69 ChoiceGroupUI MIDlet, 9598 Command class, 70 hierarchies, javax.microedition.io package, 3132 javax.microedition.rms, 7879 LabelUI MIDlet, 9395 MenuCheck MIDlet, 99101 Mobile Web Services, 276277 OrderManager, 164 P2P application, 219220 Target Practice game, 329 TestHTTP MIDlet, 109111 TestManager, 125 TickerUI MIDlet, 9899 user interface package, MIDP, 6678
J
J2EE (Java 2 Enterprise Edition), 1 J2ME (Java 2 Micro Edition), 1 converting from J2SE, 355
API differences, 357358 application models, 357 device variety and, 356 example of, 361365 hardware differences, 356 Java language support and, 355356 JavaCheck and, 359 process, 358359 virtual machines and, 355356 limited features, managing, 2526 overview, 13 J2ME Wireless Module, 86 J2ME Wireless Toolkit, 8586 J2SE (Java 2 Standard Edition), 1 converting to J2ME, 355 API differences, 357358 application models, 357 device variety and, 356 example of, 361365 hardware differences, 356 Java language support and, 355356 JavaCheck and, 359 process, 358359 virtual machines and, 355356 JAM (Java Application Manager), source code, 41 Java 2 Platform, Micro Edition, Wireless Toolkit 1.01 (J2ME), CD with book, 367 Java 2 Software Development Kit Standard Edition version 1.3 for Windows, CD with book, 367 Java Card applets, 13 java.io package CLDC, 6, 2731 MIDP, 64 java.lang package, 6 CLDC, 2730 MIDP, 64 java.microedition.io package, 3132 java.microedition.lcdui package, 9 java.microedition.rms package, 9 java.util package, 7 CLDC, 28, 31 MIDP, 64 JavaCard, 1215 JavaCheck application, 189193 J2SE conversion to J2ME, 359 JavaCodeCompact, 12 javax.microedition.io package, 7 MIDP API, 65 javax.microedition.lcdui, MIDP API, 6478 javax.microedition.midlet package, 8
372 Index
javax.microedition.midlet, MIDP API, 6566 javax.microedition.rms, MIDP API, 65, 7882 JMF (Java Media Framework), 193 JNI (Java Native Interface), 6 MaintenanceSoft.mdb file, TestManager, 126 m-commerce, 164 memory conserving, 2224 J2SE conversion to J2ME, 356 limitations, 17 MenuCheck MIDlet case study, 99101 methods Alert class, 68 ChoiceGroup class, 69 destroyApp, 64 Display class, 71 drawString, 37 Form class, 71 Gauge class, 72 Graphics class, 7375 java.lang, 2930 List class, 75 open, 32 pauseApp, 64 penDown, 4547 penMove, 40, 4547 RecordStore class, 7980 setUpperCase, 38 startApp, 64 StreamConnection interface, 33 TextBox class, 77 TextField class, 77 Ticker class, 78 MicroEdition-Configuration, MIDlet suites, 64 MicroEdition-Profile, MIDlet suites, 64 MIDlet suites, 64 MIDlets, 4, 6364 Active state, 64 AddressBook case study, 101109 ChoiceGroupUI case study, 9598 Destroyed state, 64 LabelUI case study, 9395 Loaded state, 64 MenuCheck case study, 99101 Paused state, 64 TestHTTP case study, 109111 TextFieldCheck case study, 9193 TickerUI case study, 9899 MIDP (Mobile Information Device Profile), 89, 63, 164 Alert class, 68 application lifecycle package, 6566 applications, running, 8285 class hierarchy, 8790 Command class, 70
K
kDOM, 115 KJava, 33 Button class, 3738 classes, 3536 Database class, 4041 Graphics class, 37 HelpDisplay class, 39 PDA profiles, 33 RadioButton class, 3839 RadioGroup class, 3839 ScrollTextBox, 3940 Spotlet class, 36 TestManager, 125 TextBox class, 41 TextField class, 38 KJava API, 27 KJava overlay, CLDC, 41 KJava package, Target Practice game, 329 KToolbar, 8586 KVM (K Virtual Machine), 34 XML parsers, 115 kXML APIs, CD with book, 367 kXML parser, 115117
L
LabelUI MIDlet case study, 9395 language support, J2SE to J2ME conversion, 355 LavelUI.java file, 9395 libraries, third party, 24 lightweight process, 186 limited features of J2ME, managing, 2526 List class, javax.microedition.lcdui, 7576 listener model, CommandListener, 6768 Loaded state, MIDlets, 64 local variables, 24 LookAheadReader class, kXML, 117 low-level APIs, 2526
M
MainClass.java Mobile Web Services, 280, 291294 Target Practice game, 330, 340351 MainScreen class, TestManager, 128 MainScreen.java file, TestManager, 139155
Index
Display class, 71 event handling, 6768 Form class, 7172 Graphics class, 7375 installation, 8285 List class, 7576 low-level APIs, 2526 MIDlets and, 6364 Mobile Web Services, 275 packages, 64 Palm devices, 8687 Persistence package, 7882 RecordStore class, 7982 StringItem class, 76 TextBox class, 7778 TextField class, 7677 Ticker class, 78 toolkits, 86 user interface package, 6678 MIDP CaseStudies folder, CD with book, 366 MIDP for Palm, 35 Mobile Information Device Profile, 2 Mobile Services folder, CD with book, 366 Mobile Web Services, 275 DataParser.java, 294305 interface, 276, 277 MainClass.java, 291294 MoviesList.java, 319327 News.java, 311319 running, 278 Weather.java, 305311 movies, Mobile Web Services, 276 MainClass, 280 MoviesList class, Mobile Web Services, 282 MoviesList.java, Mobile Web Services, 319327 MP3 player, 185, 193 GUI.java, 207210 JMF and, 193 MP3Client.java, 213217 MP3Player.java, 201204 NetDeamon.java, 204207 overview, 193197 protocol table, 195 running, 200 ServerDialog.java, 217218 Track.java, 210213 MP3 Player folder, CD with book, 366 MP3Client.java file, MP3 player, 213217 MP3Player.java file, MP3 player, 201204 NanoXML parser, 115 Napster, 219 .NET, 275 NetDeamon.java file, MP3 player, 204207 networking limitations, 1718 J2SE conversion to J2ME, 356 news, Mobile Web Services MainClass, 280 News class, Mobile Web Services, 284 News service, Mobile Web Services, 277 News.java, Mobile Web Services, 311319 nonvalidating parsers, 114115
373
O
objects, Database cid (creator id), 40 tid (table id), 40 online ordering, 164. See also OrderManager Online Ordering Systems folder, CD with book, 366 Online Testing Engine, 125. See also TestManager Online Testing Engine folder, CD with book, 366 Online Testing Engine, 125163 open method, 32 order table, OrderManager, 165 OrderManager, 164 interface, 164 running, 164 sql_order_mon.jsp, 181183 sql_xml.jsp, 180181 OrderManager class, 169180 OrderManager.java file, 169180 org.kxml parser package, 115117 org.kxml.io package, 115117 output methods, 1920 overloading processor, avoiding, 22
P
P to P search application folder, CD with book, 366 P2P (Peer-to-Peer) model, 219 P2P application interface, 219220 peer_application class, 220221 searchfiles, 223 server-level search, 219 serversearch, 222 showfiles, 221 source code, 265 peer_application.java, 226231 searchfiles.java, 265274
374 Index
serversearch.java, 257264 showfiles.java, 245257 userlist_screen.java, 232244 user-level search, 219 userlist_screen class, 221 pagers, alphanumeric, 19 Palm, MIDP and, 35, 8687 Palm overlay, CLDC and, 41 parseDataMovies method, Mobile Web Services, 281 ParseEvent class, kXML, 116 parsers, 112, 114 nonvalidating, 115 nonvalidating parsers, 114 validating, 115 validating parsers, 114 XML, 114 example application, 117123 KVM, 115 kXML, 115117 passing server load, 24 pauseApp method, 64 Paused state, MIDlets, 64 PDA Profiles, KJava, 33 PDAs. See also Palm changes in, 21 input methods, 19 MIDP for Palm, 35 output methods, 1920 physical characteristics, 20 synchronization, 17 peer objects, AWT, 186 peer_application class, P2P application, 220221 peer_application.java file, 226231 penDown method, 4547 penMove method, 40, 4547 persistence, javax.microedition.rms package, 7882 Personal Profile, 9 PersonalJava, 9, 1213, 185 CDC device, 185186 PersonalJava. See pJava pJava Emulation Environment, 186188 planning for programming, 10 platform, 2 Pocket PC emulation environment, 188 Pocket PCs, 185 pJava, 185 PrefixMap class, kXML parser, 116 preverifier, 6 preverifying classes, CLDC, 42 processing speed, J2SE conversion to J2ME, 356 processor speed, limitations, 1617 processor overload, avoiding, 22 profiles, 8 Foundation Profile, 9 MIDP, 89 Personal Profile, 9 programming techniques to counter limitations, 2226 protocols Generic Connection Framework, 33 MP3 player, 195
Q
QuestionParser class, TestManager, 129 QuestionParser.java file, TestManager, 155159
R
radio buttons, 4952 RadioButton class, KJava, 3839 RadioGroup class, KJava, 3839 read_category method, Mobile Web Services, 281 read_record method, Mobile Web Services, 281 Record Management System, 78 RecordStore class, javax.microedition.rms, 7982 rectangles, drawing, 37 resetDrawRegion( ) function, 37 Result.java, Target Practice game, 351354 result_screen.java file, 117 run.bat file, MIDP installation, 83 running applications CLDC, 43 MIDP, 8285 Mobile Web Services, 278 OrderManager, 164 TestManager, 126
S
sample.bat file, MIDP installation, 8485 scroll bar, 4547 ScrollTextBox class, KJava, 3940 ScrollTextBox_Spotlet, 4547 searches, P2P application, 219 searchfiles class, P2P application, 220, 223 searchfiles.java file, 265274 server functionality, 25 server load passing, 24 server sockets, 5562 ServerDialog.java, MP3 player, 217218 server-level search, P2P application, 219 servers, 55
Index
serversearch class, P2P application, 220, 222 serversearch.java file, 257264 setUpperCase method, 38 shopfile.dtd, 113 shopping. See online ordering showfiles class, P2P application, 220221 showfiles.java file, 244257 socket connections, 5562 Socket_Check, 5562 source code, CD with book, 366 Spotlet class, KJava, 36 Spotlets, 4 CheckRadio_Spotlet, 4952 HelpDisplay_Spotlet, 4749 HttpCheck_Spotlet, 5255 ScrollTextBox_Spotlet, 4547 TestManager, 125 TextField_Spotlet, 4345 sql_order_mon.jsp (OrderManager), 181183 sql_xml.jsp (OrderManager), 180181 startApp method, 64 StartTag class, kXML, 116 status command, MP3 player, 195 Status table, OrderManager, 166 storage limitations, 17 string concatenation, 24 StringItem class, javax.microedition.lcdui, 76 strings, displaying, 37 SunOne, 275 Swing API, pJava and, 185 synchronization PDAs, 17 servers, 55 SyncML, 26 SyncML, 26 system requirements CD with book, 366 KVM, 3
375
Test Manager, 125 TestFile.asp file, TestManager, 161163 TestHTTP MIDlet case study, 109111 TestManager interface, 125 running, 126 TestManager.java file, TestManager, 134138 TextBox class javax.microedition.lcdui, 7778 KJava, 41 TextEvent class, kXML, 116 TextField class, javax.microedition.lcdui, 7677 KJava, 38 TextField_Spotlet, 4345 TextFieldCheck MIDlet case study, 9193 TextFieldCheck.java file, 9193 third-party libraries, 24 Ticker class, javax.microedition.lcdui, 78 TickerUI MIDlet case study, 9899 tid (table id), 40 TinyXML parser, 115 Tomcat, CD with book, 367 Track.java file, MP3 player, 210213 troubleshooting CD with book, 367 Truffle Graphical Toolkit, 12 Truffle, pJava, 187
U
user interface package, MIDP API, 6678 user-level search, P2P application, 219 userlist_screen class, P2P application, 220221 userlist_screen.java file, 231244
V
valid documents, XML, 114 validating parsers, 114115 variables, local variables, 24 virtual machines, 23 CVM, 45 J2SE to J2ME conversion, 355 KVM (K Virtual Machine), 34 VxWorks, 185
T
tables, Mobile Web Services, 278280 Target Practice game, 329 counters, 331 interface, 329 MainClass.java, 340351 Result.java, 351354 TargetPractice class, 330 TargetPractice.java, 334340 Target Practice Game folder, CD with book, 366 targeted devices, constraints, 1621 TargetPractice.java, 334340
W
WAP (Wireless Application Programming), 2 WBXML (WAP Binary XML), 115 weather, Mobile Web Services, 276, 280 Weather.java, Mobile Web Services, 305311 well-formed documents, XML, 114 wireless networks, MP3 player and, 201
376 Index
X
XML (eXtensible Markup Language) overview, 112114 parser, 24 KVM, 115 kXML, 115117 parsing, 114115 example application, 117123 structure, 112114 tags, defining, 113 valid documents, 114 well-formed documents, 114 XML class, kXML parser, 116 Xml parser class, kXML, 116 XML Parsing CaseStudy folder, CD withbook, 366 XML Prolog, 112 XML Schemas, 114 XmlCaseStudy.java file, 117 XmlWriter class, kXML, 117
2.
3.
(b)
4.
Restrictions on Use of Individual Programs. You must follow the individual requirements and restrictions detailed for each individual program in the Whats on the CD-ROM appendix of this Book. These limitations are also contained in the individual license agreements recorded on the Software Media. These limitations may include a requirement that after using the program for a specified period of time, the user must pay a registration fee or discontinue use. By opening the Software packet(s), you will be agreeing to abide by the licenses and restrictions for these individual programs that are detailed in the Whats on the CD-ROM appendix and on the Software Media. None of the material on this Software Media or listed in this Book may ever be redistributed, in original or modified form, for commercial purposes. Limited Warranty. (a) HMI warrants that the Software and Software Media are free from defects in materials and workmanship under normal use for a period of sixty (60) days from the date of purchase of this Book. If HMI receives notification within the warranty period of defects in materials or workmanship, HMI will replace the defective Software Media.
5.
(b)
HMI AND THE AUTHOR OF THE BOOK DISCLAIM ALL OTHER WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, WITH RESPECT TO THE SOFTWARE, THE PROGRAMS, THE SOURCE CODE CONTAINED THEREIN, AND/OR THE TECHNIQUES DESCRIBED IN THIS BOOK. HMI DOES NOT WARRANT THAT THE FUNCTIONS CONTAINED IN THE SOFTWARE WILL MEET YOUR REQUIREMENTS OR THAT THE OPERATION OF THE SOFTWARE WILL BE ERROR FREE. This limited warranty gives you specific legal rights, and you may have other rights that vary from jurisdiction to jurisdiction.
(c)
6.
Remedies. (a) HMIs entire liability and your exclusive remedy for defects in materials and workmanship shall be limited to replacement of the Software Media, which may be returned to HMI with a copy of your receipt at the following address: Software Media Fulfillment Department, Attn.: Wireless Programming with J2ME: Cracking the Code, Hungry Minds, Inc., 10475 Crosspoint Blvd., Indianapolis, IN 46256, or call 1-800-762-2974. Please allow four to six weeks for delivery. This Limited Warranty is void if failure of the Software Media has resulted from accident, abuse, or misapplication. Any replacement Software Media will be warranted for the remainder of the original warranty period or thirty (30) days, whichever is longer. In no event shall HMI or the author be liable for any damages whatsoever (including without limitation damages for loss of business profits, business interruption, loss of business information, or any other pecuniary loss) arising from the use of or inability to use the Book or the Software, even if HMI has been advised of the possibility of such damages. Because some jurisdictions do not allow the exclusion or limitation of liability for consequential or incidental damages, the above limitation or exclusion may not apply to you.
(b)
(c)
7.
U.S. Government Restricted Rights. Use, duplication, or disclosure of the Software for or on behalf of the United States of America, its agencies and/or instrumentalities (the "U.S. Government") is subject to restrictions as stated in paragraph (c)(1)(ii) of the Rights in Technical Data and Computer Software clause of DFARS 252.227-7013, or subparagraphs (c) (1) and (2) of the Commercial Computer Software - Restricted Rights clause at FAR 52.227-19, and in similar clauses in the NASA FAR supplement, as applicable. General. This Agreement constitutes the entire understanding of the parties and revokes and supersedes all prior agreements, oral or written, between them and may not be modified or amended except in a writing signed by both parties hereto that specifically refers to this Agreement. This Agreement shall take precedence over any other documents that may be in conflict herewith. If any one or more provisions contained in this Agreement are held by any court or tribunal to be invalid, illegal, or otherwise unenforceable, each and every other provision shall remain in full force and effect.
8.
8. U.S. Government Restricted Rights. If Software is being acquired by or on behalf of the U.S. Government or by a U.S. Government prime contractor or subcontractor (at any tier), then the Government's rights in Software and accompanying documentation will be only as set forth in this Agreement; this is in accordance with 48 CFR 227.7201 through 227.7202-4 (for Department of Defense (DOD) acquisitions) and with 48 CFR 2.101 and 12.212 (for non-DOD acquisitions). 9. Governing Law. Any action related to this Agreement will be governed by California law and controlling U.S. federal law. No choice of law rules of any jurisdiction will apply. 10. Severability. If any provision of this Agreement is held to be unenforceable, this Agreement will remain in effect with the provision omitted, unless omission would frustrate the intent of the parties, in which case this Agreement will immediately terminate. 11. Integration. This Agreement is the entire agreement between you and Sun relating to its subject matter. It supersedes all prior or contemporaneous oral or written communications, proposals, representations and warranties and prevails over any conflicting or additional terms of any quote, order, acknowledgment, or other communication between the parties relating to its subject matter during the term of this Agreement. No modification of this Agreement will be binding, unless in writing and signed by an authorized representative of each party.
Java(TM) 2 Software Development Kit (J2SDK), Standard Edition, Version 1.3 SUPPLEMENTAL LICENSE TERMS
These supplemental license terms ("Supplemental Terms") add to or modify the terms of the Binary Code License Agreement (collectively, the "Agreement"). Capitalized terms not defined in these Supplemental Terms shall have the same meanings ascribed to them in the Agreement. These Supplemental Terms shall supersede any inconsistent or conflicting terms in the Agreement, or in any license contained within the Software. 1. Software Internal Use and Development License Grant. Subject to the terms and conditions of this Agreement, including, but not limited to Section 4 (Java(TM) Technology Restrictions) of these Supplemental Terms, Sun grants you a non-exclusive, non-transferable, limited license to reproduce internally and use internally the binary form of the Software complete and unmodified for the sole purpose of designing, developing and testing your Java applets and applications intended to run on the Java platform ("Programs"). 2. License to Distribute Software. Subject to the terms and conditions of this Agreement, including, but not limited to Section 4 (Java (TM) Technology Restrictions) of these Supplemental Terms, Sun grants you a non-exclusive, non-transferable, limited license to reproduce and distribute the Software in binary code form only, provided that (i) you distribute the Software complete and unmodified and only bundled as part of, and for the sole purpose of running, your Programs, (ii) the Programs add significant and primary functionality to the Software, (iii) you do not distribute additional software intended to replace any component(s) of the Software, (iv) you do not remove or alter any proprietary legends or notices contained in the Software, (v) you only distribute the Software subject to a license agreement that protects Sun's interests consistent with the terms contained in this Agreement, and (vi) you agree to defend and indemnify Sun and its licensors from and against any damages, costs, liabilities, settlement amounts and/or expenses (including attorneys' fees) incurred in connection with any claim, lawsuit or action by any third party that arises or results from the use or distribution of any and all Programs and/or Software. 3. License to Distribute Redistributables. Subject to the terms and conditions of this Agreement, including but not limited to Section 4 (Java Technology Restrictions) of these Supplemental Terms, Sun grants you a non-exclusive, non-transferable, limited license to reproduce and distribute the binary form of those files specifically identified as redistributable in the Software "README" file ("Redistributables") provided that: (i) you distribute the Redistributables complete and unmodified (unless otherwise specified in the applicable README file), and only bundled as part of Programs, (ii) you do not distribute additional software intended to supersede any component(s) of the Redistributables, (iii) you do not remove or alter any proprietary legends or notices contained in or on the Redistributables, (iv) you only distribute the Redistributables pursuant to a license agreement that protects Sun's interests consistent with the terms contained in the Agreement, and (v) you agree to defend and indemnify Sun and its licensors from and against any damages, costs, liabilities, settlement amounts and/or expenses (including attorneys' fees) incurred in connection
with any claim, lawsuit or action by any third party that arises or results from the use or distribution of any and all Programs and/or Software. 4. Java Technology Restrictions. You may not modify the Java Platform Interface ("JPI", identified as classes contained within the "java" package or any subpackages of the "java" package), by creating additional classes within the JPI or otherwise causing the addition to or modification of the classes in the JPI. In the event that you create an additional class and associated API(s) which (i) extends the functionality of the Java platform, and (ii) is exposed to third party software developers for the purpose of developing additional software which invokes such additional API, you must promptly publish broadly an accurate specification for such API for free use by all developers. You may not create, or authorize your licensees to create, additional classes, interfaces, or subpackages that are in any way identified as "java", "javax", "sun" or similar convention as specified by Sun in any naming convention designation. 5. Trademarks and Logos. You acknowledge and agree as between you and Sun that Sun owns the SUN, SOLARIS, JAVA, JINI, FORTE, STAROFFICE, STARPORTAL and iPLANET trademarks and all SUN, SOLARIS, JAVA, JINI, FORTE, STAROFFICE, STARPORTAL and iPLANETrelated trademarks, service marks, logos and other brand designations ("Sun Marks"), and you agree to comply with the Sun Trademark and Logo Usage Requirements currently located at http://www.sun.com/policies/trademarks. Any use you make of the Sun Marks inures to Sun's benefit. 6. Source Code. Software may contain source code that is provided solely for reference purposes pursuant to the terms of this Agreement. Source code may not be redistributed unless expressly provided for in this Agreement. 7. Termination for Infringement. Either party may terminate this Agreement immediately should any Software become, or in either party's opinion be likely to become, the subject of a claim of infringement of any intellectual property right. For inquiries please contact: Sun Microsystems, Inc. 901 San Antonio Road, Palo Alto, California 94303
License Agreement: Forte for Java, release 2.0 Community Edition for All Platforms
To obtain Forte for Java, release 2.0, Community Edition for All Platforms, you must agree to the software license below.
agree to comply strictly with all such laws and regulations and acknowledge that you have the responsibility to obtain such licenses to export, re-export, or import as may be required after delivery to you. 8. U.S. Government Restricted Rights. If Software is being acquired by or on behalf of the U.S. Government or by a U.S. Government prime contractor or subcontractor (at any tier), then the Government's rights in Software and accompanying documentation will be only as set forth in this Agreement; this is in accordance with 48 CFR 227.7201 through 227.7202-4 (for Department of Defense (DOD) acquisitions) and with 48 CFR 2.101 and 12.212 (for non-DOD acquisitions). 9. Governing Law. Any action related to this Agreement will be governed by California law and controlling U.S. federal law. No choice of law rules of any jurisdiction will apply. 10. Severability. If any provision of this Agreement is held to be unenforceable, this Agreement will remain in effect with the provision omitted, unless omission would frustrate the intent of the parties, in which case this Agreement will immediately terminate. 11. Integration. This Agreement is the entire agreement between you and Sun relating to its subject matter. It supersedes all prior or contemporaneous oral or written communications, proposals, representations and warranties and prevails over any conflicting or additional terms of any quote, order, acknowledgment, or other communication between the parties relating to its subject matter during the term of this Agreement. No modification of this Agreement will be binding, unless in writing and signed by an authorized representative of each party.
JAVA DEVELOPMENT TOOLS FORTE FOR JAVA, RELEASE 2.0, COMMUNITY EDITION SUPPLEMENTAL LICENSE TERMS
These supplemental license terms ("Supplemental Terms") add to or modify the terms of the Binary Code License Agreement (collectively, the "Agreement"). Capitalized terms not defined in these Supplemental Terms shall have the same meanings ascribed to them in the Agreement. These Supplemental Terms shall supersede any inconsistent or conflicting terms in the Agreement, or in any license contained within the Software. 1. Software Internal Use and Development License Grant. Subject to the terms and conditions of this Agreement, including, but not limited to Section 3 (Java(TM) Technology Restrictions) of these Supplemental Terms, Sun grants you a non-exclusive, non-transferable, limited license to reproduce internally and use internally the binary form of the Software complete and unmodified for the sole purpose of designing, developing and testing your [Java applets and] applications intended to run on the Java platform ("Programs"). 2. License to Distribute Redistributables. In addition to the license granted in Section 1 (Redistributables Internal Use and Development License Grant) of these Supplemental Terms, subject to the terms and conditions of this Agreement, including, but not limited to Section 3 (Java Technology Restrictions) of these Supplemental Terms, Sun grants you a non-exclusive, nontransferable, limited license to reproduce and distribute those files specifically identified as redistributable in the Software README file (Redistributables) provided that: (i) you distribute the Redistributables complete and unmodified (unless otherwise specified in the applicable README file), and only bundled as part of your Programs, (ii) you do not distribute additional software intended to supercede any component(s) of the Redistributables, (iii) you do not remove or alter any proprietary legends or notices contained in or on the Redistributables, (iv) for a particular version of the Java platform, any executable output generated by a compiler that is contained in the Software must (a) only be compiled from source code that conforms to the corresponding version of the OEM Java Language Specification; (b) be in the class file format defined by the corresponding version of the OEM Java Virtual Machine Specification; and (c) execute properly on a reference runtime, as specified by Sun, associated with such version of the Java platform, (v) you only distribute the Redistributables pursuant to a license agreement that protects Sun's interests consistent with the terms contained in the Agreement, and (vi) you agree to defend and indemnify Sun and its licensors from and against any damages, costs, liabilities, settlement amounts and/or expenses (including attorneys' fees) incurred in connection with any
claim, lawsuit or action by any third party that arises or results from the use or distribution of any and all Programs and/or Software. 3. Java Technology Restrictions. You may not modify the Java Platform Interface ("JPI", identified as classes contained within the "java" package or any subpackages of the "java" package), by creating additional classes within the JPI or otherwise causing the addition to or modification of the classes in the JPI. In the event that you create an additional class and associated API(s) which (i) extends the functionality of the Java platform, and (ii) is exposed to third party software developers for the purpose of developing additional software which invokes such additional API, you must promptly publish broadly an accurate specification for such API for free use by all developers. You may not create, or authorize your licensees to create, additional classes, interfaces, or subpackages that are in any way identified as "java", "javax", "sun" or similar convention as specified by Sun in any naming convention designation. 4. Java Runtime Availability. Refer to the appropriate version of the Java Runtime Environment binary code license (currently located at http://www.java.sun.com/jdk/index.html) for the availability of runtime code which may be distributed with Java applets and applications. 5. Trademarks and Logos. You acknowledge and agree as between you and Sun that Sun owns the SUN, SOLARIS, JAVA, JINI, FORTE, STAROFFICE, STARPORTAL and iPLANET trademarks and all SUN, SOLARIS, JAVA, JINI, FORTE, STAROFFICE, STARPORTAL and iPLANETrelated trademarks, service marks, logos and other brand designations ("Sun Marks"), and you agree to comply with the Sun Trademark and Logo Usage Requirements currently located at http://www.sun.com/policies/trademarks. Any use you make of the Sun Marks inures to Sun's benefit. 6. Source Code. Software may contain source code that is provided solely for reference purposes pursuant to the terms of this Agreement. Source code may not be redistributed unless expressly provided for in this Agreement. 7. Termination for Infringement. Either party may terminate this Agreement immediately should any Software become, or in either party's opinion be likely to become, the subject of a claim of infringement of any intellectual property right. For inquiries please contact: Sun Microsystems, Inc. 901 San Antonio Road, Palo Alto, California 94303
CD-ROM Includes:
6 professional-quality applications and 3 topical case studies, complete with over 5,700 lines of source code Java 2 Software Development Kit Standard Edition version 1.3 for Windows Java 2 Platform, Micro Edition, Wireless Toolkit 1.0.1 Forte for Java, release 2.0, Community Edition for All Platforms Tomcat JavaServer Pages Implementation Server and kXML
MP3 player for Pocket PCs Peer-to-peer search application for Palm OS devices Mobile Web services (weather, movie ticket ordering, news) for cell phones Target practice game for Palm OS devices Plus CLDC implementation, MIDP-MIDlet implementation, and XML parsing case studies and guidance on converting existing applications into J2ME
ISBN 0-7645-4885-9
Reader Level
Intermediate to Advanced
Shelving Category
Programming
,!7IA7G4-fei fh!:p;o;t;T;T