要资料 文章 文库 视频 Code iProcess 课程 认证 咨询 工具 火云堂 讲座吧   成长之路  
会员   
 
  
每天15篇文章
不仅获得谋生技能
更可以追随信仰
 
 
     
   
分享到
JavaMe开发:也说MVC设计模式
 
作者 tandesir的博客,火龙果软件    发布于 2013-11-15
 

介绍设计模式的文章和书很多,但只有使用时,才能理解设计模式的妙处。接上一篇《JavaMe连载(2)-低级界面绘图之菜单》,本文一则对UIController作出解释,一则将自己理解的MVC设计模式,结合实例,与大家交流学习。

【更新】本文将适时做出更新,所以现在不是终稿,如有不当之处,敬请指出。

【问题描述】介绍设计模式的文章和书很多,但只有使用时,才能理解设计模式的妙处。接上一篇《JavaMe连载(2)-低级界面绘图之菜单》,本文一则对UIController作出解释,一则将自己理解的MVC设计模式,结合实例,与大家交流学习。

【理论】什么是MVC?

MVC就是模型(model)、视图(view)和控制(control)。什么是模型呢?本例中,模型就是对数据使用时的封装。视图很容易理解,那就是显示内容的具体表示。控制呢?有很多人对视图和控制分不清。在本例中,控制包含视图控制器以及方法的封装。

【实例】

1、先看工程结构,如图1所示。

图1 工程结构

工程中将用户数据单独封装,作为model。供控制器和视图调用。将显示页面单独封装,作为视图。将视图控制器UIController和常用方法封装为util。UIController就是控制。

2、UML图(后续更新时补充)

先看代码,再分析工作机理

【代码清单】

MainMidlet.java

package com.token.midlet;  

import java.io.IOException;  

import javax.microedition.lcdui.*;  
import javax.microedition.midlet.MIDlet;  
import javax.microedition.midlet.MIDletStateChangeException;  
import com.token.util.UIController;  

public class MainMidlet extends MIDlet {  

    private Display display;  
    private static UIController controller;  
    public MainMidlet() {  
        // TODO Auto-generated constructor stub  
        super();  
        display=Display.getDisplay(this);     
    }  

    /* (non-Javadoc)  
     * @see javax.microedition.midlet.MIDlet#pauseApp()  
     */ 
    protected void startApp() throws MIDletStateChangeException {  
        controller=new UIController(this);  
        try {  
            controller.init();  
        } catch (IOException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }//初始化RecordStore  
    }  

    /* (non-Javadoc)  
     * @see javax.microedition.midlet.MIDlet#pauseApp()  
     */ 
    protected void pauseApp() {  
        this.notifyPaused();  
    }  
 
    /* (non-Javadoc)  
     * @see javax.microedition.midlet.MIDlet#destroyApp(boolean)  
     */ 
    protected void destroyApp(boolean arg0) throws MIDletStateChangeException {  
        controller=null;   
    }  

    public void setCurrent(Displayable disp){  
        display.setCurrent(disp);  
    }  
    public void setCurrent(Alert alert, Displayable disp){  
        display.setCurrent(alert, disp);  
    }  
    public Displayable getCurrent(){  
        return display.getCurrent();  
    }   
    public void exit(boolean arg0){  
        try{  
            destroyApp(arg0);  
            notifyDestroyed();  
        }catch(MIDletStateChangeException e){  
            //  
        }  
    }  

}  

模型(Model)

UserDataItem.java

package com.token.model;  

import com.token.util.StringDealMethod;  

public class UserDataItem {  
    private int id;  
    public String name = null;  
    public String passwd = null;  
 
    public UserDataItem(String name,String passwd)  
    {  
        this.name = name;  
        this.passwd = passwd;     
    }   
    public UserDataItem(int id,byte[] data){  
        this.id=id;  
        String temp=new String(data);  
        String temp_sub[] = StringDealMethod.split(temp, ",");  
        this.name = temp_sub[0];  
        this.passwd = temp_sub[1];  
    }   
    public int getId(){  
        return id;  
    }     
    public void setId(int id){  
        this.id=id;  
    }    
    public String getName(){  
        return name;  
    }   
    public void setName(String name){  
        this.name = name;  
    }    
    public String getPasswd(){  
        return passwd;  
    }  
    public void setPasswd(String passwd){  
        this.passwd = passwd;  
    }    
    public byte[] getBytes(){  
        String temp=null;  
        if(name==null||passwd==null){  
            return null;  
        }else{  
            temp=name+","+passwd;  
        }   
        return temp.getBytes();  
    }  
}  

控制(control)

UIController.java

package com.token.util;  

import java.io.IOException;  

import javax.microedition.lcdui.*;  

import com.token.midlet.MainMidlet;  
import com.token.model.*;  
import com.token.view.*;  
//import com.token.view.components.Color;  

public class UIController {  

    private MainMidlet midlet;  

    private TokenDataRecord tokenRecord;  

    private WelcomeScreen welcomeScreen;  
    private UserRegist reg;   
    private ActiveScreen activeScreen;  
    private MainScreen mainScreen;  
    private GenPasswd gen;  
    private CheckScreen check;  
    private ViewToken viewToken;  
    private UserManage manage;  
    private ShowHelp help;  
    private UserAuth auth;  
    private PopUpTextBox textBox;  
    int id = 1;  
    public UIController(MainMidlet midlet)  
    {  
        this.midlet = midlet;  

        tokenRecord = new TokenDataRecord();  
    }  

    public void init() throws IOException{  

        try {  
            SplashScreen splashScreen = new SplashScreen();  
            setCurrent(splashScreen);  
            Thread.sleep(1000);  

            Configure.configureColor();  
            initObject();     

            //tokenRecord.db_deleteAllRecord();  
            if(tokenRecord.db_getRecord(1)==null)  
            {  
                //System.out.println("add");  
                ChaosMethods method = new ChaosMethods();  
                TokenDataItem tokenItem = new TokenDataItem(1,(method.ChaosInitCode()+",false").getBytes());  
                id=tokenRecord.db_addRecord(tokenItem);  
            }   
            //System.out.println(id);  
            TokenDataItem tokenItem1 = tokenRecord.db_getRecord(id);  
            //System.out.println(tokenItem1.token+","+tokenItem1.isActive);  
            if(tokenItem1.getStatus().equals("false"))  
            {  
                this.handleEvent(UIController.EventID.EVENT_NEXT_WELCOME_SCREEN,null);  
            }else 
            {  
                String flag = "0";  
                Object [] args = {flag,""};  
                this.handleEvent(UIController.EventID.EVENT_MAIN_SCREEN,args);  
            }  
        } catch (InterruptedException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
    }  
    private void initObject()  
    {  
        welcomeScreen = new WelcomeScreen(this);  
        reg= new UserRegist(this);  
        activeScreen = new ActiveScreen(this);  
        ...  
        textBox = new PopUpTextBox(this,"输入文本","", 1000, TextField.ANY);  
    }  
    //getMethod  
    public void setCurrent(Displayable disp){  
        midlet.setCurrent(disp);  
    }  
    public void setCurrent(Alert alert, Displayable disp){  
        midlet.setCurrent(alert, disp);  
    }  
    //定义事件ID内部类  
    public static class EventID{  
        private EventID(){  
        }  
        public static final byte EVENT_EXIT = 0;//退出  
        public static final byte EVENT_NEXT_WELCOME_SCREEN = 1;//欢迎界面  
        public static final byte EVENT_NEXT_USER_REGIST_SCREEN = 2;//用户注册  
        public static final byte EVENT_USER_REGIST_EDIT = 3;//用户注册编辑  
        public static final byte EVENT_USER_REGIST_EDIT_BACK = 4;//用户注册编辑返回  
        public static final byte EVENT_NEXT_ACTIVE_SCREEN = 5;  
       //...  
    }  
    //事件处理  
    public void handleEvent( int eventID, Object[] args)  
    {  
        switch (eventID)  
        {     
            case EventID.EVENT_EXIT:  
            {  
                midlet.exit(false);  
                break;  
            }  
            case EventID.EVENT_NEXT_WELCOME_SCREEN:  
            {  
                    welcomeScreen.show();  
                midlet.setCurrent(welcomeScreen);  
                break;  
            }  
            case EventID.EVENT_NEXT_USER_REGIST_SCREEN:  
            case EventID.EVENT_USER_REGIST_EDIT_BACK:  
            {  
                reg.show(args);  
                Thread thread = new Thread(reg);  
                thread.start();  
                midlet.setCurrent(reg);  
                break;  
            }  
            case EventID.EVENT_USER_REGIST_EDIT:  
            {  
                textBox.init(args);  
                midlet.setCurrent(textBox);  
                break;  
            }  
            case EventID.EVENT_NEXT_ACTIVE_SCREEN:  
            {  
                activeScreen.show(args);  
                Thread thread = new Thread(activeScreen);  
                thread.start();  
                midlet.setCurrent(activeScreen);  
                break;  
            }  
            //...  
            default:  
                break;  
        }  
    }  
}  

UserDataRecord.java

package com.token.util;  
import java.util.Vector;
import javax.microedition.rms.RecordComparator;
import javax.microedition.rms.RecordEnumeration;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;

import com.token.model.*;

public class UserDataRecord {
private static final String RECORDSTORE_NAME="USER_DB";
private static RecordStore info;

public UserDataRecord(){
}

//打开RecordStore,没有则创建
public void openDataBase() {
try {
info = RecordStore.openRecordStore(RECORDSTORE_NAME, true);
}catch (RecordStoreException ex) {
info =null;
}
}
//关闭RecordStore
public void closeDataBase() {
if (info!= null) {
try {
info.closeRecordStore();
info=null;
} catch (RecordStoreException ex) {}
}
}
//增加记录
public int db_addRecord(UserDataItem item) {
try {
this.openDataBase();
byte[] data=item.getBytes();
int id=info.getNextRecordID();
info.addRecord(data,0,data.length);
this.closeDataBase();
return id;
} catch (RecordStoreException ex) { }
return -1;
}
//更新记录
public void db_updateRecord(UserDataItem item){

try {
this.openDataBase();
byte[] data=item.getBytes();
info.setRecord(item.getId(),data,0,data.length);
this.closeDataBase();
} catch (RecordStoreException ex) { }
}
//访问一条记录
public UserDataItem db_getRecord(int id){
UserDataItem item=null;

try {
this.openDataBase();
item = new UserDataItem(id,info.getRecord(id));
this.closeDataBase();
} catch (RecordStoreException ex) { }
return item;
}
//删除一条记录
public void db_deleteRecord(int id){
try {
this.openDataBase();
info.deleteRecord(id);
this.closeDataBase();
} catch (RecordStoreException ex) {}
}

//删除所有记录
public void db_deleteAllRecord(){
try {
RecordStore.deleteRecordStore(RECORDSTORE_NAME);
} catch (RecordStoreException ex) {}
}

//访问所有记录
public Vector db_getRecords(){
Vector items=new Vector(10,3);
this.openDataBase();//打开RecordStore
RecordEnumeration enum1=null;
int ind=0;
try{
UserDataItem item=null;
enum1=info.enumerateRecords(null,new InnerComparator(),false);
while(enum1.hasPreviousElement()){
ind=enum1.previousRecordId();
item=new UserDataItem(ind,info.getRecord(ind));
items.addElement(item);
}

}catch(Exception ex){ex.printStackTrace();}
finally{
try{
enum1.destroy();
}catch(Exception e){}

this.closeDataBase();//关闭RecordStore
}//end finally

return items;
}
//一个简单的比较器
private class InnerComparator implements RecordComparator{
public int compare(byte[] rec1, byte[] rec2){
if(rec1.length>rec2.length)
return FOLLOWS;
else if(rec1.length<rec2.length)
return PRECEDES;
else
return EQUIVALENT;
}

}
}

视图(view)

WelcomeScreen.java

package com.token.view;  
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.GameCanvas;
import com.token.util.UIController;
import com.token.util.StringDealMethod;
import com.token.view.components.*;
public class WelcomeScreen extends GameCanvas {
private UIController controller;
private Graphics graphics;
private Font ft;
private String info;
private String info_wrap[];
private int width;
private int height;
private Menu menu;
private Head head;
private BackGroud backGroud;
public WelcomeScreen(UIController control) {
// TODO Auto-generated constructor stub
super(false);
controller=control;
setFullScreenMode(true);
graphics = getGraphics();
width = getWidth();
height = getHeight();
menu = new Menu(this);
head = new Head(this);
backGroud = new BackGroud(this);
}
public void show() {
// TODO Auto-generated method stub
//clearScreen();
backGroud.drawBackGroud(this, graphics);
head.drawHead(this,graphics,"");
menu.drawMenu(this, graphics,"下一步","退出");
drawBody();
}
public void drawBody()
{
ft = Font.getFont(Font.FACE_PROPORTIONAL,Font.STYLE_BOLD,Font.SIZE_LARGE);

info = "欢迎使用!\n"
+"1 MVC测试;\n"
+"2 自动换行测试,绘制可自动识别换行的字符串。\n";
info_wrap = StringDealMethod.format(info, width-10, ft);

graphics.setColor(Color.text);
graphics.setFont(ft);
for(int i=0; i<info_wrap.length; i++)
{
graphics.drawString(info_wrap[i], 5, i * ft.getHeight()+40, Graphics.TOP|Graphics.LEFT);
}
}
public void clearScreen()
{
graphics.setColor(0xff,0xff,0xff);
graphics.fillRect(0, 0, width, height);
}
protected void keyPressed(int keycode)
{
switch(keycode)
{
case KeyID.SOFT_RIGHT:
{
controller.handleEvent(UIController.EventID.EVENT_EXIT,null);
break;
}
case KeyID.SOFT_LEFT:
{
String editor = "regist_name";
Object [] args = {"registScreen",editor, null,null,null};
controller.handleEvent(UIController.EventID.EVENT_NEXT_USER_REGIST_SCREEN,args);
break;
}
default:;
}
}

}

UserRegist.java

package com.token.view;  
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.GameCanvas;
import com.token.model.*;
import com.token.util.*;
import com.token.view.components.*;
public class UserRegist extends GameCanvas implements Runnable {
private UIController controller;
private Graphics graphics;
private Font ft;
private Menu menu;
private Head head;
private BackGroud backGroud;
private UserDataRecord userRecord;
private String title;
private TextEdit textEdit_name;
private TextEdit textEdit_passwd;
private TextEdit textEdit_passwd_re;
private int textEdit_name_x;
private int textEdit_name_y;
private int textEdit_passwd_x;
private int textEdit_passwd_y;
private int textEdit_passwd_re_x;
private int textEdit_passwd_re_y;
private int currentlySelectedIndex = 0;
private String username;
private String passwd;
private String passwd_re;
long caretBlinkDelay = 500L;
long lastCaretBlink = 0;
private String object_name;
private String editor;
private boolean cursorBlinkOn1;
private boolean cursorBlinkOn2;
private boolean cursorBlinkOn3;
private int width;
private int height;
public UserRegist(UIController control)
{
super(false);
this.controller=control;
this.title = "用户注册";
setFullScreenMode(true);
graphics = getGraphics();

width = getWidth();
height = getHeight();
menu = new Menu(this);
head = new Head(this);
backGroud = new BackGroud(this);
userRecord = new UserDataRecord();
textEdit_name = new TextEdit(this);
textEdit_passwd = new TextEdit(this);
textEdit_passwd_re = new TextEdit(this);
}
public void show(Object[] args) {
// TODO Auto-generated method stub
setFullScreenMode(true);
object_name = ((String)args[0]!=null)?(String)args[0]:"";
editor = ((String)args[1]!=null)?(String)args[1]:"";
username = ((String)args[2]!=null)?(String)args[2]:"";
passwd = ((String)args[3]!=null)?(String)args[3]:"";
passwd_re = ((String)args[4]!=null)?(String)args[4]:"";
if(editor.equals("regist_name"))
{
cursorBlinkOn1 = true;
cursorBlinkOn2 = false;
cursorBlinkOn3 = false;
currentlySelectedIndex =0;
}
else if(editor.equals("regist_passwd"))
{
cursorBlinkOn1 = false;
cursorBlinkOn2 = true;
cursorBlinkOn3 = false;
currentlySelectedIndex =1;
}
else if(editor.equals("regist_passwd_re"))
{
cursorBlinkOn1 = false;
cursorBlinkOn2 = false;
cursorBlinkOn3 = true;
currentlySelectedIndex =2;
}
//System.out.println(object_name);
//System.out.println(editor);
draw();
redraw();
}
public void draw()
{
//clearScreen();
backGroud.drawBackGroud(this, graphics);
head.drawHead(this,graphics,this.title);
menu.drawMenu(this,graphics,"下一步","退出");
drawBody();
}
private void redraw()
{
switch(currentlySelectedIndex)
{
case 0:
{
cursorBlinkOn2 = false;
cursorBlinkOn3 = false;
editor = "regist_name";
break;
}
case 1:
{
cursorBlinkOn1 = false;
cursorBlinkOn3 = false;
editor = "regist_passwd";
break;
}
case 2:
{
cursorBlinkOn1 = false;
cursorBlinkOn2 = false;
editor = "regist_passwd_re";
break;
}
default:;
}

textEdit_name.drawTextBox (this, graphics, username, textEdit_name_x, textEdit_name_y, cursorBlinkOn1);
textEdit_passwd.drawTextBox (this, graphics, passwd, textEdit_passwd_x, textEdit_passwd_y, cursorBlinkOn2);
textEdit_passwd.drawTextBox (this, graphics, passwd_re, textEdit_passwd_re_x, textEdit_passwd_re_y, cursorBlinkOn3);
textEdit_name.flushGraphics();
}

public void drawBody()
{
int margin =5;
ft = Font.getFont(Font.FACE_PROPORTIONAL,Font.STYLE_BOLD,Font.SIZE_LARGE);

String info = "用户名:\n";
String info_wrap1[] = StringDealMethod.format(info, width-10, ft);
graphics.setFont(ft);
graphics.setColor(Color.text);
for(int i=0; i<info_wrap1.length; i++)
{
graphics.drawString(info_wrap1[i],5, (i) * ft.getHeight()+40, Graphics.TOP|Graphics.LEFT);
}
textEdit_name_x = 5;
textEdit_name_y = info_wrap1.length * ft.getHeight()+40;
textEdit_name.drawTextBox(this, graphics, username, textEdit_name_x, textEdit_name_y, cursorBlinkOn1);
info = "用户密码:\n";
String info_wrap2[] = StringDealMethod.format(info, width-10, ft);

graphics.setFont(ft);
graphics.setColor(Color.text);
for(int i=0; i<info_wrap2.length; i++)
{
graphics.drawString(info_wrap2[i],5, (i+info_wrap1.length) * ft.getHeight()+textEdit_name.height+margin+40, Graphics.TOP|Graphics.LEFT);
}
textEdit_passwd_x = 5;
textEdit_passwd_y = (info_wrap1.length+info_wrap2.length) * ft.getHeight()+textEdit_name.height+margin+40;
textEdit_passwd.drawTextBox(this, graphics, passwd, textEdit_passwd_x, textEdit_passwd_y, cursorBlinkOn2);
info = "密码确认:\n";
String info_wrap3[] = StringDealMethod.format(info, width-10, ft);

graphics.setFont(ft);
graphics.setColor(Color.text);
for(int i=0; i<info_wrap3.length; i++)
{
graphics.drawString(info_wrap3[i],5, (i+info_wrap1.length+info_wrap2.length) * ft.getHeight()+textEdit_name.height+textEdit_passwd.height+2*margin+40, Graphics.TOP|Graphics.LEFT);
}

textEdit_passwd_re_x = 5;
textEdit_passwd_re_y = (info_wrap1.length+info_wrap2.length+info_wrap3.length) * ft.getHeight()+textEdit_name.height+textEdit_passwd.height+2*margin+40;
textEdit_passwd_re.drawTextBox(this, graphics, passwd_re, textEdit_passwd_re_x, textEdit_passwd_re_y, cursorBlinkOn3);
}
public void clearScreen()
{
graphics.setColor(0xff,0xff,0xff);
graphics.fillRect(0, 0, width, height);
}
public void checkTimeStamp()
{
long currentTime = System.currentTimeMillis();
//System.out.println("1");
if(lastCaretBlink + caretBlinkDelay < currentTime)
{
//System.out.println("2");
if(editor.equals("regist_name"))
{
cursorBlinkOn1 =! cursorBlinkOn1;
cursorBlinkOn2 = false;
cursorBlinkOn3 = false;
}
else if(editor.equals("regist_passwd"))
{
cursorBlinkOn1 = false;
cursorBlinkOn2 =! cursorBlinkOn2;
cursorBlinkOn3 = false;
}
else if(editor.equals("regist_passwd_re"))
{
cursorBlinkOn1 = false;
cursorBlinkOn2 = false;
cursorBlinkOn3 =! cursorBlinkOn3;
}
lastCaretBlink = currentTime;
}
}
public void run()
{
//System.out.println("run");
while(true)
{
checkTimeStamp();

redraw();
try
{
synchronized(this)
{
//System.out.println("3");
wait(50L);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}

protected void keyPressed(int keyCode)
{
switch(keyCode)
{
case KeyID.SOFT_RIGHT:
{
controller.handleEvent(UIController.EventID.EVENT_EXIT,null);
break;
}
case KeyID.SOFT_LEFT:
{
if(username!="" && passwd!=""&&passwd_re!="")
{
if(passwd.equals(passwd_re))
{
userRecord.db_deleteAllRecord();
if(userRecord.db_getRecord(1)==null)
{
UserDataItem userItem = new UserDataItem(1,(username+","+passwd).getBytes());
userRecord.db_addRecord(userItem);
userItem = null;
System.gc();
}

String update = "start";
Object [] args = {"activeScreen", null, update};
controller.handleEvent(UIController.EventID.EVENT_NEXT_ACTIVE_SCREEN,args);
}
}
break;
}
case KeyID.KEY_EDIT:
case KEY_NUM0:
case KEY_NUM1:
case KEY_NUM2:
case KEY_NUM3:
case KEY_NUM4:
case KEY_NUM5:
case KEY_NUM6:
case KEY_NUM7:
case KEY_NUM8:
case KEY_NUM9:
{
//System.out.println(editor);
Object[] args = {object_name,editor,username,passwd,passwd_re};
controller.handleEvent(UIController.EventID.EVENT_USER_REGIST_EDIT,args);
break;
}
default:;
}

keyCode = getGameAction(keyCode);
switch(keyCode)
{
case UP:
case LEFT:
{
currentlySelectedIndex--;
if(currentlySelectedIndex<0)
{
currentlySelectedIndex=0;
}
else
{
redraw();
}
break;
}
case DOWN:
case RIGHT:
{
currentlySelectedIndex++;
if(currentlySelectedIndex>2)
{
currentlySelectedIndex=2;
}
else
{
redraw();
}

break;
}
}
}

}

*TextEdit是利用GameCanvas绘制的自定义文本编辑框。后续文章将给出具体实现。

【分析】

1 在MainMidlet调用控制器UIController,并向UIController传递midlet作为参数。

controller=new UIController(<span style="color:#ff0000;">this</span>);  
try {
controller.init();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//

2 控制器的实现是通过一个事件的机制实现的, 在UIController中,先建立一个事件ID的内部类。

public static class EventID{  
private EventID(){
}

public static final byte EVENT_EXIT = 0;//退出
public static final byte EVENT_NEXT_WELCOME_SCREEN = 1;//欢迎界面
public static final byte EVENT_NEXT_USER_REGIST_SCREEN = 2;//用户注册
public static final byte EVENT_USER_REGIST_EDIT = 3;//用户注册编辑
public static final byte EVENT_USER_REGIST_EDIT_BACK = 4;//用户注册编辑返回
public static final byte EVENT_NEXT_ACTIVE_SCREEN = 5;
//...
}

3 一次性初始化所有界面,分配内存,调用时,只是执行视图类的show方法。为什么不将初始话放在调用时进行呢?主要是因为视图类有多次重用,如果每一次调用都new(初始化,分配内存)一次,手机有限的内存很快会被用光,这是会出现一些程序自动退出的问题。

private void initObject()  
{
welcomeScreen = new WelcomeScreen(this);
reg= new UserRegist(this);
activeScreen = new ActiveScreen(this);
...
textBox = new PopUpTextBox(this,"输入文本","", 1000, TextField.ANY);
}

4 控制器对视图的处理采用状态机实现

public void handleEvent( int eventID, Object[] args)  
{
switch (eventID)
{
case EventID.EVENT_EXIT:
{
midlet.exit(false);
break;
}
case EventID.EVENT_NEXT_WELCOME_SCREEN:
{
welcomeScreen.show();
midlet.setCurrent(welcomeScreen);
break;
}
case EventID.EVENT_NEXT_USER_REGIST_SCREEN:
case EventID.EVENT_USER_REGIST_EDIT_BACK:
{
reg.show(args);
Thread thread = new Thread(reg);
thread.start();
midlet.setCurrent(reg);
break;
}
case EventID.EVENT_USER_REGIST_EDIT:
{
textBox.init(args);
midlet.setCurrent(textBox);
break;
}
case EventID.EVENT_NEXT_ACTIVE_SCREEN:
{
activeScreen.show(args);
Thread thread = new Thread(activeScreen);
thread.start();
midlet.setCurrent(activeScreen);
break;
}
//...
default:
break;
}
}

5 视图类初始化时,需要将控制器作为参数初始化,以对事件做出判断。如WelcomeScreen.java中先做出如下声明:

private UIController controller;

再在构造函数中,传递控制器

public WelcomeScreen(UIController control) {  
// TODO Auto-generated constructor stub
super(false);
controller=control;

6 视图切换事件响应采用如下方式,在keyPressed中,对按键事件进行判断,然后调用UIController的handEvent方法。

protected void keyPressed(int keycode)  
{
switch(keycode)
{
case KeyID.SOFT_RIGHT:
{
controller.handleEvent(UIController.EventID.EVENT_EXIT,null);
break;
}
case KeyID.SOFT_LEFT:
{
String editor = "regist_name";
Object [] args = {"registScreen",editor, null,null,null};
controller.handleEvent(UIController.EventID.EVENT_NEXT_USER_REGIST_SCREEN,args);
break;
}
default:;
}
}

}

7 控制器可以通过handEvent的args传递参数,如

String update = "start";  
Object [] args = {"activeScreen", null, update};
controller.handleEvent(UIController.EventID.EVENT_NEXT_ACTIVE_SCREEN,args);

UserRegist传递了一个update变量给下一个视图。

8 在看一下模型,在UserDataItem中存储的是用户注册的信息。利用UserDataRecord类对记录进行操作。

在视图类中,通过以下方式调用:

先声明

private UserDataRecord userRecord;

构建对象

userRecord = new UserDataRecord(); 

使用对象

userRecord.db_deleteAllRecord();  
if(userRecord.db_getRecord(1)==null)
{
UserDataItem userItem = new UserDataItem(1,(username+","+passwd).getBytes());
userRecord.db_addRecord(userItem);
userItem = null;
System.gc();
}

9 包com.token.view.components是对视图类中使用的自定义控件的封装

综述,这样就实现了模型、视图、控制的分离。

相关文章

深度解析:清理烂代码
如何编写出拥抱变化的代码
重构-使代码更简洁优美
团队项目开发"编码规范"系列文章
相关文档

重构-改善既有代码的设计
软件重构v2
代码整洁之道
高质量编程规范
相关课程

基于HTML5客户端、Web端的应用开发
HTML 5+CSS 开发
嵌入式C高质量编程
C++高级编程
 
分享到
 
 


Java 中的中文编码问题
Java基础知识的三十个经典问答
玩转 Java Web 应用开发
使用Spring更好地处理Struts
用Eclipse开发iPhone Web应用
插件系统框架分析
更多...   


Struts+Spring+Hibernate
基于J2EE的Web 2.0应用开发
J2EE设计模式和性能调优
Java EE 5企业级架构设计
Java单元测试方法与技术
Java编程方法与技术


Struts+Spring+Hibernate/EJB+性能优化
华夏基金 ActiveMQ 原理与管理
某民航公司 Java基础编程到应用开发
某风电公司 Java 应用开发平台与迁移
日照港 J2EE应用开发技术框架与实践
某跨国公司 工作流管理JBPM
东方航空公司 高级J2EE及其前沿技术
更多...   
 
 
 
 
 
每天2个文档/视频
扫描微信二维码订阅
订阅技术月刊
获得每月300个技术资源
 
 

关于我们 | 联系我们 | 京ICP备10020922号 京公海网安备110108001071号