WEB开发网
开发学院软件开发Java 实战程序管理器和多语言程序 阅读

实战程序管理器和多语言程序

 2007-12-23 12:32:48 来源:WEB开发网   
核心提示:这两天又研究了一下MIDlet程序的设计方法,发现通过写一个程序管理器可以大大方便MIDlet编程,实战程序管理器和多语言程序,并在这个基础上扩展了多语言支持,在MIDlet编程中,只需要App.setCurrent(),你还有更多的好主意吗?跟我分享一下如何?有意见或建议请联系vmlinuxx@Gmail.com,很

这两天又研究了一下MIDlet程序的设计方法,发现通过写一个程序管理器可以大大方便MIDlet编程,并在这个基础上扩展了多语言支持。

在MIDlet编程中,很多系统的属性要通过一个MIDlet实例来访问,比如Display.getDisplay,那么在需要切换界面的类里面你必须把MIDlet实例或者Display实例传送给他,尤其在设计弹出和可以返回的界面时。没有更好的办法吗?又比如程序的暂停功能,有没有根方便的方法把他们集成起来?还有错误处理,程序退出等等,利用以往的方法是不是很不爽?

嗯,真是不爽,于是我写了这个程序管理器:App。首先看他的组织方式:

 static App instance;
 Display disp_;
 MIDlet app_;
 public static void createInstance(MIDlet app)
 {
 if(instance==null)
  instance=new App();
 instance.app_=app;
 instance.disp_=Display.getDisplay(app);
 }
 PRivate App()
 {
 
 }

每个MIDlet只需要一个管理器,所以只允许一个实例。这样,我们就可以通过静态方法提供一些系统参数的访问方法:

   public static String getProperty(String name)
   {
     return instance.app_.getAppProperty(name);
   }
 public static Display getDisplay()
 {
 return instance.disp_;
 }

他还应该提供返回前一屏的功能,如何实现呢?既然有了display,难道每次还是要App.getDisplay().setCurrent(xxx)?索性提供一个App.setCurrent():

 public static void setCurrent(Displayable d)
 {
     if(d!=instance.old_)
     {
       instance.old_=instance.disp_.getCurrent();
       instance.disp_.setCurrent(d);
     }
 }

对了,我们就利用这个来实现切换到前一屏的功能:

 public static void restore()
 {
     if(instance.old_!=null)
     {
       instance.disp_.setCurrent(instance.old_);
       instance.old_=null;
     }
 }

接下去该轮到程序暂停和恢复的处理以及一些常用命令

   public static boolean restart()
   {
     if(instance.paused_)
     {
       instance.disp_.setCurrent(instance.bef_);
       instance.paused_=false;
       return true;
     }
     else
       return false;
   }
   public static void pause()
   {
     instance.bef_=instance.disp_.getCurrent();
     instance.paused_=true;
   }
 public static void exit()
 {
 instance.app_.notifyDestroyed();
 }
   public static void handleError(String msg, Exception ex)
   {
     System.out.println(msg+"::"+ex);
   }


下面讲述多语言支持的集成。语言选择当然需要一个界面,就是这个:

   class LanguageMenu extends List implements CommandListener
   {
     Command cmdOK_;
     Object[] langlist_=new Object[]{
         "Chinese","zh_cn",null,
         "USA","en_us",null
     };

   public LanguageMenu()
     {
       super("Select Language",List.IMPLICIT);
       for(int i=0;i       {
         this.append((String)langlist_[i],(Image)langlist_[i+2]);
       }
       cmdOK_=new Command("OK",Command.SCREEN,2);
       this.addCommand(cmdOK_);
       this.setSelectCommand(cmdOK_);
       this.setCommandListener(this);
     }
    
     public void commandAction(Command c, Displayable d) {
       if(c==cmdOK_)
       {
             。。。
       }
     }
   }

这个时候又碰到了一个在实现SNProtector的时候碰到的问题,如何中断程序然后在用户确认后继续执行?在制作SNProtector的时候采用了Pause-Resume的方法实现了功能,但是效果不太理想。那只好自己多写些代码避免用户的麻烦。

这个方法通过引入一个IApp的接口,MIDlet类要实现这个接口:

   public interface IApp
   {
     public void start();
   }

然后把原来在startApp的内容放入start之中。在App中增加一个方法:

   static void continueRun()
   {
     if(instance.app_ instanceof IApp)
     {
       ((IApp)instance.app_).start();
     }
   }


嗯,好了,然后该具体实现一下语言选择菜单了:

   class LanguageMenu extends List implements CommandListener
   {
     Command cmdOK_;
     Object[] langlist_=new Object[]{
         "Chinese","zh_cn",null,
         "USA","en_us",null
     };

   public LanguageMenu()
     {
       super("Select Language",List.IMPLICIT);
       for(int i=0;i       {
         this.append((String)langlist_[i],(Image)langlist_[i+2]);
       }
       cmdOK_=new Command("OK",Command.SCREEN,2);
       this.addCommand(cmdOK_);
       this.setSelectCommand(cmdOK_);
       this.setCommandListener(this);
     }
    
     public void commandAction(Command c, Displayable d) {
       if(c==cmdOK_)
       {
         int cmd=this.getSelectedIndex();
         instance.lang_=(String)langlist_[cmd*3+1];
         try
         {
           RecordStore.deleteRecordStore(LanguageRMS);
         }
         catch(Exception ex)
         {
         }
         try
         {
           RecordStore rs=RecordStore.openRecordStore(LanguageRMS,true);
           byte[] buf=instance.lang_.getBytes();
           rs.addRecord(buf,0,buf.length);
           rs.closeRecordStore();
         }
         catch(Exception ex)
         {
         }
         continueRun();
       }
     }
   }


同样通过RMS保存了用户的选项,不用每次都选择,最后当然需要有个函数对这些工作进行调度:

   public static boolean selectLanguage()
   {
     boolean r=(instance.lang_!=null);
     if(!r)
     {
       try
       {
         RecordStore rs=RecordStore.openRecordStore(LanguageRMS,true);
         RecordEnumeration e=rs.enumerateRecords(null,null,false);
         if(e.hasNextElement())
         {
           instance.lang_=new String(e.nextRecord());
           r=true;
         }
         else
         {
           r=false;
         }
         rs.closeRecordStore();
       }
       catch(Exception ex)
       {
         r=false;
       }
       if(!r)
       {
         App.setCurrent(instance.new LanguageMenu());
       }
     }
     return r;
   }

程序管理器写完了,那么如何把他整合进MIDlet里面?看一下几个主要的函数就清楚了:

 public TestSM()
 {
 App.createInstance(this);
 }
 
 protected void startApp() throws MIDletStateChangeException {
     if(App.selectLanguage() && !App.restart())
     {
       start();
     }
 }
  
   public void start()
   {
     SM.getInstance(App.getLanguage()).load("1");
     App.setCurrent(new TestCanvas());
   }


 protected void pauseApp() {
     App.pause();
 }

ok,这回是大功告成了。总结一下他的优点:
1。在需要返回前一屏的地方只需要一个App.restore();
2。自动处理暂停和恢复;
3。随时取得系统参数App.getProperty();
4。统一的错误处理;
5。整合多语言功能;
6。更方便的切换屏幕,只需要App.setCurrent()。

你还有更多的好主意吗?跟我分享一下如何?
有意见或建议请联系vmlinuxx@Gmail.com,共同学习,共同提高:)

(出处:http://www.cncms.com)


Tags:实战 程序 管理

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接