Part 4
Java XML Programmers Reference
Chapter 11: XML Tools for Information Appliances
October 15, 2001
Brought to you by:
Check It Out!
|
Painting the Screen and Reading the Contact Book
Let's take a look at the paint() method, which is called to clear and paint the screen:
private void paint() {
Graphics g = Graphics.getGraphics();
Unlike other GUI environments you might be used to, which may have multiple graphics objects and device contexts, there is one and only com.sun.kjava.Graphics object available to all Spotlets. It's with this object that all screen painting is done.
g.clearScreen(); //clear the screen
//draw exit button and title
exitBtn.paint();
g.drawString("Select Contact to Beam", 35, 0);
Now we open the contact book database:
int numRecords = 0;
try {
Database db = new Database(0x44415441, 0x61646472,
com.sun.kjava.Database.READONLY);
if (db == null)
System.out.println("Error opening contact book");
With the database open for read access, we're ready to read contact book records and display a page of buttons.
The first step is to determine, based on the current record being viewed, how many buttons we'll need for this page. When the user is viewing the 10th-15th records with 17 records in the database, and the user selects the Next button, we only need two buttons for the new page. We'll save this value in numEntryBtns, defined with class scope:
private int numEntryBtns = 0;
We need this value to have class scope so that when a penDown() event is handled, we know how buttons are being displayed on the current page.
To calculate numEntryBtns, we also need to store the number of records in the database. We'll call this numRecords. We also use this value to determine whether a Next button should be drawn at the bottom of a page. numRecords only needs method scope:
int numRecords = 0;
ENTRIES_PER_PAGE is the constant that determines how many records are displayed per page. It is also defined with class scope. You can change this value to easily vary how many buttons (contact entries) are displayed per page:
private final static int ENTRIES_PER_PAGE = 6;
We chose six because six fit nicely on a 160x160 pixel screen without looking cramped. If you have a 320x320 pixel Palm OS device, such as the Sony PEG-N710C, you should be able to double this value.
Each record's first and last name are displayed in a button. These buttons are defined with class scope so they are accessible in both penDown() and paint(). In penDown(), we ask each button individually if it was pressed() (see Handling penDown() Events). The buttons are stored in entryBtns
private Button[] entryBtns;
Here's the code to allocate the number of buttons we'll need for this page:
//get at most ENTRIES_PER_PAGE records, but less if
there aren't that many records left
numRecords = db.getNumberOfRecords();
numEntryBtns = Math.min(ENTRIES_PER_PAGE, numRecords -
currentRecord);
entryBtns = new Button[numEntryBtns+1];
Now we can read first and last names in each record, and display the allocated buttons with those names. First, let's look at the currentRecord variable, defined with class scope:
private int currentRecord = 0;
This integer represents which record in the database is currently being displayed at the top of the page. It's used in the penDown() method to determine which, if any, of the contact buttons were pressed. In our paint() method, however, we use currentRecord to draw the next or previous page of buttons:
for (int j=currentRecord; j<currentRecord + numEntryBtns;
j++) {
byte[] buf = db.getRecord(j);
kXMLElement elem = new kXMLElement();
elem.parseString(new String(buf));
String lname = elem.getProperty("lname"), //last name
fname = elem.getProperty("fname"); //first name
entryBtns[j-currentRecord] = new Button(fname+" " +lname,
5, (j-currentRecord)*20+15);
entryBtns[j-currentRecord].paint();}
Here we make use of NanoXML to parse the first and last name in the record. The first and last name become the button text. nanoxml.kXMLElement is the CLDC/KVM port of nanoxml.XMLElement and has the same public methods. Records are written by class AddRecord (see Generating XML from the Form). A typical document instance might look like this:
<contact fname="Frantic" lname="Neumann"
address="123 Fake Street" city="Denver"
state="Colorado" zip="80202" country="USA"
phone="303-303-3000"/>
Since we're through with the database, we can close it. The only thing that's left is to draw Next and Prev buttons.
db.close(); //close the database
We don't want to draw the Next button if there aren't any more records to be displayed, so this logic accounts for that:
//draw the "Next " button, if appropriate
if (currentRecord + numEntryBtns + 1 <= numRecords){
nextBtn = new Button("Next", 100, 140);
nextBtn.paint();
}
else
nextBtn = null;
Likewise, we don't want to draw the Prev button if we're displaying the first page of records.
//draw the "Previous" button, if appropriate
if (currentRecord >= ENTRIES_PER_PAGE) {
prevBtn = new Button("Prev", 65, 140);
prevBtn.paint();
}
else
prevBtn = null;
|