Download (direct link):
174 Item 22
257: String response = sw2.toString();
258: return response;
// - removed main() method (used for testing) 323: }
Listing 22.2 (continued)
The httpGet() method instantiates a URL object from the urlBuf StringBuffer (line 238), opens a connection to the URL (line 240) and then reads lines of text from the Web server (line 252) and prints them to a PrintWriter/StringWriter buffer. Lastly, the contents of the StringWriter are retrieved as a single String (line 257).
To examine the API differences between J2SE and J2ME, we attempt a straightforward port of the code to J2ME, changing as little code as necessary. Listing 22.3 is our direct port of SwinginAmazonSearch.java to J2ME. We will examine specific API differences as we cover each section of code.
001 package org.javapitfalls.item22;
003 import java.io.*;
004 import java.util.*;
005 import javax.microedition.midlet.*;
006 import javax.microedition.lcdui.*;
007 import org.kxml.*;
008 import org.kxml.kdom.*;
009 import org.kxml.parser.*;
011: public class BadMicroAmazonSearch extends MIDlet implements 2
013 public static final String CMD_SEARCH = "Search";
014 public static final String CMD_DETAILS = "Details";
015 public static final String CMD_NEXT_TEN = "More";
// - removed other static constant Strings
020 // commands
021: private Command searchCommand;
022 private Command detailsCommand;
// - removed other Command references for brevity
027 // display
028 private Display display;
030 // screens
Listing 22.3 BadMicroAmazonSearch.java
J2ME Performance and Pitfalls 175
031 private Form searchScreen;
032 private List resultsScreen;
033 private TextBox detailsScreen;
035 // screen components
036 ChoiceGroup opsChoice;
037 ChoiceGroup modeChoice;
038 TextField targetTF;
039 BadMicroAmazonHttpGet getter = new BadMicroAmazonHttpGet();
040 int page = 1;
042 Vector productNodes;
044 boolean debug = true;
045 Timer ticker = new Timer();
Listing 22.3 (continued)
The class BadMicroAmazonSearch extends MIDlet and implements CommandLis-tener (instead of implementing ActionListener). A MIDlet is a Mobile Information Device Profile (MIDP) application. The MIDlet is an abstract class with three abstract methods that must be overridden by the subclass: startApp(), pauseApp(), and destroyApp(). In this sense, a MIDlet is similar to an applet in that it has a lifecycle controlled by an external Management application.
Before we examine the details of the class, notice the import statements: two packages are the same as J2SE packages (java.io and java.util), although they are limited in scope, and the two javax packages are new (javax.midlet, which has the MIDlet class, and javax.lcdui, which has the GUI classes). The kxml package is an open-source package available at http://kxml.enhydra.org/. We will discuss the kxml package in more detail later. Now let's examine the GUI differences apparent in the BadMicroAmazonSearch class definition. Since we are dealing with such a small screen size, as shown in Figure 22.2, I divided the single Swing Frame into three "displayable" screens (Screen objects).
Figure 22.2 MIDP screen size on a Motorola phone.
Motorola and the Motorola logo are trademarks of Motorola, Inc.
176 Item 22
A major difference between Swing and J2ME GUIs is that there are no Frames in J2ME. In essence, there is only a single Display (line 28) and you can switch the Display to any subclass of Screen. Our Screen subclasses are a Form for the search screen, a List for the results screen, and a TextBox for the details screen. One other important difference is that there are no JButton or Button classes in J2ME; instead, there is a Command class. You add your commands to the appropriate screen. You will also notice that we shortened the "Next Results" label to "More" (line 15) to take into account the smaller screen size. The last difference is that ComboBox has been replaced by ChoiceGroup (lines 36 and 37).
047 public BadMicroAmazonSearch()
049 // Create GUI components here...
050 display = Display.getDisplay(this);
052 // commands
053 searchCommand = new Command(CMD_SEARCH, Command.SCREEN, 1);
054 detailsCommand = new Command(CMD_DETAILS, Command.SCREEN, 1);
// - removed the Instantiation of other Commands
059 // Create 3 screens: 1. Search, 2. Results, 3. Details
060 // search form
061 searchScreen = new Form("Search Terms");
062 opsChoice = new ChoiceGroup("Operation:", Choice.EXCLUSIVE, 2
064 targetTF = new TextField("Search For:", '", 20,
066 modeChoice = new ChoiceGroup("Category:", Choice.EXCLUSIVE,