• 应用MVC设计模式解决J2ME应用程序导航问题 mingjava


          开发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)
        {
            // TODO Auto-generated method stub
            if (arg0 == backCommand)
            {
                uicontroller
                        .handleEvent(UIController.EventID.EVENT_NEWPHONE_BACK_MAINUI);
            }

        }这样就基本上完成了导航问题,扩展起来非常容易,添加一个界面类,然后在控制器类中初始化并添加适当的事件编号就可以了。

          想起来,这种解决方法真是非常经典!!

    loop's blog
  • 相关阅读:
    RDD 常用方法
    spark 机器学习
    java 读写文件内容
    hive datediff
    【转】[hadoop源代码解读] 【SequenceFile】
    【转】[Hadoop源码解读](六)MapReduce篇之MapTask类
    【转】[Hadoop源码解读](五)MapReduce篇之Writable相关类
    【转】[Hadoop源码解读](四)MapReduce篇之Counter相关类
    【转】[Hadoop源码解读](三)MapReduce篇之Job类
    【转】[Hadoop源码解读](二)MapReduce篇之Mapper类
  • 原文地址:https://www.cnblogs.com/goodloop/p/51401.html
Copyright © 2020-2023  润新知