Commits

chunlinyao  committed 7479219

implement All

  • Participants
  • Parent commits 54c0881

Comments (0)

Files changed (7)

File nbproject/private/private.properties

-#Fri, 18 Feb 2011 23:33:41 -0300
+#Fri, 13 May 2011 16:50:51 +0800
 app-version.autoincrement=true
 config.active=
-deployment.counter=64
-deployment.number=0.0.63
+deployment.counter=65
+deployment.number=0.0.64
 javadoc.preview=true
 netbeans.user=/home/yaochunlin/.netbeans/7.0

File src/TokenGenerator/Account.java

+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package TokenGenerator;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/**
+ *
+ * @author yaochunlin
+ */
+public class Account {
+
+    /**
+     * Types of secret keys.
+     */
+    public static class OtpType {
+
+        public static final OtpType TOTP = new OtpType(0); // time based
+        public static final OtpType HOTP = new OtpType(1); // counter based
+        private static final OtpType[] values = {TOTP, HOTP};
+        public final Integer value; // value as stored in database
+
+        OtpType(int value) {
+            this.value = new Integer(value);
+        }
+
+        public static OtpType getEnum(Integer i) {
+            for (int index = 0; index < values.length; index++) {
+                OtpType type = values[index];
+                if (type.value.intValue() == i.intValue()) {
+                    return type;
+                }
+            }
+            return null;
+        }
+
+        public static OtpType[] values() {
+            return values;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            if (this == TOTP) {
+                return "时间密码";
+            } else if (this == HOTP) {
+                return "次数密码";
+            } else {
+                return super.toString();
+            }
+        }
+    }
+    private String accountName;
+    private String secret;
+    private int interval = 30;
+    private long counter;
+    private OtpType otpType = OtpType.TOTP;
+
+    public String getAccountName() {
+        return accountName;
+    }
+
+    public void setAccountName(String accountName) {
+        this.accountName = accountName;
+    }
+
+    public long getCounter() {
+        return counter;
+    }
+
+    public void setCounter(long counter) {
+        this.counter = counter;
+    }
+
+    public int getInterval() {
+        return interval;
+    }
+
+    public void setInterval(int interval) {
+        this.interval = interval;
+    }
+
+    public OtpType getOtpType() {
+        return otpType;
+    }
+
+    public void setOtpType(OtpType otpType) {
+        this.otpType = otpType;
+    }
+
+    public String getSecret() {
+        return secret;
+    }
+
+    public void setSecret(String secret) {
+        this.secret = secret;
+    }
+
+    public void fromDataStream(DataInputStream din)
+            throws IOException {
+        accountName = din.readUTF();
+        secret = din.readUTF();
+        otpType = OtpType.getEnum(new Integer(din.readInt()));
+        interval = din.readInt();
+        counter = din.readLong();
+    }
+
+    public void toDataStream(DataOutputStream dout)
+            throws IOException {
+        dout.writeUTF(getAccountName());
+        dout.writeUTF(getSecret());
+        dout.writeInt(getOtpType().value.intValue());
+        dout.writeInt(getInterval());
+        dout.writeLong(getCounter());
+    }
+
+    public void fromByteArray(byte[] data) {
+        try {
+            ByteArrayInputStream bin = new ByteArrayInputStream(data);
+            DataInputStream din = new DataInputStream(bin);
+
+            fromDataStream(din);
+            din.close();
+        } catch (IOException ex) {
+            throw new RuntimeException("account from bytearray error");
+        }
+    }
+
+    public byte[] toByteArray() {
+        try {
+            ByteArrayOutputStream bout = new ByteArrayOutputStream();
+            DataOutputStream dout = new DataOutputStream(bout);
+
+            toDataStream(dout);
+            dout.close();
+
+            return bout.toByteArray();
+        } catch (IOException ex) {
+            throw new RuntimeException("account to bytearray error");
+        }
+    }
+}

File src/TokenGenerator/AccountDB.java

+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package TokenGenerator;
+
+import TokenGenerator.Account.OtpType;
+import javax.microedition.rms.*;
+import java.util.Vector;
+
+/**
+ *
+ * @author bruj0
+ */
+public class AccountDB {
+
+    public static final String ACCOUNTDB = "AccountDB";
+    private static Vector accounts;
+
+    static {
+        RecordStore rs = null;
+        try {
+            rs =
+                    RecordStore.openRecordStore(
+                    ACCOUNTDB, true);
+            System.out.println(rs == null);
+            if (rs.getNumRecords() > 0) {
+                loadAccounts(rs);
+            } else {
+                accounts = new Vector(5);
+            }
+        } catch (RecordStoreException rse) {
+            System.out.println(rse.getMessage());
+        } finally {
+            try {
+                rs.closeRecordStore();
+            } catch (Exception ex) {
+                ex.printStackTrace();
+            }
+        }
+    }
+
+    static private void loadAccounts(RecordStore rs) throws RecordStoreException {
+        final int numRecords = rs.getNumRecords();
+        accounts = new Vector(numRecords);
+        RecordEnumeration e = rs.enumerateRecords(null, null, false);
+        while (e.hasNextElement()) {
+            byte[] record = e.nextRecord();
+            Account acc = new Account();
+            acc.fromByteArray(record);
+            accounts.addElement(acc);
+        }
+    }
+
+    static private int getRecordID(RecordStore rs, final String name) throws RecordStoreException {
+        RecordEnumeration e = rs.enumerateRecords(new RecordFilter() {
+
+            public boolean matches(byte[] candidate) {
+                Account acc = new Account();
+                acc.fromByteArray(candidate);
+                return acc.getAccountName().equals(name);
+            }
+        }, null, false);
+        if (e.hasNextElement()) {
+            return e.nextRecordId();
+        }
+        throw new RuntimeException("record id not found");
+    }
+
+    static String[] getAccountNames() {
+        String[] names = new String[accounts.size()];
+        for (int i = 0; i < accounts.size(); i++) {
+            final Account acc = (Account) accounts.elementAt(i);
+            names[i] = acc.getAccountName();
+        }
+        return names;
+    }
+
+    static Account getAccount(String name) {
+        if (name != null) {
+
+            for (int i = 0; i < accounts.size(); i++) {
+                final Account acc = (Account) accounts.elementAt(i);
+                if (acc.getAccountName().equals(name)) {
+                    return acc;
+                }
+            }
+        }
+        return null;
+    }
+
+    static int getAccountIndex(String name) {
+        if (name != null) {
+            for (int i = 0; i < accounts.size(); i++) {
+                final Account acc = (Account) accounts.elementAt(i);
+                if (acc.getAccountName().equals(name)) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
+    static String getSecret(String name) {
+        Account acc = getAccount(name);
+        return acc != null ? acc.getSecret() : null;
+    }
+
+    static OtpType getOtpType(String name) {
+        Account acc = getAccount(name);
+        return acc != null ? acc.getOtpType() : null;
+    }
+
+    static int getInterval(String name) {
+        Account acc = getAccount(name);
+        return acc != null ? acc.getInterval() : 30;
+    }
+
+    static long getCounter(String name) {
+        Account acc = getAccount(name);
+        return acc != null ? acc.getCounter() : 0L;
+    }
+
+    static boolean nameExists(String accountName) {
+        return getAccount(accountName) != null;
+    }
+
+    private AccountDB() {
+    }
+
+    static public void update(String oldname, String name, String secret, OtpType type, int interval, long counter) {
+        int index = getAccountIndex(oldname);
+        Account acc = oldname != null ? (Account) accounts.elementAt(index) : null;
+        if (acc == null) {
+            acc = new Account();
+            index = -1;
+        }
+        acc.setAccountName(name);
+        acc.setSecret(secret);
+        acc.setOtpType(type);
+        acc.setInterval(interval);
+        acc.setCounter(counter);
+        RecordStore rs = null;
+        try {
+            rs = RecordStore.openRecordStore(
+                    ACCOUNTDB, true);
+            if (index < 0) {
+                final byte[] out = acc.toByteArray();
+
+                rs.addRecord(out, 0, out.length);
+                accounts.addElement(acc);
+            } else {
+                final byte[] out = acc.toByteArray();
+                rs.setRecord(getRecordID(rs, oldname), out, 0, out.length);
+            }
+
+        } catch (RecordStoreException rse) {
+            throw new RuntimeException("delete account error");
+        } finally {
+            try {
+                rs.closeRecordStore();
+            } catch (Exception ex) {
+                ex.printStackTrace();
+            }
+        }
+
+    }
+
+    public static void delete(String name) {
+        int index = getAccountIndex(name);
+        if (index > -1) {
+            RecordStore rs = null;
+            try {
+                rs = RecordStore.openRecordStore(
+                        ACCOUNTDB, true);
+                rs.deleteRecord(getRecordID(rs, name));
+                accounts.removeElementAt(index);
+            } catch (RecordStoreException rse) {
+                throw new RuntimeException("delete account error");
+            } finally {
+                try {
+                    rs.closeRecordStore();
+                } catch (Exception ex) {
+                    ex.printStackTrace();
+                }
+            }
+        }
+    }
+}

File src/TokenGenerator/Base32.java

  * To change this template, choose Tools | Templates
  * and open the template in the editor.
  */
-
 package TokenGenerator;
 
 /**
  *
  * @author bruj0
  */
+public class Base32 {
 
-public class Base32
-{
     private static final String base32Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
     private static final int[] base32Lookup = {
         0xFF, 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
      * @return Encoded byte array <code>bytes</code> as a String.
      *
      */
-    static public String encode(final byte[] bytes)
-    {
+    static public String encode(final byte[] bytes) {
         int i = 0, index = 0, digit = 0;
         int currByte, nextByte;
         StringBuffer base32 = new StringBuffer((bytes.length + 7) * 8 / 5);
 
-        while (i < bytes.length)
-        {
+        while (i < bytes.length) {
             currByte = (bytes[i] >= 0) ? bytes[i] : (bytes[i] + 256); // unsign
 
             /* Is the current digit going to span a byte boundary? */
-            if (index > 3)
-            {
-                if ((i + 1) < bytes.length)
-                {
+            if (index > 3) {
+                if ((i + 1) < bytes.length) {
                     nextByte = (bytes[i + 1] >= 0) ? bytes[i + 1] : (bytes[i + 1] + 256);
-                }
-                else
-                {
+                } else {
                     nextByte = 0;
                 }
 
                 digit <<= index;
                 digit |= nextByte >> (8 - index);
                 i++;
-            }
-            else
-            {
+            } else {
                 digit = (currByte >> (8 - (index + 5))) & 0x1F;
                 index = (index + 5) % 8;
-                if (index == 0)
+                if (index == 0) {
                     i++;
+                }
             }
             base32.append(base32Chars.charAt(digit));
         }
      * @param base32
      * @return Decoded <code>base32</code> String as a raw byte array.
      */
-    static public byte[] decode(final String base32)
-    {
+    static public byte[] decode(final String base32) {
         int i, index, lookup, offset, digit;
         byte[] bytes = new byte[base32.length() * 5 / 8];
 
-        for (i = 0, index = 0, offset = 0; i < base32.length(); i++)
-        {
+        for (i = 0, index = 0, offset = 0; i < base32.length(); i++) {
             lookup = base32.charAt(i) - '0';
 
             /* Skip chars outside the lookup table */
-            if (lookup < 0 || lookup >= base32Lookup.length)
-            {
+            if (lookup < 0 || lookup >= base32Lookup.length) {
                 continue;
             }
 
             digit = base32Lookup[lookup];
 
             /* If this digit is not in the table, ignore it */
-            if (digit == 0xFF)
-            {
+            if (digit == 0xFF) {
                 continue;
             }
 
-            if (index <= 3)
-            {
+            if (index <= 3) {
                 index = (index + 5) % 8;
-                if (index == 0)
-                {
+                if (index == 0) {
                     bytes[offset] |= digit;
                     offset++;
-                    if (offset >= bytes.length)
+                    if (offset >= bytes.length) {
                         break;
-                }
-                else
-                {
+                    }
+                } else {
                     bytes[offset] |= digit << (8 - index);
                 }
-            }
-            else
-            {
+            } else {
                 index = (index + 5) % 8;
                 bytes[offset] |= (digit >>> index);
                 offset++;
 
-                if (offset >= bytes.length)
-                {
+                if (offset >= bytes.length) {
                     break;
                 }
                 bytes[offset] |= digit << (8 - index);

File src/TokenGenerator/Main.java

  * To change this template, choose Tools | Templates
  * and open the template in the editor.
  */
+package TokenGenerator;
 
-package TokenGenerator;
-import java.util.*;
-
-
+import TokenGenerator.Account.OtpType;
 import javax.microedition.midlet.*;
 import javax.microedition.lcdui.*;
-import javax.microedition.rms.*;
-import java.io.*;
-
+import javax.microedition.rms.RecordStoreException;
+import javax.microedition.rms.RecordStoreNotOpenException;
 
 /**
  * @author bruj0
 public class Main extends MIDlet implements CommandListener {
 
     private boolean midletPaused = false;
-
     //<editor-fold defaultstate="collapsed" desc=" Generated Fields ">//GEN-BEGIN:|fields|0|
+    private Command exitCommand;
+    private Command itemCommand;
     private Command CancelCommand;
     private Command OKCommand;
-    private Command exitCommand;
-    private Command itemCommand;
     private Command exitCommand1;
+    private Command addCommand;
     private Command okCommand;
-    private Command itemCommand1;
+    private Command okCommand1;
+    private Command deleteCommand;
+    private Command cancelCommand1;
+    private Command editCommand;
+    private Command okCommand2;
+    private Command reCalcTokenCommand;
     private Form passForm;
     private StringItem tokenStringItem;
     private Form addForm;
     private TextField secretTextfield;
     private TextField accountNameTextField;
+    private TextField counterField;
+    private TextField intervalField;
+    private ChoiceGroup otyType;
     private List accountList;
+    private Alert alert;
+    private Form deleteForm;
+    private StringItem deleteAccountName;
+    private StringItem stringItem;
     //</editor-fold>//GEN-END:|fields|0|
-    private StockDB db = null;
-
-
+    private String oldName;
 
     /**
      * The HelloMIDlet constructor.
      */
     public Main() {
-        
-
     }
 
+    private void updateAccount() {
+        // write pre-action user code here
+        try {
+            String tokenKey = getSecretTextfield().getString();
+            String accountName = getAccountNameTextField().getString();
+            if (tokenKey.length() == 0) {
+                throw new RuntimeException("密钥不能为空");
+            }
+            if (accountName.length() == 0) {
+                throw new RuntimeException("帐号名不能为空");
+            }
+            if (oldName == null || oldName.equals(accountName) == false) {
+                if (AccountDB.nameExists(accountName)) {
+                    throw new RuntimeException("帐号名不能重复");
+                }
+            }
+            OtpType otpType = OtpType.getEnum(new Integer(getOtyType().getSelectedIndex()));
+            int interval = Integer.valueOf(getIntervalField().getString()).intValue();
+            long counter = Long.parseLong(getCounterField().getString());
+
+            AccountDB.update(oldName, accountName, tokenKey, otpType, interval, counter);
+            refreshAccountList();
+            switchDisplayable(null, getAccountList());
+        } catch (Exception e) {
+            getAlert().setString(e.getMessage());
+            switchDisplayable(null, getAlert());
+        }
+    }
+
+    private void editAccount() {
+        oldName = getAccountList().getString(getAccountList().getSelectedIndex());
+        getAccountNameTextField().setString(oldName);
+        getSecretTextfield().setString(AccountDB.getSecret(oldName));
+        getOtyType().setSelectedIndex(AccountDB.getOtpType(oldName).value.intValue(), true);
+        getIntervalField().setString(String.valueOf(AccountDB.getInterval(oldName)));
+        getCounterField().setString(String.valueOf(AccountDB.getCounter(oldName)));
+        switchDisplayable(null, getAddForm());
+    }
+
+    private void deleteAccount() {
+        oldName = getAccountList().getString(getAccountList().getSelectedIndex());
+        getDeleteAccountName().setText(oldName);
+        switchDisplayable(null, getDeleteForm());
+    }
     //<editor-fold defaultstate="collapsed" desc=" Generated Methods ">//GEN-BEGIN:|methods|0|
     //</editor-fold>//GEN-END:|methods|0|
-
     //<editor-fold defaultstate="collapsed" desc=" Generated Method: initialize ">//GEN-BEGIN:|0-initialize|0|0-preInitialize
     /**
      * Initializes the application.
     private void initialize() {//GEN-END:|0-initialize|0|0-preInitialize
         // write pre-initialize user code here
 
-            timer = new Timer();
-            timerTaskOne = new MyTimerTask();
-            timer.schedule(timerTaskOne, 0, 1000);
-            db = new StockDB("TokenKey");
-            TokenKey = db.readRecord(1);
-            TokenGen = new TokenGen(TokenKey);
-            tokenStringItem = new StringItem("\u5BC6\u7801:", "");//GEN-BEGIN:|0-initialize|1|0-postInitialize
-            tokenStringItem.setLayout(StringItem.LAYOUT_CENTER | StringItem.LAYOUT_VCENTER);//GEN-END:|0-initialize|1|0-postInitialize
+
+        stringItem = new StringItem("\u786E\u8BA4\u5220\u9664\u4EE5\u4E0B\u5E10\u53F7\u5417\uFF1F", null);//GEN-LINE:|0-initialize|1|0-postInitialize
         // write post-initialize user code here
     }//GEN-BEGIN:|0-initialize|2|
     //</editor-fold>//GEN-END:|0-initialize|2|
                 // write pre-action user code here
                 accountListAction();//GEN-LINE:|7-commandAction|2|76-postAction
                 // write post-action user code here
-            } else if (command == exitCommand1) {//GEN-LINE:|7-commandAction|3|80-preAction
+            } else if (command == addCommand) {//GEN-LINE:|7-commandAction|3|86-preAction
                 // write pre-action user code here
-                exitMIDlet();//GEN-LINE:|7-commandAction|4|80-postAction
+                oldName = null;
+                getAccountNameTextField().setString(oldName);
+                getSecretTextfield().setString(oldName);
+                getOtyType().setSelectedIndex(0, true);
+                getIntervalField().setString("30");
+                getCounterField().setString("0");
+                switchDisplayable(null, getAddForm());
+//GEN-LINE:|7-commandAction|4|86-postAction
                 // write post-action user code here
-            } else if (command == itemCommand1) {//GEN-LINE:|7-commandAction|5|86-preAction
+            } else if (command == deleteCommand) {//GEN-LINE:|7-commandAction|5|104-preAction
                 // write pre-action user code here
-                switchDisplayable(null, getAddForm());//GEN-LINE:|7-commandAction|6|86-postAction
+                deleteAccount();
+//GEN-LINE:|7-commandAction|6|104-postAction
                 // write post-action user code here
-            } else if (command == okCommand) {//GEN-LINE:|7-commandAction|7|83-preAction
+            } else if (command == editCommand) {//GEN-LINE:|7-commandAction|7|107-preAction
                 // write pre-action user code here
-                switchDisplayable(null, getPassForm());//GEN-LINE:|7-commandAction|8|83-postAction
+                editAccount();
+//GEN-LINE:|7-commandAction|8|107-postAction
                 // write post-action user code here
-            }//GEN-BEGIN:|7-commandAction|9|69-preAction
+            } else if (command == exitCommand1) {//GEN-LINE:|7-commandAction|9|80-preAction
+                // write pre-action user code here
+                exitMIDlet();//GEN-LINE:|7-commandAction|10|80-postAction
+                // write post-action user code here
+            } else if (command == okCommand) {//GEN-LINE:|7-commandAction|11|83-preAction
+                // write pre-action user code here
+                oldName = getAccountList().getString(getAccountList().getSelectedIndex());
+                getTokenStringItem().setText(TokenGen.computePin(AccountDB.getSecret(oldName), null));
+                switchDisplayable(null, getPassForm());//GEN-LINE:|7-commandAction|12|83-postAction
+                // write post-action user code here
+            }//GEN-BEGIN:|7-commandAction|13|69-preAction
         } else if (displayable == addForm) {
-            if (command == CancelCommand) {//GEN-END:|7-commandAction|9|69-preAction
+            if (command == CancelCommand) {//GEN-END:|7-commandAction|13|69-preAction
                 // write pre-action user code here
 
-                switchDisplayable(null, getAccountList());//GEN-LINE:|7-commandAction|10|69-postAction
+                switchDisplayable(null, getAccountList());//GEN-LINE:|7-commandAction|14|69-postAction
                 // write post-action user code here
-            } else if (command == OKCommand) {//GEN-LINE:|7-commandAction|11|66-preAction
+            } else if (command == OKCommand) {//GEN-LINE:|7-commandAction|15|66-preAction
+                // 添加帐号
+                updateAccount();
+//GEN-LINE:|7-commandAction|16|66-postAction
+                // write post-action user code here
+            }//GEN-BEGIN:|7-commandAction|17|92-preAction
+        } else if (displayable == alert) {
+            if (command == okCommand1) {//GEN-END:|7-commandAction|17|92-preAction
                 // write pre-action user code here
-                //TokenKey = secretTextfield.getString();
-                /*if(TokenKey.length() > 0)
-                {
-                    String tmp="newToken="+TokenKey;
-                    form1.append(tmp);
-                }*/
-                //TokenGen.setKey(TokenKey);
-                //db.saveRecord(TokenKey);
-                switchDisplayable(null, getAccountList());//GEN-LINE:|7-commandAction|12|66-postAction
+                switchDisplayable(null, getAddForm());//GEN-LINE:|7-commandAction|18|92-postAction
                 // write post-action user code here
-            }//GEN-BEGIN:|7-commandAction|13|19-preAction
+            }//GEN-BEGIN:|7-commandAction|19|111-preAction
+        } else if (displayable == deleteForm) {
+            if (command == cancelCommand1) {//GEN-END:|7-commandAction|19|111-preAction
+                // write pre-action user code here
+                switchDisplayable(null, getAccountList());//GEN-LINE:|7-commandAction|20|111-postAction
+                // write post-action user code here
+            } else if (command == okCommand2) {//GEN-LINE:|7-commandAction|21|113-preAction
+                // write pre-action user code here
+                AccountDB.delete(oldName);
+                refreshAccountList();
+                switchDisplayable(null, getAccountList());//GEN-LINE:|7-commandAction|22|113-postAction
+                // write post-action user code here
+            }//GEN-BEGIN:|7-commandAction|23|19-preAction
         } else if (displayable == passForm) {
-            if (command == exitCommand) {//GEN-END:|7-commandAction|13|19-preAction
+            if (command == exitCommand) {//GEN-END:|7-commandAction|23|19-preAction
                 // write pre-action user code here
-                switchDisplayable(null, getAccountList());//GEN-LINE:|7-commandAction|14|19-postAction
+                switchDisplayable(null, getAccountList());//GEN-LINE:|7-commandAction|24|19-postAction
                 // write post-action user code here
-            }//GEN-BEGIN:|7-commandAction|15|7-postCommandAction
-        }//GEN-END:|7-commandAction|15|7-postCommandAction
+            } else if (command == reCalcTokenCommand) {//GEN-LINE:|7-commandAction|25|118-preAction
+                // write pre-action user code here
+                getTokenStringItem().setText(TokenGen.computePin(AccountDB.getSecret(oldName), null));
+//GEN-LINE:|7-commandAction|26|118-postAction
+                // write post-action user code here
+            }//GEN-BEGIN:|7-commandAction|27|7-postCommandAction
+        }//GEN-END:|7-commandAction|27|7-postCommandAction
         // write post-action user code here
-    }//GEN-BEGIN:|7-commandAction|16|
-    //</editor-fold>//GEN-END:|7-commandAction|16|
-
-
-
+    }//GEN-BEGIN:|7-commandAction|28|
+    //</editor-fold>//GEN-END:|7-commandAction|28|
 
     //<editor-fold defaultstate="collapsed" desc=" Generated Getter: exitCommand ">//GEN-BEGIN:|18-getter|0|18-preInit
     /**
     public Form getPassForm() {
         if (passForm == null) {//GEN-END:|14-getter|0|14-preInit
             // write pre-init user code here
-            
-            passForm = new Form("\u5BC6\u7801\u751F\u6210\u5668", new Item[] { tokenStringItem });//GEN-BEGIN:|14-getter|1|14-postInit
+
+            passForm = new Form("\u5BC6\u7801\u751F\u6210\u5668", new Item[] { getTokenStringItem() });//GEN-BEGIN:|14-getter|1|14-postInit
             passForm.addCommand(getExitCommand());
+            passForm.addCommand(getReCalcTokenCommand());
             passForm.setCommandListener(this);//GEN-END:|14-getter|1|14-postInit
             // write post-init user code here
+
         }//GEN-BEGIN:|14-getter|2|
         return passForm;
     }
     //</editor-fold>//GEN-END:|14-getter|2|
-    //</editor-fold>
-
-
-
-
-
-
 
     //<editor-fold defaultstate="collapsed" desc=" Generated Getter: itemCommand ">//GEN-BEGIN:|59-getter|0|59-preInit
     /**
     public Form getAddForm() {
         if (addForm == null) {//GEN-END:|61-getter|0|61-preInit
             // write pre-init user code here
-            addForm = new Form("\u6DFB\u52A0\u5E10\u53F7", new Item[] { getAccountNameTextField(), getSecretTextfield() });//GEN-BEGIN:|61-getter|1|61-postInit
+            addForm = new Form("\u6DFB\u52A0\u5E10\u53F7", new Item[] { getAccountNameTextField(), getSecretTextfield(), getOtyType(), getIntervalField(), getCounterField() });//GEN-BEGIN:|61-getter|1|61-postInit
             addForm.addCommand(getOKCommand());
             addForm.addCommand(getCancelCommand());
             addForm.setCommandListener(this);//GEN-END:|61-getter|1|61-postInit
     }
     //</editor-fold>//GEN-END:|61-getter|2|
 
-
-
     //<editor-fold defaultstate="collapsed" desc=" Generated Getter: secretTextfield ">//GEN-BEGIN:|71-getter|0|71-preInit
     /**
      * Returns an initiliazed instance of secretTextfield component.
             accountList = new List("\u5E10\u53F7\u5217\u8868", Choice.IMPLICIT);//GEN-BEGIN:|74-getter|1|74-postInit
             accountList.addCommand(getExitCommand1());
             accountList.addCommand(getOkCommand());
-            accountList.addCommand(getItemCommand1());
-            accountList.setCommandListener(this);//GEN-END:|74-getter|1|74-postInit
+            accountList.addCommand(getAddCommand());
+            accountList.addCommand(getDeleteCommand());
+            accountList.addCommand(getEditCommand());
+            accountList.setCommandListener(this);
+            accountList.setFitPolicy(Choice.TEXT_WRAP_DEFAULT);
+            accountList.setSelectedFlags(new boolean[] {  });//GEN-END:|74-getter|1|74-postInit
             // write post-init user code here
+            refreshAccountList();
         }//GEN-BEGIN:|74-getter|2|
         return accountList;
     }
     }
     //</editor-fold>//GEN-END:|82-getter|2|
 
-    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: itemCommand1 ">//GEN-BEGIN:|85-getter|0|85-preInit
+    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: addCommand ">//GEN-BEGIN:|85-getter|0|85-preInit
     /**
-     * Returns an initiliazed instance of itemCommand1 component.
+     * Returns an initiliazed instance of addCommand component.
      * @return the initialized component instance
      */
-    public Command getItemCommand1() {
-        if (itemCommand1 == null) {//GEN-END:|85-getter|0|85-preInit
+    public Command getAddCommand() {
+        if (addCommand == null) {//GEN-END:|85-getter|0|85-preInit
             // write pre-init user code here
-            itemCommand1 = new Command("\u6DFB\u52A0\u5E10\u53F7", Command.ITEM, 0);//GEN-LINE:|85-getter|1|85-postInit
+            addCommand = new Command("\u6DFB\u52A0\u5E10\u53F7", Command.ITEM, 0);//GEN-LINE:|85-getter|1|85-postInit
             // write post-init user code here
         }//GEN-BEGIN:|85-getter|2|
-        return itemCommand1;
+        return addCommand;
     }
     //</editor-fold>//GEN-END:|85-getter|2|
 
     }
     //</editor-fold>//GEN-END:|88-getter|2|
 
+    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: tokenStringItem ">//GEN-BEGIN:|89-getter|0|89-preInit
+    /**
+     * Returns an initiliazed instance of tokenStringItem component.
+     * @return the initialized component instance
+     */
+    public StringItem getTokenStringItem() {
+        if (tokenStringItem == null) {//GEN-END:|89-getter|0|89-preInit
+            // write pre-init user code here
+            tokenStringItem = new StringItem("\u5BC6\u7801\uFF1A", null, Item.PLAIN);//GEN-BEGIN:|89-getter|1|89-postInit
+            tokenStringItem.setLayout(ImageItem.LAYOUT_CENTER | Item.LAYOUT_TOP | Item.LAYOUT_BOTTOM | Item.LAYOUT_VCENTER);//GEN-END:|89-getter|1|89-postInit
+            // write post-init user code here
+        }//GEN-BEGIN:|89-getter|2|
+        return tokenStringItem;
+    }
+    //</editor-fold>//GEN-END:|89-getter|2|
 
+    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: okCommand1 ">//GEN-BEGIN:|91-getter|0|91-preInit
+    /**
+     * Returns an initiliazed instance of okCommand1 component.
+     * @return the initialized component instance
+     */
+    public Command getOkCommand1() {
+        if (okCommand1 == null) {//GEN-END:|91-getter|0|91-preInit
+            // write pre-init user code here
+            okCommand1 = new Command("\u786E\u5B9A", Command.OK, 0);//GEN-LINE:|91-getter|1|91-postInit
+            // write post-init user code here
+        }//GEN-BEGIN:|91-getter|2|
+        return okCommand1;
+    }
+    //</editor-fold>//GEN-END:|91-getter|2|
 
+    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: alert ">//GEN-BEGIN:|90-getter|0|90-preInit
+    /**
+     * Returns an initiliazed instance of alert component.
+     * @return the initialized component instance
+     */
+    public Alert getAlert() {
+        if (alert == null) {//GEN-END:|90-getter|0|90-preInit
+            // write pre-init user code here
+            alert = new Alert("\u9519\u8BEF", "\u5E10\u53F7\u540D\u548C\u5BC6\u94A5\u4E0D\u80FD\u4E3A\u7A7A", null, AlertType.ERROR);//GEN-BEGIN:|90-getter|1|90-postInit
+            alert.addCommand(getOkCommand1());
+            alert.setCommandListener(this);
+            alert.setTimeout(Alert.FOREVER);//GEN-END:|90-getter|1|90-postInit
+            // write post-init user code here
+        }//GEN-BEGIN:|90-getter|2|
+        return alert;
+    }
+    //</editor-fold>//GEN-END:|90-getter|2|
 
-    //</editor-fold>
+    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: otyType ">//GEN-BEGIN:|96-getter|0|96-preInit
+    /**
+     * Returns an initiliazed instance of otyType component.
+     * @return the initialized component instance
+     */
+    public ChoiceGroup getOtyType() {
+        if (otyType == null) {//GEN-END:|96-getter|0|96-preInit
+            // write pre-init user code here
+            otyType = new ChoiceGroup("\u7C7B\u578B", Choice.EXCLUSIVE);//GEN-BEGIN:|96-getter|1|96-postInit
+            otyType.append("\u65F6\u95F4\u5BC6\u7801", null);
+            otyType.append("\u6B21\u6570\u5BC6\u7801", null);
+            otyType.setSelectedFlags(new boolean[] { true, false });//GEN-END:|96-getter|1|96-postInit
+            // write post-init user code here
+        }//GEN-BEGIN:|96-getter|2|
+        return otyType;
+    }
+    //</editor-fold>//GEN-END:|96-getter|2|
 
+    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: intervalField ">//GEN-BEGIN:|101-getter|0|101-preInit
+    /**
+     * Returns an initiliazed instance of intervalField component.
+     * @return the initialized component instance
+     */
+    public TextField getIntervalField() {
+        if (intervalField == null) {//GEN-END:|101-getter|0|101-preInit
+            // write pre-init user code here
+            intervalField = new TextField("\u65F6\u95F4\u95F4\u9694:", "30", 32, TextField.NUMERIC);//GEN-LINE:|101-getter|1|101-postInit
+            // write post-init user code here
+        }//GEN-BEGIN:|101-getter|2|
+        return intervalField;
+    }
+    //</editor-fold>//GEN-END:|101-getter|2|
 
+    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: counterField ">//GEN-BEGIN:|102-getter|0|102-preInit
+    /**
+     * Returns an initiliazed instance of counterField component.
+     * @return the initialized component instance
+     */
+    public TextField getCounterField() {
+        if (counterField == null) {//GEN-END:|102-getter|0|102-preInit
+            // write pre-init user code here
+            counterField = new TextField("\u5F53\u524D\u8BA1\u6570:", "0", 32, TextField.NUMERIC);//GEN-LINE:|102-getter|1|102-postInit
+            // write post-init user code here
+        }//GEN-BEGIN:|102-getter|2|
+        return counterField;
+    }
+    //</editor-fold>//GEN-END:|102-getter|2|
 
+    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: deleteCommand ">//GEN-BEGIN:|103-getter|0|103-preInit
+    /**
+     * Returns an initiliazed instance of deleteCommand component.
+     * @return the initialized component instance
+     */
+    public Command getDeleteCommand() {
+        if (deleteCommand == null) {//GEN-END:|103-getter|0|103-preInit
+            // write pre-init user code here
+            deleteCommand = new Command("\u5220\u9664", Command.ITEM, 0);//GEN-LINE:|103-getter|1|103-postInit
+            // write post-init user code here
+        }//GEN-BEGIN:|103-getter|2|
+        return deleteCommand;
+    }
+    //</editor-fold>//GEN-END:|103-getter|2|
 
+    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: editCommand ">//GEN-BEGIN:|106-getter|0|106-preInit
+    /**
+     * Returns an initiliazed instance of editCommand component.
+     * @return the initialized component instance
+     */
+    public Command getEditCommand() {
+        if (editCommand == null) {//GEN-END:|106-getter|0|106-preInit
+            // write pre-init user code here
+            editCommand = new Command("\u7F16\u8F91", Command.ITEM, 0);//GEN-LINE:|106-getter|1|106-postInit
+            // write post-init user code here
+        }//GEN-BEGIN:|106-getter|2|
+        return editCommand;
+    }
+    //</editor-fold>//GEN-END:|106-getter|2|
 
+    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: cancelCommand1 ">//GEN-BEGIN:|110-getter|0|110-preInit
+    /**
+     * Returns an initiliazed instance of cancelCommand1 component.
+     * @return the initialized component instance
+     */
+    public Command getCancelCommand1() {
+        if (cancelCommand1 == null) {//GEN-END:|110-getter|0|110-preInit
+            // write pre-init user code here
+            cancelCommand1 = new Command("\u53D6\u6D88", Command.CANCEL, 0);//GEN-LINE:|110-getter|1|110-postInit
+            // write post-init user code here
+        }//GEN-BEGIN:|110-getter|2|
+        return cancelCommand1;
+    }
+    //</editor-fold>//GEN-END:|110-getter|2|
 
-    //</editor-fold>
+    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: okCommand2 ">//GEN-BEGIN:|112-getter|0|112-preInit
+    /**
+     * Returns an initiliazed instance of okCommand2 component.
+     * @return the initialized component instance
+     */
+    public Command getOkCommand2() {
+        if (okCommand2 == null) {//GEN-END:|112-getter|0|112-preInit
+            // write pre-init user code here
+            okCommand2 = new Command("\u786E\u5B9A", Command.OK, 0);//GEN-LINE:|112-getter|1|112-postInit
+            // write post-init user code here
+        }//GEN-BEGIN:|112-getter|2|
+        return okCommand2;
+    }
+    //</editor-fold>//GEN-END:|112-getter|2|
 
+    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: deleteForm ">//GEN-BEGIN:|108-getter|0|108-preInit
+    /**
+     * Returns an initiliazed instance of deleteForm component.
+     * @return the initialized component instance
+     */
+    public Form getDeleteForm() {
+        if (deleteForm == null) {//GEN-END:|108-getter|0|108-preInit
+            // write pre-init user code here
+            deleteForm = new Form("\u5220\u9664\u5E10\u53F7", new Item[] { stringItem, getDeleteAccountName() });//GEN-BEGIN:|108-getter|1|108-postInit
+            deleteForm.addCommand(getCancelCommand1());
+            deleteForm.addCommand(getOkCommand2());
+            deleteForm.setCommandListener(this);//GEN-END:|108-getter|1|108-postInit
+            // write post-init user code here
+        }//GEN-BEGIN:|108-getter|2|
+        return deleteForm;
+    }
+    //</editor-fold>//GEN-END:|108-getter|2|
 
+    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: deleteAccountName ">//GEN-BEGIN:|109-getter|0|109-preInit
+    /**
+     * Returns an initiliazed instance of deleteAccountName component.
+     * @return the initialized component instance
+     */
+    public StringItem getDeleteAccountName() {
+        if (deleteAccountName == null) {//GEN-END:|109-getter|0|109-preInit
+            // write pre-init user code here
+            deleteAccountName = new StringItem("\u5E10\u53F7\u540D:", null);//GEN-LINE:|109-getter|1|109-postInit
+            // write post-init user code here
+        }//GEN-BEGIN:|109-getter|2|
+        return deleteAccountName;
+    }
+    //</editor-fold>//GEN-END:|109-getter|2|
 
-
-    //</editor-fold>
-
-
-
-
-
-
-
-
-
-
+    //<editor-fold defaultstate="collapsed" desc=" Generated Getter: reCalcTokenCommand ">//GEN-BEGIN:|117-getter|0|117-preInit
+    /**
+     * Returns an initiliazed instance of reCalcTokenCommand component.
+     * @return the initialized component instance
+     */
+    public Command getReCalcTokenCommand() {
+        if (reCalcTokenCommand == null) {//GEN-END:|117-getter|0|117-preInit
+            // write pre-init user code here
+            reCalcTokenCommand = new Command("\u786E\u5B9A", Command.OK, 0);//GEN-LINE:|117-getter|1|117-postInit
+            // write post-init user code here
+        }//GEN-BEGIN:|117-getter|2|
+        return reCalcTokenCommand;
+    }
+    //</editor-fold>//GEN-END:|117-getter|2|
 
     /**
      * Returns a display instance.
      * @return the display instance.
      */
-    public Display getDisplay () {
+    public Display getDisplay() {
         return Display.getDisplay(this);
     }
 
      * Exits MIDlet.
      */
     public void exitMIDlet() {
-        switchDisplayable (null, null);
+        switchDisplayable(null, null);
         destroyApp(true);
         notifyDestroyed();
     }
      */
     public void startApp() {
         if (midletPaused) {
-            resumeMIDlet ();
+            resumeMIDlet();
         } else {
-            initialize ();
-            startMIDlet ();
+            initialize();
+            startMIDlet();
         }
         midletPaused = false;
     }
      * @param unconditional if true, then the MIDlet has to be unconditionally terminated and all resources has to be released.
      */
     public void destroyApp(boolean unconditional) {
-         try {
-        db.close();
-      } catch(Exception e) {}
     }
 
+    private void refreshAccountList() {
+        accountList.deleteAll();
+        String[] names = AccountDB.getAccountNames();
+        for (int i = 0; i < names.length; i++) {
+            accountList.append(names[i], null);
+        }
+    }
 }

File src/TokenGenerator/Main.vmd

                 <Component componentID="17" typeID="C#ItemCommandListener"/>
             </Component>
             <Component componentID="8" typeID="C#CommandsCategory">
-                <Component componentID="68" typeID="Cjavax.microedition.lcdui.Command">
-                    <Property name="instanceName" typeID="Pjava.lang.String" value="VCancelCommand"/>
-                    <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
-                    <Property name="label" typeID="Pjava.lang.String" value="V取消"/>
-                    <Property name="type" typeID="Pint" value="V3"/>
-                </Component>
-                <Component componentID="65" typeID="Cjavax.microedition.lcdui.Command">
-                    <Property name="instanceName" typeID="Pjava.lang.String" value="VOKCommand"/>
-                    <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
-                    <Property name="label" typeID="Pjava.lang.String" value="V确定"/>
-                    <Property name="type" typeID="Pint" value="V4"/>
-                </Component>
-                <Component componentID="73" typeID="C#PIMBrowserOpenCommand">
-                    <Property name="label" typeID="Pjava.lang.String" value="VOpen"/>
-                    <Property name="type" typeID="Pint" value="V4"/>
-                    <Property name="priority" typeID="Pint" value="V0"/>
-                    <Property name="ordinary" typeID="Pboolean" value="Vfalse"/>
-                </Component>
                 <Component componentID="18" typeID="Cjavax.microedition.lcdui.Command">
                     <Property name="instanceName" typeID="Pjava.lang.String" value="VexitCommand"/>
                     <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
                     <Property name="longLabel" typeID="Pjava.lang.String" value="VNew Key"/>
                     <Property name="type" typeID="Pint" value="V8"/>
                 </Component>
-                <Component componentID="75" typeID="C#ListSelectCommand">
-                    <Property name="label" typeID="Pjava.lang.String" value="V"/>
-                    <Property name="type" typeID="Pint" value="V1"/>
-                    <Property name="priority" typeID="Pint" value="V0"/>
-                    <Property name="ordinary" typeID="Pboolean" value="Vfalse"/>
+                <Component componentID="68" typeID="Cjavax.microedition.lcdui.Command">
+                    <Property name="instanceName" typeID="Pjava.lang.String" value="VCancelCommand"/>
+                    <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
+                    <Property name="label" typeID="Pjava.lang.String" value="V取消"/>
+                    <Property name="type" typeID="Pint" value="V3"/>
+                </Component>
+                <Component componentID="65" typeID="Cjavax.microedition.lcdui.Command">
+                    <Property name="instanceName" typeID="Pjava.lang.String" value="VOKCommand"/>
+                    <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
+                    <Property name="label" typeID="Pjava.lang.String" value="V确定"/>
+                    <Property name="type" typeID="Pint" value="V4"/>
                 </Component>
                 <Component componentID="79" typeID="Cjavax.microedition.lcdui.Command">
                     <Property name="instanceName" typeID="Pjava.lang.String" value="VexitCommand1"/>
                     <Property name="label" typeID="Pjava.lang.String" value="V退出"/>
                     <Property name="type" typeID="Pint" value="V7"/>
                 </Component>
+                <Component componentID="73" typeID="C#PIMBrowserOpenCommand">
+                    <Property name="label" typeID="Pjava.lang.String" value="VOpen"/>
+                    <Property name="type" typeID="Pint" value="V4"/>
+                    <Property name="priority" typeID="Pint" value="V0"/>
+                    <Property name="ordinary" typeID="Pboolean" value="Vfalse"/>
+                </Component>
+                <Component componentID="75" typeID="C#ListSelectCommand">
+                    <Property name="label" typeID="Pjava.lang.String" value="V"/>
+                    <Property name="type" typeID="Pint" value="V1"/>
+                    <Property name="priority" typeID="Pint" value="V0"/>
+                    <Property name="ordinary" typeID="Pboolean" value="Vfalse"/>
+                </Component>
+                <Component componentID="85" typeID="Cjavax.microedition.lcdui.Command">
+                    <Property name="instanceName" typeID="Pjava.lang.String" value="VaddCommand"/>
+                    <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
+                    <Property name="label" typeID="Pjava.lang.String" value="V添加帐号"/>
+                    <Property name="type" typeID="Pint" value="V8"/>
+                </Component>
                 <Component componentID="82" typeID="Cjavax.microedition.lcdui.Command">
                     <Property name="instanceName" typeID="Pjava.lang.String" value="VokCommand"/>
                     <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
                     <Property name="label" typeID="Pjava.lang.String" value="V确定"/>
                     <Property name="type" typeID="Pint" value="V4"/>
                 </Component>
-                <Component componentID="85" typeID="Cjavax.microedition.lcdui.Command">
-                    <Property name="instanceName" typeID="Pjava.lang.String" value="VitemCommand1"/>
+                <Component componentID="91" typeID="Cjavax.microedition.lcdui.Command">
+                    <Property name="instanceName" typeID="Pjava.lang.String" value="VokCommand1"/>
                     <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
-                    <Property name="label" typeID="Pjava.lang.String" value="V添加帐号"/>
+                    <Property name="label" typeID="Pjava.lang.String" value="V确定"/>
+                    <Property name="type" typeID="Pint" value="V4"/>
+                </Component>
+                <Component componentID="103" typeID="Cjavax.microedition.lcdui.Command">
+                    <Property name="instanceName" typeID="Pjava.lang.String" value="VdeleteCommand"/>
+                    <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
+                    <Property name="label" typeID="Pjava.lang.String" value="V删除"/>
                     <Property name="type" typeID="Pint" value="V8"/>
                 </Component>
+                <Component componentID="110" typeID="Cjavax.microedition.lcdui.Command">
+                    <Property name="instanceName" typeID="Pjava.lang.String" value="VcancelCommand1"/>
+                    <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
+                    <Property name="label" typeID="Pjava.lang.String" value="V取消"/>
+                    <Property name="type" typeID="Pint" value="V3"/>
+                </Component>
+                <Component componentID="106" typeID="Cjavax.microedition.lcdui.Command">
+                    <Property name="instanceName" typeID="Pjava.lang.String" value="VeditCommand"/>
+                    <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
+                    <Property name="label" typeID="Pjava.lang.String" value="V编辑"/>
+                    <Property name="type" typeID="Pint" value="V8"/>
+                </Component>
+                <Component componentID="112" typeID="Cjavax.microedition.lcdui.Command">
+                    <Property name="instanceName" typeID="Pjava.lang.String" value="VokCommand2"/>
+                    <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
+                    <Property name="label" typeID="Pjava.lang.String" value="V确定"/>
+                    <Property name="type" typeID="Pint" value="V4"/>
+                </Component>
+                <Component componentID="117" typeID="Cjavax.microedition.lcdui.Command">
+                    <Property name="instanceName" typeID="Pjava.lang.String" value="VreCalcTokenCommand"/>
+                    <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
+                    <Property name="label" typeID="Pjava.lang.String" value="V确定"/>
+                    <Property name="type" typeID="Pint" value="V4"/>
+                </Component>
             </Component>
             <Component componentID="10" typeID="C#DisplayablesCategory">
                 <Component componentID="14" typeID="Cjavax.microedition.lcdui.Form">
                     <Property name="instanceName" typeID="Pjava.lang.String" value="VpassForm"/>
                     <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
-                    <Property name="commands" typeID="1C#CommandEventSource" value="A1:3_R19"/>
+                    <Property name="commands" typeID="1C#CommandEventSource" value="A2:3_R194_R118"/>
                     <Property name="title" typeID="Pjava.lang.String" value="V密码生成器"/>
                     <Property name="commandListener" typeID="C#CommandListener" value="R7"/>
-                    <Property name="items" typeID="1Cjavax.microedition.lcdui.Item" value="A1:3_R34"/>
+                    <Property name="items" typeID="1Cjavax.microedition.lcdui.Item" value="A1:3_R89"/>
                     <Component componentID="19" typeID="C#CommandEventSource">
                         <Property name="eventHandler" typeID="C#EventHandler" value="R78"/>
                         <Property name="displayable" typeID="Cjavax.microedition.lcdui.Displayable" value="R14"/>
                             <Property name="displayable" typeID="Cjavax.microedition.lcdui.Displayable" value="R74"/>
                         </Component>
                     </Component>
-                    <Component componentID="34" typeID="Cjavax.microedition.lcdui.StringItem">
+                    <Component componentID="89" typeID="Cjavax.microedition.lcdui.StringItem">
                         <Property name="instanceName" typeID="Pjava.lang.String" value="VtokenStringItem"/>
-                        <Property name="lazyInit" typeID="Pboolean" value="Vfalse"/>
                         <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
-                        <Property name="label" typeID="Pjava.lang.String" value="V密码:"/>
-                        <Property name="layout" typeID="Pint" value="UStringItem.LAYOUT_CENTER | StringItem.LAYOUT_VCENTER"/>
+                        <Property name="label" typeID="Pjava.lang.String" value="V密码:"/>
+                        <Property name="layout" typeID="Pint" value="V51"/>
                         <Property name="itemCommandListener" typeID="C#ItemCommandListener" value="R17"/>
-                        <Property name="text" typeID="Pjava.lang.String" value="V"/>
+                        <Property name="appearanceMode" typeID="Pint" value="V0"/>
+                    </Component>
+                    <Component componentID="118" typeID="C#CommandEventSource">
+                        <Property name="displayable" typeID="Cjavax.microedition.lcdui.Displayable" value="R14"/>
+                        <Property name="command" typeID="Cjavax.microedition.lcdui.Command" value="R117"/>
                     </Component>
                 </Component>
                 <Component componentID="61" typeID="Cjavax.microedition.lcdui.Form">
                     <Property name="commands" typeID="1C#CommandEventSource" value="A2:3_R663_R69"/>
                     <Property name="title" typeID="Pjava.lang.String" value="V添加帐号"/>
                     <Property name="commandListener" typeID="C#CommandListener" value="R7"/>
-                    <Property name="items" typeID="1Cjavax.microedition.lcdui.Item" value="A2:3_R883_R71"/>
+                    <Property name="items" typeID="1Cjavax.microedition.lcdui.Item" value="A5:3_R883_R713_R964_R1014_R102"/>
                     <Component componentID="69" typeID="C#CommandEventSource">
                         <Property name="eventHandler" typeID="C#EventHandler" value="R70"/>
                         <Property name="displayable" typeID="Cjavax.microedition.lcdui.Displayable" value="R61"/>
                         <Property name="constraints" typeID="Pint" value="V0"/>
                     </Component>
                     <Component componentID="66" typeID="C#CommandEventSource">
-                        <Property name="eventHandler" typeID="C#EventHandler" value="R67"/>
                         <Property name="displayable" typeID="Cjavax.microedition.lcdui.Displayable" value="R61"/>
                         <Property name="command" typeID="Cjavax.microedition.lcdui.Command" value="R65"/>
-                        <Component componentID="67" typeID="C#SwitchDisplayableEventHandler">
-                            <Property name="eventSource" typeID="C#EventSource" value="R66"/>
-                            <Property name="displayable" typeID="Cjavax.microedition.lcdui.Displayable" value="R74"/>
-                        </Component>
                     </Component>
                     <Component componentID="88" typeID="Cjavax.microedition.lcdui.TextField">
                         <Property name="instanceName" typeID="Pjava.lang.String" value="VaccountNameTextField"/>
                         <Property name="maxSize" typeID="Pint" value="V32"/>
                         <Property name="constraints" typeID="Pint" value="V0"/>
                     </Component>
+                    <Component componentID="102" typeID="Cjavax.microedition.lcdui.TextField">
+                        <Property name="instanceName" typeID="Pjava.lang.String" value="VcounterField"/>
+                        <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
+                        <Property name="label" typeID="Pjava.lang.String" value="V当前计数:"/>
+                        <Property name="itemCommandListener" typeID="C#ItemCommandListener" value="R17"/>
+                        <Property name="text" typeID="Pjava.lang.String" value="V0"/>
+                        <Property name="maxSize" typeID="Pint" value="V32"/>
+                        <Property name="constraints" typeID="Pint" value="V2"/>
+                    </Component>
+                    <Component componentID="101" typeID="Cjavax.microedition.lcdui.TextField">
+                        <Property name="instanceName" typeID="Pjava.lang.String" value="VintervalField"/>
+                        <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
+                        <Property name="label" typeID="Pjava.lang.String" value="V时间间隔:"/>
+                        <Property name="itemCommandListener" typeID="C#ItemCommandListener" value="R17"/>
+                        <Property name="text" typeID="Pjava.lang.String" value="V30"/>
+                        <Property name="maxSize" typeID="Pint" value="V32"/>
+                        <Property name="constraints" typeID="Pint" value="V2"/>
+                    </Component>
+                    <Component componentID="96" typeID="Cjavax.microedition.lcdui.ChoiceGroup">
+                        <Property name="instanceName" typeID="Pjava.lang.String" value="VotyType"/>
+                        <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
+                        <Property name="label" typeID="Pjava.lang.String" value="V类型"/>
+                        <Property name="itemCommandListener" typeID="C#ItemCommandListener" value="R17"/>
+                        <Property name="choiceType" typeID="Pint" value="V1"/>
+                        <Property name="elements" typeID="1C#ChoiceElement" value="A2:3_R973_R98"/>
+                        <Component componentID="98" typeID="C#ChoiceElement">
+                            <Property name="string" typeID="Pjava.lang.String" value="V次数密码"/>
+                        </Component>
+                        <Component componentID="97" typeID="C#ChoiceElement">
+                            <Property name="string" typeID="Pjava.lang.String" value="V时间密码"/>
+                            <Property name="selected" typeID="Pboolean" value="Vtrue"/>
+                        </Component>
+                    </Component>
                 </Component>
                 <Component componentID="74" typeID="Cjavax.microedition.lcdui.List">
                     <Property name="instanceName" typeID="Pjava.lang.String" value="VaccountList"/>
                     <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
-                    <Property name="commands" typeID="1C#CommandEventSource" value="A4:3_R763_R803_R833_R86"/>
+                    <Property name="commands" typeID="1C#CommandEventSource" value="A6:3_R763_R803_R833_R864_R1044_R107"/>
                     <Property name="title" typeID="Pjava.lang.String" value="V帐号列表"/>
                     <Property name="commandListener" typeID="C#CommandListener" value="R7"/>
+                    <Property name="elements" typeID="1C#ListElementEventSource" value="A0:"/>
+                    <Property name="listType" typeID="Pint" value="V3"/>
+                    <Property name="fitPolicy" typeID="Pint" value="V0"/>
                     <Property name="selectCommand" typeID="C#CommandEventSource" value="R76"/>
                     <Component componentID="76" typeID="C#ListSelectCommandEventSource">
                         <Property name="eventHandler" typeID="C#EventHandler" value="R77"/>
                             <Property name="eventSource" typeID="C#EventSource" value="R76"/>
                         </Component>
                     </Component>
+                    <Component componentID="86" typeID="C#CommandEventSource">
+                        <Property name="displayable" typeID="Cjavax.microedition.lcdui.Displayable" value="R74"/>
+                        <Property name="command" typeID="Cjavax.microedition.lcdui.Command" value="R85"/>
+                    </Component>
                     <Component componentID="80" typeID="C#CommandEventSource">
                         <Property name="eventHandler" typeID="C#EventHandler" value="R81"/>
                         <Property name="displayable" typeID="Cjavax.microedition.lcdui.Displayable" value="R74"/>
                             <Property name="displayable" typeID="Cjavax.microedition.lcdui.Displayable" value="R14"/>
                         </Component>
                     </Component>
-                    <Component componentID="86" typeID="C#CommandEventSource">
-                        <Property name="eventHandler" typeID="C#EventHandler" value="R87"/>
+                    <Component componentID="107" typeID="C#CommandEventSource">
                         <Property name="displayable" typeID="Cjavax.microedition.lcdui.Displayable" value="R74"/>
-                        <Property name="command" typeID="Cjavax.microedition.lcdui.Command" value="R85"/>
-                        <Component componentID="87" typeID="C#SwitchDisplayableEventHandler">
-                            <Property name="eventSource" typeID="C#EventSource" value="R86"/>
+                        <Property name="command" typeID="Cjavax.microedition.lcdui.Command" value="R106"/>
+                    </Component>
+                    <Component componentID="104" typeID="C#CommandEventSource">
+                        <Property name="displayable" typeID="Cjavax.microedition.lcdui.Displayable" value="R74"/>
+                        <Property name="command" typeID="Cjavax.microedition.lcdui.Command" value="R103"/>
+                    </Component>
+                </Component>
+                <Component componentID="90" typeID="Cjavax.microedition.lcdui.Alert">
+                    <Property name="instanceName" typeID="Pjava.lang.String" value="Valert"/>
+                    <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
+                    <Property name="commands" typeID="1C#CommandEventSource" value="A1:3_R92"/>
+                    <Property name="title" typeID="Pjava.lang.String" value="V错误"/>
+                    <Property name="commandListener" typeID="C#CommandListener" value="R7"/>
+                    <Property name="string" typeID="Pjava.lang.String" value="V帐号名和密钥不能为空"/>
+                    <Property name="timeout" typeID="Pint" value="V-2"/>
+                    <Property name="type" typeID="Ejavax.microedition.lcdui.AlertType" value="EERROR"/>
+                    <Component componentID="92" typeID="C#CommandEventSource">
+                        <Property name="eventHandler" typeID="C#EventHandler" value="R93"/>
+                        <Property name="displayable" typeID="Cjavax.microedition.lcdui.Displayable" value="R90"/>
+                        <Property name="command" typeID="Cjavax.microedition.lcdui.Command" value="R91"/>
+                        <Component componentID="93" typeID="C#SwitchDisplayableEventHandler">
+                            <Property name="eventSource" typeID="C#EventSource" value="R92"/>
                             <Property name="displayable" typeID="Cjavax.microedition.lcdui.Displayable" value="R61"/>
                         </Component>
                     </Component>
                 </Component>
+                <Component componentID="108" typeID="Cjavax.microedition.lcdui.Form">
+                    <Property name="instanceName" typeID="Pjava.lang.String" value="VdeleteForm"/>
+                    <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
+                    <Property name="commands" typeID="1C#CommandEventSource" value="A2:4_R1114_R113"/>
+                    <Property name="title" typeID="Pjava.lang.String" value="V删除帐号"/>
+                    <Property name="commandListener" typeID="C#CommandListener" value="R7"/>
+                    <Property name="items" typeID="1Cjavax.microedition.lcdui.Item" value="A2:4_R1164_R109"/>
+                    <Component componentID="111" typeID="C#CommandEventSource">
+                        <Property name="eventHandler" typeID="C#EventHandler" value="R115"/>
+                        <Property name="displayable" typeID="Cjavax.microedition.lcdui.Displayable" value="R108"/>
+                        <Property name="command" typeID="Cjavax.microedition.lcdui.Command" value="R110"/>
+                        <Component componentID="115" typeID="C#SwitchDisplayableEventHandler">
+                            <Property name="eventSource" typeID="C#EventSource" value="R111"/>
+                            <Property name="displayable" typeID="Cjavax.microedition.lcdui.Displayable" value="R74"/>
+                        </Component>
+                    </Component>
+                    <Component componentID="109" typeID="Cjavax.microedition.lcdui.StringItem">
+                        <Property name="instanceName" typeID="Pjava.lang.String" value="VdeleteAccountName"/>
+                        <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
+                        <Property name="label" typeID="Pjava.lang.String" value="V帐号名:"/>
+                        <Property name="itemCommandListener" typeID="C#ItemCommandListener" value="R17"/>
+                    </Component>
+                    <Component componentID="116" typeID="Cjavax.microedition.lcdui.StringItem">
+                        <Property name="instanceName" typeID="Pjava.lang.String" value="VstringItem"/>
+                        <Property name="lazyInit" typeID="Pboolean" value="Vfalse"/>
+                        <Property name="codeGenerated" typeID="Pboolean" value="Vtrue"/>
+                        <Property name="label" typeID="Pjava.lang.String" value="V确认删除以下帐号吗?"/>
+                        <Property name="itemCommandListener" typeID="C#ItemCommandListener" value="R17"/>
+                    </Component>
+                    <Component componentID="113" typeID="C#CommandEventSource">
+                        <Property name="eventHandler" typeID="C#EventHandler" value="R114"/>
+                        <Property name="displayable" typeID="Cjavax.microedition.lcdui.Displayable" value="R108"/>
+                        <Property name="command" typeID="Cjavax.microedition.lcdui.Command" value="R112"/>
+                        <Component componentID="114" typeID="C#SwitchDisplayableEventHandler">
+                            <Property name="eventSource" typeID="C#EventSource" value="R113"/>
+                            <Property name="displayable" typeID="Cjavax.microedition.lcdui.Displayable" value="R74"/>
+                        </Component>
+                    </Component>
+                </Component>
             </Component>
             <Component componentID="13" typeID="C#ResourcesCategory"/>
             <Component componentID="21" typeID="C#DatabindingCategory"/>
     </Document>
     <FlowScene version="1">
         <Node componentID="2" descriptorID="componentNode2" x="34" y="181"/>
-        <Node componentID="61" descriptorID="componentNode61" x="620" y="257"/>
         <Node componentID="14" descriptorID="componentNode14" x="268" y="31"/>
         <Node componentID="74" descriptorID="componentNode74" x="259" y="411"/>
+        <Node componentID="61" descriptorID="componentNode61" x="594" y="251"/>
+        <Node componentID="90" descriptorID="componentNode90" x="664" y="117"/>
+        <Node componentID="108" descriptorID="componentNode108" x="558" y="399"/>
     </FlowScene>
 </VisualDesign>

File src/TokenGenerator/StockDB.java

-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-
-package TokenGenerator;
-import javax.microedition.rms.*;
-import java.io.*;
-
-
-/**
- *
- * @author bruj0
- */
-public class StockDB {
-
-   RecordStore rs = null;
-   public StockDB() {}
-
-   public StockDB(String fileName) {
-      try {
-        rs =
-              RecordStore.openRecordStore(
-		           fileName, true);
-      } catch(RecordStoreException rse) {
-        rse.printStackTrace();
-      }
-   }
-    public void saveRecord(String record)
-    {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-	DataOutputStream outputStream = new DataOutputStream(baos);
-	try {
-	    outputStream.writeUTF(record);
-	}
-	catch (IOException ioe) {
-	    System.out.println(ioe);
-	    ioe.printStackTrace();
-	}
-	byte[] b = baos.toByteArray();
-	try {
-            if(rs.getNumRecords() >=1)
-                rs.setRecord(1, b, 0, b.length);
-            else
-                rs.addRecord(b,0, b.length);
-	}
-	catch (RecordStoreException rse) {
-	    System.out.println(rse);
-	    rse.printStackTrace();
-	}
-    }
-   public void close()
-	    throws RecordStoreNotOpenException,
-                       RecordStoreException {
-        if (rs.getNumRecords() == 0) {
-            String fileName = rs.getName();
-            rs.deleteRecordStore(fileName);
-            rs.closeRecordStore();
-        } else {
-            rs.closeRecordStore();
-        }
-    }
-public String readRecord(int index){
-    byte [] recData = null;
-    int len = 0;
-    try{
-        if(rs.getNumRecords() >= index)
-        {
-            recData = new byte[rs.getRecordSize(index)];
-            len = rs.getRecord(index, recData, 0);
-        }
-        else
-             return new String();
-      }catch (Exception e){}
-    return  new String(recData, 0, len);
-}
-
-}
-