程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> J2ME >> 應用MVC模式解決J2ME導航問題

應用MVC模式解決J2ME導航問題

編輯:J2ME
開發MIDlet的程序員也許經常會被界面的導航問題所困擾,尤其界面比較多的時候,通常有七、八個界面就會很讓人頭疼了。本文講述如何應用MVC設計模式解決這類的問題。

    MVC設計模式已經非常的成熟並在WEB Application的開發中廣泛使用,apache的開源項目struts就是典型的例子。MVC的本質就是是邏輯和顯示分開,通過控制器進行協調。通常我們會感到控制器比較的肥大,這個是個有爭議的問題。MIDP的用戶界面開發是比較簡單的,只有那麼20幾個類。但是由於導航一般只能通過Command來實現,所以界面增多的情況下,如果沒有有效的組織那麼程序寫起來非常的亂,最致命的是這樣的程序可讀性差、擴展性差、可維護性差。

    應用MVC解決這個問題的關鍵是提供一個橋梁作用的控制器,它通常要有一個MIDlet作為參數。例如   
    public UIController(PhoneBookMIDlet pbm)
    {
        this.phoneBookMIDlet = pbm;
    }
    為了傳遞事件,你可以定義一個內部類,在裡面定義事件的代號。這樣用起來非常的方便例如
    public static class EventID
    {
        private EventID()
        {
        }

        public static final byte EVENT_NEW_RECORD_SELECTED = 1;
        public static final byte EVENT_SAVE_RECORD = 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 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;
    }

    我們要在這個控制器內初始化各個界面類,這樣我們才能根據不同的事件代號進行導航。
    public void init(Model model)
    {
        this.display = Display.getDisplay(phoneBookMIDlet);
        this.model = model;
        indexFunctionUI = new IndexFunctionUI(this);
        infomationUI = new InfomationUI();
        newPhoneUI = new NewPhoneUI(this);
        listPhoneUI = new ListPhoneUI(this);
        searchPhoneUI = new SearchPhoneUI(this);
        displayWelcome();
    }

    public void setCurrent(Displayable disp)
    {
        display.setCurrent(disp);
    }

    public void setCurrent(Alert alert, Displayable disp)
    {
        display.setCurrent(alert, disp);
    }
    由於本文主要講述如何實現導航,因此關於Model不做任何介紹。細心的話你也許可以看出來我這些代碼是在完成一個電話簿的功能。在從Record Management System從入門到精通之四中我會介紹自己編寫的電話本。在控制器類中最重要的就是接受事件然後進行導航,也就是顯示不通的界面。因此它的事件處理的方法是這樣的。
public void handleEvent( int eventID)
    {
        switch (eventID)
        {
            case EventID.ADD_NEW_RECORD:
            {
                display.setCurrent(newPhoneUI);
                break;
            }
            case EventID.LIST_RECORD:
            {
                display.setCurrent(listPhoneUI);
                break;
            }
            case EventID.SEARCH_RECORD:
            {
                display.setCurrent(searchPhoneUI);
                break;
            }
            case EventID.EVENT_NEWPHONE_BACK_MAINUI:
            {
                display.setCurrent(indexFunctionUI);
                break;
            }
            case EventID.EVENT_LISTPHONE_BACK_MAINUI:
            {
                display.setCurrent(indexFunctionUI);
                break;
            }
            case EventID.EVENT_SEARCHUI_BACK_MAINNUI:
            {
                display.setCurrent(indexFunctionUI);
                break;
            }
            default:
                break;
        }
    }

    public void handleEvent(int eventID,  Object[] obj)
    {

    }這是個重載的方法,當有參數傳遞過來的時候我們調用後面的方法。

    接下來我們看界面類,它們通常包括控制器類、界面的Item還有一些Command。
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(Title.choice, 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);
    }
    通常他們把控制器類作為參數傳遞給構造器,並在構造器內部注冊監聽器,繪制界面等。它們通過commandAction()方法來傳遞事件編號給控制器類去處理,例如
    public void commandAction(Command arg0, Displayable arg1)
    {
        if (arg0 == backCommand)
        {
            uicontroller
                    .handleEvent(UIController.EventID.EVENT_NEWPHONE_BACK_MAINUI);
        }

    }這樣就基本上完成了導航問題,擴展起來非常容易,添加一個界面類,然後在控制器類中初始化並添加適當的事件編號就可以了。

      想起來,這種解決方法真是非常經典!!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved