作者:Eric Giguere
October 4, 2002
MIDP 定义了一组类,是你能够以一种抽象风格创建用户界面。这些类,被称为高层用户界面 API,是应用创建表单-顶层窗口-超出了独立的用户界面元素,被称为项目。每个项目标是一个明确的用户交互,像显示输入域和从用户收集一个文本。
其中最有用的一个项目是Choice Group,帮助用户从列表中选择一个或多个值。定义一个choice group的类是ChoiceGroup类,javax.microedition.lcdui包的一部分。ChoiceGroup与List类共享很多方法,在“使用列表组件”讨论过。实际上,两个类都实现了Choice界面,定义了用于添加,删除,和操作一个列表或Choice Group显示中的数值。不象Choice Group, Lists是顶层窗口,而不是表单项目-一个list基本上是一个预定义的含有一个choice group的表单项目和一些预定义的功能。
MIDP 1.0为Choice Group定义了两种选择方式:exclusive和multiple。在exclusive方式,用户一次可以准确选择一个数值,就像一组radioboxes。在multiple方式,用户可以同时选择多个项目,就像一组Checkboxes。MIDP 2.0定义了第三种方式,popup方式,它类似于exclusive方式,但是为被选择的值在它们不需要被选择之前是隐藏的。使用常量Choice.EXCLUSIVE,Choice.MULTIPLE,Choice.POPUP来指定你所喜欢的方式。注意:还有第四种方式,由常量Choice.IMPLICIT表示,但是它只能用于列表,而不能用于Choice Group。每个存储在Choice Group中的值由一个非0字符串和一个可选图像组成。设备将显示你提供的任何图像,如果你能够提供的话,但是它可以随意忽略任何图像,而只显示字符串。在MIDP 1.0中只有不可变的图像可以被添加到Choice Group,MIDP 2.0在允许你使用可变图像的同时,也允许你添加不可变图像到一个组种。不象1.0版,MIDP 2.0版也允许应用为Group指定字体和text-wrapping设置参数-象往常一样,由于这些参数是选项,MIDP实现可以忽略这些参数。
Choice Group类定义两个构造函数:
public ChoiceGroup( String label, int mode );
public ChoiceGroup( String label, int mode, String[] values, Image[] images );
第一个参数定义一个label,一个可选字符串,显示在Choice Group的上方或旁边。如果不需要Label就传递null。第二个参数定义选择方式。第一个构造函数创建一个空的choice group,在内容是在运行时是变化的情况下有用。如果一个choice group的内容是静态的,使用第二种构造函数的第三和第四个参数定义group的初始内容,如下所示:
public static final String[] values = new String[] { "Apples", "Oranges", "Bananas" }; ChoiceGroup cg = new ChoiceGroup("Fruit", Choice.MULTIPLE, values, null);
无论choice group是如何被初始化的,你可以在运行是修改它的设置值,使用append(), delete(), 和insert()方法,以及使用set()方法来修改每个数值。
为了显示choice group,使用Form.append()将它添加到一个Form,并使Form成为当前可显示的Form:
Display display = .... // the MIDlet's display object Form f = new Form(); ChoiceGroup cg = new ChoiceGroup("Send?", Choice.EXCLUSIVE); cg.append("Yes", null); cg.append("No", null); f.append(cg); display.setCurrent(f);
底层用户界面元素的显示在这一点上是你无法控制的;当然,实现对外观是完全可以控制的。一组radiobox或checkbox是常用的。
两种方法可以提供有关用户在choice group中选择的信息。在选择exclusive方式是使用getSelectedIndex(),它返回选择值的索引(从0开始),或-1如果没有数值被选中。注意,如果选择方式是multiple,即使你只选择一个选项,这个方法通常返回-1。对于多选choice group,是用getSelectedFlags(),传递个它一个布尔数组:
ChoiceGroup cg = ..... boolean[] flags = new boolean[cg.size()]; cg.getSelectedFlags(flags);
数组被设置为选项相应的数值。编程的方式设置或重新设置这个值,使用setSelectedIndex()或setSelectedFlags()。
当用户在Form中注册了一个ItemStateListener时,应用可以跟踪用户的选择。Listener的itemStateChanged()方法在每次Form项目改变时被调用,包括每次choice group的数值被选择和取消选择。跟踪项目选择状态的更多信息,参见“Validating Input Using the ItemStateListener Interface”。
以下示例是一个简单的MIDlet,用于引导用户选择一些值并显示结果。
import java.util.*; import javax.microedition.lcdui.*; import javax.microedition.midlet.*; public class ChoiceGroupTest extends MIDlet implements CommandListener { private Display display; private PromptForm prompt; private ResultForm result; public static final Command exitCommand = new Command("Exit", Command.EXIT, 1); public static final Command okCommand = new Command("OK", Command.OK, 1); public static final Command clearCommand = new Command("Clear", Command.SCREEN, 1); public ChoiceGroupTest() { } public void commandAction(Command c, Displayable d) { if (c == exitCommand) { exitMIDlet(); } else if (c == okCommand) { display.setCurrent(new ResultForm()); } else if (c == clearCommand) { prompt.clearAll(); } } protected void destroyApp(boolean unconditional) throws MIDletStateChangeException { exitMIDlet(); } public void exitMIDlet() { notifyDestroyed(); } public Display getDisplay() { return display; } protected void initMIDlet() { prompt = new PromptForm(); display.setCurrent(prompt); } protected void pauseApp() { } protected void startApp() throws MIDletStateChangeException { if (display == null) { display = Display.getDisplay(this); initMIDlet(); } } private static final String[] ageList = { "under 18", "18 to 25", "26 to 39", "40 and higher" }; private static final String[] fruitList = { "apples", "bananas", "oranges", "pears" }; public class PromptForm extends Form { public PromptForm() { super("Who are you?"); append(age); append(fruits); addCommand(okCommand); addCommand(clearCommand); setCommandListener(ChoiceGroupTest.this); } public void clearAll() { age.setSelectedIndex(0, true); boolean[] flags = new boolean[fruits.size()]; for (int i = 0; i < flags.length; ++i) { flags[i] = false; } fruits.setSelectedFlags(flags); } public String getAge() { return ageList[age.getSelectedIndex()]; } public Enumeration getFruits() { Vector v = new Vector(); boolean[] flags = new boolean[fruits.size()]; fruits.getSelectedFlags(flags); for (int i = 0; i < flags.length; ++i) { if (flags[i]) { v.addElement(fruitList[i]); } } return v.elements(); } ChoiceGroup age = new ChoiceGroup("Select age range", Choice.EXCLUSIVE, ageList, null); ChoiceGroup fruits = new ChoiceGroup("Select the fruits you like", Choice.MULTIPLE, fruitList, null); } public class ResultForm extends Form { public ResultForm() { super("Results"); append("Your age is " + prompt.getAge()); append(" and you like these fruits: "); int count = 0; Enumeration e = prompt.getFruits(); StringBuffer b = new StringBuffer(); while (e.hasMoreElements()) { b.setLength(0); if (count++ > 0) { b.append(", "); } b.append((String) e.nextElement()); append(b.toString()); } if (count == 0) { append("(none)"); } addCommand(exitCommand); setCommandListener(ChoiceGroupTest.this); } } }