持久性排序程序 : 数据库持续性 « 基于J2ME « Java

En
Java
1. 图形用户界面
2. 三维图形动画
3. 高级图形
4. 蚂蚁编译
5. Apache类库
6. 统计图
7. 
8. 集合数据结构
9. 数据类型
10. 数据库JDBC
11. 设计模式
12. 开发相关类
13. EJB3
14. 电子邮件
15. 事件
16. 文件输入输出
17. 游戏
18. 泛型
19. GWT
20. Hibernate
21. 本地化
22. J2EE平台
23. 基于J2ME
24. JDK-6
25. JNDI的LDAP
26. JPA
27. JSP技术
28. JSTL
29. 语言基础知识
30. 网络协议
31. PDF格式RTF格式
32. 映射
33. 常规表达式
34. 脚本
35. 安全
36. Servlets
37. Spring
38. Swing组件
39. 图形用户界面
40. SWT-JFace-Eclipse
41. 线程
42. 应用程序
43. Velocity
44. Web服务SOA
45. 可扩展标记语言
Java 教程
Java » 基于J2ME » 数据库持续性屏幕截图 
持久性排序程序


/*
J2ME in a Nutshell
By Kim Topley
ISBN: 0-596-00253-X

*/


import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;

import javax.microedition.rms.RecordComparator;
import javax.microedition.rms.RecordEnumeration;
import javax.microedition.rms.RecordFilter;
import javax.microedition.rms.RecordListener;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;


import java.util.Vector;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.List;
import javax.microedition.lcdui.Screen;
import javax.microedition.lcdui.StringItem;
import javax.microedition.lcdui.TextField;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
import javax.microedition.rms.RecordEnumeration;
import javax.microedition.rms.RecordListener;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;


public class PersistentRankingMIDlet extends MIDlet
                implements CommandListener, RecordListener, Runnable {

    private Command exitCommand;
    private Command okCommand;
    private Command cancelCommand;
    private Command newCommand;
    private Command checkCommand;
    private Command detailsCommand;
    private Command backCommand;
    private Command deleteCommand;
    private Display display;
    private TextField isbnField;
    private StringItem isbnDisplay;
    private StringItem titleDisplay;
    private StringItem rankingDisplay;
    private StringItem reviewDisplay;
    private StringItem checkTitle;
    private Form isbnForm;
    private Form searchForm;
    private Form resultForm;
    private Form checkForm;
    private List bookList;
    private Vector bookInfoList;
    private Thread searchThread;
    private BookStore bookStore;
    private BookInfo searchBookInfo;

    protected void startApp() throws MIDletStateChangeException {
        if (display == null) {
            initialize();

            // If there are any books in the
            // book store, display the list.
            // Otherwise, start with the ISBN form.
            display.setCurrent(getSelectionScreen());
        }
    }

    protected void pauseApp() {
    }

    protected void destroyApp(boolean unconditional)
                        throws MIDletStateChangeException {
        // Close the book store
        if (bookStore != null) {
            try {
                bookStore.removeRecordListener(this);
                bookStore.close();
            catch (RecordStoreException ex) {
            }
        }
    }

    public void commandAction(Command cmd, Displayable d) {
        if (cmd == exitCommand) {
            try {
                destroyApp(true);
            catch (MIDletStateChangeException ex) {
            }
            notifyDestroyed();
        else if (cmd == okCommand) {
            String isbn = isbnField.getString().trim();
            if (!isbn.equals("")) {
                isbnDisplay.setText(isbn);
                display.setCurrent(searchForm);
                searchForBook(new BookInfo(isbn));
            }
        else if (cmd == cancelCommand) {
            searchThread = null;
            isbnField.setString(null);
            display.setCurrent(getSelectionScreen());
        else if (cmd == newCommand) {
            isbnField.setString(null);
            display.setCurrent(isbnForm);
        else if (cmd == detailsCommand || cmd == List.SELECT_COMMAND) {
            int index = bookList.getSelectedIndex();
            searchBookInfo = (BookInfo)bookInfoList.elementAt(index);
            isbnDisplay.setText(searchBookInfo.getIsbn());
            showBookInfo(searchBookInfo);
        else if (cmd == deleteCommand) {
            int index = bookList.getSelectedIndex();
            BookInfo bookInfo = (BookInfo)bookInfoList.elementAt(index);
            try {
                bookStore.deleteBook(bookInfo);
            catch (RecordStoreException ex) {
                System.out.println("Delete failed: " + ex);
            }
        else if (cmd == checkCommand) {
            String isbn = searchBookInfo.getIsbn();
            checkTitle.setText(searchBookInfo.getTitle());
            display.setCurrent(checkForm);
            searchForBook(searchBookInfo);
        else if (cmd == backCommand) {
            display.setCurrent(getSelectionScreen());
        }
    }

    public void searchForBook(BookInfo info) {
        searchBookInfo = info;
        searchThread = new Thread(this);
        searchThread.start();
    }

    public void recordAdded(RecordStore recordStore, int recordId) {
        // Update the book list
        populateBookList();
    }

    public void recordChanged(RecordStore recordStore, int recordId) {
        // Update the book list
        populateBookList();
    }

    public void recordDeleted(RecordStore recordStore, int recordId) {
        // Update the book list
        populateBookList();
    }

    public void run() {
        try {
            boolean found = Fetcher.fetch(searchBookInfo);
            if (searchThread == Thread.currentThread()) {
                if (found && searchBookInfo.getTitle() != null) {
                    // Display the book details
                    showBookInfo(searchBookInfo);

                    // Add the new book to the book store
                    bookStore.saveBookInfo(searchBookInfo);
                else {
                    Alert alert = new Alert("Book not found", null,
                                        null, AlertType.ERROR);
                    alert.setTimeout(Alert.FOREVER);
                    alert.setString("No book with ISBN " +
                                        searchBookInfo.getIsbn() +
                                        " was found.");
                    isbnField.setString(null);
                    display.setCurrent(alert, getSelectionScreen());
                }
            }
        catch (Throwable ex) {
            if (searchThread == Thread.currentThread()) {
                Alert alert = new Alert("Search Failed", null,
                                        null, AlertType.ERROR);
                alert.setTimeout(Alert.FOREVER);
                alert.setString("Search failed:\n" + ex.getMessage());
                isbnField.setString(null);
                display.setCurrent(alert, getSelectionScreen());
            }
        }
    }

    // Shows book details on the result screen
    private void showBookInfo(BookInfo info) {
        titleDisplay.setText(info.getTitle());

        int ranking = info.getRanking();
        int lastRanking = info.getLastRanking();
        int change = ranking - lastRanking;
        String rankingText =
                ranking == "" :
                    String.valueOf(ranking);
        if (change > 0) {
            rankingText += ", down by " + change;
        else if (change < 0) {
            rankingText += ", UP by " (-change);
        }
        rankingDisplay.setText(rankingText);

        int reviews = info.getReviews();
        int lastReviews = info.getLastReviews();
        change = reviews - lastReviews;
        String reviewText =
            reviews == "" :
                    String.valueOf(reviews);
        if (change > 0) {
            reviewText += ", up by " + change;
        
        reviewDisplay.setText(reviewText);

        display.setCurrent(resultForm);
    }

    // If there are any books in the
    // book store, display the list.
    // Otherwise, start with the ISBN form.
    private Screen getSelectionScreen() {
        return
            bookInfoList.isEmpty() (Screen)isbnForm : (Screen)bookList;
    }

    // Populates the list of books
    private void populateBookList() {
        // Clear out any existing content
        int count = bookList.size();
        for (int i = 0; i < count; i++) {
            bookList.delete(0);
        }
        bookInfoList.removeAllElements();

        // Add an entry for each book in the store
        try {
            RecordEnumeration e = bookStore.getBooks();
            while (e.hasNextElement()) {
                int id = e.nextRecordId();
                BookInfo info = bookStore.getBookInfo(id);
                bookInfoList.addElement(info);
                String title = info.getTitle();
                if (title == null || title.equals("")) {
                    title = info.getIsbn();
                }
                bookList.append(title, null);
            }
            e.destroy();
        catch (Exception ex) {
            // Just leave an empty list.
        }

        // The ISBN list should have an exit command
        // only if the List screen is empty.
        isbnForm.removeCommand(exitCommand);
        if (bookInfoList.isEmpty()) {
            isbnForm.addCommand(exitCommand);
        }
    }

    private void initialize() {
        display = Display.getDisplay(this);

        // Open the book store
        bookStore = new BookStore();
 
        exitCommand = new Command("Exit", Command.EXIT, 0);
        okCommand = new Command("OK", Command.OK, 0);
        cancelCommand = new Command("Cancel", Command.CANCEL, 0);
        newCommand = new Command("New", Command.SCREEN, 1);
        detailsCommand = new Command("Details", Command.OK, 0);
        checkCommand = new Command("Check", Command.OK, 0);
        backCommand = new Command("Back", Command.CANCEL, 1);
        deleteCommand = new Command("Delete", Command.SCREEN, 1);

        bookList = new List("Books", List.IMPLICIT);
        bookList.addCommand(detailsCommand);
        bookList.addCommand(newCommand);
        bookList.addCommand(deleteCommand);
        bookList.addCommand(exitCommand);
        bookInfoList = new Vector();

        isbnForm = new Form("Book Query");
        isbnForm.append("Enter an ISBN and press OK:");
        isbnField = new TextField("", null, 10, TextField.ANY);
        isbnForm.append(isbnField);
        isbnForm.addCommand(okCommand);
        isbnForm.addCommand(exitCommand);
        isbnForm.addCommand(backCommand);

        searchForm = new Form("Book Search");
        searchForm.append("Searching for ISBN\n");
        isbnDisplay = new StringItem(null, null);
        searchForm.append(isbnDisplay);
        searchForm.append("\nPlease wait....");
        searchForm.addCommand(cancelCommand);

        checkForm = new Form("Details Update");
        checkForm.append("Getting details for\n");
        checkTitle = new StringItem(null, null);
        checkForm.append(checkTitle);
        checkForm.append(" from amazon.com\nPlease wait....");
        checkForm.addCommand(cancelCommand);

        resultForm = new Form("Search Results");
        titleDisplay = new StringItem("Book title: "null);
        rankingDisplay = new StringItem("Ranking:    "null);
        reviewDisplay = new StringItem("Reviews:    "null);
        resultForm.append(titleDisplay);
        resultForm.append(rankingDisplay);
        resultForm.append(reviewDisplay);
        resultForm.addCommand(backCommand);
        resultForm.addCommand(checkCommand);

        // Register for events from all of the forms
        isbnForm.setCommandListener(this);
        searchForm.setCommandListener(this);
        resultForm.setCommandListener(this);
        bookList.setCommandListener(this);

        // Listen for changes in the content of the book store
        bookStore.addRecordListener(this);

        // Install the books held in the record store
        populateBookList();
    }
}

// A class that implements a persistent store
// of books, keyed by ISBN.
class BookStore implements RecordComparator, RecordFilter {

    // The name of the record store used to hold books
    private static final String STORE_NAME = "BookStore";

    // The record store itself
    private RecordStore store;

    // ISBN to be used during a filter operation
    private String searchISBN;

    // Creates a bookstore and opens it
    public BookStore() {
        try {
            store = RecordStore.openRecordStore(STORE_NAME, true);
        catch (RecordStoreException ex) {
            System.err.println(ex);
        }
    }

    // Closes the bookstore
    public void close() throws RecordStoreException {
        if (store != null) {
            store.closeRecordStore();
        }
    }

    // Gets the number of books in the book store
    public int getBookCount() throws RecordStoreException {
        if (store != null) {
            return store.getNumRecords();
        }
        return 0;
    }

    // Adds a listener to the book store
    public void addRecordListener(RecordListener l) {
        if (store != null) {
            store.addRecordListener(l);
        }
    }

    // Removes a listener from the book store
    public void removeRecordListener(RecordListener l) {
        if (store != null) {
            store.removeRecordListener(l);
        }
    }

    // Gets a sorted list of all of the books in
    // the store.
    public RecordEnumeration getBooks() throws RecordStoreException {
        if (store != null) {
            return store.enumerateRecords(null, this, false);
        }
        return null;
    }

    
    // Gets a BookInfo from a store record
    // given its ISBN
    public BookInfo getBookInfo(String isbnthrows RecordStoreException,
                                                    IOException {
        BookInfo bookInfo = null;
        searchISBN = isbn; 
        
        // Look for a book with the given ISBN
        RecordEnumeration e = store.enumerateRecords(
                                        this, null, false);
        
        // If found, get its identifier and
        // fetch its BookInfo object
        if (e.numRecords() 0) {
            int id = e.nextRecordId();
            bookInfo = getBookInfo(id);
        }
        
        // Release the enumeration
        e.destroy();
        
        return bookInfo;
    }
        
    // Gets a BookInfo from a store record
    // given its record identifier
    
    
    public BookInfo getBookInfo(int idthrows RecordStoreException,
                                                    IOException {
        byte[] bytes = store.getRecord(id);
        DataInputStream is = new DataInputStream(
                            new ByteArrayInputStream(bytes));

        String isbn = is.readUTF();
        BookInfo info = new BookInfo(isbn);
        info.id = id;
        info.title = is.readUTF();
        info.ranking = is.readInt();
        info.reviews = is.readInt();
        info.lastRanking = is.readInt();
        info.lastReviews = is.readInt();

        return info;
    }
    
    // Adds an entry to the store or modifies the existing
    // entry if a matching ISBN exists.
    public void saveBookInfo(BookInfo bookInfo)
                                throws IOException, RecordStoreException {
        if (store != null) {
            searchISBN = bookInfo.getIsbn();
            RecordEnumeration e = store.enumerateRecords(
                                        this, null, false);
            if (e.numRecords() 0) {
                // A matching record exists. Set the id
                // of the BookInfo to match the existing record
                bookInfo.id = e.nextRecordId();
                byte[] bytes = toByteArray(bookInfo);
                store.setRecord(bookInfo.id, bytes, 0, bytes.length);
            else {
                // Create a new record
                bookInfo.id = store.getNextRecordID();
                byte[] bytes = toByteArray(bookInfo);
                store.addRecord(bytes, 0, bytes.length);
            }

            // Finally, destroy the RecordEnumeration
            e.destroy();
        }
    }

    // Deletes the entry for a book from the store
    public void deleteBook(BookInfo bookInfothrows RecordStoreException {
        if (store != null) {
            store.deleteRecord(bookInfo.id);
        }
    }

    // RecordComparator implementation
    public int compare(byte[] book1, byte[] book2) {
        try {
            DataInputStream stream1 =
                new DataInputStream(new ByteArrayInputStream(book1));
            DataInputStream stream2 =
                new DataInputStream(new ByteArrayInputStream(book2));

            // Match based on the ISBN, but sort based on the title.
            String isbn1 = stream1.readUTF();
            String isbn2 = stream2.readUTF();
            if (isbn1.equals(isbn2)) {
                return RecordComparator.EQUIVALENT;
            }
            String title1 = stream1.readUTF();
            String title2 = stream2.readUTF();
            int result = title1.compareTo(title2);
            if (result == 0) {
                return RecordComparator.EQUIVALENT;
            }
            return result < ? RecordComparator.PRECEDES :
                                RecordComparator.FOLLOWS;
        catch (IOException ex) {
            return RecordComparator.EQUIVALENT;
        }
    }

    // RecordFilter implementation
    public boolean matches(byte[] book) {
        if (searchISBN != null) {
            try {
                DataInputStream stream =
                    new DataInputStream(new ByteArrayInputStream(book));

                // Match based on the ISBN.
                return searchISBN.equals(stream.readUTF());
            catch (IOException ex) {
                System.err.println(ex);
            }
        }

        // Default is not to match
        return false;
    }
    
    // Writes a record into a byte array.
    private byte[] toByteArray(BookInfo bookInfothrows IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream os = new DataOutputStream(baos);

        os.writeUTF(bookInfo.isbn);
        os.writeUTF(bookInfo.title == null "" : bookInfo.title);
        os.writeInt(bookInfo.ranking);
        os.writeInt(bookInfo.reviews);
        os.writeInt(bookInfo.lastRanking);
        os.writeInt(bookInfo.lastReviews);

        return baos.toByteArray();
    }
}




/**
 * A class that represents a book listing
 * at an online book set, including the number
 * of reviews for the book and its sales ranking.
 */
class BookInfo {

    int    id;          // Used when persisting
    String isbn;        // The book ISBN
    String title;       // The book title
    int    reviews;     // Number of reviews
    int    ranking;     // Current ranking
    int    lastReviews; // Last review count
    int    lastRanking;  // Last ranking

    public BookInfo(String isbn) {
        this.isbn = isbn;
    }

    public String getIsbn() {
        return isbn;
    }

    public String getTitle() {
        return title;
    }

    public int getReviews() {
        return reviews;
    }

    public int getRanking() {
        return ranking;
    }

    public int getLastReviews() {
        return lastReviews;
    }

    public int getLastRanking() {
        return lastRanking;
    }

    // Installs details parsed from an input stream
    public void setFromInputStream(InputStream is) {
        // Use an InputHelper to search the input
        InputHelper helper = new InputHelper(is);
        try {

            // Default new values to current values
            int newRanking = this.ranking;
            int newReviews = this.reviews;

            boolean found = helper.moveAfterString("buying info: ");
            if (!found) {
                return;
            }

            // Gather the title from the rest of this line
            StringBuffer titleBuffer = helper.getRestOfLine();

            // Look for the number of reviews
            found = helper.moveAfterString("Based on ");
            if (!found) {
                return;
            }

            // Gather the number of reviews from the current location
            String reviewString = helper.gatherNumber();

            // Look for the sales rank
            found = helper.moveAfterString("Sales Rank: ");
            if (!found) {
                return;
            }

            // Gather the number from the current location
            String rankingString = helper.gatherNumber();

            // Having safely found everything, set the new title
            title = titleBuffer.toString().trim();

            // Now convert the reviews and ranking to integers.
            // If they fail to convert, just leave the existing
            // values.
            try {
                newRanking = Integer.parseInt(rankingString);
            catch (NumberFormatException ex) {
            }

            if (newRanking != ranking) {
                lastRanking = ranking;
                ranking = newRanking;
                if (lastRanking == 0) {
                    // First time, set last and current
                    // to the same value
                    lastRanking = ranking;
                }
            }

            try {
                newReviews = Integer.parseInt(reviewString);
            catch (NumberFormatException ex) {
            }

            if (newReviews != reviews) {
                lastReviews = reviews;
                reviews = newReviews;
                if (lastReviews == 0) {
                    // First time, set last and current
                    // to the same value
                    lastReviews = reviews;
                }
            }
        catch (IOException ex) {
        finally {
            // Allow garbage collection
            helper.dispose();
            helper = null;
        }
    }
}

// A class that scans through an input
// stream for strins without reading the
// entire stream into a large string.
class InputHelper {

    // Size of the input buffer
    private static final int BUFFER_SIZE = 1024;

    // The input buffer
    private final char[] buffer = new char[BUFFER_SIZE];

    // Number of characters left in the buffer
    private int charsLeft;

    // Index of the next character in the buffer
    private int nextChar;

    // InputStreamReader used to map to Unicode
    private InputStreamReader reader;

    // Constructs a helper to read a given stream
    public InputHelper(InputStream is) {
        reader = new InputStreamReader(is);
    }
    
    // Cleans up when no longer needed
    public void dispose() {
        if (reader != null) {
            try {
                reader.close();
            catch (IOException ex) {
            }
            reader = null;
        }
    }

    // Looks for a given string in the input
    // stream and positions the stream so that the
    // next character read is one beyond the string.
    // Returns true if the string was found, false if
    // not (and the stream will have been completely read).
    public boolean moveAfterString(String strthrows IOException {
        char[] chars = str.toCharArray();
        int count = chars.length;
        char firstChar = chars[0];

        char c = (char)0;
        for (;;) {
            if (c != firstChar && !findNext(firstChar)) {
                // Reached the end of the input stream
                return false;
            }

            boolean mismatch = false;
            for (int i = 1; i < count; i++) {
                c = getNext();
                if (c != chars[i]) {
                    mismatch = true;
                    break;
                }
            }

            if (!mismatch) {
                return true;
            }

            // Mismatch. 'c' has the first mismatched
            // character - start the loop again with
            // that character. This is necessary because we
            // could have found "wweb" while looking for "web"
        }
    }
    
    // Gets the characters for a number, ignoring
    // the grouping separator. The number starts at the
    // current input position, but any leading non-numerics
    // are skipped.
    public String gatherNumber() throws IOException {
        StringBuffer sb = new StringBuffer();
        boolean gotNumeric = false;
        for (;;) {
            char c = getNext();
            
            // Skip until we find a digit.
            boolean isDigit = Character.isDigit(c);
            if (!gotNumeric && !isDigit) {
                continue;
            }
            gotNumeric = true;
            if (!isDigit) {
                if (c == '.' || c == ',') {
                    continue;
                }
                break;
            }
            sb.append(c);
        }
        return sb.toString();
    }
    
    // Gets the balance of the current line
    // and returns it as a StringBuffer
    public StringBuffer getRestOfLine() throws IOException {
    
        StringBuffer sb = new StringBuffer();
        char c;
        for (;;) {
            c = getNext();
            if (c == '\n' || c == (char)0) {
                break;
            }
            sb.append(c);
        }
        return sb;
    
    
    // Gets the next character from the stream,
    // returning (char)0 when all input has been read.
    private char getNext() throws IOException {
        if (charsLeft == 0) {
            charsLeft = reader.read(buffer, 0, BUFFER_SIZE);
            if (charsLeft < 0) {
                return (char)0;
            }
            nextChar = 0;
        }
        charsLeft--;
        return buffer[nextChar++];
    }
       
    // Finds the next instance of a given character in the
    // input stream. The input stream is positioned after
    // the located character. If EOF is reached without
    // finding the character, false is returned.
    private boolean findNext(char cthrows IOException {
        for (;;) {
            if (charsLeft == 0) {
                charsLeft = reader.read(buffer, 0, BUFFER_SIZE);
                if (charsLeft < 0) {
                    return false;
                }
                nextChar = 0;
            }
            charsLeft--;
            if (c == buffer[nextChar++]) {
                return true;
            }
        }
    }
}
           
       
Related examples in the same category
1. Write Read Mixed Data Types Example Write Read Mixed Data Types Example
2. Record Enumeration Example Record Enumeration Example
3. Mixed Record Enumeration Example Mixed Record Enumeration Example
4. 排序记录示例
5. Sort Mixed Record Data Type Example Sort Mixed Record Data Type Example
6. 搜索示例搜索示例
7. 搜索好坏参半的记录数据类型示例搜索好坏参半的记录数据类型示例
8. 记录应用程序记录应用程序
9. 存储数据库存储数据库
10. Test the RMS listener methodsTest the RMS listener methods
11. Use streams to read and write Java data types to the record store.Use streams to read and write Java data types to the record store.
12. 读取和写入记录。读取和写入记录。
13. 持久性:存储和显示游戏得分
14. 阅读显示文件阅读显示文件
www.java2java.com | Contact Us
Copyright 2010 - 2030 Java Source and Support. All rights reserved.
All other trademarks are property of their respective owners.