Java/J2ME/Sort Search

Материал из Java эксперт
Перейти к: навигация, поиск

A simple class that shows various functionality of RMS.

/*
 * Copyright (c) 2000-2001 Sun Microsystems, Inc. All Rights Reserved.
 */
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.rumand;
import javax.microedition.lcdui.rumandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.List;
import javax.microedition.lcdui.Screen;
import javax.microedition.midlet.MIDlet;
import javax.microedition.rms.RecordComparator;
import javax.microedition.rms.RecordEnumeration;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;
import javax.microedition.rms.RecordStoreNotOpenException;
/**
 * A simple class that shows various functionality of RMS.
 * The general flow of this MIDlet is:
 *      
 *      In the constructor (See RMSMIDlet),
 *      create and populate two record stores, one of personal
 *      contacts, the other with business contacts.
 *      Display the first screen. This screen shows a list
 *      of all RMS stores found in the MIDlet suite"s name
 *      space. This screen allows the user to select a
 *      record store and either display pertinent information
 *      about the record store such as size, etc., or to view
 *      the contents of the selected store. When the contents
 *      of a record store are viewed, they are sorted by last
 *      name, though this can be changed by instantiate a
 *      SimpleComparator object with the appropriate
 *      sort order parameter.
 *
 *      Traversal from screen to screen is handled
 *      by RMSMIDlet, commandAction.
 *      
 */
public class RMSMIDlet extends MIDlet implements CommandListener {
    private Display myDisplay;  // handle to the display
    private Alert alert;        // used to display errors
    // Our commands to display on every screen.
    private Command CMD_EXIT;
    private Command CMD_DETAILS;
    private Command CMD_OK;
    // Our screens
    private List mainScr;
    private List detailScr;
    private List dataScr;
    // An array of all RMS stores found in this
    // MIDlets name space.
    private String[] recordStoreNames;
    /**
     * Seed data for creating personal contacts RMS store
     */
    private final String personalContacts[] = {
        "John", "Zach", "2225556669",
        "Mark", "Lynn", "5125551212",
        "Joy", "Beth", "2705551234",
        "Abby", "Lynn", "4085558566",
    };
    /**
     * Seed data for creating business contacts RMS store
     */
    private final String businessContacts[] = {
        "Ted", "Alan", "4125552235",
        "Sterling", "Wincle", "9995559111",
        "Deborah", "Elaine", "4445552323",
        "Suzanne", "Melissa"," 5125556064",
        "Frank", "Kenneth", "7775551212",
        "Dwight", "Poe", "1115557234",
        "Laura", "Beth", "2055558888",
        "Lisa", "Dawn", "2705551267",
        "Betty", "June", "5555551556",
        "Yvonne", "Poe", "6665558888",
        "Lizzy", "Loo", "5025557971",
        "John", "Gerald", "3335551256",
    };
    /**
     * Display a warning on the screen and revert
     * to the main screen.
     *
     * s  A warning string to display
     */
    private void doAlert(String s) {
        alert.setString(s);
        myDisplay.setCurrent(alert, mainScr);
    }
    /**
     * Notify the system we are exiting.
     */
    private void doExit() {
        destroyApp(false);
        notifyDestroyed();
    }
    /**
     * In our simple MIDlet, all screens have the same commands,
     * with the possible exception of the detailScr.
     * 
     * Also set up the command listener to call commandAction.
     * See RMSMIDlet#commandAction
     */
    private void addCommonCommands(Screen s,
                                   boolean doDetails) {
        s.addCommand(CMD_OK);
        s.addCommand(CMD_EXIT);
        if (doDetails) {
            s.addCommand(CMD_DETAILS);
        }
        s.setCommandListener(this);
    }
    /**
     * The public constructor. In our constructor, we get
     * a handle to our display and create two record stores.
     * In the event of an error, we display an alert.
     */
    public RMSMIDlet() {
        CMD_EXIT = new Command("Exit", Command.EXIT, 3);
        CMD_DETAILS = new Command("Details", Command.SCREEN, 2);
        CMD_OK = new Command("OK", Command.OK, 1);
        myDisplay = Display.getDisplay(this);
        alert = new Alert("Warning");
        alert.setTimeout(2000);
        CreateAddressBook.createRecordStore("Personal",
                                            personalContacts);
        CreateAddressBook.createRecordStore("Business",
                                            businessContacts);
        // Now, get a list of RMS stores and add their
        // names to the mainScr.
        recordStoreNames = RecordStore.listRecordStores();
        mainScr = new List("Select RMS Store", List.IMPLICIT,
                           recordStoreNames, null);
        addCommonCommands(mainScr, true);
    }
    /**
     * Called by the system to start our MIDlet.
     */
    protected void startApp() {
        myDisplay.setCurrent(mainScr);
    }
    /**
     * Called by the system to pause our MIDlet.
     * No actions required by our MIDLet.
     */
    protected void pauseApp() {}
    /**
     * Called by the system to end our MIDlet.
     * No actions required by our MIDLet.
     */
    protected void destroyApp(boolean unconditional) {}
    /**
     * Generate a screen with a sorted list of the contents
     * of the selected RMS store identified by index
     * If any errors encountered, display an alert and
     * redisplay the mainScr.
     *
     * index  an index into recordStoreNames
     */
    public void genDataScr(int index) {
        SimpleComparator rc;
        RecordEnumeration re;
        RecordStore rs;
        dataScr = null;
        byte record[];
        try {
            rs = RecordStore.openRecordStore(
                                recordStoreNames[index], false);
        } catch (RecordStoreException e) {
            doAlert("Could not open " + recordStoreNames[index]);
            return;
        }
        // Create an enumeration that sorts by last name
        rc = new SimpleComparator(
                     SimpleComparator.SORT_BY_LAST_NAME);
        try {
            re = rs.enumerateRecords(null, rc, false);
        } catch (RecordStoreNotOpenException e) {
            doAlert("Could not create enumeration: " + e);
            return;
        }
        // Create a screen and append the contents of the
        // selected RMS store.
        dataScr = new List(recordStoreNames[index] + " Data",
                           List.IMPLICIT);
        addCommonCommands(dataScr, false);
        try {
            while (re.hasNextElement()) {
                byte[] b = re.nextRecord();
                dataScr.append(SimpleRecord.getFirstName(b) +
                               " " + SimpleRecord.getLastName(b),
                               null);
            }
        } catch (Exception e) {
            doAlert("Could not build list: " + e);
            dataScr = null;
        } finally {
            try {
                rs.closeRecordStore();
            } catch (RecordStoreException e) {}
        }
    }
    /**
     * Generate a screen that shows some of the details
     * of the selected RMS store.
     *
     * RMS store information displayed:
     * - name
     * - number of records
     * - size, in bytes
     * - available size, in bytes
     * - version number
     *
     * index  an index into recordStoreNames
     */
    public void genDetailScr(int index) {
        RecordStore rs;
        detailScr = null;
        try {
            rs = RecordStore.openRecordStore(
                                        recordStoreNames[index],
                                        false);
        } catch (Exception e) {
            doAlert("Could not open " + recordStoreNames[index]);
            return;
        }
        detailScr = new List(recordStoreNames[index] + " Details",
                             List.IMPLICIT);
        addCommonCommands(detailScr, false);

        try {
            detailScr.append("Name: "  + rs.getName(), null);
            detailScr.append("# recs: " +
                             rs.getNumRecords(), null);
            detailScr.append("Size: " + rs.getSize(), null);
            detailScr.append("Avail: " + 
                             rs.getSizeAvailable(),null);
            detailScr.append("Version: " +
                             rs.getVersion(), null);
        } catch (Exception e) {
            detailScr = null;
            doAlert("Failed to retrieve data");
            return;
        } finally {
            try {
                rs.closeRecordStore();
            } catch (RecordStoreException e) {}
        }
    }
    /***
     * Respond to command selections.
     * Commands are:
     * EXIT: if selected, then exit
             (see RMSMIDlet, doExit)
     * OK:   if selected, interpreted in the context of
     *       the current screen.
     *
     * This method implements a state machine that drives
     * the MIDlet from one state (screen) to the next.
     */
    public void commandAction(Command c,
                              Displayable d) {
        // Every screen has an EXIT command.
        // Handle this consistently for all screens.
        if (c == CMD_EXIT) {
            doExit();
            return;
        }
        // switch based on screen.
        if (d == mainScr) {
            // main screen: two commands to handle. If
            // OK was selected, then generate the dataScr
            // and make it active. If DETAILS was selected,
            // generate the detailScr and make it active.
            if ((c == List.SELECT_COMMAND) || (c == CMD_OK)) {
                genDataScr(mainScr.getSelectedIndex());
                myDisplay.setCurrent(dataScr);
            } else if (c == CMD_DETAILS) {
                genDetailScr(mainScr.getSelectedIndex());
                myDisplay.setCurrent(detailScr);
            }
        } else if (d == detailScr) {
            // If OK selected, go back to mainScr
            if (c == CMD_OK) {
                myDisplay.setCurrent(mainScr);
            }
        } else if (d == dataScr) {
            // If OK selected, go back to mainScr
            if (c == CMD_OK) {
                myDisplay.setCurrent(mainScr);
            }
        }
    }
}
/*
 * Copyright (c) 2000-2001 Sun Microsystems, Inc. All Rights Reserved.
 */

/**
 * Static helper class that creates a record
 * store from data in an array.
 */
class CreateAddressBook {
    // Don"t allow this class to be instantiated
    private CreateAddressBook() {}
    /**
     * Helper method that creates a record
     * store from data in an array.
     * Returns:
     *  true      if RMS store was created
     *  false     otherwise
     *  name      the name of the record store to create
     *  seedData  an array w/ data to seed record store
     */
    static boolean createRecordStore(String name,
                                     String[] seedData) {
        RecordStore recordStore;
        boolean ret = false;
        // Delete any previous record store with same name.
        // Silently ignore failure.
        try {
            RecordStore.deleteRecordStore(name);
        } catch (Exception rse) {}
        // Create new RMS store. If we fail, return false.
        try {
            recordStore = RecordStore.openRecordStore(name, true);
        } catch (RecordStoreException rse) {
            return ret;
        }
        ret = true; // assume success
        // Now, populate the record store with the seed data
        for (int i = 0; i < seedData.length; i += 3) {
            byte[] record = SimpleRecord.createRecord(seedData[i],
                                                      seedData[i+1],
                                                      seedData[i+2]);
            try {
                recordStore.addRecord(record, 0, record.length);
            } catch (RecordStoreException rse) {
                ret = false;
                break;
            }
        }
        // Get here when adds are complete, or an error occured.
        // In any case, close the record store. We shouldn"t
        // have a failure, so silently ignore any exceptions.
        try {
            recordStore.closeRecordStore();
        } catch (RecordStoreException rsne) {}
        return ret;
    }
}
/*
 * Copyright (c) 2000-2001 Sun Microsystems, Inc. All Rights Reserved.
 */

/**
 * This class implements the RecordComparator interface.
 * It works on the records created by SimpleRecord.
 * It sorts on either first name or last name.
 */
class SimpleComparator implements RecordComparator {
    /**
     * Sorting values (sort by first or last name)
     */
    public final static int SORT_BY_FIRST_NAME = 1;
    public final static int SORT_BY_LAST_NAME = 2;
    /**
     * Sort order.  Set by constructor.
     */
    private int sortOrder = -1;
    /**
     * Public constructor: sets the sort order to be
     * used for this instantiation.
     *
     * Sanitize s: if it is not one of the
     * valid sort codes, set it to SORT_BY_LAST_NAME
     * silently.
     *  s  the desired sort order
     */
    SimpleComparator(int s) {
        switch (s) {
        case SORT_BY_FIRST_NAME:
        case SORT_BY_LAST_NAME:
            this.sortOrder = s;
            break;
        default:
            this.sortOrder = SORT_BY_LAST_NAME;
            break;
        }
    }
    /**
     * This is the compare method. It takes two
     * records, and depending on the sort order
     * extracts and lexicographically compares the
     * subfields as two Strings.
     *
     *  r1  First record to compare
     *  r2  Second record to compare
     * return one of the following:
     * 
     * RecordComparator.PRECEDES
     *     if r1 is lexicographically less than r2
     * RecordComparator.FOLLOWS
     *     if r1 is lexicographically greater than r2
     * RecordComparator.EQUIVALENT
     *     if r1 and r2 are lexicographically equivalent
     */
    public int compare(byte[] r1,
                       byte[] r2) {
        String n1 = null;
        String n2 = null;
        // Based on sortOrder, extract the correct fields
        // from the record and convert them to lower case
        // so that we can perform a case-insensitive compare.
        if (sortOrder == SORT_BY_FIRST_NAME) {
            n1 = SimpleRecord.getFirstName(r1).toLowerCase();
            n2 = SimpleRecord.getFirstName(r2).toLowerCase();
        } else if (sortOrder == SORT_BY_LAST_NAME) {
            n1 = SimpleRecord.getLastName(r1).toLowerCase();
            n2 = SimpleRecord.getLastName(r2).toLowerCase();
        }
        int n = n1.rupareTo(n2);
        if (n < 0) {
            return RecordComparator.PRECEDES;
        }
        if (n > 0) {
            return RecordComparator.FOLLOWS;
        }
        return RecordComparator.EQUIVALENT;
    }
}
/*
 * Copyright (c) 2000-2001 Sun Microsystems, Inc. All Rights Reserved.
 */

/**
 * This class provides static methods that allow us
 * to hide the format of a record.
 * N.B. no synchronized access is provided
 */
final class SimpleRecord {
    private final static int FIRST_NAME_INDEX = 0;
    private final static int LAST_NAME_INDEX = 20;
  private final static int FIELD_LEN = 20;
    private final static int PHONE_INDEX = 40;
    private final static int MAX_REC_LEN = 60;
    private static StringBuffer recBuf =
        new StringBuffer(MAX_REC_LEN);
    // Don"t let anyone instantiate this class
    private SimpleRecord() {}
    // Clear internal buffer
    private static void clearBuf() {
        for (int i = 0; i < MAX_REC_LEN; i++) {
            recBuf.insert(i, " ");
        }
        recBuf.setLength(MAX_REC_LEN);
    }
    /**
     * Takes component parts and return a record suitable
     * for our address book.
     *
     *  return  byte[] the newly created record
     *  first   record field: first name
     *  last    record field: last name
     *  num     record field: phone number
     */
    public static byte[] createRecord(String first,
                                      String last,
                                      String num) {
        clearBuf();
        recBuf.insert(FIRST_NAME_INDEX, first);
        recBuf.insert(LAST_NAME_INDEX, last);
        recBuf.insert(PHONE_INDEX, num);
        recBuf.setLength(MAX_REC_LEN);
        return recBuf.toString().getBytes();
    }
    /**
     * Extracts the first name field from a record.
     *  return  String contains the first name field
     *  b       the record to parse
     */
    public static String getFirstName(byte[] b) {
        return new String(b, FIRST_NAME_INDEX, FIELD_LEN).trim();
    }
    /**
     * Extracts the last name field from a record.
     *  return  String contains the last name field
     *  b       the record to parse
     */
    public static String getLastName(byte[] b) {
        return new String(b, LAST_NAME_INDEX, FIELD_LEN).trim();
    }
    /**
     * Extracts the phone number field from a record.
     *  return  String contains the phone number field
     *  b       the record to parse
     */
    public static String getPhoneNum(byte[] b) {
        return new String(b, PHONE_INDEX, FIELD_LEN).trim();
    }
}





Birthday Database

/**** Chapter 5 Sample code for RMS Package****/
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.rms.*;

public class BirthdayDB extends MIDlet {
    static final String RSNAME = "birthdayDB";
  private RecordStore rs = null;
    public BirthdayDB() {
      try {
      openBirthdayDB(RSNAME);
      populateSampleRecords();
      //BEGIN: Test for basic funcitionality of a record store
      displayRecordStoreinfo();
      searchAndDisplayRecords(null, null); //Simple enumeration withouit any criteria
      deleteBirthday(2);
      updateBirthday(3, "Lisa", "03/07/99");
      searchAndDisplayRecords(null, null); //Simple enumeration withouit any criteria
      //END: Test for basic funcitionality of a record store
      //BEGIN: Test for record listener
      rs.addRecordListener((RecordListener) new BirthdayDBListener());
      addBirthday("Maya","09/08/96");
      deleteBirthday(3);
      updateBirthday(4, "NewLisa", "03/08/99");
      rs.removeRecordListener((RecordListener) new BirthdayDBListener());
      //END: Test for record listener
      //BEGIN: Complex test for record enumeration with record filter and record comparator
      NameFilter nameFilter = new NameFilter("John");
      NameComparator nameComparator = new NameComparator();
      searchAndDisplayRecords(nameFilter,nameComparator);
      //END: Complex test for record enumeration with record filter and record comparator
      closeBirthdayDB();
        }
        catch( Exception e ){
            System.out.print("Error in BirthdayDB.BirthdayDB-> ");
      System.out.println("Exception : " + e.getMessage());
        }
        notifyDestroyed();
    }
  /****
  This function will create/open database.
  ****/
  private void openBirthdayDB(String name) {
        // Just to avoid using wrong DB,
    // First clear out the old record store
        try {
            RecordStore.deleteRecordStore( name );
        }
        catch( Exception e ){
            // ignore any errors...
        }
    // attempt to create a new RecordStore database
    try {
          rs = RecordStore.openRecordStore( name, true );
        }
        catch( Exception e ){
      System.out.print("Error in BirthdayDB.openBirthdayDB -> ");
      System.out.println("Exception : " + e.getMessage());
        }
  }
  /****
  This function closes the DB if it is open.
  ****/
  private void closeBirthdayDB() {
    if (rs != null) {
      try {
          rs.closeRecordStore();
      } catch (Exception e) {
        System.out.print("Error in BirthdayDB.closeBirthdayDB -> ");
        System.out.println("Exception : " + e.getMessage());
      }
    }
  }
  /****
  This function will search for the records using criteria defined in
  Filter class and it will display records in the order specfied in
  Comparator class
  ****/
  public void searchAndDisplayRecords(NameFilter f, NameComparator c){
    try {
        RecordEnumeration rEnum = rs.enumerateRecords( f, c , false);
        System.out.println("Total Records in Enumeration: " + rEnum.numRecords());
        while (rEnum.hasNextElement()){
          byte [] bRec = rEnum.nextRecord();
          //unpack a multi-column record
          ByteArrayInputStream bais = new ByteArrayInputStream(bRec);
          DataInputStream dis = new DataInputStream(bais);
          String name = dis.readUTF();
          String bDay = dis.readUTF();
          System.out.println("Name: " + name + " BirthDay: "+ bDay);
        }
      }
      catch (Exception e) {
        System.out.print("Error in BirthdayDB.searchAndDisplayRecords -> ");
        System.out.println("Exception : " + e.getMessage());
      }
      return;
  }
  /****
  This function creates a byte stream for record and adds a record to database
  ****/
  public void addBirthday(String name, String bDay) {
    try{
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      DataOutputStream dos = new DataOutputStream(baos);
      dos.writeUTF(name);
      dos.writeUTF(bDay);
      byte [] bRec = baos.toByteArray();
      rs.addRecord(bRec,0,bRec.length);
      dos.close();
      baos.close();
    }
    catch (Exception e) {
      System.out.print("Error in BirthdayDB.addBirthdayDB -> ");
      System.out.println("Exception : " + e.getMessage());
    }
    return;
  }
  /****
  This function deleted a record with given recordId
  ****/
  public void deleteBirthday(int recordId) {
    try{
      rs.deleteRecord(recordId);
    }
    catch (Exception e) {
      System.out.print("Error in BirthdayDB.deleteBirthday -> ");
      System.out.println("Exception : " + e.getMessage());
    }
    return;
  }
  /****
  This function updates the record with new name and birthday at given recordId
  ****/
  public void updateBirthday(int recordId, String newName, String newBDay) {
    try{
      // convert new data into byte stream
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      DataOutputStream dos = new DataOutputStream(baos);
      dos.writeUTF(newName);
      dos.writeUTF(newBDay);
      byte [] bRec = baos.toByteArray();
      rs.setRecord(recordId, bRec,0,bRec.length);
      dos.close();
      baos.close();
    }
    catch (Exception e) {
      System.out.print("Error in BirthdayDB.updateBirthday -> ");
      System.out.println("Exception : " + e.getMessage());
    }
    return;
  }
  /****
  This function populates seed records
  ****/
  public void populateSampleRecords() {
    addBirthday("John", "01/04/1969");
    addBirthday("Joe", "05/05/1976");
    addBirthday("Keran", "09/12/1976");
    addBirthday("Marry", "04/22/1979");
    addBirthday("Paul", "06/26/1972");
    addBirthday("Robert", "08/30/1971");
    addBirthday("John", "01/04/1970");
  }
  /****
  This function displays information of a record store
  ****/
  public void displayRecordStoreinfo() {
    try {
      System.out.println("Name of the record store is " + rs.getName());
      System.out.println("Number of records in this record store are " + rs.getNumRecords());
      System.out.println("Size of record store is " + rs.getSize());
      System.out.println("Available size for the record store " + rs.getSizeAvailable());
      System.out.println("Version number of the record store is " + rs.getVersion());
      System.out.println("Last Modified Date is " + rs.getLastModified());
    }
    catch (Exception e) {
      System.out.print("Error in BirthdayDB.displayRecordStoreinfo -> ");
      System.out.println("Exception : " + e.getMessage());
    }
  }
  /****
  MIDlet lifecycle functions
  ****/
    public void destroyApp( boolean unconditional ) {
    if (rs != null)
      closeBirthdayDB();
    }
    public void startApp() {
    }
    public void pauseApp() {
    }
}
class NameFilter implements RecordFilter {
String name;
public NameFilter(String filterOnThisName) {
  name = filterOnThisName;
}
public boolean matches(byte [] candidateRecord) {
  try{
    ByteArrayInputStream bais = new ByteArrayInputStream(candidateRecord);
    DataInputStream dis = new DataInputStream(bais);
    String nameFromRec = dis.readUTF();
    dis.close();
    bais.close();
    if (name.rupareTo(nameFromRec) == 0 )
      return true;
    }
  catch (Exception e) {
    System.out.print("Error in NameFilter.matches -> ");
    System.out.println("Exception : " + e.getMessage());
  }
  return false;
}
}

class NameComparator implements RecordComparator {
public int compare(byte [] rec1, byte [] rec2) {
  try{
    // read first record and extract name
    ByteArrayInputStream bais1 = new ByteArrayInputStream(rec1);
    DataInputStream dis1 = new DataInputStream(bais1);
    String name1 = dis1.readUTF();
    dis1.close();
    bais1.close();
    // read second record and extract name
    ByteArrayInputStream bais2 = new ByteArrayInputStream(rec2);
    DataInputStream dis2 = new DataInputStream(bais2);
    String name2 = dis2.readUTF();
    dis2.close();
    bais2.close();
    if (name1.rupareTo(name2) < 0 )
      return PRECEDES;
    if (name1.rupareTo(name2) > 0 )
      return FOLLOWS;
  }
  catch (Exception e) {
    System.out.print("Error in NameComparator.rupare -> ");
    System.out.println("Exception : " + e.getMessage());
  }
  return EQUIVALENT;
}
}
class BirthdayDBListener implements RecordListener {
public void recordAdded(RecordStore rs, int recordId) {
  System.out.println("Record Added in record store " );
}
public void recordDeleted(RecordStore rs, int recordId) {
  System.out.println("Record Deleted from record store ");
}
public void recordChanged(RecordStore rs, int recordId) {
  System.out.println("Record Changed in record store ");
}
}





Demonstrates simple record sorting and filtering

/* License
 * 
 * Copyright 1994-2004 Sun Microsystems, Inc. All Rights Reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  
 *  * Redistribution of source code must retain the above copyright notice,
 *      this list of conditions and the following disclaimer.
 * 
 *  * Redistribution in binary form must reproduce the above copyright notice,
 *      this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 * 
 * Neither the name of Sun Microsystems, Inc. or the names of contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *  
 * This software is provided "AS IS," without a warranty of any kind. ALL
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
 * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
 * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
 * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
 * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
 * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
 * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 *  
 * You acknowledge that this software is not designed, licensed or intended
 * for use in the design, construction, operation or maintenance of any
 * nuclear facility. 
 */
import java.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import javax.microedition.rms.*;
// Demonstrates simple record sorting and filtering
public class EnumDemoMIDlet extends MIDlet
                      implements CommandListener {
    // Data members we need
    private Display              display;
    private RecordStore          rs;
    private EnumList             enumListScreen;
    private SortOptions          sortOptionsScreen;
    private String               firstName;
    private String               lastName;
    private byte[]               data = new byte[200];
    private ByteArrayInputStream bin =
      new ByteArrayInputStream( data );
    private DataInputStream      din =
      new DataInputStream( bin );
    // Define the four commands we use
    private Command exitCommand = new Command( "Exit",
                                    Command.EXIT, 1 );
    private Command sortCommand = new Command( "Sort",
                                  Command.SCREEN, 1 );
    private Command cancelCommand = new Command( "Cancel",
                                  Command.CANCEL, 1 );
    private Command okCommand = new Command( "OK",
                                      Command.OK, 1 );
    // Define the sorting modes
    private static final int SORT_NONE = 0;
    private static final int SORT_FIRST_LAST = 1;
    private static final int SORT_LAST_FIRST = 2;
    // Define the filtering modes
    private static final int FILTER_NONE = 0;
    private static final int FILTER_STARTSWITH = 1;
    private static final int FILTER_CONTAINS = 2;
    // A simple class to hold the parts of a record
    private static class Record {
        String firstName;
        String lastName;
    }
    // Precanned names
    private static final String[][] names = {
        { "Eric", "Giguere" },
        { "John", "Doe" },
        { "Lisa", "Munro" },
        { "Stephanie", "Kwaly" },
        { "Dave", "Boyer" },
        { "Gwen", "Stephens" },
        { "Jennifer", "Lopert" },
        { "Ed", "Ort" },
    };
    // Constructor
    public EnumDemoMIDlet(){
    }
    // Clean up
    protected void destroyApp( boolean unconditional )
                   throws MIDletStateChangeException {
        exitMIDlet();
    }
    // Close the record store for now
    protected void pauseApp(){
        closeRecordStore();
    }
    // Initialize things and reopen record store
    // if not open
    protected void startApp() throws
      MIDletStateChangeException {
        if( display == null ){ // first time called...
            initMIDlet();
        }
        if( rs == null ){
            openRecordStore();
        }
    }
    // Once-only initialization code
    private void initMIDlet(){
        display = Display.getDisplay( this );
        enumListScreen = new EnumList();
        sortOptionsScreen = new SortOptions();
        if( openRecordStore() ){
            enumListScreen.resort();
            display.setCurrent( enumListScreen );
        }
    }
    // Termination code
    public void exitMIDlet(){
        closeRecordStore();
        notifyDestroyed();
    }
    // Add a first-last name pair to the record store
    private void addName( String first, String last,
                          ByteArrayOutputStream bout,
                          DataOutputStream dout ){
        try {
            dout.writeUTF( first );
            dout.writeUTF( last );
            dout.flush();
            byte[] data = bout.toByteArray();
            rs.addRecord( data, 0, data.length );
            bout.reset();
        }
        catch( Exception e ){
        }
    }
    // Fill record store with some precanned names
    private void fillRecordStore(){
        ByteArrayOutputStream bout =
          new ByteArrayOutputStream();
        DataOutputStream dout =
          new DataOutputStream( bout );
        for( int i = 0; i < names.length; ++i ){
            addName( names[i][0], names[i][1], bout,
                                             dout );
        }
    }
    // Open record store, if empty then fill it
    private boolean openRecordStore(){
        try {
            if( rs != null ) closeRecordStore();
            rs = RecordStore.openRecordStore(
                            "EnumDemo", true );
            if( rs.getNumRecords() == 0 ){
                fillRecordStore();
            }
            return true;
        }
        catch( RecordStoreException e ){
            return false;
        }
    }
    // Close record store
    private void closeRecordStore(){
        if( rs != null ){
            try {
                rs.closeRecordStore();
            }
            catch( RecordStoreException e ){
            }
            rs = null;
        }
    }
    // Move to and read in a record
    private boolean readRecord( int id, Record r ){
        boolean ok = false;

        r.firstName = null;
        r.lastName = null;
        if( rs != null ){
            try {
                rs.getRecord( id, data, 0 );
                r.firstName = din.readUTF();
                r.lastName = din.readUTF();
                din.reset();
                ok = true;
            }
            catch( Exception e ){
            }
        }
        return ok;
    }
    // Event handling
    public void commandAction( Command c, Displayable d ){
        if( c == exitCommand ){
            exitMIDlet();
        } else if( c == sortCommand ){
            display.setCurrent( sortOptionsScreen );
        } else if( d == sortOptionsScreen ){
            if( c == okCommand ){
                enumListScreen.resort();
            }
            display.setCurrent( enumListScreen );
        }
    }
    // Main screen -- a list of names
    class EnumList extends List
                   implements RecordComparator,
                                 RecordFilter {
        private int    sortBy;
        private int    filterBy;
        private String filterText;
        private Record r1 = new Record();
        private Record r2 = new Record();

        // Constructor
        EnumList(){
            super( "Enum Demo", IMPLICIT );
            addCommand( exitCommand );
            addCommand( sortCommand );
            setCommandListener( EnumDemoMIDlet.this );
        }
        // Resort the data and refill the list
        public void resort(){
          sortBy = sortOptionsScreen.getSortType();
          filterBy = sortOptionsScreen.getFilterType();
          filterText = sortOptionsScreen.getFilterText();
            RecordComparator comparator = null;
            RecordFilter     filter = null;
            if( sortBy != 0 ){
                comparator = this;
            }
            if( filterBy != 0 ){
                filter = this;
            }
            deleteAll();
            try {
              RecordEnumeration e = rs.enumerateRecords(
                          filter, comparator, false );
              Record            r = new Record();
              while( e.hasNextElement() ){
                    int id = e.nextRecordId();
                    if( readRecord( id, r ) ){
                      if( sortBy == SORT_LAST_FIRST ){
                            append( r.lastName + ", " +
                                    r.firstName, null );
                        } else {
                            append( r.firstName + " " +
                                     r.lastName, null );
                        }
                    }
                }

                e.destroy();
            }
            catch( RecordStoreException e ){
            }
        }
        // Delete all items in the list
        public void deleteAll(){
            int n = size();
            while( n > 0 ){
                delete( --n );
            }
        }
        // The comparator
        public int compare( byte[] rec1, byte[] rec2 ){
            try {
                ByteArrayInputStream  bin =
                     new ByteArrayInputStream( rec1 );
                DataInputStream       din =
                           new DataInputStream( bin );
                r1.firstName = din.readUTF();
                r1.lastName = din.readUTF();
                bin = new ByteArrayInputStream( rec2 );
                din = new DataInputStream( bin );
                r2.firstName = din.readUTF();
                r2.lastName = din.readUTF();
                if( sortBy == SORT_FIRST_LAST ){
                    int cmp = r1.firstName.rupareTo(
                                       r2.firstName );
                 System.out.println( r1.firstName +
                  " compares to " + r2.firstName +
                                    " gives " + cmp );
                    if( cmp != 0 ) return (
                       cmp < 0 ? PRECEDES : FOLLOWS );
                    cmp = r2.lastName.rupareTo( r2.lastName );
                    if( cmp != 0 ) return (
                       cmp < 0 ? PRECEDES : FOLLOWS );
                } else if( sortBy == SORT_LAST_FIRST ){
                    int cmp = r1.lastName.rupareTo(
                                        r2.lastName );
                    if( cmp != 0 ) return (
                        cmp < 0 ? PRECEDES : FOLLOWS );
                    cmp = r2.firstName.rupareTo(
                                        r2.firstName );
                    if( cmp != 0 ) return (
                                  cmp < 0 ? PRECEDES :
                                            FOLLOWS );
                }
            }
            catch( Exception e ){
            }
            return EQUIVALENT;
        }
        // The filter
        public boolean matches( byte[] rec ){
            try {
                ByteArrayInputStream  bin =
                      new ByteArrayInputStream( rec );
                DataInputStream       din =
                           new DataInputStream( bin );
                r1.firstName = din.readUTF();
                r1.lastName = din.readUTF();
                if( filterBy == FILTER_STARTSWITH ){
                    return( r1.firstName.startsWith(
                                         filterText )
                            ||
                          r1.lastName.startsWith(
                                       filterText ) );
                } else if( filterBy ==
                  FILTER_CONTAINS ){
                    return( r1.firstName.indexOf(
         filterText )
          >=0 ||
          r1.lastName.indexOf(
        filterText) >= 0);  
                }
            }
            catch( Exception e ){
            }
            return false;
        }
    }
    // The options screen for choosing which sort and
    // filter modes to use, including the filter text
    class SortOptions extends Form {
        // Constructor
        SortOptions(){
            super( "Sort Options" );
            addCommand( okCommand );
            addCommand( cancelCommand );
            setCommandListener( EnumDemoMIDlet.this );
            append( sortTypes );
            append( filterTypes );
            append( filterText );
        }
        // Return current sort type
        public int getSortType(){
            return sortTypes.getSelectedIndex();
        }
        // Return current filter type
        public int getFilterType(){
            return filterTypes.getSelectedIndex();
        }
        // Return current filter text
        public String getFilterText(){
            return filterText.getString();
        }
        // Labels and user interface components

        private String[] sortLabels =
                         { "None", "First Last",
                                "Last, First" };
        private String[] filterLabels =
                           { "None", "Starts With",
                                      "Contains" };
        private ChoiceGroup sortTypes =
                                 new ChoiceGroup(
                                        "Sort Type:",
                                ChoiceGroup.EXCLUSIVE,
                                   sortLabels, null );
        private ChoiceGroup filterTypes =
                                 new ChoiceGroup(
                                       "Filter Type:",
                                ChoiceGroup.EXCLUSIVE,
                                 filterLabels, null );
        private TextField filterText = new TextField(
                                       "Filter Text:",
                                        null, 20, 0 );
    }
}





Display a Form and TextField for searching records. Each record contains a String object.

/*--------------------------------------------------
* SimpleSearch.java
*
* Display a Form and TextField for searching records
* Each record contains a String object.
*
* Uses: Enumeration, RecordFilter
*
* Example from the book:     Core J2ME Technology
* Copyright John W. Muchow   http://www.CoreJ2ME.ru
* You may use/modify for any non-commercial purpose
*-------------------------------------------------*/
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.rms.*;
import javax.microedition.lcdui.*;
public class SimpleSearch extends MIDlet implements CommandListener
{
  private Display display;      // Reference to Display object
  private Form fmMain;         // The main form
  private StringItem siMatch;  // The matching text, if any
  private Command cmFind;      // Command to search record store
  private Command cmExit;      // Command to insert items
  private TextField tfFind;    // Search text as requested by user
  private RecordStore rs = null;    // Record store
  static final String REC_STORE = "db_6"; // Name of record store
  public SimpleSearch()
  {
    display = Display.getDisplay(this);
    
    // Define textfield, stringItem and commands
    tfFind = new TextField("Find", "", 10, TextField.ANY); 
    siMatch = new StringItem(null, null);    
    cmExit = new Command("Exit", Command.EXIT, 1);
    cmFind = new Command("Find", Command.SCREEN, 2);
    // Create the form, add commands
    fmMain = new Form("Record Search");
    fmMain.addCommand(cmExit);    
    fmMain.addCommand(cmFind);
  
    // Append textfield and stringItem
    fmMain.append(tfFind);
    fmMain.append(siMatch);
    // Capture events
    fmMain.setCommandListener(this);    
    //--------------------------------
    // Open and write to record store
    //--------------------------------    
    openRecStore();   // Create the record store
    writeTestData();  // Write a series of records
  }
  public void destroyApp( boolean unconditional )
  {
    closeRecStore();  // Close record store
  }
  public void startApp()
  {
    display.setCurrent(fmMain);   
  }
  public void pauseApp()
  {
  }
  public void openRecStore()
  {
    try
    {
      // The second parameter indicates that the record store
      // should be created if it does not exist
      rs = RecordStore.openRecordStore(REC_STORE, true );
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }    
  
  public void closeRecStore()
  {
    try
    {
      rs.closeRecordStore();
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }
  /*--------------------------------------------------
  * Create array of data to write into record store
  *-------------------------------------------------*/
  public void writeTestData()
  {
    String[] golfClubs = {
                    "Wedge...good from the sand trap", 
                    "One Wood...off the tee", 
                    "Putter...only on the green",
                    "Five Iron...middle distance"};
    writeRecords(golfClubs);
  }
  /*--------------------------------------------------
  * Write to record store.
  *-------------------------------------------------*/    
  public void writeRecords(String[] sData)
  {
    byte[] record;
    try
    {
      // Only add the records once
      if (rs.getNumRecords() > 0)
        return;
      for (int i = 0; i < sData.length; i++)
      {
        record = sData[i].getBytes();
        rs.addRecord(record, 0, record.length);
      }
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }
  /*--------------------------------------------------
  * Search using enumerator and record filter
  *-------------------------------------------------*/
  private void searchRecordStore()
  {
    try
    {
      // Record store is not empty
      if (rs.getNumRecords() > 0)
      {
        // Setup the search filter with the user requested text
        SearchFilter search = new SearchFilter(tfFind.getString());
        
        RecordEnumeration re = rs.enumerateRecords(search, null, false);
        // A match was found using the filter
        if (re.numRecords() > 0)
          // Show match in the stringItem on the form        
          siMatch.setText(new String(re.nextRecord()));
  
        re.destroy();   // Free enumerator
      }
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }
  public void commandAction(Command c, Displayable s)
  {
    if (c == cmFind)
    {
      searchRecordStore();
    }
    else if (c == cmExit)
    {
      destroyApp(false);
      notifyDestroyed();
    }
  }  
    
  /*--------------------------------------------------
  * Simple message to console for debug/errors
  * When used with Exceptions we should handle the 
  * error in a more appropriate manner.
  *-------------------------------------------------*/
  private void db(String str)
  {
    System.err.println("Msg: " + str);
  }
}
/*--------------------------------------------------
* Search for text within a record
* Each record passed in contains only text (String)
*-------------------------------------------------*/
class SearchFilter implements RecordFilter
{
  private String searchText = null;
  
  public SearchFilter(String searchText)
  {
    // This is the text to search for
    this.searchText = searchText.toLowerCase();
  }
  public boolean matches(byte[] candidate)
  {
    String str = new String(candidate).toLowerCase();
    // Look for a match   
    if (searchText != null && str.indexOf(searchText) != -1)
      return true;
    else
      return false;
  }
}





Int Sort

/*--------------------------------------------------
* IntSort.java
*
* Sort records that contain multiple Java
* data types. Sort using integer type.
*
* Uses: Streams, Enumeration, RecordComparator
*
* No GUI interface, all output is to the console
* Example from the book:     Core J2ME Technology
* Copyright John W. Muchow   http://www.CoreJ2ME.ru
* You may use/modify for any non-commercial purpose 
*-------------------------------------------------*/
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.rms.*;
public class IntSort extends MIDlet
{
  private RecordStore rs = null;    // Record store
  static final String REC_STORE = "db_4"; // Name of record store
  public IntSort()
  {
    openRecStore();   // Create the record store
    
    writeTestData();  // Write a series of records
    readStream();     // Read back the records
        
    closeRecStore();  // Close record store
    deleteRecStore(); // Remove the record store
  }
  public void destroyApp( boolean unconditional )
  {
  }
  public void startApp()
  {
    // There is no user interface, go ahead and shutdown
    destroyApp(false);
    notifyDestroyed();
  }
  public void pauseApp()
  {
  }
  public void openRecStore()
  {
    try
    {
      // The second parameter indicates that the record store
      // should be created if it does not exist
      rs = RecordStore.openRecordStore(REC_STORE, true );
    }
    catch (Exception e)
    {
      // We should pay attention to the actual error thrown
      db(e.toString());
    }
  }    
  
  public void closeRecStore()
  {
    try
    {
      rs.closeRecordStore();
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }
  public void deleteRecStore()
  {
    if (RecordStore.listRecordStores() != null)
    {
      try
      {
        RecordStore.deleteRecordStore(REC_STORE);
      }
      catch (Exception e)
      {
        db(e.toString());
      }
    }      
  }
  /*--------------------------------------------------
  * Create three arrays to write to record store
  *-------------------------------------------------*/
  public void writeTestData()
  {
   String[] pets = {"duke", "tiger", "spike", "beauregard"};
   boolean[] dog = {true, false, true, true};    
   int[] rank = {3, 0, 1, 2};
 
   writeStream(pets, dog, rank);                    
  }
  
  /*--------------------------------------------------
  * Write to record store using streams.
  *-------------------------------------------------*/  
  public void writeStream(String[] sData, boolean[] bData, int[] iData)
  {
    try
    {
       // Write data into an internal byte array
      ByteArrayOutputStream strmBytes = new ByteArrayOutputStream();
      
      // Write Java data types into the above byte array
      DataOutputStream strmDataType = new DataOutputStream(strmBytes);
      
      byte[] record;
      for (int i = 0; i < sData.length; i++)
      {
        // Write Java data types      
        strmDataType.writeUTF(sData[i]);
        strmDataType.writeBoolean(bData[i]);
        strmDataType.writeInt(iData[i]);                
        
        // Clear any buffered data
        strmDataType.flush();
        // Get stream data into byte array and write record      
        record = strmBytes.toByteArray();
        rs.addRecord(record, 0, record.length);      
        // Toss any data in the internal array so writes 
        // starts at beginning (of the internal array)
        strmBytes.reset();
      }
      
      strmBytes.close();
      strmDataType.close();
  
    }
    catch (Exception e)
    {
       db(e.toString());
    }
  }
  /*--------------------------------------------------
  * Read from the record store using streams
  *-------------------------------------------------*/
  public void readStream()
  {
    try
    {
      // Careful: Make sure this is big enough!
      // Better yet, test and reallocate if necessary      
      byte[] recData = new byte[50];
       // Read from the specified byte array
      ByteArrayInputStream strmBytes = new ByteArrayInputStream(recData);
      // Read Java data types from the above byte array
      DataInputStream strmDataType = new DataInputStream(strmBytes);
      if (rs.getNumRecords() > 0)
      {
        ComparatorInt comp = new ComparatorInt();
        
        int i = 1;
        RecordEnumeration re = rs.enumerateRecords(null, comp, false);
        while (re.hasNextElement())
        {
          // Get data into the byte array          
          rs.getRecord(re.nextRecordId(), recData, 0);
                  
          // Read back the data types      
          System.out.println("Record #" + i++);        
          
          System.out.println("Name: " + strmDataType.readUTF());
          System.out.println("Dog: " + strmDataType.readBoolean());
          System.out.println("Rank: " + strmDataType.readInt());                    
          System.out.println("--------------------");        
          // Reset so read starts at beginning of array 
          strmBytes.reset();
        }
        
        comp.rupareIntClose();
        // Free enumerator
        re.destroy();        
      }
      strmBytes.close();
      strmDataType.close();
    
    }
    catch (Exception e)
    {
       db(e.toString());
    }
  }
  
  /*--------------------------------------------------
  * Simple message to console for debug/errors
  * When used with Exceptions we should handle the 
  * error in a more appropriate manner.
  *-------------------------------------------------*/
  private void db(String str)
  {
    System.err.println("Msg: " + str);
  }
}
/*--------------------------------------------------
* Compares two integers to determine sort order
* Each record passed in contains multiple Java data 
* types - use only the integer data for sorting
*-------------------------------------------------*/
class ComparatorInt implements RecordComparator
{
  private byte[] recData = new byte[10];
  
  // Read from a specified byte array  
  private ByteArrayInputStream strmBytes = null;
  
  // Read Java data types from the above byte array
  private DataInputStream strmDataType = null;
  
  public void compareIntClose()
  {
    try
    {
      if (strmBytes != null)
        strmBytes.close();
      if (strmDataType != null)
        strmDataType.close();
    }
    catch (Exception e)
    {}
  }
  
  public int compare(byte[] rec1, byte[] rec2)
  {
    int x1, x2;
    
    try
    {
      // If either record is larger than our buffer, reallocate
      int maxsize = Math.max(rec1.length, rec2.length);
      if (maxsize > recData.length)
        recData = new byte[maxsize];
      // Read record #1
      // We want the integer from the record, which is
      // the last "field" thus we must read the String
      // and boolean to get to the integer
      strmBytes = new ByteArrayInputStream(rec1);
      strmDataType = new DataInputStream(strmBytes);
      strmDataType.readUTF();
      strmDataType.readBoolean();
      x1 = strmDataType.readInt();  // Here"s our data
      // Read record #2            
      strmBytes = new ByteArrayInputStream(rec2);
      strmDataType = new DataInputStream(strmBytes);
      strmDataType.readUTF();
      strmDataType.readBoolean();
      x2 = strmDataType.readInt();  // Here"s our data  
      
      // Compare record #1 and #2
      if (x1 == x2)
        return RecordComparator.EQUIVALENT;
      else if (x1 < x2)
        return RecordComparator.PRECEDES;
      else
        return RecordComparator.FOLLOWS;          
      
    }      
    catch (Exception e)
    { 
      return RecordComparator.EQUIVALENT;
    } 
  }
}





J2ME Data Management: Record Management System

/*
J2ME: The Complete Reference
James Keogh
Publisher: McGraw-Hill
ISBN 0072227109
*/
//jad file (please verify the jar size)
/*
MIDlet-Name: RecordStoreExample
MIDlet-Version: 1.0
MIDlet-Vendor: MyCompany
MIDlet-Jar-URL: RecordStoreExample.jar
MIDlet-1: RecordStoreExample, , RecordStoreExample
MicroEdition-Configuration: CLDC-1.0
MicroEdition-Profile: MIDP-1.0
MIDlet-JAR-SIZE: 100
*/
import javax.microedition.rms.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.io.*;
public class RecordStoreExample 
            extends MIDlet implements CommandListener
{
  private Display display;
  private Alert alert;
  private Form form; 
  private Command exit; 
  private Command start;
  private RecordStore recordstore = null;
  private RecordEnumeration recordenumeration = null;
  public RecordStoreExample ()
  {
    display = Display.getDisplay(this);
    exit = new Command("Exit", Command.SCREEN, 1);
    start = new Command("Start", Command.SCREEN, 1);
    form = new Form("Record Store");
    form.addCommand(exit);
    form.addCommand(start);
    form.setCommandListener(this);
  }
  public void startApp()
  {
    display.setCurrent(form);
  }
  public void pauseApp()
  {
  }
  public void destroyApp( boolean unconditional )
  {
  }
  public void commandAction(Command command, Displayable displayable)
  {
    if (command == exit)
    {
      destroyApp(true);
      notifyDestroyed();
    }
    else if (command == start)
    {
      try
      {
        recordstore = RecordStore.openRecordStore("myRecordStore", 
                                                    true );
      }
      catch (Exception error)
      {
        alert = new Alert("Error Creating", error.toString(), 
                           null, AlertType.WARNING); 
        alert.setTimeout(Alert.FOREVER); 
        display.setCurrent(alert);
      }
      try
      {
        recordstore.closeRecordStore();
      }
      catch (Exception error)
      {
        alert = new Alert("Error Closing", error.toString(), 
                          null, AlertType.WARNING); 
        alert.setTimeout(Alert.FOREVER); 
        display.setCurrent(alert);
      }
      if (RecordStore.listRecordStores() != null)
      {
        try
        {
          RecordStore.deleteRecordStore("myRecordStore");
        }
        catch (Exception error)
        {
         alert = new Alert("Error Removing", error.toString(), 
                           null, AlertType.WARNING); 
         alert.setTimeout(Alert.FOREVER); 
         display.setCurrent(alert);
        }
      }      
    }
  }     
}





My Record Listener

/*
J2ME: The Complete Reference
James Keogh
Publisher: McGraw-Hill
ISBN 0072227109
*/
public class MyRecordListener implements RecordListener
{
  public void recordAdded(RecordStore recordstore, int recordid)
  { 
    try
    {
      //do something 
    }
    catch (Exception error)
    {
      //do something
    } 
  } 
  public void recordDeleted(RecordStore recordstore, int recordid)
  {
    try
    {
      //do something
    } 
    catch (Exception error)
    {
      //do something
    }
  }
  public void recordChanged(RecordStore recordstore, int recordid)
  {
    try
    {
      //do something
    } 
    catch (Exception error)
    {
      //do something
    }
  } 
}





Search Streams

/*--------------------------------------------------
* SearchStreams.java
*
* Display a Form and TextField for searching records
* Each record contains multiple Java data types -  
* (String, boolean and integer). Use the String 
* data for searching
*
* Uses: Enumeration, RecordFilter
*
* Example from the book:     Core J2ME Technology
* Copyright John W. Muchow   http://www.CoreJ2ME.ru
* You may use/modify for any non-commercial purpose
*-------------------------------------------------*/
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.rms.*;
import javax.microedition.lcdui.*;
public class SearchStreams extends MIDlet implements CommandListener
{
  private Display display;      // Reference to Display object
  private Form fmMain;         // The main form
  private StringItem siMatch;  // The matching text, if any
  private Command cmFind;      // Command to search record store
  private Command cmExit;      // Command to insert items
  private TextField tfFind;    // Search text
  private RecordStore rs = null;    // Record store
  static final String REC_STORE = "db_7"; // Name of record store
  public SearchStreams()
  {
    display = Display.getDisplay(this);
    
    // Define textfield, stringItem and commands
    tfFind = new TextField("Find", "", 10, TextField.ANY); 
    siMatch = new StringItem(null, null);    
    cmExit = new Command("Exit", Command.EXIT, 1);
    cmFind = new Command("Find", Command.SCREEN, 2);
    // Create the form, add commands
    fmMain = new Form("Record Search");
    fmMain.addCommand(cmExit);    
    fmMain.addCommand(cmFind);
  
    // Append textfield and stringItem
    fmMain.append(tfFind);
    fmMain.append(siMatch);
    // Capture events
    fmMain.setCommandListener(this);    
    //--------------------------------
    // Open and write to record store
    //--------------------------------
    openRecStore();   // Create the record store
    writeTestData();  // Write a series of records
  }
  public void destroyApp( boolean unconditional )
  {
    closeRecStore();  // Close record store
  }
  public void startApp()
  {
    display.setCurrent(fmMain);   
  }
  public void pauseApp()
  {
  }
  public void openRecStore()
  {
    try
    {
      // The second parameter indicates that the record store
      // should be created if it does not exist
      rs = RecordStore.openRecordStore(REC_STORE, true );
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }    
  
  public void closeRecStore()
  {
    try
    {
      rs.closeRecordStore();
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }
  /*--------------------------------------------------
  * Create three arrays to write into record store
  *-------------------------------------------------*/
  public void writeTestData()
  {
   String[] pets = {"duke - big, goofy golden retriever", 
                    "tiger - we found in a field", 
                    "spike - loves chasing car tires",
                     "beauregard - barks at everything"};
   boolean[] dog = {true, false, true, true};    
   int[] rank = {3, 0, 1, 2};
 
   writeStream(pets, dog, rank);                    
  }
  /*--------------------------------------------------
  * Write to record store using streams.
  *-------------------------------------------------*/  
  public void writeStream(String[] sData, boolean[] bData, int[] iData)
  {
    try
    {
      // Only add the records once
      if (rs.getNumRecords() > 0)
        return;
      
       // Write data into an internal byte array
      ByteArrayOutputStream strmBytes = new ByteArrayOutputStream();
      
      // Write Java data types into the above byte array
      DataOutputStream strmDataType = new DataOutputStream(strmBytes);
      
      byte[] record;
      for (int i = 0; i < sData.length; i++)
      {
        // Write Java data types      
        strmDataType.writeUTF(sData[i]);    
        strmDataType.writeBoolean(bData[i]);
        strmDataType.writeInt(iData[i]);                
        
        // Clear any buffered data
        strmDataType.flush();
        // Get stream data into byte array and write record
        record = strmBytes.toByteArray();
        rs.addRecord(record, 0, record.length);      
        // Toss any data in the internal array so writes 
        // starts at beginning (of the internal array)
        strmBytes.reset();
      }
      
      strmBytes.close();
      strmDataType.close();
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }
  
  /*--------------------------------------------------
  * Search using enumerator and record filter
  *-------------------------------------------------*/
  private void searchRecordStore()
  {
  try
    {
      // Record store is not empty
      if (rs.getNumRecords() > 0)
      {
        // Setup the search filter with the user requested text
        SearchFilter search = 
              new SearchFilter(tfFind.getString());
        
        RecordEnumeration re = 
              rs.enumerateRecords(search, null, false);
        // A match was found using the filter        
        if (re.numRecords() > 0)
        {
          // Read from the specified byte array
          ByteArrayInputStream strmBytes = 
                new ByteArrayInputStream(re.nextRecord());
          // Read Java data types from the above byte array
          DataInputStream strmDataType = 
                new DataInputStream(strmBytes);
          // Show matching result in stringItem component on form          
          siMatch.setText(strmDataType.readUTF());
    
          search.searchFilterClose(); // Close record filter
          strmBytes.close();          // Close stream
          strmDataType.close();       // Close stream
          re.destroy();               // Free enumerator
        }
      }
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }
  public void commandAction(Command c, Displayable s)
  {
    if (c == cmFind)
    {
      searchRecordStore();
    }
    else if (c == cmExit)
    {
      destroyApp(false);
      notifyDestroyed();
    }
  }  
    
  /*--------------------------------------------------
  * Simple message to console for debug/errors
  * When used with Exceptions we should handle the 
  * error in a more appropriate manner.
  *-------------------------------------------------*/
  private void db(String str)
  {
    System.err.println("Msg: " + str);
  }
}
/*--------------------------------------------------
* Search for text within a record
* Each record passed in contains multiple Java data 
* types (String, boolean and integer) 
*-------------------------------------------------*/
class SearchFilter implements RecordFilter
{
  private String searchText = null;
  
   // Read from a specified byte array
  private ByteArrayInputStream strmBytes = null;
  // Read Java data types from the above byte array  
  private DataInputStream strmDataType = null;
  public SearchFilter(String searchText)
  {
    // This is the text to search for
    this.searchText = searchText.toLowerCase();
  }
  // Cleanup
  public void searchFilterClose()
  {
    try
    {
      if (strmBytes != null)
        strmBytes.close();
      if (strmDataType != null)
        strmDataType.close();
    }
    catch (Exception e)
    {}
  }
  public boolean matches(byte[] candidate)
  {
    String str = null;
    
    try
    {
      strmBytes = new ByteArrayInputStream(candidate);
      strmDataType = new DataInputStream(strmBytes);
      
      // Although 3 pieces of data were written to
      // the record (String, boolean and integer) 
      // we only need one read because the string to 
      // search is the first "field" in the record
      str = strmDataType.readUTF().toLowerCase();
    }
    catch (Exception e)
    { 
      return false;
    }
    // Look for a match     
    if (str != null && str.indexOf(searchText) != -1)
      return true;
    else
      return false;
  }
}





Simple Sort for RMS

/*--------------------------------------------------
* SimpleSort.java
*
* No GUI interface, all output is to the console
*
* Example from the book:     Core J2ME Technology
* Copyright John W. Muchow   http://www.CoreJ2ME.ru
* You may use/modify for any non-commercial purpose
*-------------------------------------------------*/
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.rms.*;
public class SimpleSort extends MIDlet
{
  private RecordStore rs = null;
  static final String REC_STORE = "db_1";
  public SimpleSort()
  {
    openRecStore();   // Create the record store
    
    // Write a few records
    writeRecord("Sand Wedge");
    writeRecord("One Wood");
    writeRecord("Putter");    
    writeRecord("Five Iron");        
    // Read back with enumerator, sorting the results
    readRecords();
    
    closeRecStore();  // Close record store
    deleteRecStore(); // Remove the record store
  }
  public void destroyApp( boolean unconditional )
  {
  }
  public void startApp()
  {
    // There is no user interface, go ahead and shutdown
    destroyApp(false);
    notifyDestroyed();
  }
  public void pauseApp()
  {
  }
  public void openRecStore()
  {
    try
    {
      // The second parameter indicates that the record store
      // should be created if it does not exist
      rs = RecordStore.openRecordStore(REC_STORE, true );
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }    
  
  public void closeRecStore()
  {
    try
    {
      rs.closeRecordStore();
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }
  public void deleteRecStore()
  {
    if (RecordStore.listRecordStores() != null)
    {
      try
      {
        RecordStore.deleteRecordStore(REC_STORE);
      }
      catch (Exception e)
      {
        db(e.toString());
      }
    }      
  }
  public void writeRecord(String str)
  {
    byte[] rec = str.getBytes();
    try
    {
      rs.addRecord(rec, 0, rec.length);
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }
  public void readRecords()
  {
    try
    {
      if (rs.getNumRecords() > 0)
      {
        Comparator comp = new Comparator();
        
        RecordEnumeration re = rs.enumerateRecords(null, comp, false);
        while (re.hasNextElement())
        {
          // Calls String constructor that takes an array of bytes as input
          String str = new String(re.nextRecord());
          System.out.println(str);
          System.out.println("------------------------------");                        
    
        }
      }
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }
  /*--------------------------------------------------
  * Simple message to console for debug/errors
  * When used with Exceptions we should handle the 
  * error in a more appropriate manner.
  *-------------------------------------------------*/
  private void db(String str)
  {
    System.err.println("Msg: " + str);
  }
}

/*--------------------------------------------------
* Compares two records to determine sort order
*-------------------------------------------------*/
class Comparator implements RecordComparator
{
  public int compare(byte[] rec1, byte[] rec2)
  {
    String str1 = new String(rec1), str2 = new String(rec2);
    
    int result = str1.rupareTo(str2);
    if (result == 0)
      return RecordComparator.EQUIVALENT;
    else if (result < 0)
      return RecordComparator.PRECEDES;
    else
      return RecordComparator.FOLLOWS;          
  }
}





Sort records that contain multiple Java data types. Sort using String type.

/*--------------------------------------------------
* StringSort.java
*
* Sort records that contain multiple Java
* data types. Sort using String type.
*
* Uses: Streams, Enumeration, RecordComparator
*
* No GUI interface, all output is to the console
*
* Example from the book:     Core J2ME Technology
* Copyright John W. Muchow   http://www.CoreJ2ME.ru
* You may use/modify for any non-commercial purpose
*-------------------------------------------------*/
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.rms.*;
public class StringSort extends MIDlet
{
  private RecordStore rs = null;    // Record store
  static final String REC_STORE = "db_3"; // Name of record store
  public StringSort()
  {
    openRecStore();   // Create the record store
    
    writeTestData();  // Write a series of records
    readStream();     // Read back the records
        
    closeRecStore();  // Close record store
    deleteRecStore(); // Remove the record store
  }
  public void destroyApp( boolean unconditional )
  {
  }
  public void startApp()
  {
    // There is no user interface, go ahead and shutdown
    destroyApp(false);
    notifyDestroyed();
  }
  public void pauseApp()
  {
  }
  public void openRecStore()
  {
    try
    {
      // The second parameter indicates that the record store
      // should be created if it does not exist
      rs = RecordStore.openRecordStore(REC_STORE, true );
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }    
  
  public void closeRecStore()
  {
    try
    {
      rs.closeRecordStore();
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }
  public void deleteRecStore()
  {
    if (RecordStore.listRecordStores() != null)
    {
      try
      {
        RecordStore.deleteRecordStore(REC_STORE);
      }
      catch (Exception e)
      {
        db(e.toString());
      }
    }      
  }
  /*--------------------------------------------------
  * Create three arrays to write to record store
  *-------------------------------------------------*/
  public void writeTestData()
  {
   String[] pets = {"duke", "tiger", "spike", "beauregard"};
   boolean[] dog = {true, false, true, true};    
   int[] rank = {3, 0, 1, 2};
 
   writeStream(pets, dog, rank);                    
  }
  
  /*--------------------------------------------------
  * Write to record store using streams.
  *-------------------------------------------------*/
  public void writeStream(String[] sData, boolean[] bData, int[] iData)
  {
    try
    {
       // Write data into an internal byte array
      ByteArrayOutputStream strmBytes = new ByteArrayOutputStream();
      
      // Write Java data types into the above byte array
      DataOutputStream strmDataType = new DataOutputStream(strmBytes);
      
      byte[] record;
      for (int i = 0; i < sData.length; i++)
      {
        // Write Java data types      
        strmDataType.writeUTF(sData[i]);
        strmDataType.writeBoolean(bData[i]);
        strmDataType.writeInt(iData[i]);                
        
        // Clear any buffered data
        strmDataType.flush();
        // Get stream data into byte array and write record      
        record = strmBytes.toByteArray();
        rs.addRecord(record, 0, record.length);      
        // Toss any data in the internal array so writes 
        // starts at beginning (of the internal array)
        strmBytes.reset();
      }
      
      strmBytes.close();
      strmDataType.close();
  
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }
  /*--------------------------------------------------
  * Read from the record store using streams
  *-------------------------------------------------*/
  public void readStream()
  {
    try
    {
      // Careful: Make sure this is big enough!
      // Better yet, test and reallocate if necessary
      byte[] recData = new byte[50];
       // Read from the specified byte array
      ByteArrayInputStream strmBytes = new ByteArrayInputStream(recData);
      // Read Java data types from the above byte array
      DataInputStream strmDataType = new DataInputStream(strmBytes);
      if (rs.getNumRecords() > 0)
      {
        ComparatorString comp = new ComparatorString();
        
        int i = 1;
        RecordEnumeration re = rs.enumerateRecords(null, comp, false);
        while (re.hasNextElement())
        {
          // Get data into the byte array          
          rs.getRecord(re.nextRecordId(), recData, 0);
                  
          // Read back the data types      
          System.out.println("Record #" + i++);        
          
          System.out.println("Name: " + strmDataType.readUTF());
          System.out.println("Dog: " + strmDataType.readBoolean());
          System.out.println("Rank: " + strmDataType.readInt());                    
          System.out.println("--------------------");        
          // Reset so read starts at beginning of array 
          strmBytes.reset();
        }
        
        comp.rupareStringClose();
        // Free enumerator
        re.destroy();        
      }
      strmBytes.close();
      strmDataType.close();
    
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }
  
  /*--------------------------------------------------
  * Simple message to console for debug/errors
  * When used with Exceptions we should handle the 
  * error in a more appropriate manner.
  *-------------------------------------------------*/
  private void db(String str)
  {
    System.err.println("Msg: " + str);
  }
}

/*--------------------------------------------------
* Compares two strings to determine sort order
* Each record passed in contains multiple Java data 
* types - use only the String data for sorting
*-------------------------------------------------*/
class ComparatorString implements RecordComparator
{
  private byte[] recData = new byte[10];
  // Read from a specified byte array    
  private ByteArrayInputStream strmBytes = null;
  
  // Read Java data types from the above byte array
  private DataInputStream strmDataType = null;
  
  public void compareStringClose()
  {
    try
    {
      if (strmBytes != null)
        strmBytes.close();
      if (strmDataType != null)
        strmDataType.close();
    }
    catch (Exception e)
    {}
  }
  
  public int compare(byte[] rec1, byte[] rec2)
  {
    String str1, str2;
    
    try
    {
      // If either record is larger than our buffer, reallocate
      int maxsize = Math.max(rec1.length, rec2.length);
      if (maxsize > recData.length)
        recData = new byte[maxsize];
      // Read record #1
      // Only need one read because the string to
      // sort on is the first "field" in the record
      strmBytes = new ByteArrayInputStream(rec1);
      strmDataType = new DataInputStream(strmBytes);
      str1 = strmDataType.readUTF();
      // Read record #2      
      strmBytes = new ByteArrayInputStream(rec2);
      strmDataType = new DataInputStream(strmBytes);
      str2 = strmDataType.readUTF();  
      
      // Compare record #1 and #2      
      int result = str1.rupareTo(str2);
      if (result == 0)
        return RecordComparator.EQUIVALENT;
      else if (result < 0)
        return RecordComparator.PRECEDES;
      else
        return RecordComparator.FOLLOWS;          
      
    }      
    catch (Exception e)
    { 
      return RecordComparator.EQUIVALENT;
    } 
  }
}





Write Read Example

/*
J2ME: The Complete Reference
James Keogh
Publisher: McGraw-Hill
ISBN 0072227109
*/
//jad file (please verify the jar size)
/*
MIDlet-Name: WriteReadExample
MIDlet-Version: 1.0
MIDlet-Vendor: MyCompany
MIDlet-Jar-URL: WriteReadExample.jar
MIDlet-1: WriteReadExample, , WriteReadExample
MicroEdition-Configuration: CLDC-1.0
MicroEdition-Profile: MIDP-1.0
MIDlet-JAR-SIZE: 100
*/
import javax.microedition.rms.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.io.*;
public class WriteReadExample extends MIDlet implements CommandListener
{
  private Display display;
  private Alert alert;
  private Form form; 
  private Command exit; 
  private Command start;
  private RecordStore recordstore = null;
  public WriteReadExample()
  {
    display = Display.getDisplay(this);
    exit = new Command("Exit", Command.SCREEN, 1);
    start = new Command("Start", Command.SCREEN, 1);
    form = new Form("Record");
    form.addCommand(exit);
    form.addCommand(start);
    form.setCommandListener(this);
  }
  public void startApp()
  {
    display.setCurrent(form);
  }
  public void pauseApp()
  {
  }
  public void destroyApp( boolean unconditional )
  {
  }
  public void commandAction(Command command, Displayable displayable)
  {
    if (command == exit)
    {
      destroyApp(true);
      notifyDestroyed();
    }
    else if (command == start)
    {
      try
      {
       recordstore = RecordStore.openRecordStore(
                                   "myRecordStore", true );
      }
      catch (Exception error)
      {
        alert = new Alert("Error Creating", 
                        error.toString(), null, AlertType.WARNING); 
        alert.setTimeout(Alert.FOREVER); 
        display.setCurrent(alert);
      }
      try
      {
        String outputData = "First Record";
        byte[] byteOutputData = outputData.getBytes();
        recordstore.addRecord(byteOutputData, 0, 
                     byteOutputData.length);
      }
      catch ( Exception error)
      {
        alert = new Alert("Error Writing", 
                     error.toString(), null, AlertType.WARNING); 
        alert.setTimeout(Alert.FOREVER); 
        display.setCurrent(alert);
      }
      try
      {
        byte[] byteInputData = new byte[1]; 
        int length = 0;
        for (int x = 1; x <= recordstore.getNumRecords(); x++)
        {
          if (recordstore.getRecordSize(x) > byteInputData.length)
          {
            byteInputData = new byte[recordstore.getRecordSize(x)];
          }
          length = recordstore.getRecord(x, byteInputData, 0);
        }
          alert = new Alert("Reading", new String(byteInputData, 0, 
                          length), null, AlertType.WARNING); 
          alert.setTimeout(Alert.FOREVER); 
          display.setCurrent(alert); 

      }
      catch (Exception error)
      {
        alert = new Alert("Error Reading", error.toString(), 
                            null, AlertType.WARNING); 
        alert.setTimeout(Alert.FOREVER); 
        display.setCurrent(alert);
      }
      try
      {
        recordstore.closeRecordStore();
      }
      catch (Exception error)
      {
        alert = new Alert("Error Closing", error.toString(), 
                         null, AlertType.WARNING); 
        alert.setTimeout(Alert.FOREVER); 
        display.setCurrent(alert);
      }
      if (RecordStore.listRecordStores() != null)
      {
        try
        {
          RecordStore.deleteRecordStore("myRecordStore");
        }
        catch (Exception error)
        {
         alert = new Alert("Error Removing", error.toString(), 
                        null, AlertType.WARNING); 
         alert.setTimeout(Alert.FOREVER); 
         display.setCurrent(alert);
        }
      }      
    }
  }
}