4.3.3 高级用户界面事件处理
 

4.3.3 事件处理

       在界面编程中,需要处理各种用户对于界面的操作,这种处理叫做事件处理。在高级用户界面编程中,可以处理的事件非常有限,主要只能处理两类事件:

u       Command被按下事件

u       控件状态改变事件,例如文本框中输入的内容变化,选择框选中的内容变化等。说明:因为控件只能添加到Form中,所以该事件只在Form中触发和处理。

       除了这两类事件以外,其他的事件一般不能处理,所以高级界面的表现力比较差。下面就来介绍一下高级用户界面是如何进行事件处理的。

       在高级用户界面的事件处理中,和AWT/Swing一样,使用监听器(Listener)模式。在Command按下或者控件内容改变时,首先被手机中的系统捕获,然后将这个事件传递给界面对应的XXXListener,把事件的处理交给该XXXListener实现,这就是事件处理模型的简单介绍。

       针对两种事件类型,在事件处理时设计了两个Listener来对应,依次是:

u       CommandListener——Command被按下的事件

u       ItemStateListener——控件状态改变

基于以上说明,所以进行事件处理时一般有三个步骤:

u       声明一个类实现XXXListener接口,可以在界面类中实现也可以实现在其他类中。

u       为界面指定对应的XXXListener,使用界面类的setXXXListener方法

u       在实现了XXXListener接口类中对应的方法内部编写事件处理的代码。

       其中CommandListener的方法是commandAction(Command c, Displayable d)

              ItemStateListener的方法是itemStateChanged(Item item)

       具体使用可以参看后面的示例代码以及API文档。

       下面以CommandListener为例子来介绍一下事件处理代码的编写,在该示例中事件处理的代码只实现检测输入是否为空。具体的代码如下:

//文件名:CommandListenerMIDlet.java

import javax.microedition.lcdui.*;

import javax.microedition.midlet.*;

/**

 * CommandListener的基础使用

 */

public class CommandListenerMIDlet extends MIDlet{

       /**显示控制对象*/

       private Display display;

      

       public CommandListenerMIDlet(){

              //创建显示控制对象

              display = Display.getDisplay(this);

              //创建界面

              CommandListenerForm clf = new CommandListenerForm();

              //在手机中显示该界面

              display.setCurrent(clf);

       }

      

       public void startApp(){}

 

       public void pauseApp(){}

 

       public void destroyApp(boolean b){}

}

 

//文件名:CommandListenerForm.java

import javax.microedition.lcdui.*;

/**

 * CommandListener的基本使用

 */

public class CommandListenerForm extends Form implements CommandListener{

       /**TextField对象*/

       TextField tf;

       /**Command对象*/

       Command cmdOK;

       /**

        * 默认构造方法

        */

       public CommandListenerForm(){

              super("TextField使用");       

              //创建TextField对象

              tf = new TextField("用户名:","",16,TextField.ANY);

              //添加到界面类中

              this.append(tf);

              //创建Command对象

              cmdOK = new Command("确定",Command.OK,1);

              //添加到界面类

              this.addCommand(cmdOK);

             

              //注册事件监听器

              this.setCommandListener(this);

       }

      

       public void commandAction(Command c,Displayable d){

              //判断按下的按钮是否是确定按钮

              if(c == cmdOK){

                     //获得文本框中的输入

                     String inputStr = tf.getString();

                     //判断是否为空

                     if(inputStr.length() == 0){

                            System.out.println("输入为空!");      

                     }else{

                            System.out.println("输入不为空!");

                     }

              }

       }

}

       在该代码中,使界面类CommandListenerForm实现了CommandListener接口,按照语法要求覆盖了CommandListener接口的抽象方法commandAction,然后在界面类的构造方法中为该界面注册事件监听器,代码如下:

       //注册事件监听器

       this.setCommandListener(this);

       其中这里的this代表CommandListenerForm类本身,CommandListenerForm类既继承了Form类又实现了CommandListener接口,所以第一个this调用Form类中的方法setCommandListener为界面注册事件监听器,因为该类本身实现了CommandListener接口,所以这里把该界面的事件处理注册给自身,所以在参数部分也写成了this

       这样当用户按下按钮时,系统就会自动调用当前类中的commandAction方法进行事件处理,该方法中的两个参数依次是按下的按钮对象以及该按钮所在的界面对象。

       所以只需要在commandAction方法内部编写事件处理的代码即可,在发生对应的事件时,手机系统会自动调用该方法,然后该方法内部的代码就会得到执行。

       如果需要在界面类中实现界面的切换,则需要把Display对象作为参数从MIDlet类传递到界面类内部,然后使用Display类的setCurrent方法进行切换,示例的代码如下:

              //文件名:AnotherCommandListenerMIDlet.java

import javax.microedition.lcdui.*;

import javax.microedition.midlet.*;

/**

 * 演示界面切换的一种方法

 */

public class AnotherCommandListenerMIDlet extends MIDlet{

       /**显示控制对象*/

       private Display display;

      

       public AnotherCommandListenerMIDlet(){

              //创建显示控制对象

              display = Display.getDisplay(this);

              //创建界面

              AnotherCommandListenerForm clf = new AnotherCommandListenerForm(display);

              //在手机中显示该界面

              display.setCurrent(clf);

       }

      

       public void startApp(){}

 

       public void pauseApp(){}

 

       public void destroyApp(boolean b){}

}

 

//文件名:AnotherCommandListenerForm.java

import javax.microedition.lcdui.*;

/**

 * 演示界面切换

 */

public class AnotherCommandListenerForm extends Form implements CommandListener{

       /**TextField对象*/

       TextField tf;

       /**Command对象*/

       Command cmdOK;

       /**Display对象*/

       Display display;

       /**

        * 使用Display对象进行构造

        * @param display 显示控制对象

        */

       public AnotherCommandListenerForm(Display display){

              super("TextField使用");

             

              this.display = display;

             

              //创建TextField对象

              tf = new TextField("用户名:","",16,TextField.ANY);

              //添加到界面类中

              this.append(tf);

              //创建Command对象

              cmdOK = new Command("确定",Command.OK,1);

              //添加到界面类

              this.addCommand(cmdOK);

             

              //注册事件监听器

              this.setCommandListener(this);

       }

      

       public void commandAction(Command c,Displayable d){

              //判断按下的按钮是否是确定按钮

              if(c == cmdOK){

                     //获得文本框中的输入

                     String inputStr = tf.getString();

                     //提示框界面

                     Alert alert = new Alert("信息提示","",null,AlertType.INFO);

                     //判断是否为空

                     if(inputStr.length() == 0){

                            alert.setString("输入为空!");     

                     }else{

                            alert.setString("输入不为空!");

                     }

                     //切换界面,显示提示框

                     display.setCurrent(alert);

              }

       }

}

       在该示例代码中,将在MIDlet类中创建好的Display对象通过界面类的构造方法传递到界面类内部,然后在事件处理的方法内部调用该对象的setCurrent方法实现界面的切换,这是一种简单的界面切换方法。当然其他的切换方法还有很多,这里就不一一介绍了。

       ItemStateListener的使用和CommandListener类似,大家可以自己动手使用一下,加深对于监听器模式和事件处理的理解和认识。