使用 MIDP Choice Group 组件

作者: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);
        }
    }
}