欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JavaMe开发绘制文本框TextEdit

程序员文章站 2024-03-05 21:30:13
【问题描述】 textedit是采用gamecanvas绘制的文本编辑器。本文结合实例给出实现的方法。 【原理】 1 运用graphics、gamecanvas绘制文...

【问题描述】

textedit是采用gamecanvas绘制的文本编辑器。本文结合实例给出实现的方法。

【原理】

1 运用graphics、gamecanvas绘制文本框和光标。

2 检测到输入事件时,跳转到 高级界面->textbox 。通过系统调用输入法完成输入。

3 将textbox输入的值返回给textedit对象。

【设计模式】

这个过程有点类似装饰模式,实际上,实现输入的还是textbox,只是给textbox装饰了一下,形成了一个漂亮的外观。

【代码清单】

textedit.java

package com.token.view.components; 
 
import javax.microedition.lcdui.font; 
import javax.microedition.lcdui.graphics; 
import javax.microedition.lcdui.game.gamecanvas; 
 
public class textedit extends gamecanvas 
{ 
  private font ft; 
   
  public int width; 
  public int height; 
   
  public textedit(gamecanvas canvas)  
  { 
    super(false); 
     
  } 
   
  //绘制文本框 
  public void drawtextbox(gamecanvas canvas, graphics graphics, string text, int x, int y, boolean cursorblinkon) 
  { 
    //system.out.println("draw"); 
    int padding = 4; 
    int margin = 2; 
     
    ft = font.getfont(font.face_proportional,font.style_plain,font.size_medium); 
    graphics.setfont(ft); 
     
    width = 3*canvas.getwidth()/5+2*padding; 
    height = ft.getheight()+2*padding; 
 
    graphics.setcolor(color.frame); 
    graphics.fillrect(x+1,y+1,width+margin,height+margin); 
     
    graphics.setcolor(color.framebg); 
    graphics.drawrect(x, y,width, height); 
    graphics.setcolor(color.background); 
    graphics.fillrect(x+1, y+1,width-1,height-1); 
     
    graphics.setcolor(color.text); 
    graphics.drawstring(text, x+padding, y+padding, graphics.top|graphics.left); 
     
    drawcursor(graphics, x+ft.stringwidth(text)+padding, y+padding, 1, ft.getheight(), cursorblinkon); 
     
    canvas.flushgraphics(x,y,width,height); 
  } 
 
 
  //绘制光标 
  public void drawcursor(graphics graphics, int x, int y, int width, int height, boolean cursorblinkon) 
  { 
    if(cursorblinkon) 
    { 
      ft = font.getfont(font.face_proportional,font.style_plain,font.size_medium); 
      graphics.setfont(ft); 
      graphics.setcolor(0x0,0x0,0x0); 
      graphics.drawline(x+width,y,x+width,y+height); 
    } 
  } 
} 
popuptextbox.java

package com.token.view; 
 
import javax.microedition.lcdui.command; 
import javax.microedition.lcdui.commandlistener; 
import javax.microedition.lcdui.displayable; 
import javax.microedition.lcdui.textbox; 
 
import com.token.util.uicontroller; 
 
public class popuptextbox extends textbox { 
 
   private uicontroller controller; 
   protected string canvastext = ""; 
   private command okcommand; 
   private command cancelcommand; 
   private string object_name = null; 
   private string editor = null; 
   private object args_t[]; 
   private object[] args; 
    
   
   public popuptextbox(uicontroller control, string title, string text, int maxsize, int constraints)  
   { 
     super(title, text, maxsize, constraints); 
     controller = control; 
      
     args = new object[6]; 
      
     okcommand = new command("确定", command.ok, 1); 
     cancelcommand = new command("取消", command.cancel, 1); 
      
     this.addcommand(okcommand); 
     this.addcommand(cancelcommand); 
     this.setcommandlistener(new textboxlistener()); 
   } 
    
   public void init(object[] args) 
   { 
     object_name = ((string)args[0]!=null)?(string)args[0]:""; 
     editor = ((string)args[1]!=null)?(string)args[1]:""; 
     //system.out.println(object_name); 
     //system.out.println(editor); 
     args_t = args; 
     this.setstring(""); 
   } 
      
   protected void closetextbox(boolean update) { 
      if (update) canvastext = this.getstring(); 
      //system.out.println(canvastext); 
 
      if(object_name.equals("registscreen")) 
      { 
        if(editor.equals("regist_name")) 
        { 
          if(args_t[3]!=""||args_t[3]!=null||args_t[4]!=""||args_t[4]!=null) 
          { 
            args[0] = object_name; 
            args[1] = editor; 
            args[2] = this.canvastext; 
            args[3] = args_t[3]; 
            args[4] = args_t[4]; 
          } 
          controller.handleevent(uicontroller.eventid.event_user_regist_edit_back,args); 
        } 
        else if(editor.equals("regist_passwd")) 
        { 
          if(args_t[2]!=""||args_t[2]!=null||args_t[4]!=""||args_t[4]!=null) 
          { 
            args[0] = object_name; 
            args[1] = editor; 
            args[2] = args_t[2]; 
            args[3] = this.canvastext; 
            args[4] = args_t[4]; 
          } 
          controller.handleevent(uicontroller.eventid.event_user_regist_edit_back,args); 
        } 
        else if(editor.equals("regist_passwd_re")) 
        { 
          if(args_t[2]!=""||args_t[2]!=null||args_t[3]!=""||args_t[3]!=null) 
          { 
            args[0] = object_name; 
            args[1] = editor; 
            args[2] = args_t[2]; 
            args[3] = args_t[3]; 
            args[4] = this.canvastext; 
          } 
          controller.handleevent(uicontroller.eventid.event_user_regist_edit_back,args); 
        } 
      } 
       
      //... 
  } 
    
   private class textboxlistener implements commandlistener 
   {  
    public void commandaction(command command, displayable disp) 
    { 
      if(command==okcommand) 
      { 
        closetextbox(true); 
      } 
      else if(command==cancelcommand) 
      { 
        closetextbox(false); 
      } 
    } 
  } 
} 
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_token_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; 
      } 
    } 
  } 
} 

【分析】

1 文本框的绘制(textedit.java)

需要传递gamecanvas、graphics对象,实现绘图,策略是谁使用,谁传递该参数。此外需要床底文本框左上角坐标(x,y)以及控制光标闪烁的变量cursorblinkon。

public void drawtextbox(gamecanvas canvas, graphics graphics, string text, int x, int y, boolean cursorblinkon) 
{ 
  //system.out.println("draw"); 
  int padding = 4; 
  int margin = 2; 
   
  ft = font.getfont(font.face_proportional,font.style_plain,font.size_medium); 
  graphics.setfont(ft); 
   
  width = 3*canvas.getwidth()/5+2*padding; 
  height = ft.getheight()+2*padding; 
 
  graphics.setcolor(color.frame); 
  graphics.fillrect(x+1,y+1,width+margin,height+margin); 
     
  graphics.setcolor(color.framebg); 
  graphics.drawrect(x, y,width, height); 
  graphics.setcolor(color.background); 
  graphics.fillrect(x+1, y+1,width-1,height-1); 
     
  graphics.setcolor(color.text); 
  graphics.drawstring(text, x+padding, y+padding, graphics.top|graphics.left); 
     
  drawcursor(graphics, x+ft.stringwidth(text)+padding, y+padding, 1, ft.getheight(), cursorblinkon); 
     
  canvas.flushgraphics(x,y,width,height); 
} 

2 绘制光标(textedit.java)

public void drawcursor(graphics graphics, int x, int y, int width, int height, boolean cursorblinkon) 
{ 
  if(cursorblinkon) 
  { 
    ft = font.getfont(font.face_proportional,font.style_plain,font.size_medium); 
    graphics.setfont(ft); 
    graphics.setcolor(0x0,0x0,0x0); 
    graphics.drawline(x+width,y,x+width,y+height); 
  } 
} 

3 实现光标闪烁

光标闪烁的实现需要用到线程,在uicontroller.java类中,需要绘制文本框的视图类,需要实现线程接口。

uicontroller.java

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; 
} 
userregist.java

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(); 
    } 
       
  } 
} 


4 调用高级界面textbox子类popuptextbox

调用时,将调用对象名、编辑对象名、以及编辑框参数传递给popuptextbox对象(一定要有,目的是保存编辑框的值,否则多次调用返回时,不同编辑框的值被刷新为空了)

userregist.java(keypressed)

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; 
} 
uicontroller.java

case eventid.event_user_regist_edit: 
{ 
   textbox.init(args); 
     midlet.setcurrent(textbox); 
   break; 
} 


5 popuptextbox参数的接收

public void init(object[] args) 
{ 
   object_name = ((string)args[0]!=null)?(string)args[0]:""; 
   editor = ((string)args[1]!=null)?(string)args[1]:""; 
   //system.out.println(object_name); 
   //system.out.println(editor); 
   args_t = args; 
   this.setstring(""); 
} 

6 popuptextbox返回输入法输入的值

if (update) canvastext = this.getstring();
7 popuptextbox输入值处理

依据调用的对象,以及编辑对象,对输入的值进行处理,传递给父对象编辑框

if(object_name.equals("registscreen")) 
{ 
    if(editor.equals("regist_name")) 
    { 
        if(args_t[3]!=""||args_t[3]!=null||args_t[4]!=""||args_t[4]!=null) 
        { 
          args[0] = object_name; 
          args[1] = editor; 
          args[2] = this.canvastext; 
          args[3] = args_t[3]; 
          args[4] = args_t[4]; 
        } 
        controller.handleevent(uicontroller.eventid.event_user_regist_edit_back,args); 
  } 
  else if(editor.equals("regist_passwd")) 
  { 
        if(args_t[2]!=""||args_t[2]!=null||args_t[4]!=""||args_t[4]!=null) 
        { 
          args[0] = object_name; 
          args[1] = editor; 
          args[2] = args_t[2]; 
          args[3] = this.canvastext; 
          args[4] = args_t[4]; 
        } 
        controller.handleevent(uicontroller.eventid.event_user_regist_edit_back,args); 
  } 
  else if(editor.equals("regist_passwd_re")) 
  { 
        if(args_t[2]!=""||args_t[2]!=null||args_t[3]!=""||args_t[3]!=null) 
        { 
          args[0] = object_name; 
          args[1] = editor; 
          args[2] = args_t[2]; 
          args[3] = args_t[3]; 
          args[4] = this.canvastext; 
        } 
        controller.handleevent(uicontroller.eventid.event_user_regist_edit_back,args); 
  } 
}


8 输入值的显示

(1) 新建对象

private textedit textedit_name; 
textedit_name = new textedit(this); 

(2) 接受输入的参数

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]:""; 

(3) 光标控制,定位到编辑对象,控制编辑对象的光标闪烁(run方法)

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:; 
  } 
//... 
 
} 


(4) 编辑框的绘制

private void redraw() 
{ 
  ...    
  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(); 
} 

实现的效果如图1所示:

JavaMe开发绘制文本框TextEdit