3.1 概述 我们在这一节要介绍一下整个LCDUI包的结构,让读者对我们整个UI的学习的有个大致的了解。下图为我们展示了整个LCDUI包的体系: Screen类属于高级图形用户界面组件,就是我们这一章要着重介绍的内容,Canvas是低级图形用户界面组件,在同一时刻,只能有唯一一个Screen或者Canvas类的子类显示在屏幕上,我们可以调用Display的setCurrent()的方法来将前一个画面替换掉,我们必须自行将前一个画面的状态保留起来,并自己控制整个程序画面的切换。 同时我们可以运用javax.microedition.lcdui.Command类来给我们的提供菜单项目的功能,分别是:Command.BACKCommand、Command.CANCEL、Command.EXIT、Command.HELP、Command.ITEM、Command.OK、Command.SCREEN和Command.STOP,我们在Displayable对象中定义了addCommand()和removeCommand()两个方法,这就意味着我们可以在高级UI和低级UI中同时使用Command类,同时我们通过注册Command事件来达到事件处理的目的,即Command必须与CommandListener接口配合使用才能反映用户的动作,具体的使用方法我们在具体的示例中会给出详细的用法,读者可以参阅API的说明文档获得进一步的认识。 还有在Displayable类的子类中都加入了Ticker,我们可以用setTicker()来设定画面上的Ticker,或者用getTicker()这个方法来取得画面所含的Ticker对象。 下面我们给出Screen类的主要结构图: 3.2 列表List 根据第零节的概述我们已经大概了解了Lcdui这个包,现在让我们来开始介绍Screen这个类里面的几个重要的类,我们本节介绍的是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类型。 3.2.1 Exclusive(单选式) 和所有的List一样,我们可以在构造函数中指定它的标题和类型(构造函数类型1),也可以使用另一种构造函数类型,即直接传入一个String数组和一个Image数组,这种构造函数可以直接对List内容进行初试化(构造函数类型2),在我们进行的大多数开发中,类型1的使用是比较常见的,读者可以通过阅读API说明文档对其进行深入的掌握。 在类型1当中,我们需要对其增加内容的时候,就需要用到前面提到的append()方法了,该构造函数的第一个参数是屏幕上的文字,第二个则是代表选项的图标,当不需要图标的时候,和我们大多数的处理方法相同,只需传入NULL这个参数就行了,任何时候我们可以用insert()方法来插入项目,用set()方法来来重新设置一个项目,当我们不需要一个项目的时候,可以用delete()方法来删除特定的选项,我们只需往该方法内传入索引值即可,需要注意的是我们的索引值是从0开始,deleteAll()这个方法则是一次性删除所有的指定List的内容。 我们在命令处理函数commandAction()中,可以用上面提到的几种方法来对用户选择的操作进行侦测,同时定义好对应的处理函数,来达到对应的处理效果。 3.2.2 Implicit (隐含式) IMPLICIT(隐含式)其实和上面的单选式没什么大的区别,唯一不同的地方在于命令的处理机制上有一些细微的区别:Choice.IMPLICIT类型的List会在用户选择之后立刻引发事件,并将List.SELECTCOMMAND作为第一个参数传入。 如果我们不希望该类型的List在按下后发出该命令作为commandAction ()的第一个参数传入,我们可以用setSelectCommand(null),将它关掉,需要注意的是,这样做的后果是使commandAction()接受到的第一个参数为null。 3.2.3 Multiple(多选式) multiple(多选式)类型的List顾名思义,可以进行多重选择,其他的地方和上面两种类型大同小异,可以进行多项的List选择。 下面我们以WTK2.1自带的DEMO为例,通过一段代码来加深巩固我们这一小节的内容: public class ListDemoextends MIDlet implements CommandListener { //这里注意如何使用 //CommandListener这个接口 private final static Command CMD_EXIT = new Command("Exit", Command.EXIT, 1); private final static Command CMD_BACK = new Command("Back", Command.BACK, 1); private Display display; private List mainList; private List exclusiveList; private List implicitList; private List multipleList; private boolean firstTime; public ListDemo() { display = Display.getDisplay(this); String[] stringArray = { "Option A", "Option B", "Option C", "Option D" }; //待传入进行初始化的String数组,即Choice选项的文字部分。 Image[] imageArray = null; //我们这里只是为Image[]数组进行初始化。 exclusiveList = new List("Exclusive", Choice.EXCLUSIVE, stringArray, imageArray); exclusiveList.addCommand(CMD_BACK); exclusiveList.addCommand(CMD_EXIT); exclusiveList.setCommandListener(this); //ExlcusiveList的声明 implicitList = new List("Implicit", Choice.IMPLICIT, stringArray, imageArray); implicitList.addCommand(CMD_BACK); implicitList.addCommand(CMD_EXIT); implicitList.setCommandListener(this); //ImplicitList的声明 multipleList = new List("Multiple", Choice.MULTIPLE, stringArray, imageArray); multipleList.addCommand(CMD_BACK); multipleList.addCommand(CMD_EXIT); multipleList.setCommandListener(this); //MutipleList的声明 firstTime = true; } protected void startApp() { if(firstTime) Image[] imageArray = null; try { Image icon = Image.createImage("/midp/uidemo/Icon.png"); //注意!这里的路径是相对路径,请大家千万注意这里的细节问题 imageArray = new Image[] { icon, icon, icon }; } catch (java.io.IOException err) { // ignore the image loading failure the application can recover. } String[] stringArray = { "Exclusive", "Implicit", "Multiple" }; mainList = new List("Choose type", Choice.IMPLICIT, stringArray, imageArray); mainList.addCommand(CMD_EXIT); mainList.setCommandListener(this); display.setCurrent(mainList); firstTime = false; } } protected void destroyApp(boolean unconditional) { } protected void pauseApp() { } public void commandAction(Command c, Displayable d) { //注意这里是如何实现CommandListener这个接口的! if (d.equals(mainList)) { if (c == List.SELECT_COMMAND) { if (d.equals(mainList)) { switch (((List)d).getSelectedIndex()) { case 0: display.setCurrent(exclusiveList); break; case 1: display.setCurrent(implicitList); break; case 2: display.setCurrent(multipleList); break; } } } } else { // in one of the sub-lists if (c == CMD_BACK) { display.setCurrent(mainList); } } if (c == CMD_EXIT) { destroyApp(false); notifyDestroyed(); } } } 3.3 TextBox 当我们要在移动设备上输入数据时,TextBox就派上用场了,我们可以TextBox的构造函数参数共有四个,第一个是我们长说的Title,即标题,第二个是TextBox的初始内容,第三个是允许输入字符的最大长度,第四个是限制类型,关于限制类型我们一般按照限制存储内容和限制系统的类型分为两种,这两种各有6个具体的类型,大家可以参阅API说明文档,获得具体类型的运用,在这里我想要提醒读者注意的一点是:一个TextBox必须附加一个命令,否则,用户将不能激发任何行为,而陷入这个TextBox中。 我们给出一个常见的TextBox的例子,让大家进一步了解一下TextBox: import javax.microedition.lcdui.*; import javax.microedition.midlet.MIDlet; public class TextBoxDemo extends MIDlet implements CommandListener { private Display display; private ChoiceGroup types; private ChoiceGroup options; private Form mainForm; private final static Command CMD_EXIT = new Command("Exit", Command.EXIT, 1); private final static Command CMD_BACK = new Command("Back", Command.BACK, 1); private final static Command CMD_SHOW = new Command("Show", Command.SCREEN, 1); /** TextBox的labels * */ static final String[] textBoxLabels = { "Any Character", "E-Mail", "Number", "Decimal", "Phone", "Url" }; /** * 这里列出了几种TextBox的Types */ static final int[] textBoxTypes = { TextField.ANY, TextField.EMAILADDR, TextField.NUMERIC, TextField.DECIMAL, TextField.PHONENUMBER, TextField.URL }; private boolean firstTime; public TextBoxDemo() { display = Display.getDisplay(this); firstTime = true; } protected void startApp() { if(firstTime) { mainForm = new Form("Select a Text Box Type"); mainForm.append("Select a text box type"); // the string elements will have no images Image[] imageArray = null; types = new ChoiceGroup("Choose type", Choice.EXCLUSIVE, textBoxLabels, imageArray); mainForm.append(types); // 进一步选择的选项 String[] optionStrings = { "As Password", "Show Ticker" }; options = new ChoiceGroup("Options", Choice.MULTIPLE, optionStrings, null); mainForm.append(options); mainForm.addCommand(CMD_SHOW); mainForm.addCommand(CMD_EXIT); mainForm.setCommandListener(this); firstTime =false; } display.setCurrent(mainForm); } protected void destroyApp(boolean unconditional) { /*抛出异常throws MIDletStateChangeException*/ } protected void pauseApp() { } public void commandAction(Command c, Displayable d) { if (c == CMD_EXIT) { destroyApp(false); notifyDestroyed(); } else if (c == CMD_SHOW) { // these are the images and strings for the choices. Image[] imageArray = null; int index = types.getSelectedIndex(); String title = textBoxLabels[index]; int choiceType = textBoxTypes[index]; boolean[] flags = new boolean[2]; options.getSelectedFlags(flags); if (flags[0]) { choiceType |= TextField.PASSWORD; } TextBox textBox = new TextBox(title, "", 50, choiceType); if (flags[1]) { textBox.setTicker(new Ticker("TextBox: " + title)); } textBox.addCommand(CMD_BACK); textBox.setCommandListener(this); display.setCurrent(textBox); } else if (c == CMD_BACK) { display.setCurrent(mainForm); } } }

评论