Java/J2ME/Sort Search
Версия от 18:01, 31 мая 2010; (обсуждение)
Содержание
- 1 A simple class that shows various functionality of RMS.
- 2 Birthday Database
- 3 Demonstrates simple record sorting and filtering
- 4 Display a Form and TextField for searching records. Each record contains a String object.
- 5 Int Sort
- 6 J2ME Data Management: Record Management System
- 7 My Record Listener
- 8 Search Streams
- 9 Simple Sort for RMS
- 10 Sort records that contain multiple Java data types. Sort using String type.
- 11 Write Read Example
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);
}
}
}
}
}