/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package lession17;import java.util.Hashtable;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.midlet.*;/**
 * 案例:电话本
 * 界面出现,显示一个欢迎界面,右下角按钮:电话本,左下角按钮:退出
 *
 * 按电话本按钮,显示电话本界面,用List显示所有电话,界面左下角:返回,
 * 右下角三个按钮:添加电话,删除电话,修改电话
 * 按删除电话,删掉当前电话
 * 按添加电话,进入添加电话界面
 * 按修改电话,进入添加电话界面,并在该界面中显示将被修改的姓名和电话
 * 
 * 添加电话界面有姓名和电话两个文本框,右下角确定按钮,左下角返回按钮。
 * 输入姓名和电话,按确定,可以添加,添加完毕后返回电话本界面
 * 按返回,退到电话本界面
 *
 * 本案例,将分成三个不同的类(界面)来完成
 * 记录集的操作使用一个专有的类来完成
 * @author mouyong
 */
public class PhoneMidlet extends MIDlet {    WelcomeCanvas welcome = new WelcomeCanvas();//欢迎界面
    PhoneList phoneList = new PhoneList();//电话列表界面
    AddPhone addPhone = new AddPhone();//添加电话的界面
    Display dis = Display.getDisplay(this);
    RecordDao rd = new RecordDao();//记录集的处理类
    int changeId = 0;//用于标志修改电话的值,0表示新添加电话,非0表示修改电话的记录ID
    String oldData=null;//用于保存电话修改前的值    public void startApp() {
        //初始化手机欢迎界面
        dis.setCurrent(welcome);
        listen();
    }    public void pauseApp() {
    }    public void destroyApp(boolean unconditional) {
    }
    //界面监听器注册方法    private void listen() {
        /*********************欢迎界面的监听器***************************/
        welcome.setCommandListener(new CommandListener() {            public void commandAction(Command c, Displayable d) {
                if (c == welcome.getCmdPhone()) {
                    //添加电话到电话本上
                    addPhone();
                    dis.setCurrent(phoneList);//如果点电话本,就转到电话本界面
                } else if (c == welcome.getCmdExit()) {
                    PhoneMidlet.this.notifyDestroyed();//如果点退出,就退出系统
                }
            }
        });        /*********************电话本界面的监听器***************************/
        phoneList.setCommandListener(new CommandListener() {            public void commandAction(Command c, Displayable d) {
                if (c == phoneList.getCmdAdd()) {
                    dis.setCurrent(addPhone);//如果点击添加电话,则切换到添加电话界面
                } else if (c == phoneList.getCmdBack()) {
                    dis.setCurrent(welcome);//如果点击返回,则切换到欢迎界面
                } else if (c == phoneList.getCmdDel()) {
                    //如果点击删除电话,则删除当前选择的电话
                    rd.deleteRecord(phoneList.getString(phoneList.getSelectedIndex()));
                    //更新列表
                    addPhone();
                } else if (c == phoneList.getCmdModify()) {
                    //如果选择修改,则将当前选择的文字取出
                    oldData = phoneList.getString(phoneList.getSelectedIndex());
                    //查出它的记录ID
                    changeId = ((Integer) rd.getHtrs().get(oldData)).intValue();
                    //截取姓名和电话
                    String name = oldData.substring(0, oldData.indexOf(":"));
                    String phone = oldData.substring(oldData.indexOf(":") + 1);
                    //放入添加电话的文本框中
                    addPhone.setName(name);
                    addPhone.setPhone(phone);
                    //切换到添加电话界面
                    dis.setCurrent(addPhone);
                }
            }
        });        /*********************添加电话界面的监听器***************************/
        addPhone.setCommandListener(new CommandListener() {            public void commandAction(Command c, Displayable d) {
                if (c == addPhone.getCmdOK()) {
                    //判断是电话添加还是电话修改
                    if(changeId!=0){
                        //如果是修改
                        rd.modRecord(changeId, oldData,addPhone.getName(), addPhone.getPhone());
                        //修改完毕之后把标志改回原样
                        changeId=0;
                    }else{
                    //如果是确定,添加电话信息到记录集
                    rd.addRecord(addPhone.getName(), addPhone.getPhone());
                    }
                    //清除两个文本框的内容
                    addPhone.setName("");
                    addPhone.setPhone("");
                    //添加电话到电话本上
                    addPhone();
                    //添加完毕之后,返回到电话列表界面
                    dis.setCurrent(phoneList);
                } else if (c == addPhone.getCmdBack()) {
                    //如果是返回,则回到电话列表界面
                    dis.setCurrent(phoneList);
                }
            }
        });
    }    private void addPhone() {
        Hashtable v = rd.getHtrs();
        phoneList.changePhone(v);
    }
}/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */package lession17;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.TextField;/**
 *添加电话界面有姓名和电话两个文本框,右下角确定按钮,左下角返回按钮。
 * @author mouyong
 */
public class AddPhone extends Form {
    private Command cmdOK=new Command("确定",Command.OK,1);
    private Command cmdBack=new Command("返回",Command.BACK,1);    private TextField txtName=new TextField("姓名", "", 20, TextField.ANY);
    private TextField txtPhone=new TextField("电话", "", 11, TextField.PHONENUMBER);    public AddPhone(){
        super("添加电话");
        this.append(txtName);
        this.append(txtPhone);
        this.addCommand(cmdOK);
        this.addCommand(cmdBack);
    }    /**
     * @return the cmdOK
     */
    public Command getCmdOK() {
        return cmdOK;
    }    /**
     * @return the cmdBack
     */
    public Command getCmdBack() {
        return cmdBack;
    }    /**
     * @return the txtName
     */
    public String getName() {
        return txtName.getString();
    }    /**
     * @param txtName the txtName to set
     */
    public void setName(String name) {
        this.txtName.setString(name);
    }    /**
     * @return the txtPhone
     */
    public String getPhone() {
        return txtPhone.getString();
    }    /**
     * @param txtPhone the txtPhone to set
     */
    public void setPhone(String txtPhone) {
        this.txtPhone.setString(txtPhone);
    }}
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */package lession17;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.List;/**
 *电话本界面,用List显示所有电话,界面左下角:返回,
 *右下角三个按钮:添加电话,删除电话,修改电话
 * @author mouyong
 */
public class PhoneList extends List {
    private Command cmdBack=new Command("返回",Command.BACK,1);
    private Command cmdAdd=new Command("添加电话",Command.SCREEN,1);
    private Command cmdDel=new Command("删除电话",Command.SCREEN,1);
    private Command cmdModify=new Command("修改电话",Command.SCREEN,1);    public PhoneList(){
        super("电话本",List.IMPLICIT);
        this.addCommand(cmdAdd);
        this.addCommand(cmdBack);
        this.addCommand(cmdDel);
        this.addCommand(cmdModify);
    }    /**
     * @return the cmdBack
     */
    public Command getCmdBack() {
        return cmdBack;
    }    /**
     * @return the cmdAdd
     */
    public Command getCmdAdd() {
        return cmdAdd;
    }    /**
     * @return the cmdDel
     */
    public Command getCmdDel() {
        return cmdDel;
    }    //更换列表内容
    public void changePhone(Hashtable v){
        this.deleteAll();
        Enumeration en=v.keys();        while(en.hasMoreElements()){
           String key=(String)en.nextElement();
           this.append(key, null);
           
        }
    }    /**
     * @return the cmdModify
     */
    public Command getCmdModify() {
        return cmdModify;
    }}
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package lession17;import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import javax.microedition.rms.InvalidRecordIDException;
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 javax.microedition.rms.RecordStoreNotOpenException;//为得到将被删除的记录ID而设置的过滤器
/**
 *  操作记录集的类
 * @author mouyong
 */
public class RecordDao {    private RecordStore rs = null;
    private Hashtable htrs = new Hashtable();//一个同步更新的Hashtable    public RecordDao(){
        init();
    }
    //初始化,填充Hashtable
    private void init(){
        try {
            open();
             //填充Hashtable
            RecordEnumeration re = rs.enumerateRecords(null, null, false);
            while (re.hasNextElement()) {
                int i = re.nextRecordId();
                htrs.put(new String(rs.getRecord(i)), new Integer(i));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            close();
        }       
    }
    //打开记录集
    private void open() {
        try {
            rs = RecordStore.openRecordStore("Phone", true);           
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    //关闭记录集
    private void close() {
        if (rs != null) {
            try {
                rs.closeRecordStore();
                rs = null;
            } catch (RecordStoreNotOpenException ex) {
                ex.printStackTrace();
            } catch (RecordStoreException ex) {
                ex.printStackTrace();
            }
        }
    }    //添加一条记录
    public boolean addRecord(String name, String phone) {
        byte[] info = (name + ":" + phone).getBytes();
        try {
            open();
            //添加记录
            rs.addRecord(info, 0, info.length);
            //添加Hashtable中的记录
            this.getHtrs().put(new String(info), new Integer(rs.getNextRecordID()-1));
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            close();
        }
    }    //删除一条或多条记录
    public boolean deleteRecord(String record) {
        try {
            open();
            //获得被删除记录的id
            int deletedId = ((Integer) htrs.get(record)).intValue();
            //删除记录
            rs.deleteRecord(deletedId);
            //删除Hashtable中的数据
            this.getHtrs().remove(record);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            close();
        }
    }    public void modRecord(int recordId,String oldData, String name, String phone) {
        try {
            open();
            byte[] newData = (name + ":" + phone).getBytes();
            //更新记录集
            rs.setRecord(recordId, newData, 0, newData.length);
            //更新Hashtable:先将旧数据删除,然后添加新数据
            this.getHtrs().remove(oldData);
            this.getHtrs().put(new String(newData), new Integer(recordId));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            close();
        }
    }    /**
     * @return the htrs
     */
    public Hashtable getHtrs() {
        return htrs;
    }
} 
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */package lession17;
import java.io.IOException;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;/**
 * 欢迎界面,右下角按钮:电话本,左下角按钮:退出
 *
 * @author mouyong
 */
public class WelcomeCanvas extends Canvas {
    private Command cmdPhone=new Command("电话本", Command.SCREEN, 1);
    private Command cmdExit=new Command("退出",Command.EXIT,1);
    //构造函数,完成监听注册和组装
    public WelcomeCanvas(){
        this.addCommand(cmdExit);
        this.addCommand(cmdPhone);
    }
    //画一个欢迎界面,这里我画了一幅图
    protected void paint(Graphics g) {
        Image img=null;
        try {
            img = Image.createImage("/lession17/welcome.jpg");
        } catch (IOException ex) {
            ex.printStackTrace();
        }        //将图片画在界面上
        g.drawImage(img, 0, 0, Graphics.LEFT|Graphics.TOP);
    }    /**
     * @return the cmdPhone
     */
    public Command getCmdPhone() {
        return cmdPhone;
    }    /**
     * @return the cmdExit
     */
    public Command getCmdExit() {
        return cmdExit;
    }}