亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

基于MIDP1.0實現通信錄

2019-11-18 16:08:18
字體:
來源:轉載
供稿:網友
    項目簡介 
    基于MIDP1.0實現的個人通信錄是我在學習MIDP子系統Record Management System的時候自己編寫的應用程序,整個應用程序涉及到MIDP的高級和低級API、應用MVC實現界面導航、RMS的高級應用、多線程等知識。是學習J2ME開發不錯的范例。由于本站有較多的文章介紹RMS,因此本文對開發中的部分問題進行了介紹。如果您有興趣,可以直接下載源文件研究代碼。如果提供下載請注明作者和出處
 
    作者簡介:
     詹建飛(mingjava),北京郵電大學信息工程學院信號與信息處理專業研究生。
     電子信箱:eric.zhan@263.net

    本文將向大家講述如何給予MIDP1.0實現手機通信錄,讀者需要具備J2ME的基本知識,了解它的構架和主要內容。開發工具選擇了eclipse+wtk2.1+j2sdk1.4.2+eclipseME。

  • 關于開發環境請參考搭建J2ME開發環境
  • 關于J2ME的體系結構請參考J2ME平臺的體系結構
       
  • 精通MIDP用戶界面設計
             個人通信錄提供了添加記錄、瀏覽記錄、刪除記錄、刪除電話本、查找記錄等功能。圖4是幾個主要界面的截圖。細心的讀者可能發現這里沒有提供編輯的功能,讀者可以免費得到個人通信錄的源代碼,這樣您可以嘗試添加這項功能。多讀代碼、多寫代碼是提高水平、掌握知識最快捷的途徑。
    基于MIDP1.0實現通信錄(圖一)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

    在MIDP1.0中的javax.microedition.lcdui包內定義了21個類和3個接口,這比J2SE中的AWT和SWING要簡單很多。在這24個類中,Display是負責設備的顯示以及輸入的管理器,通常我們通過調用setCurrent(Displayable displayable)方法來把displayable組件顯示在手機屏幕上。Displayable代表了能夠在屏幕上顯示的組件對象,它的兩個抽象子類是Canvas和Screen,他們分別代表了MIDP中的低級用戶界面和高級用戶界面。

    Form,Alert,List和TextBox都是從Screen繼承過來的,他們構成了MIDP中的高級用戶界面。要清楚他們每個組件都必須單獨占用一個屏幕,不能與其他組件放在一起。Form類在javax.microedition.lcdui包中至關重要,它是Item的容器,通過調用append(Item item)方法,你可以把TextField、DateField等Item放在Form內。例如下面的代碼:
public NewPhoneUI(UIController uicontroller)
    {
        super(Title.add_record);
        this.uicontroller = uicontroller;
        nameField = new TextField(Title.name, null, 25, TextField.ANY);
        mobileField = new TextField(Title.mobile, null, 25,
                TextField.PHONENUMBER);
        choice = new ChoiceGroup(null, ChoiceGroup.MULTIPLE);
        phoneField=new     TextField(Title.phone,null,25,TextField.PHONENUMBER);
        emailField=new
TextField(Title.email, null, 25, TextField.EMAILADDR);
        choice.append(Title.detail, null);
        this.append(nameField);
        this.append(mobileField);
        this.append(choice);
        this.addCommand(saveCommand);
        this.addCommand(backCommand);
        this.setCommandListener(this);
        this.setItemStateListener(this);
    }
    Canvas類代表了MIDP的低級用戶界面,它是一個抽象類。你需要繼承Canvas并實現它的抽象方法paint(Graphics g)來構建你自己的Canvas實例。Paint()方法中的參數g非常重要。因為通過它提供的方法你才能在屏幕上繪畫你的界面。如果有時間您應該多多研究一下Canvas類和Graphics類。在個人通信錄中我們提供了一個WaitCanvas類并通過它構建了Dialog組件。從下面的代碼中您能學會如何使用Canvas類。
package com.north.phonebook.ui;
import java.util.*;
import javax.microedition.lcdui.*;


public class WaitCanvas extends Canvas
{

    PRivate int mCount, mMaximum;
    private int mInterval;

    private int mWidth, mHeight, mX, mY, mRadius;
    private String mMessage;
    private boolean run = false;

    public WaitCanvas(String message, boolean run)
    {
        this.mMessage = message;
        mCount = 0;
        mMaximum = 36;
        mInterval = 100;

        mWidth = getWidth();
        mHeight = getHeight();

        // Calculate the radius.
        int halfWidth = (mWidth - mRadius) / 2;
        int halfHeight = (mHeight - mRadius) / 2;
        mRadius = Math.min(halfWidth, halfHeight);

        //   Calculate the location.
        mX = halfWidth - mRadius / 2;
        mY = halfHeight - mRadius / 2;

        //   Create a Timer to update the display.
        if (run)
        {
            TimerTask task = new TimerTask()
            {
                public void run()
                {
                    mCount = (mCount + 1) % mMaximum;
                    repaint();
                }
            };
            Timer timer = new Timer();
            timer.schedule(task, 0, mInterval);
        }
    }

 
    public void setMMessage(String message)
    {
        mMessage = message;
    }
    public void paint(Graphics g)
    {
        int theta = -(mCount * 360 / mMaximum);


        g.setColor(255, 255, 255);
        g.fillRect(0, 0, mWidth, mHeight);
        g.setColor(128, 128, 255);
        g.drawArc(mX, mY, mRadius, mRadius, 0, 360);
        g.fillArc(mX, mY, mRadius, mRadius, theta + 90, 90);
        g.fillArc(mX, mY, mRadius, mRadius, theta + 270, 90);

        if (mMessage != null)
        {
            g.drawString(mMessage,mWidth/2,mHeight,Graphics.BOTTOM
                    Graphics.HCENTER);
        }
    }

}
    下面我們看看MIDP中的事件處理機制,它同樣分為高級事件處理和低級事件處理。高級事件處理由Command和Item事件組成。他們分別對應CommandListener和ItemStateListener接口。你可以在Displayable組件上添加Command并實現CommandListener接口。這個接口只定義了一個方法commandAction(Command cmd,Displayable),因此你要實現這個接口告訴應用程序當指定的command按下的時候它應該去執行什么操作,當然你不能忘記了注冊Listener。例如:
public void commandAction(Command arg0, Displayable arg1)
    {
        if(arg0 == backCommand)
        {
            uicontroller.handleEvent
(UIController.EventID.EVENT_SEARCHUI_BACK_MAINNUI); 
        }
        else if(arg0 == searchCommand)
        {
            String userName = inputField.getString();
            if(userName.length()!= 0)
            {
                uicontroller.handleEvent(UIController.EventID.EVENT_SEARCH_RECORD_ANYWAY,new Object[]{userName});
            }
        }

    }
    ItemStateListener定義的方法是itemStateChanged(Item item),它的含義是當指定的item的內容發生變化的時候告訴應用程序去執行相應的操作,例如當TextField中用戶輸入了姓名,那么應用程序去RMS中去查詢相關的記錄并返回。例如
public void itemStateChanged(Item item)
    {
        if(item == inputField)
        {
            String userName = inputField.getString();
            if(userName.length()!= 0)
            {
                uicontroller.handleEvent(UIController.EventID.EVENT_SEARCH_RECORD,new Object[]{userName});
            }
        }
    }
    MIDP中的低級事件處理是通過實現Canvas類的相關方法來實現的,例如當用戶按下某個按鍵,應用程序應該去處理相應的操作。由于個人通信錄中并未涉及相關內容因此不做講解。

  • 應用MVC設計模式實現界面導航


    MIDP中的UI類使用起來比不難,然而界面導航問題卻并不容易解決,事實上它是困擾很多J2ME程序員的問題。在MIDP中我們只能通過調用Display類中的setCurrent()方法來實現不同界面之間的切換,如果界面多起來比如有8-10個界面的時候就會顯得非常的麻煩。你也許想構造一個樹形的結構來記錄每個界面的父親界面例如:
public ChildUI(Displayable parent,Dispaly display)
{
 this.parent = parent;
 this.display = display; 
}
    但是當界面以及相互之間的聯系增加的時候,界面的導航問題仍然是一個噩夢。MVC設計模式在Web application應用開發方面已經被證明是非常成功的,例如Apache的開源項目struts,在本文中我將講述如何應用MVC設計模式解決MIDP應用程序的界面導航問題。
    MVC的目的就是實現顯示(View)與邏輯(Model)的分離,而在其中起到重要作用的就是控制器(Controller)。在控制器內通常我們要定義一些事件的代號以便和UI類通信,保證正確處理相應的事件,我們可以使用內部類來標記這些事件的代號。
public static class EventID
{
        private EventID()
        {
        }

        public static final byte EVENT_NEW_RECORD_SELECTED = 1;
        public static final byte EVENT_SAVE_RECORD_SELECTED = 2;
        public static final byte EVENT_NEWPHONE_BACK_MAINUI = 3;
        public static final byte EVENT_LISTPHONE_BACK_MAINUI = 4;
        public static final byte EVENT_SEARCHUI_BACK_MAINNUI = 5;
        public static final byte EVENT_CLEAR_RECORD_YES = 6;
        public static final byte EVENT_CLEAR_RECORD_NO = 7;
        public static final byte EVENT_DELETE_RECORD = 8;
        public static final byte EVENT_DELETE_RECORD_YES = 9;
        public static final byte EVENT_DELETE_RECORD_NO = 10;
        public static final byte EVENT_DISPLAY_INFOMATION = 11;
        public static final byte EVENT_DETAIL_BACK_LIST = 12;
        public static final byte EVENT_SEARCH_RECORD = 13;
        public static final byte EVENT_SEARCH_RECORD_ANYWAY = 14;

        public static final byte ADD_NEW_RECORD = 100;
        public static final byte SEARCH_RECORD = 101;
        public static final byte CLEAR_RECORD = 102;
        public static final byte LIST_RECORD = 103;
        public static final byte HELP = 104;
    }


    當UI類中有事件發生的時候它可以向UIController類傳輸事件的代碼,UIController類根據代碼來進行相應的事件處理。例如:
if (arg0 == backCommand)
{
  uicontroller.handleEvent(UIController.EventID.EVENT_NEWPHONE_BACK_MAINUI)      
}
UIController的handleEvent()方法則在接收到UI類的請求之后調用Model類的相關方法得到響應,然后再顯示相關的界面。
public void handleEvent(int eventID)
    {
        switch (eventID)
        {
            case EventID.ADD_NEW_RECORD:
            {
                newPhoneUI.clear();
                display.setCurrent(newPhoneUI);
                break;
            }


            case EventID.CLEAR_RECORD:
            {
                dialog.setMessage(Title.delete_phonebook);
                dialog.display(EventID.CLEAR_RECORD);
                break;
            }

            case EventID.EVENT_CLEAR_RECORD_YES:
            {
                try
                {
                    model.clearAllRecord();
                    display.setCurrent(indexFunctionUI);
                } catch (ApplicationException e)
                {
                    e.printStackTrace();
                }
                break;
            }
   ……
   ……
}
有的時候我們不光要告訴控制類要做什么還要傳輸給他一些從界面類采集到的數據,這時候我們可以在UIController類中重載handleEvent()方法,添加一個Object[]類型的參數來接收數據,如下所示:
 
public void handleEvent(int eventID, Object[] obj)
    {
        switch (eventID)
        {
            case EventID.EVENT_SAVE_RECORD_SELECTED:
            {
                try
                {
                    Account account = (Account) obj[0];
                    if (model.isRecordExist(account.getUserName()))
                    {
                        showAlert(Title.record_exist, indexFunctionUI,
                                AlertType.WARNING);
                    } else
                    {
                        model.addRecord(account);
                       
                        showAlert(Title.record_added, indexFunctionUI,
                                AlertType.CONFIRMATION);
                    }
                } catch (ApplicationException e)
                {
                    e.printStackTrace();
                }
                break;
            }
}
}
例如在添加新電話記錄的時候,我們可以這樣實現commandAction()方法向UIController傳送消息。
if (arg0 == saveCommand)
  {
……
……
          Account newAccount = new Account(userName, mobilePhone, phone,
                    email);
            uicontroller.handleEvent(
                    UIController.EventID.EVENT_SAVE_RECORD_SELECTED,
                    new Object[] { newAccount });
   }
我們很難保證用戶輸入的數據有效,也很難保證用戶的操作都合理,因此我們必須針對用戶的不合理的操作給出相對的提示或者警告。在javax.microedition.lcdui包中Alert類能夠很好的完成這個任務,因此我們自己提供一個方法如下所示:
    public void showAlert(String message, Displayable next, AlertType type)
    {
        alert = new Alert(Title.alertTitle, message, null, type);
        alert.setTimeout(1500);
        setCurrent(alert, next);
    }
當不合理的事件發生的時候我們應該調用它。
String userName = nameField.getString();
if (userName.length() == 0)
{
   uicontroller.showAlert(Title.userNameNull, this,AlertType.WARNING);
   return;
}
例如當用戶并沒有輸入姓名就按下了保存的按鈕的時候,應該提示用戶“用戶名不能為空”。
基于MIDP1.0實現通信錄(圖二)


 

 

 

 

 

    有些時候,某些操作可能會被堵塞,例如聯網或者從RMS中讀取大量的數據,這個時候我們應該使用多線程,多線程是java語言中內嵌的特性,使用起來也非常簡單。在本例中當我們瀏覽的電話本中包含很多數據的時候,如果不使用多線程,主界面會持續幾秒鐘不動,這對用戶來說很不友好,因為用戶不知道現在應用程序在做什么,在這個時候使用多線程就顯得非常必要。
基于MIDP1.0實現通信錄(圖三)

 

 

 

 

 

 

 

  • 關于RMS子系統的詳細介紹請參考本站專題精通MIDP子系統RMS

    本文從介紹J2ME平臺,搭建開發環境到最后發布應用程序,詳細的介紹了J2ME的開發過程,其中對MIDP的用戶界面和Record Management System做了詳細、深入的分析。這是本人在進行J2ME開發的一點經驗和體會,希望和讀者一起分享。由于水平有限,錯誤在所難免,歡迎大家批評指正

(出處:http://www.49028c.com)



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产欧美久久一区二区| 亚洲欧美三级伦理| 国产97在线|日韩| 欧美性生交xxxxxdddd| 欧美激情精品久久久久久黑人| 亚洲成人av片在线观看| 91久久国产婷婷一区二区| 91精品国产免费久久久久久| 91亚洲精品一区| 91在线|亚洲| 国产精品第一区| 欧美成人免费在线视频| 日韩欧美有码在线| 久久综合久中文字幕青草| 粗暴蹂躏中文一区二区三区| 中文字幕精品一区久久久久| 亚洲国产精品网站| 91精品视频免费观看| 久久成人人人人精品欧| 伊是香蕉大人久久| 成人精品在线视频| 日韩av手机在线看| 亚洲人成亚洲人成在线观看| 欧美视频在线观看免费网址| 欧美激情视频网址| 欧美成人黑人xx视频免费观看| 日韩高清人体午夜| 国产97在线|亚洲| 久久精品色欧美aⅴ一区二区| 日韩中文字幕欧美| 俺去了亚洲欧美日韩| 欧美大胆在线视频| 亚洲男人天堂网| 国产精品入口福利| 欧美激情影音先锋| 欧美激情第一页xxx| 中文字幕日韩欧美精品在线观看| 亲子乱一区二区三区电影| 亚洲天堂av图片| 久色乳综合思思在线视频| 国产福利视频一区二区| 午夜精品视频在线| 疯狂蹂躏欧美一区二区精品| 欧美电影电视剧在线观看| 久久久噜噜噜久久久| 亚洲成人网在线观看| 国产精品久久久久久久7电影| 亚洲香蕉成视频在线观看| 91中文字幕一区| 日本午夜在线亚洲.国产| 亚洲女人天堂视频| 欧美丝袜美女中出在线| 欧美成人免费va影院高清| 国产91九色视频| 91精品视频在线播放| 91久久国产婷婷一区二区| 国产精品黄页免费高清在线观看| 久久免费成人精品视频| 日本精品视频在线播放| 欧美韩国理论所午夜片917电影| 啊v视频在线一区二区三区| 性色av香蕉一区二区| 久久国产精品久久久久久久久久| 91精品综合视频| 成人久久久久久久| 日韩欧美国产高清91| 日本国产一区二区三区| 欧美日韩国产在线看| 精品久久久久久久久久久久| 成人国产精品日本在线| 91chinesevideo永久地址| 亚洲美女中文字幕| 国产精品久久久久一区二区| 超碰91人人草人人干| 国产精品6699| 欧美成人免费全部观看天天性色| 欧美大片在线看| 亚洲电影免费观看高清完整版在线观看| 人体精品一二三区| 亚洲片av在线| 欧美日韩国产在线播放| 91在线免费视频| 九九久久综合网站| 精品无人国产偷自产在线| 国产精品久久久久久久久久久久久| 久久精视频免费在线久久完整在线看| 欧美激情成人在线视频| 国产一区二区三区四区福利| 欧美成人h版在线观看| 亲子乱一区二区三区电影| 庆余年2免费日韩剧观看大牛| 国产在线视频2019最新视频| 国产一区二区动漫| 欧美日韩亚洲激情| 久久精品99无色码中文字幕| 国产精品久久久久aaaa九色| 97在线精品国自产拍中文| 久久久久99精品久久久久| 国产精品偷伦一区二区| 欧美电影免费观看电视剧大全| 亚洲成人在线视频播放| 欧美一级成年大片在线观看| 性色av一区二区三区红粉影视| 97视频免费观看| 国内成人精品视频| 国产免费一区二区三区香蕉精| 精品久久久久久中文字幕| 亚洲最新av网址| 精品日韩视频在线观看| 欧美亚洲伦理www| 欧洲成人免费aa| 欧美成人午夜视频| 69精品小视频| 欧美华人在线视频| 欧美日本国产在线| 91豆花精品一区| 国产日产久久高清欧美一区| 欧美日韩福利视频| 午夜精品一区二区三区av| 成人精品久久久| 亚洲一区亚洲二区| 91久久精品一区| 国产精品吴梦梦| 欧美疯狂xxxx大交乱88av| 国产精品久久精品| 欧美一区二区大胆人体摄影专业网站| 亚洲最大福利网站| 欧美激情免费看| 久久影院在线观看| 国产99视频在线观看| 欧美国产激情18| 欧美激情在线狂野欧美精品| 亚洲一区中文字幕在线观看| 91久久国产综合久久91精品网站| 久久久999精品免费| 精品国产一区二区三区久久久| 亚洲伊人久久综合| 亚洲免费视频观看| 欧美精品一区二区免费| 欧美久久精品一级黑人c片| 91精品国产色综合久久不卡98| 91精品视频在线免费观看| 国产成人自拍视频在线观看| 久久99久久亚洲国产| 欧美成人精品在线观看| 日韩电影在线观看永久视频免费网站| 国产精品中文在线| 国产精品久久二区| 爽爽爽爽爽爽爽成人免费观看| 91精品国产免费久久久久久| 欧美日韩精品在线视频| 国产精品一二区| 亚洲精美色品网站| 日本久久亚洲电影| 国产精品99久久久久久白浆小说| 2019中文字幕在线| 午夜精品一区二区三区在线| 国产成人午夜视频网址| 成人亚洲欧美一区二区三区| 日韩成人黄色av| 日韩激情视频在线| 久久777国产线看观看精品| 91嫩草在线视频| 国模视频一区二区三区|