快捷搜索:

J2ME中文教程 3 MIDP高级UI 的使用<BR><a name="_Toc1

第3章MIDP高档UI 的应用

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.1Exclusive(单选式)

和所有的List一样,我们可以在构造函数中指定它的标题和类型(构造函数类型1),也可以应用另一种构造函数类型,即直接传入一个String数组和一个Image数组,这种构造函数可以直接对List内容进行初试化(构造函数类型2),在我们进行的大年夜多半开拓中,类型1的应用是对照常见的,读者可以经由过程涉猎API阐明文档对其进行深入的掌握。

在类型1傍边,我们必要对其增添内容的时刻,就必要用到前面提到的append()措施了,该构造函数的第一个参数是屏幕上的翰墨,第二个则是代表选项的图标,当不必要图标的时刻,和我们大年夜多半的处置惩罚措施相同,只需传入NULL这个参数就行了,任何时刻我们可以用insert()措施来插入项目,用set()措施来来从新设置一个项目,当我们不必要一个项目的时刻,可以用delete()措施来删除特定的选项,我们只需往该措施内传入索引值即可,必要留意的是我们的索引值是从0开始,deleteAll()这个措施则是一次性删除所有的指定List的内容。

我们在敕令处置惩罚函数commandAction()中,可以用上面提到的几种措施来对用户选择的操作进行侦测,同时定义好对应的处置惩罚函数,来达到对应的处置惩罚效果。

3.2.2Implicit (隐含式)

IMPLICIT(隐含式)着实和上面的单选式没什么大年夜的差别,独一不合的处所在于敕令的处置惩罚机制上有一些细微的差别:Choice.IMPLICIT类型的List会在用户选择之后立即激发事故,并将List.SELECTCOMMAND作为第一个参数传入。

假如我们不盼望该类型的List在按下后发出该敕令作为commandAction ()的第一个参数传入,我们可以用setSelectCommand(null),将它关掉落,必要留意的是,这样做的后果是使commandAction()吸收到的第一个参数为null。

3.2.3Multiple(多选式)

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.3TextBox

当我们要在移动设备上输入数据时,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);

}

}

}

3.4Alert

这个类对照故意思,它是用来提醒用户关于差错或者其他非常环境的屏幕工具,这个警告只能作为简短的信息记录和提醒,假如我们必要长一点的,我们可以应用其它的Screen子类,最常见的是Form。同时我们顺便提一下跟它相关的一个类AlertType,必要提醒读者留意的一点是AlertType是一个本身无法实体化的对象类。(即我们不能象Form那样孕育发生详细的工具)

AlertType共有5个类型:ALARM(警报),CONFIRMATION(确定),ERROR(差错),INFO(信息提示),WARNING(警告)。

Alert是一个对照特殊的屏幕工具,当我们在setCurrent()措施中调用它的时刻,它会先发出一段警告的声音,然后彩绘显示在屏幕上,过了一段光阴之后,它会自动跳回之前的画面。

我们必要留意的是我们必须在应用setCurrent()显示Alert之前定义好它可以跳回的画面,否则会发生非常。

在Alert中我们可以经由过程setTimeout()措施来设定距离的光阴,setType()来调用我们上面提到的四种类型,setImage()来定义图片,setString()来定义内含翰墨,同时经由过程getType(),getImage(),getString()来取得响应的工具。

当Alert显示了我们在setTimeout()中指定的距离光阴后,它会跳回我们之前指定的工具,假如我们在指定显示光阴时传入了Alert.FOREVER作为参数,这时,除非用户按下定义哈哦的打仗键,否则,屏幕会不停显示这个Alert。假如在一个准时的Alert中只有一个敕令,那么超时发生时敕令会自动激活。

import javax.microedition.lcdui.*;

import javax.microedition.midlet.MIDlet;

public class AlertDemo

extends MIDlet {

private final static Command CMD_EXIT = new Command("Exit", Command.EXIT,

1);

private final static Command CMD_SHOW = new Command("Show", Command.SCREEN,

1);

private final static String[] typeStrings = {

"Alarm", "Confirmation", "Error", "Info", "Warning"

};

private final static String[] timeoutStrings = {

"2 Seconds", "4 Seconds", "8 Seconds", "Forever"

};

private final static int SECOND = 1000;

private Display display;

private boolean firstTime;

private Form mainForm;

public AlertDemo() {

firstTime = true;

mainForm = new Form("Alert Options");

}

protected void startApp() {

display = Display.getDisplay(this);

showOption();

}

/**

* 制造这个MIDlet的基础显示

* 在这个Form里面我们可以选择Alert的其中类型和特点

*/

private void showOption() {

if(firstTime) {

// choice-group for the type of the alert:

// "Alarm", "Confirmation", "Error", "Info" or"Warning"

ChoiceGroup types = new ChoiceGroup("Type", ChoiceGroup.POPUP,

typeStrings, null);

mainForm.append(types);

// choice-group for the timeout of the alert:

// "2 Seconds", "4 Seconds", "8 Seconds" or "Forever"

ChoiceGroup timeouts = new ChoiceGroup("Timeout", ChoiceGroup.POPUP,

timeoutStrings, null);

mainForm.append(timeouts);

// a check-box to add an indicator to the alert

String[] optionStrings = { "Show Indicator" };

ChoiceGroup options = new ChoiceGroup("Options", Choice.MULTIPLE,

optionStrings, null);

mainForm.append(options);

mainForm.addCommand(CMD_SHOW);

mainForm.addCommand(CMD_EXIT);

mainForm.setCommandListener(new AlerListener(types, timeouts, options));

firstTime = false;

}

display.setCurrent(mainForm);

}

private class AlerListener

implements CommandListener {

AlertType[] alertTypes = {

AlertType.ALARM, AlertType.CONFIRMATION, AlertType.ERROR,

AlertType.INFO, AlertType.WARNING

};

ChoiceGroup typesCG;

int[] timeouts = { 2 * SECOND, 4 * SECOND, 8 * SECOND, Alert.FOREVER };

ChoiceGroup timeoutsCG;

ChoiceGroup indicatorCG;

public AlerListener(ChoiceGroup types, ChoiceGroup timeouts,

ChoiceGroup indicator) {

typesCG = types;

timeoutsCG = timeouts;

indicatorCG = indicator;

}

public void commandAction(Command c, Displayable d) {

if (c == CMD_SHOW) {

int typeIndex = typesCG.getSelectedIndex();

Alert alert = new Alert("Alert");

alert.setType(alertTypes[typeIndex]);

int timeoutIndex = timeoutsCG.getSelectedIndex();

alert.setTimeout(timeouts[timeoutIndex]);

alert.setString(

typeStrings[typeIndex] + " Alert, Running " + timeoutStrings[timeoutIndex]);

boolean[] SelectedFlags = new boolean[1];

indicatorCG.getSelectedFlags(SelectedFlags);

if (SelectedFlags[0]) {

Gauge indicator = createIndicator(timeouts[timeoutIndex]);

alert.setIndicator(indicator);

}

display.setCurrent(alert);

} else if (c == CMD_EXIT) {

destroyApp(false);

notifyDestroyed();

}

}

}

protected void destroyApp(boolean unconditional) {

}

protected void pauseApp() {

}

/**

* 我们在这里天生Alert的indicator.

* 假如这里没有timeout, 那么这个indicator 将是一个 "非交互性的" gauge

*用有一个后台运行的thread更新.

*/

private Gauge createIndicator(int maxValue) {

if (maxValue == Alert.FOREVER) {

return new Gauge(null, false, Gauge.INDEFINITE,

Gauge.CONTINUOUS_RUNNING);

}

final int max = maxValue / SECOND;

final Gauge indicator = new Gauge(null, false, max, 0);

//if (maxValue != Gauge.INDEFINITE) {

new Thread() {

public void run() {

int value = 0;

while (value

indicator.setValue(value);

++value;

try {

Thread.sleep(1000);

} catch (InterruptedException ie) {

// ignore

}

}

}

}.start();

}

return indicator;

}

}

3.5Form概述

Form是J2ME里面一个对照紧张的容器类型,可以说是集中了高档UI中的英华,是开拓傍边经常用到的一个关键类,下图很好的阐清楚明了FORM及其相关子类的关系:

我们平日是往Form里面添加其中Item的子类(应用append()措施),从而达到让画面加倍富厚的目的,每一个Item的子类在同一时候只能属于同一个容器,否则会激发非常。

在Form画面中,我们经由过程Item.LAYOUT_LEFT、Item.LAYOUT_CENTER和Item.LAYOUT_RIGHT来节制各个Item在Form的位置,经由过程这几个参数的字面意思我们很轻易明白分手是左,中,右。在不设定的环境下,Item会依照LAYOUT_DEFAULT来绘制,假如我们盼望自己来设定等效线,可以用setLayout()这个措施来节制。

同时,Form缺省的设定会在空间足够的环境下,尽可能让Item呈现在同一个逻辑区域中。假如组件在显示时,比我们预期的最大年夜的尺寸要大年夜(或比预期最小尺寸更小),那么系统会自动轻忽我们之前的设定,转而采纳最大年夜尺寸或者最小尺寸,这时系统会自动调用setPreferredSize(),将预期尺寸设置好。

3.6StringItem及ImageItem

3.6.1StringItem

StringItem的感化,从它字面上意思来看就可以很明白,便是在屏幕上显示一串字,共同不合的外不雅类型, StringItem有两个构造函数,最长见的是必要三个参数的,第一个是Label,第二个是内容,第三个则是外不雅,外不雅共分三种:PLAIN,BUTTON,HYPERLINK,(只需两个参数的构造函数等同于应用PLAIN的外不雅的三个参数的构造函数),对付外不雅的提取,我们可以应用getAppearanceMode()取得,以此类推,必要改动/获得响应的参数只需进行响应的set/get操作即可。

我们可以把Item和其他的高档UI部分结合起来,这样也是对我们进修的一种匆匆进:

import javax.microedition.lcdui.*;

import javax.microedition.midlet.MIDlet;

public class StringItemDemo

extends MIDlet

implements CommandListener, ItemCommandListener {

private Display display;

private Form mainForm;

private final static Command CMD_GO = new Command("Go", Command.ITEM, 1);

private final static Command CMD_PRESS = new Command("Press", Command.ITEM, 1);

private final static Command CMD_EXIT = new Command("Exit", Command.EXIT, 1);

protected void startApp() {

display = Display.getDisplay(this);

mainForm = new Form("String Item Demo");

mainForm.append("This is a simple label");

StringItem item = new StringItem("This is a StringItem label: ",

"This is the StringItems text");

mainForm.append(item);

item = new StringItem("Short label: ", "text");

mainForm.append(item);

item = new StringItem("Hyper-Link ", "hyperlink", Item.HYPERLINK);

item.setDefaultCommand(CMD_GO);

item.setItemCommandListener(this);

mainForm.append(item);

item = new StringItem("Button ", "Button", Item.BUTTON);

item.setDefaultCommand(CMD_PRESS);

item.setItemCommandListener(this);

mainForm.append(item);

mainForm.addCommand(CMD_EXIT);

mainForm.setCommandListener(this);

display.setCurrent(mainForm);

}

public void commandAction(Command c, Item item) {

if (c == CMD_GO) {

String text = "Go to the URL...";

Alert a = new Alert("URL", text, null, AlertType.INFO);

display.setCurrent(a);

} else if (c == CMD_PRESS) {

String text = "Do an action...";

Alert a = new Alert("Action", text, null, AlertType.INFO);

display.setCurrent(a);

}

}

public void commandAction(Command c, Displayable d) {

destroyApp(false);

notifyDestroyed();

}

protected void destroyApp(boolean unconditional) {

}

protected void pauseApp() {

}

}

3.6.2ImageItem

下面我们来看ImageItem,ImageItem和StringItem着实差别仅仅在于一个是显示图像,一个是翰墨,它同样有两个构造函数,此顶用到最多的是5个参数的构造函数,第一个是该Item的Label,第二个是图片,第三个是等效线,第四个是取代的翰墨(图片无法实际时),第五个是外不雅(和StringItem相同)。

import javax.microedition.lcdui.*;

import javax.microedition.midlet.*;

public class ImageItemMIDlet extends MIDlet

implements ItemCommandListener

{

private Display display;

public ImageItemMIDlet()

{

display = Display.getDisplay(this);

}

public void startApp()

{

Image img = null ;

try

{

img = Image.createImage("/pic.png") ;

}catch(Exception e){}

Form f = new Form("ImageItem测试") ;

f.append(img) ;

ImageItem ii1 =

new ImageItem("图片1",img,

Item.LAYOUT_CENTER|Item.LAYOUT_NEWLINE_BEFORE,"图片1取代翰墨",Item.BUTTON);

f.append(ii1) ;

ImageItem ii2 =

new ImageItem("图片2",img,

Item.LAYOUT_RIGHT|Item.LAYOUT_NEWLINE_BEFORE,"图片2取代翰墨",Item.HYPERLINK);

f.append(ii2) ;

display.setCurrent(f);

}

public void commandAction(Command c,Item i)

{

System.out.println(c.getLabel());

System.out.println(i.getLabel());

}

public void pauseApp()

{

}

public void destroyApp(boolean unconditional)

{

}

}

3.7CustomItem

CustomItem是Item中一个对照紧张的子类,它最大年夜的优点是前进了Form中的可交互性。它和Canvas有很大年夜的相似处。我们经由过程改写CustomItem可以实现完全节制在新的子类中条款区域的显示,它可以定义应用的颜色,字体和图形,包括特殊高亮的条款可能有的所有的焦点状态,只有条款的Label是有系统节制天生的,然则Label老是天生在CustomItem的内容区域外。

每个CustomItem都认真把它的行径与目标设备上可用的交互模式匹配。一个CustomItem调用措施来察看特定设备所支持的交互模式,这个措施会返回一个支持模式的位标记,支持的模式会的返回对应位会被设置,不支持的不被设置。

CustomItem一个对照紧张的特点等于Form内部的遍历,即实现可能临时把遍历的责任委派给Item本身,这样可以实现特殊的高亮,动画等等效果。

因为customItem在Form类里扮演很紧张的角色,其内容很繁芜,我们经由过程三个代码段来教读者若何应用CustomItem,盼望大年夜家经由过程对代码的深刻熟识,前进自己对CustomItem的掌握程度。

import javax.microedition.lcdui.*;

import javax.microedition.midlet.MIDlet;

public class CustomItemDemo extends MIDlet implements CommandListener {

private final static Command CMD_EXIT = new Command("Exit", Command.EXIT, 1);

private Display display;

private boolean firstTime;

private Form mainForm;

public CustomItemDemo() {

firstTime = true;

mainForm = new Form("Custom Item");

}

protected void startApp() {

if(firstTime) {

display = Display.getDisplay(this);

mainForm.append(new TextField("Upper Item", null, 10, 0));

mainForm.append(new Table("Table", Display.getDisplay(this)));

mainForm.append(new TextField("Lower Item", null, 10, 0));

mainForm.addCommand(CMD_EXIT);

mainForm.setCommandListener(this);

firstTime = false;

}

display.setCurrent(mainForm);

}

public void commandAction(Command c, Displayable d) {

if (c == CMD_EXIT) {

destroyApp(false);

notifyDestroyed();

}

}

protected void destroyApp(boolean unconditional) {

}

protected void pauseApp() {

}

}

import javax.microedition.lcdui.*;

public class Table

extends CustomItem

implements ItemCommandListener {

private final static Command CMD_EDIT = new Command("Edit",

Command.ITEM, 1);

private Display display;

private int rows = 5;

private int cols = 3;

private int dx = 50;

private int dy = 20;

private final static int UPPER = 0;

private final static int IN = 1;

private final static int LOWER = 2;

private int location = UPPER;

private int currentX = 0;

private int currentY = 0;

private String[][] data = new String[rows][cols];

// Traversal stuff

//indicating support of horizontal traversal internal to the CustomItem

boolean horz;

//indicating support for vertical traversal internal to the CustomItem.

boolean vert;

public Table(String title, Display d) {

super(title);

display = d;

setDefaultCommand(CMD_EDIT);

setItemCommandListener(this);

int interactionMode = getInteractionModes();

horz = ((interactionMode & CustomItem.TRAVERSE_HORIZONTAL) != 0);

vert = ((interactionMode & CustomItem.TRAVERSE_VERTICAL) != 0);

}

protected int getMinContentHeight() {

return (rows * dy) + 1;

}

protected int getMinContentWidth() {

return (cols * dx) + 1;

}

protected int getPrefContentHeight(int width) {

return (rows * dy) + 1;

}

protected int getPrefContentWidth(int height) {

return (cols * dx) + 1;

}

protected void paint(Graphics g, int w, int h) {

for (int i = 0; i

g.drawLine(0, i * dy, cols * dx, i * dy);

}

for (int i = 0; i

g.drawLine(i * dx, 0, i * dx, rows * dy);

}

int oldColor = g.getColor();

g.setColor(0x00D0D0D0);

g.fillRect((currentX * dx) + 1, (currentY * dy) + 1, dx - 1, dy - 1);

g.setColor(oldColor);

for (int i = 0; i

for (int j = 0; j

if (data[i][j] != null) {

// store clipping properties

int oldClipX = g.getClipX();

int oldClipY = g.getClipY();

int oldClipWidth = g.getClipWidth();

int oldClipHeight = g.getClipHeight();

g.setClip((j * dx) + 1, i * dy, dx - 1, dy - 1);

g.drawString(data[i][j], (j * dx) + 2, ((i + 1) * dy) - 2,

Graphics.BOTTOM | Graphics.LEFT);

// restore clipping properties

g.setClip(oldClipX, oldClipY, oldClipWidth, oldClipHeight);

}

}

}

}

protected boolean traverse(int dir, int viewportWidth, int viewportHeight,

int[] visRect_inout) {

if (horz && vert) {

switch (dir) {

case Canvas.DOWN:

if (location == UPPER) {

location = IN;

} else {

if (currentY

currentY++;

repaint(currentX * dx, (currentY - 1) * dy, dx, dy);

repaint(currentX * dx, currentY * dy, dx, dy);

} else {

location = LOWER;

return false;

}

}

break;

case Canvas.UP:

if (location == LOWER) {

location = IN;

} else {

if (currentY > 0) {

currentY--;

repaint(currentX * dx, (currentY + 1) * dy, dx, dy);

repaint(currentX * dx, currentY * dy, dx, dy);

} else {

location = UPPER;

return false;

}

}

break;

case Canvas.LEFT:

if (currentX > 0) {

currentX--;

repaint((currentX + 1) * dx, currentY * dy, dx, dy);

repaint(currentX * dx, currentY * dy, dx, dy);

}

break;

case Canvas.RIGHT:

if (currentX

currentX++;

repaint((currentX - 1) * dx, currentY * dy, dx, dy);

repaint(currentX * dx, currentY * dy, dx, dy);

}

}

} else if (horz || vert) {

switch (dir) {

case Canvas.UP:

case Canvas.LEFT:

if (location == LOWER) {

location = IN;

} else {

if (currentX > 0) {

currentX--;

repaint((currentX + 1) * dx, currentY * dy, dx, dy);

repaint(currentX * dx, currentY * dy, dx, dy);

} else if (currentY > 0) {

currentY--;

repaint(currentX * dx, (currentY + 1) * dy, dx, dy);

currentX = cols - 1;

repaint(currentX * dx, currentY * dy, dx, dy);

} else {

location = UPPER;

return false;

}

}

break;

case Canvas.DOWN:

case Canvas.RIGHT:

if (location == UPPER) {

location = IN;

} else {

if (currentX

currentX++;

repaint((currentX - 1) * dx, currentY * dy, dx, dy);

repaint(currentX * dx, currentY * dy, dx, dy);

} else if (currentY

currentY++;

repaint(currentX * dx, (currentY - 1) * dy, dx, dy);

currentX = 0;

repaint(currentX * dx, currentY * dy, dx, dy);

} else {

location = LOWER;

return false;

}

}

}

} else {

//In case of no Traversal at all: (horz|vert) == 0

}

visRect_inout[0] = currentX;

visRect_inout[1] = currentY;

visRect_inout[2] = dx;

visRect_inout[3] = dy;

return true;

}

public void setText(String text) {

data[currentY][currentX] = text;

repaint(currentY * dx, currentX * dy, dx, dy);

}

public void commandAction(Command c, Item i) {

if (c == CMD_EDIT) {

TextInput textInput = new TextInput(data[currentY][currentX], this,

display);

display.setCurrent(textInput);

}

}

}

import javax.microedition.lcdui.*;

import javax.microedition.midlet.MIDlet;

public class TextInput extends TextBox implements CommandListener {

private final static Command CMD_OK = new Command("OK", Command.OK,

1);

private final static Command CMD_CANCEL = new Command("Cancel", Command.CANCEL,

1);

private Table parent;

private Display display;

public TextInput(String text, Table parent, Display display) {

super("Enter Text", text, 50, TextField.ANY);

this.parent = parent;

this.display = display;

addCommand(CMD_OK);

addCommand(CMD_CANCEL);

setCommandListener(this);

}

public void commandAction(Command c, Displayable d) {

if (c == CMD_OK) {

// update the table's cell and return

parent.setText(getString());

display.setCurrentItem(parent);

} else if (c == CMD_CANCEL) {

// return without updating the table's cell

display.setCurrentItem(parent);

}

}

}

3.8TextField和DateField

TextField和我们前面讲的TextBox大年夜同小异,只是它是作为Form的一个子类存在,而TextBox则是和Form中分秋色,是以我们直接给出代码方便大年夜家的进修。

import javax.microedition.lcdui.*;

import javax.microedition.midlet.*;

public class TextFieldWithItemStateListenerMIDlet extends MIDlet

implements ItemStateListener

{

private Display display;

public TextFieldWithItemStateListenerMIDlet()

{

display = Display.getDisplay(this);

}

TextField name ;

TextField tel ;

TextField summary ;

public void startApp()

{

Form f = new Form("TextField测试") ;

name = new TextField("姓名","",8,TextField.ANY) ;

tel = new TextField("电话","",14,TextField.PHONENUMBER) ;

summary = new TextField("总结","",30,TextField.UNEDITABLE) ;

f.append(name) ;

f.append(tel) ;

f.append(summary) ;

f.setItemStateListener(this);

display.setCurrent(f);

}

public void itemStateChanged(Item item)

{

if(item==name)

{

summary.setString("输入的姓名为:"+name.getString());

}else if(item==tel)

{

summary.setString("输入的电话为:"+tel.getString());

}else

{

summary.setString("");

}

}

public void pauseApp()

{

}

public void destroyApp(boolean unconditional)

{

}

}

DateField的目的是方便用户输入光阴,它的构造函数共有三个参数,一个是Label,一个是输入模式,一个是java.util.TimeZone工具,也可以省去第三个参数,只应用前两个。

3.9Gauge和Spacer,ChoiceGroup

3.9.1Gauge

Alert有一套措施可以显示进度,使用setIndicator()/getIndicator()这组函数,可以显示进度的画面。Gauge的最大年夜用场便是拿来当进度显示应用。

拿来当进度显示用的Gauge工具必须满意如下要求:

l节制与用户交互的构造函数的第二个参数必须为flase

l不能被其他的Form或者Alert应用

l不能加入Command

l不能有Label

l不能自己设定等效线的位置。

l不能自己设定组件的大年夜小。

大年夜家可以参考如下的代码:

import javax.microedition.lcdui.*;

import javax.microedition.midlet.*;

public class AlertWithIndicatorMIDlet extends MIDlet

implements CommandListener

{

private Display display;

public AlertWithIndicatorMIDlet()

{

display = Display.getDisplay(this);

}

Gauge g ;

public void startApp()

{

Alert al = new Alert("处置惩罚中");

al.setType(AlertType.INFO);

al.setTimeout(Alert.FOREVER);

al.setString("系统正在处置惩罚中");

g = new Gauge(null,false,10,0) ;

al.setIndicator(g);

Command start = new Command("开始",Command.OK,1) ;

Command stop = new Command("竣事",Command.STOP,1) ;

al.addCommand(start);

al.addCommand(stop);

al.setCommandListener(this);

display.setCurrent(al);

}

public void commandAction(Command c,Displayable s)

{

String cmd = c.getLabel() ;

if(cmd.equals("开始"))

{

for(int i=0 ; i

{

g.setValue(i);

try

{

Thread.sleep(500);

}catch(Exception e){}

}

}else if(cmd.equals("竣事"))

{

notifyDestroyed() ;

}

}

public void pauseApp()

{

}

public void destroyApp(boolean unconditional)

{

}

}

3.9.2Spacer

Spacer的用场很简单,便是加一处空缺,大年夜家可以参考API文档进行实际开拓。

3.9.3ChoiceGroup

ChoiceGroup和List大年夜同小异,由于二者都实现了Choice接口,以是在很多地方是一样的,然则请留意一点,在这里我们不能应用Choice.IMPLICIT类型,只能用Choice.EXCLUSIVE,Choice.MUTIPLE,Choice.POPUP,三种类型,与List的差别即第三种弹出式菜单。

J2ME中文教程 1 J2ME技巧概述

您可能还会对下面的文章感兴趣: