第4章高级用户界面及事件处理MIDP用户界面API的结构4.1Command和高级事件处理4.2高层用户界面4.3基本控件编程实例4.4小结4.54.1MIDP用户界面API的结构图形用户界面是应用程序和用户交互的接口,一个好的用户界面应该做到:操作方便、易懂、美观。图形用户界面通常包括图形和文字,手机的性能特点决定了手机平台无法实现类似Windows的用户界面。MIDP提供了一套完整的用户界面接口,全部定义在javax.microedition.lcdui包中。图4-1所示为用户界面类的阶层体系。图4-1MIDP用户界面类的体系4.2Command和高级事件处理在Java程序中,实现和用户交互功能的控件都是通过事件来处理的,这就需要指定控件所用的监听器。javax.microedition.lcdui包中定义了Command和CommandListener,使用它们可以很好的处理高级事件。一般是指按钮事件,比如用户按下键盘某键。Command类用于实现应用程序的特定操作。它必须被添加到一个Displayable对象上,当这个Displayable被显示时,所有相关的Command都会显示在手机界面下方的左右两侧。用户选择一个Command后,与当前Displayable对象相关的CommandListener会自动调用方法CommandAction(Commandc,Dispayabled)。创建新的Command对象需要调用Command类的构造方法,其构造方法语法如下:newCommand(Lablesl,Typet,Priorityp);其中Lables表示在屏幕上显示的文字。Type指定了Command对象的类型,具体类型如表4-1所示,参数“Priority”定义了Command对象的重要指数,数值越小表示越重要,数值越小的命令对象会安排在屏幕的左边。当创建了多个命令对象的时候,数值大的会安排在右边的菜单中,当数值相同的时候,会使用方法本身默认的数值。表4-1命令类型表创建一个“Exit”的命令对象代码如下:PrivateCommandexitCommand;exitCommand=newCommand(“Exit”,Command.EXIT,1);如果添加到Displayable的Command对象数量很多,MIDP会自动合并一些按钮,并将它们集中到一个菜单中,通常合并的依据是选取同类型的Command对象。图4-2说明了多个Command对象合并到一个菜单的情形。图4-2多个Command合并到一个菜单参考Exit示例4.3高层用户界面高层用户界面API是为了那些客户组件运行在移动信息设备上的商业程序设计的。对这些应用程序而言,设备间的可移植性非常重要。为了达到这样的可移植性,高层的用户界面API使用了更高的抽象,而且极少提供观感的控制。对高层MIDP用户界面API而言,这就使设备可以使用本地的用户界面观感。这意味着当一个应用程序使用高层API编写时,它的观感自动使用当前程序所运行的设备上的观感。对终端用户而言,这提供了无缝的用户交互:MIDP应用程序和设备上其他的(本地)应用程序以相同的方式工作。高层用户界面的特点显示屏上的绘图由设备系统软件执行。应用程序并不定义组件的虚拟外观(例如形状、颜色等)。导航、卷动和其他一些与用户界面组件的原始交互由设备来进行。应用程序不用了解这些交互。应用程序不能访问如个别按键等具体的输入机制。高层的API通过Screen类及其子类提供:List——允许从一个预定义的选择集中选择。TextBox——是一个拥有可控制编辑方法的文本编辑器。Alert——显示临时信息或者简单选择问询。Form——更宽泛的容器,允许显示多个密切相关的叫做Item的用户界面元素。当带一个方法的screen不够用时,就可以使用Form类。类Form被设计用来保持少量紧密关联的用户界面项目(Item)。例如,一个应用程序也许有两个TextField或者一个TextField和一个简单ChoiceGroup。如果一个Form的所有元素不能完全显示在屏幕上,那么实现也许会让Form可卷动,当用户编辑它的时候自动扩展Item,或者使用一种弹出式的显示方式。每个Form都可保持下面Item子类的组合StringItem:用于静态文本显示,或者作为一个按钮或超链接。ImageItem:用于静态图像显示,或者作为一个图像按钮或超链接。TextField:用于带约束的文本类型输入。DateField:用于时间或者日期值的显示或输入。Gauge:用于进度条或者来自某个特定范围的数值输入。ChoiceGroup:用于一个元素集合的单选或多选。CustomItem(MIDP2.0):用于创建特定应用程序的Item;绘图通过底层Graphics应用程序接口完成。Spacer(MIDP2.0):用于为层创建空的空间。虽然Form类允许任意组件组合的创建,开发人员应该牢记移动设备显示尺寸有限,尽量让Form简单、功能单一。4.4基本控件编程实例ListTextBoxAlertForm本节介绍的是Screen的一个子类List,它一共有三种具体的类型:implicit(简易式),exclusive(单选式),multiple(多选式)。与List元素相关的应用程序操作一般可概括为ITEM型命令(在后续章节将会有详细介绍)或者SCREEN类型命令,其作用域范围的判断依据是看该操作是影响到被选择原则元素还是整个List。List对象上的操作包括insert、append和delete,用于约束List具体类型的类是ChoiceGroup,List中的元素可以用getString、insert、set、append、delete、getImage等方法来具体操纵。对于项目的选择我们则使用getSelectedIndex()、setSelectedIndex()、getSelectedFlags()、setSelectedFlags()和isSelected()来处理。创建一个List屏幕类的对象可以使用两种构造方法:(1)List(Stringtitle,intlistType)(2)List(Stringtitle,intlistType,String[]stringElements,image[]imageElements)1.Exclusive(单选式)图4-3单选式List2.Implicit(隐含式)图4-4隐含式List3.Multiple(多选式)图4-5多选式List4.4.2TextBox当我们要在移动设备上输入数据时,TextBox(见图4-6)就派上用场了,创建一个TextBox我们必须使用它的构造方法。TextBox的构造方法如下:TextBox(Stringtitle,Stringtext,intmaxSize,intconstraints)。其中参数共有四个,第一个是Title,即标题,第二个是TextBox的初始内容,第三个是允许输入字符的最大长度,第四个是限制类型,限制类型有下列6个。图4-6TextBoxANY:允许输入任何文本。EMAILADDR:允许输入一个E-mail地址。NUMERIC:允许输入一个整数。PHONENUMBER:允许输入一个电话号码。URL:允许输入一个网络URL地址。PASSWORD:允许输入字符被*代替的密码。需要注意的一点是:一个TextBox必须附加一个命令,否则,用户将不能激发任何行为,而陷入这个TextBox中。4.4.3AlertAlert用来提醒用户关于错误或者其他异常情况的屏幕对象,这个警告只能作为简短的信息记录和提醒,如果我们需要长一点的,我们可以使用其他的Screen子类,最常见的是Form。同时我们顺便提一下跟它相关的一个类AlertType,需要提醒读者注意的一点是AlertType是一个本身无法实体化的工具类(即不能像Form那样产生具体的对象)。创建一个Alert对象需要用到它的构造方法,Alert的构造方法有两个。(1)Alert(Stringtitle);(2)Alert(Stringtitle,StringalertText,ImagealertImage,AlertTypealertType);其中,参数“title”指定了Alert屏幕的标题,参数“alertText”指定了Alert屏幕要显示的信息,参数“alertImage”指定了Alert屏幕要显示的图片,参数“alertType”指定了Alert的类型。Alert的类型共有下列5个。ALARM:提示已经通知系统处理用户的请求。CONFIRMATION:提示用户确认。ERROR:提示错误信息。INFO:提供给用户非威胁性的信息。WARNING:警告用户在进行有潜在危险的操作。Alert是一个比较特殊的屏幕对象,当我们在setCurrent()方法中调用它的时候,它会先发出一段警告声音,然后才会显示在屏幕上,过了一段时间之后,它会自动跳回之前的画面。需要注意的是必须在使用setCurrent()显示Alert之前定义好它可以跳回的画面,否则会发生异常。在Alert中可以通过setTimeout()方法来设定间隔的时间,通过setType()来调用我们上面提到的四种类型,setImage()用来定义图片,setString()用来定义内含文字,同时还可以通过getType(),getImage(),getString()来取得相应的对象。可以利用setTimeout()来定义Alert显示的时间,当Alert在屏幕上显示了指定的时间间隔后,它会跳回我们指定的屏幕对象,或回到前一个屏幕。如果我们调用setTimeout()时传入Alert.FOREVER作为参数,那么除非用户按下指定按键,否则,屏幕会一直显示这个Alert。如果在一个定时的Alert中只有一个命令,那么超时发生时命令会自动激活。图4-7Alert4.4.4Form概述Form是J2ME里面一个比较重要的容器类型,可以说是集中了高级UI中的精华,是开发当中常常用到的一个关键类,图4-8很好地说明了FORM及其相关子类的关系。我们通常是往Form里面添加各种Item的子类(使用append()方法),从而达到让画面更加丰富的目的,每一个Item的子类在同一时刻只能属于同一个容器,否则会引发异常。创建一个Form很简单,如:FormmainForm=newForm(“HelloWorld”)。现在我们通过append()方法添加新的控件,如添加一个TextField类型控件:mainForm.append(newTextField(“helloworld”,null,23,TextField.ANY))。图4-8FORM及其相关子类的关系在Form画面中,我们通过Item.LAYOUT_LEFT、Item.LAYOUT_CENTER和Item.LAYOUT_RIGHT来控制各个Item在Form中的位置,通过这几个参数的字面意思我们很容易明白分别是左、中、右。在不设定的情况下,Item会依照LAYOUT_DEFAULT来绘制,如果我们希望自己来设定等效线,可以用setLayout()方法来控制。同时,Form缺省的设定会在空间足够的情况下,可能让Item出现在同一个逻辑区域中。如果组件在显示时,比我们预期的最大的尺寸要大或比预期的最小尺寸更小,那么系统会自动忽略我们之前的设定,转而采用最大尺寸或者最小尺寸,这时系统会自动调用setPreferredSize(),将预期尺寸设置好。4.4.5StringItem及ImageItem1.StringItemStringItem的作用,就是在屏幕上显示一串