End-to-end J2ME App Development Instance - Introduction Smart Ticket

xiaoxiao2021-03-06  43

Author: Norman Richards and Michael Yuan2001 released in the first Java technology blueprint Java Pet Store has fully demonstrated the advantage of Sun's J2EE technology. The blueprint not only provides sample code not only for multi-storey, database-driven e-commerce applications, but also provides design guidelines to demonstrate common mode. Since the release of the first release, Java technology blueprints have become the most valuable resources and best practices for developers who want to learn J2EE's latest technology.

The Smart Ticket Blueprint adds a new feature: mobility. It demonstrates how to create a complete end-to-end mobile business system that implements a movie booking feature, uses J2ME MIDP for wireless front ends, and uses J2EE application servers and relational databases for backends. Learning how this program is designed and constructs to greatly enhance your understanding of mobile enterprise applications and their solutions.

The article contains the code of Early Access 2.0 version of the Smart Ticket published in April 2003. The screenshots and sample code in the Early-Access version may have a subtle change in the final version, but you are still useful from the experience of learning from the design. Smart Ticket 1.2 is still valid. It has the same model and background with the version we discussed now, so many detailed explanations are applicable regardless of the versions of the past or future. In addition to special instructions, Sun Microsystems reserves all source code of this article.

Download and install

The Smart Ticket application can be obtained from the Sun's Blueprints website. The ZIP compressed file contains source code, Ant build scripts, and pre-built configurable applications.

The Smart Ticket application contains a J2ME component and a J2EE component. Run it requires a J2EE application server (such as Sun's J2EE reference implementation, version 1.3 or higher), and any device or suitable simulation program with an Internet connection. Such as Sun's J2ME Wireless Toolkit 2.0. The Smart Ticket release includes a special instruction to help build and deploy this application. Start now:

Make sure you have the following resources:

JDK V1.4.1 or higher. J2EE V1.3.1 or higher. J2ME Wireless Toolkit 2.0 or later. Set the following environment variables:

Java_Home: JDK installation directory. J2EE_HOME: J2EE RI Installation Directory. J2MEWTK_HOME: J2ME Wireless Toolkit Installation Directory. Start J2EE Server:

J2EE_HOME / BIN / Cloudscape -start

J2EE_HOME / BIN / J2EE -VERBOSE

Configure the J2EE application. In setup.xml files, use the following setup script to call the deploy Ant task:

Setup deploy

Specify your browser connection http: // localhost: 8000 / smartticket, click the Populate Database link to import the analog cinema and movie data into the database. If you use an old-fashioned computer, this is very slow process, so you have to be patient! The analog data includes two postal codes located in 95054 and 95130. Start J2ME Wireless Toolkit 2.0 and run the MIDlet specified in Smart_Ticket-Client.jad.

SMART Ticket in operation

After running MIDlet, you can achieve user needs. You will find that you need to complete four tasks.

Manage User Parameters: When you run the MIDP client for the first time, you need to create a configuration file, including the username, password, the preferred postal code for theater search, the first-week preferred day, or the credit card number. Smart Ticket With account credentials Create a user account on the server side, and the preferred data is cached in the computer. You can also configure the MIDP client to cache the credentials so that you do not need manual input every time you purchase or submit a movie rating. You can also modify user parameters at any time.

(Click on the picture to enlarge) Search movies and ticket: As long as you log in success, you can search for the cinema, movies, and show time that meet the preferred conditions. As long as you choose a pre-movie, MIDlet provides a seating chart showing the vacancy. This process includes a series of real-time queries for J2EE servers. With the rich user interface (UI) of MIDP, you can choose or subscribe to a seat. The subscription information will be written to the server-side database and will be reflected in the seating chart in the next search.

(Click on the picture to enlarge) Movie rating: You can rating you through the movie. This operation will not be submitted immediately to the server. These movies are slow to the client, and whenever you rating at any time, you can submit to the server synchronously. Therefore, even in your phone exceeds the network range, you can rating (for example, in a shielded theater!). Synchronous agents can intelligently prevent you from "lie": If you have multiple times to a movie, it only keeps the last result in the database. Cache Cinema Show Timetable: To avoid cumbersome viewing procedures, you can download a cinema timetable to the client application to go offline. You can delete or download the schedule again when you need it.

SMART Ticket

Older mobile business platforms, such as WAP / WML-based micro browsers put all information processing on the server side. An important advantage of J2ME is that it supports the smart client program running on the client. Smart Ticket fully reflects the advantages of intelligent client application examples:

Rich UI: Using LCDUI enhancements in MIDP 2.0, the Smart Ticke client provides an excellent user interface. For example, it allows the user to select a seat by an interactive seating view. When you browse the cinema show schedule and select the date, the MIDlet will dynamically add a show time in the current screen. Cache Preferences: User Preferences are completely cached to support complete personalization - this is the core value of mobile commerce. For example, you don't need to enter postal coding, credit card numbers, or even enter your personal login information using Smart Ticket every time you enter, this greatly reduces the strike workload. Offline function: limited and unstable mobile network coverage has hindered the development of "continuous connection" applications based on micro browsers. J2ME Smart Client Program follows the "Intermittent Connection" example, using data stored on the client device and synchronizes the data on the server-side data as needed - Smart Ticket supports the download schedule and rating the movie to the movie is a very Good example. High performance: The downloaded screen schedule is also suitable for performance caching, even when the client device is connected. This reduces the need for multiple round-trip processes because this process is very slow. Intelligent synchronization: The program cache used by the smart client program requires regular updates from the server. The movie screen schedule can be downloaded directly by the user, and the rating can be synchronized by the smart agent residing in the client and the server.

How to achieve these features?

Important architecture model

Overall MVC mode

The overall architecture of the Smart Ticket application follows the mode - View-Controller mode. This application is divided into multiple logical layers, so the developer does not affect other parts when modifying a part. Smart Ticket complies with the MVC model as follows:

View: Each view class displays an interactive UI (User Interface) screen, waiting for the user to enter. When the user selects a UI event by pressing a key or from the list, the event handler of the view class captures this event and passes the control to the controller class. Most classes in com.sun.j2me.blueprints.smartticket.client.midp.ui are view classes. Public Class Choosemovieui EXTENDS FORM IMPLEMENTS

CommandListener, ItemStatelistener,

ItemCommandListener {

Private uiicontroller uiController;

// ...

Public void CommandAction (Command Command, Displayable)

Displayable) {UiController.commandAction (Command,

Displayable);

}

Public void CommandAction (Command Command, Item Item) {

IF (command == selectseatsCommand) {

IF (Numoftickets.getstring (). Length () == 0

|| integer.parseint (Numoftickets.getstring ())

<1) {

UiController.showerRoralert

UiController.getstring

UICONSTANTS.NUM_OF_TICKET_ERR);

} else {

UiController.selectsetesselected (

Movieschedules [movielist.getSelected ",

GetShowTimes ());

}

}

}

}

Controller: Controller Clauses Perceive all possible interactions between users and programs. In Smart Ticket, the UiController class has a method for each possible action, for example, PurchaseRequested (). The action method often initiates two new threads, one for performing the motion of the background, and the other is used to display the progress bar to the user. The action thread is represented by the EventDispatcher class, and its Run () method includes a long SWITCH statement that completes the event request in the model layer calls the appropriate method. When the last call of these methods returns, the controller initializes the next UI screen and displayed.

Package com.sun.j2me.blueprints.smartticket.client.midp.ui;

Public class uiicontroller {

// References to all ui classes

// ...

Public UiController (MIDlet MIDET, ModelFacade Model) {

This.display = display.getdisplay (midlet);

THIS.MODEL = Model;

}

// ...

Public void selectseatsselected (theaterschedule.movieschedule

Movieschedule, Int [] showtime) {

SELECTEDSHOWTIME = ShowTime;

SelectedMovie = Movieschedule.getmovie ();

SelectedMovieschedule = Movieschester;

RunwithProgress

New eventdispatcher (eventids.event_id_selectseatsselected, mainmenuu),

GetString (Uiconstants.Processing), False;

}

Class EventDispatcher Extends thread {

Private int taskid;

Private Displayable Fallbackui;

EventDispatcher (int Taskid, Displayable Fallbackui) {

THIS.TASKID = TASKID;

THIS.FALLBACKUI = Fallbackui;

Return;

}

Public void run () {

Try {

Switch (task) {

// Cases ...

Case eventids.event_id_selectsetesselected: {

SeatingPlan seatingPlan =

SelectedMovieschedule.GetSeatingPlan (SELECTEDSHOWTIME);

String moviename = selectedMovie.gettitle ();

SeatingPlanui.init (SelectdTheater.getName (), Moviename,

SEATINGPLAN, SELECTEDSHOWTIME

Display.SetCurrent (SEATINGPLANUI);

Break;

}

Case eventids.event_id_seatsselected: {

RESERVATION =

Model.reserveseats (SelectedTheater.GetPrimaryKey (),

SelectedMovie.GetPrimaryKey (),

SELECTEDSHOWTIME, SELECTEDSEATS;

Purchaseticketsui.init (Model.GetAccountInfo ());

Display.SetCurrent (Purchaase Acketui);

Break;

}

Case eventids.event_id_purchaserequester: {

Model.purchaseticickets (RESERVATION);

PurchaseCompleteui.init (reservation.getid (),

Selectedtheater.getname (),

SelectedMovie.getTitle (),

SELECTEDSHOWTIME

Display.SetCurrent (PurchaseCompleteui);

Break;

}

// Other Cases ...

}

} catCH (Exception Exception) {

// Handle Exceptions

}

} // end of run () Method

} // End of EventDispatcher Class

}

Mode: The class in the model layer includes all application logic. In fact, the cache and communication classes in the entire J2EE server component are in the model layer. The model layer plays an important role in the complex interface mode of the client and the server.

Let's take a look at the details of the model layer.

Client interface

For most application actions, the controller entry to the model layer is the ModelfAde class. In order to comply with the MVC mode, the ModelfAcade class contains a method of responding to each event in the model layer. Depending on the nature of the action, the interface will delegate one or more models of the following:

LocalModel class handles the action that needs to be accessed on the data stored on the local device. For example, if an action requires reading and writing the preferred data, ModelfAcade calls the appropriate action method in LOCALMODEL. The RemoteModelProxy class, which implements the RemoteModel interface, and the processing needs to access the J2EE server, such as ticket purchase. The method in RemoteModelProxy is a remote procedure call (RPC), which we will talk about the background when discussing the background. The SynchronizationAgent class is synchronized with local data. Remote server-side data. In the Smart Ticket program, only the rating is synchronized. This agent has two action methods: synchronizations () synchronizes the rating; the commitMoVieratings () method submits the analyzed synchronization request to the background and updates the content stored locally. Package com.sun.j2me.blueprints.smartticket.client.midp.model;

Public class modelfacade {

Private synchronizationAgent syncagent;

Private remotemodelproxy remotemodel;

Private LocalModel LocalModel;

// Action methods ...

Public RESERVATION RESERVESeats (String Theaterkey,

String MovieKey,

Int [] showtime, seat [] seats)

Throws ApplicationException {

Try {

Return RemoteModel.reserveseats (TheaterKey,

MovieKey, ShowTime, Seats;

} catch (modelexception me) {

// ...

}

}

Public Void Purchaseticickets (RESERVATION RESERVATION)

Throws ApplicationException {

Try {

Remotemodel.purchasetickets (reservation.getid ());

Localmodel.addmovierating (

NEW MOVIERATING (RemoteModel.getmovie (RESERVATION.GETMOVIEID ()),

RESERVATION.GETSHOWTIME ()));

} catch (modelexception me) {

// ...

}

Return;

}

Public Void Synchronizations (int

ConflicTResolutionStrategyID)

Throws ApplicationException {

Try {

SyncAgent.synchronizemovieratings (ConflicTResolutionStrategyId);

Return;

} catch (modelexception me) {

// ...

}

}

// ...

}

Service interface

The server's server uses a lot of Enterprise JavaBeans Components (EJBs) to encapsulate business logic and management and relational database interactions. When the client's RemoteModelProxy issues RPC call to the server, the HTTP Servlet SmartticketServlet calls the appropriate action method in Session EJB through the Service Agent Object SmartticketBD. According to request nature, it further entrusts one of two other session beans, TicketingBean or SynchronizingBean. A set of entity beans updates the database using the container managed by EJB 2.0 when needed. Package com.sun.j2me.blueprints.smartticket.server.Web.midp;

Public class smartticketServlet Extends httpservlet {

Public Static Final String session_attribute_smart_ticket_bd =

"com.sun.j2me.blueprints.smartticket.server.web.midp.smartticketbd";

Protected Void Dopost (httpservletRequest Request,

Httpservletresponse response

Throws servletexception, ioException {

HttpSession session = request.getations (TRUE);

Smartticketbd smartticketbd = (smartticketbd)

Session.getaTribute (session_attribute_smart_ticket_bd);

// Calls Handlecall () Method and Encodes the Url for

// session tracking

}

Public Int Handlecall (SmartticketBD SmartticketBD,

InputStream in, OutputStream Out

THROWS IOException, ApplicationException {

// Identifies The Requested Action Method

// Executes the Method, As SELECTED IN A SWITCH STATEMENT

Switch (Method) {

// Cases ...

Case MessageConstants.operation_get_movie: {

GetMovie (SmartTicketBd, Call, SuccessFulResult);

Break;

}

// More Cases ...

}

}

}

Package com.sun.j2me.blueprints.smartticket.server.Web.midp;

Public class smartticketbd imports remotemodel {

Public Static Final String EJB_REF_FACADE =

"ejb / smartticketfacade";

Private smartticketfacadelocal facade;

Private servletContext servletContext = NULL;

Public SmartTicketBd (ServletContext ServletContext)

Throws ApplicationException {

THIS.SERVLETCONTEXT = servletContext; Try {

Context context = (context)

New InitialContext (). Lookup ("Java: Comp / ENV");

Facade = ((SmartTicketFacadeloCalhome)

Context.lookup (EJB_REF_FACADE)). CREATE ();

Return;

} catch (exception e) {

Throw New ApplicationException (E);

}

}

Public Movie getMovie (String moviekey)

Throws modelexception, ApplicationException {

Try {

Movielocal movielocal = facade.getmovie (moviekey);

Movie movie = new movie (movielocal.getid (),

Movielocal.gettitle (),

Movielocal.getsummary (),

Movielocal.getrating ());

Return movie;

} catch (smartticketfacadeexception stfe) {

Throw new

Modelexception (ModeException.cause_movie_not_found);

} catch (exception e) {

Throw New ApplicationException (E);

}

}

// Other action methods in RemoteModel Interface ...

}

Package com.sun.j2me.blueprints.smartticket.server.ejb;

Public Class SmartticketFacadeBeans SessionBean {

// ...

Public Movielocal GetMovie (String Movieid)

Throws smartticketfacadeexception {

Try {

Return Moviehome.FindByPrimaryKey (movieid);

} catch (FINDEREXCEPTION FE) {

Throw new

SmartTicketFacadeException ("No Matching Movie.");

}

}

// ...

}

The following figure shows the architecture of the overall MVC and interface:

Implementation mode

The MVC and interface mode define the overall structure of the application. In addition, Smart Ticket lists some important behavioral modes that help developers improve efficiency.

Processing program chain

The RemoteModelProxy class entrusts each request action to the Handler class chain to transparently resolve an exception pipeline for RMS serialization and HTTP connections. The handler architecture of the link is based on the RequestHandler interface and the RemoteModelRequestHandler abstract class:

Public interface requesthandler {

Requesthandler getNextHandler ();

VoidiniT () throws ApplicationException;

Void destroy () throws ApplicationException;

}

Abstract Public Class RemotemodelRequestHandler

Implements Requesthandler, RemoteModel {

Private remotemodelrequesthandler nexthandler; private preferences preferences

Protected Static ProgressobServer Progressobserver;

Public RemoteModelrequestHandler

RemoteModelrequestHandler nexthandler) {

this.nexthandler = nextHandler;

}

Public Requesthandler getNextHandler () {

Return nextHandler;

}

Public void init () throws applicationException {

IF (NextHandler! = NULL) {

NextHandler.init ();

}

Return;

}

Public void destroy () throws ApplicationException {

IF (NextHandler! = NULL) {

NextHandler.DESTROY ();

}

Return;

}

Public void login (String Username, String Password)

Throws modelexception, ApplicationException {

GetRemoteModelrequestHandler (). login (username, password);

Return;

}

Public Void CreateAccount (Accountinfo Accountinfo)

Throws modelexception,

ApplicationException {

GetRemoteModelrequestHandler (). CreateAccount (Accountinfo);

Return;

}

// Other action methods declared in RemoteModel

// ...

}

The specific Handler class extends the RemoteModelRequestHandler class. Nested constructor creates a handler chain. Smart Ticket enables two handler classes: RMSCacheHandler and HttpCommunicationHandler. Therefore, the link assembly method is as follows:

Public Class RemotemodelProxy Extends ModelobjectLoader

Implements remotemodel {

Private remotemodelrequesthandler Requesthandlerchain

PRIVATE preferences preferences = NULL;

Private hashtable movies = new hashtable ();

Public RemoteModelProxy (String ServiceURL)

Throws ApplicationException {

Requesthandlerchain =

New rmscachehandler

New httpcommunicationHandler (NULL, ServiceURL);

Return;

}

// ...

Public Movie getMovie (String moviekey)

Throws modelexception,

ApplicationException {

Movie movie = (movie) Movies.get (moviekey);

IF (movie == null) {

Movie = RequestHandlerchain.getMovie (moviekey); Movies.Put (MovieKey, Movie);

}

Return movie;

}

// Other Methods ...

}

A handler can selectively implement a method of action in any RemoteModel interface, one of two ways:

If a REMOTEMODELPROXY class calls an action method that cannot be done by the previous Handler class, the base class RemoteModelRequestHandler class ensures that this call is passed to the next handler in the chain. If a handler in the chain determines that it has completed the processing of an action, it will return directly. Otherwise, it calls the same action method in the superclass and passes it to the next handler in the chain.

Public class rmscachehandler extends RemotemodelrequestHandler {

// ...

Public Movie getMovie (String moviekey)

Throws modelexception,

ApplicationException {

Indexentry indexentry =

RMSADAPTER.GETIndExentry (moviekey,

Indexentry.Type_Movie, Indexentry.mode_any;

IF (indexentry! = null) {

Return Rmsadapter.loadMovie (IndexEntry.getRecordId ());

}

Return super.getmovie (moviekey);

}

// ...

}

Binary remote procedure call on HTTP

In the model layer, the HTTPCommunicationHandler class in the RemoteModelProxy class calls the server-side remote procedure through the binary RPC protocol on the HTTP connection. The protocol is defined as follows:

All RPC requests from the client to the server are followed by the same basic mode. The first byte of the data stream specifies the action method of the server-side interface session bean, and the remaining byte is encoded as a UTF data serial sequence, which indicates the parameters passed to the remote method. The HTTP data stream contains RPC return values. The format of the request and response is unique to each method, so you must see the source code for each method to determine the exact format.

Enter the RPC encoding of the first byte of the request data stream to define in the MessageConstants class:

Package com.sun.j2me.blueprints.smartticket.shared.midp;

Public final class message messageconstants {

Public static final byte operation_login_user = 0;

Public static final byte Operation_create_account = 1;

Public static final byte Operation_update_account = 2;

Public static final byte operation_get_theaters = 3;

Public static factory byte operation_get_theater_schedule = 4;

Public static final byte operation_get_movie = 5;

Public static final byte operation_get_movie_poster = 6;

Public static factory Byte Operation_get_movie_showtimes = 7; public static final byte operation_get_seating_plan = 8;

Public static final byte operation_reserve_seats = 9;

Public static factory byte operation_purchase_tickets = 10;

Public static final byte operation_cancel_seat_reservation = 11;

Public static factory byte operation_get_locales = 12;

Public static final byte operation_get_resource_bundle = 13;

Public static final byte operation_initiate_synchronization = 14;

Public static final byte operation_synchronize_movie_ratings = 15;

Public static final byte operation_commit_movie_RATINGS = 16;

Public static factory byte error_none = 0;

Public static factory byte error_unknown_operation = 1;

Public static final byte error_server_error = 2;

Public static factory byte error_model_exception = 3;

Public static factory byte error_request_format = 4;

PRIVATE MessageConstants () {}

}

The following two classes explain an RPC round-trip process, the action method of the HTTPCommunicationHandler class requests to specify the information of the movie, and call a method of the MOVIE class to extract the return value in the response stream.

Package com.sun.j2me.blueprints.smartticket.client.midp.model;

Public Class HttpCommunicationHandler

Extends RemotemodelrequestHandler {

// ...

Public Movie getMovie (String moviekey)

Throws modelexception,

ApplicationException {

HTTPConnection Connection = NULL;

DataOutputstream outputstream = null;

DataInputStream InputStream = NULL;

Try {

Connection = OpenConnection ();

UpdateProgress ();

OutputStream = OpenConnectionOutputStream (Connection);

// the rpc request

OutputStream.writebyTe (MessageConstants.operation_get_movie);

OutputStream.writeutf (moviekey);

OutputStream.Close ();

UpdateProgress ();

// unmarshal the return value

InputStream = OpenConnectionInputStream (Connection); Movie Movie = Movie.Deserialize (InputStream);

UpdateProgress ();

Return movie;

} catch (ioexception ie) {

Throw new

ApplicationException (ErrorMessageCodes.Error_cannot_connect);

} finally {

CloseConnection (Connection, OutputStream, InputStream);

}

}

// Other Action Methods ...

}

Package com.sun.j2me.blueprints.smartticket.shared.midp.model;

Public class movie {

PRIVATE STRING PRIMARYKEY;

PRIVATE STRING TITLE;

PRIVATE STRING SUMMARY;

PRIVATE STRING

Private boolean alreadyseen = false;

Transient private byte [] POSTER = NULL;

Public Static Movie Deserialize (DataInputStream

DataStream) throws ApplicationException {

Try {

Movie movie = new movie ();

// read the RPC Response Stream

Movie.primaryKey = DataStream.ReadUTF ();

Movie.title = DataStream.readUTF ();

Movie.summary = DataStream.readUTF ();

Movie.Rating = DataStream.readutf ();

Try {

Movie.alreadyseen = DataStream.readBoolean ();

} catch (ioexception ie) {

Movie.alreadysen = false;

}

Try {

Return

ModelObjectLoader.getInstance (). GetMovie (movie);

} catch (modelexception me) {

Throw new ApplicationException ();

}

} catch (ioexception ie) {

Throw New ApplicationException (IOE);

}

}

// Other Methods ...

}

At the server side, the SmartTicketServlet first determines the action expressed in the first byte encoding in the request data, and then assigns the appropriate action method to request the request through the interface and passed all RPC parameters retained in the data stream.

In the Smart Ticket program, the client and server are closely linked. This approach improves network performance because each RPC exchange can be specially designed and optimized. However, we must trade between development speed and robustness. Even if the minor changes in the server side are also likely to change the client's protocols and resolution codes, there are many potential possible factors. Developers need to keep track of all possible code and update it if necessary. They also need to recompile and re-distribute client programs often, otherwise it will cause errors.

Client thread model

The Smart Ticket application uses a complex thread model in the client, there are two important aspects:

The MIDP specification requests the commandListener.commandAction () method "Returns now" to avoid blocking the UI, so any long-term operation must be placed in other threads. The running thread can display a dynamic progress bar indicating the progress of the operation, in particular a thread involving a remote network operation. The schedule screen provides a cancel button for the lack of patient users, which can terminate too long. (Click on the image to enlarge)

Maybe you have long noticed that the action method in the UiController class is just a simple packaging of the RunwithProgress () method, which sets the screen for ProgressobServerui and launch the EventDispatcher thread. The ProgressobServerUI screen displays a progress bar and a STOP button to monitor it through the main MIDlet system UI thread. As mentioned earlier, the EventDispatcher thread finally entrusts the requesting action of the model layer method. Each of these methods calls ProgressobServerui.UpdateProgress () in a certain phase, to inform the user's progress.

Public class uiicontroller {

// Action methods ...

Public void choosemovierequsted () {

RunwithProgress

New eventdispatcher

Eventids.event_id_choosemovierequested,

MainMenuui,

GetString (Uiconstants.Processing), False;

}

// Action methods ...

Public void RunwithProgress (Thread Thread, String Title,

Boolean stoppable) {

ProgressobServerui.init (title, stoppable);

GetDisplay (). setCurrent (ProgressobServerui);

Thread.start ();

}

Class EventDispatcher Extends thread {

// ...

Public void run () {

// Switch - Case Statements to Delegate

// actions to the model Layer

}

}

}

Public Class ProgressobServerui Extends Form

Implements progressobserver,

CommandListener {

Private uiicontroller uiController;

PRIVATE STATIC FINAL INT GAGE_MAX = 8;

Private static final int gauge_levels = 4;

INT CURRENT = 0;

Gauge gauge;

Command stopcommand;

Boolean stoppable;

Boolean stopped;

Public Progressobserverui (UiController UiController) {

Super ("");

Gauge = new gauge (", false, gauge_max, 0);

StopCommand = New

Command (UiController.getstring (uiconstants.stop),

Command.stop, 10);

append (gauge);

SetCommandListener (this);

}

Public void init (String Note, Boolean Stoppable) {

Gauge.SetValue (0); setNote (Note);

SetStoppable;

STOPPED = FALSE;

}

Public void setnote (String Note) {

SetTitle (Note);

}

Public boolean isstoppable () {

Return stoppable;

}

Public void setStoppable (Boolean Stoppable) {

THIS.STOPPABLE = STOPPABLE;

IF (stoppable) {

Addcommand (StopCommand);

} else {

RemoveCommand (StopCommand);

}

}

/ **

* Indicates WHETHER THE User Has Stopped The Progress.

* This Message Should Be Called Before Calling Update.

* /

Public boolean isstopped () {

Return stopped;

}

Public void updateprogress () {

Current = (Current 1)% Gauge_levels;

Gauge.SetValue (Current * Gauge_max / gauge_levels);

}

Public void CommandAction (Command C, Displayable D) {

IF (c == stopcommand) {

STOPPED = True;

}

}

}

Conclude

This article introduces a new SMART Ticket V2.0 blueprint. Several major improvements for earlier versions use the rich features of intelligent clients. Smart Ticket shows you how to use several important design patterns that we just briefly told to achieve advanced features. We hope that the contents of this article will allow you to start quickly in the end-to-end design mode.

Reference

Sun Java Wireless Blueprints "Developing an End to End Wireless Application Using Java Smart Ticket Demo", Author: Eric Larson (covers Smart Ticket v1.1)

About the Author: Norman Richards is an engineer in Austin, Texas, United States of Zilliant. He is the computing from the book of XDoclet in Action (Many In the Summer 2003). . Michael Yuan is a doctor at the University of Texas, Austin. He regularly writes JavaWorld's "Wireless Java" column. He is currently writing a book about J2ME for Prentice Hall, Enterprise J2me: Developing Java Mobile Applications (2003).

转载请注明原文地址:https://www.9cbs.com/read-57288.html

New Post(0)