骑猪闯天下

J2ME随笔,记录成长的脚步

统计

留言簿(3)

阅读排行榜

评论排行榜

[J2ME] MIDP高级界面开发

MIDP高低级界面开发


LCDUI——Limited Configuration Device UI。

1. LCDUI包的设计:
两种API:
􀁺 高级API(Screen):画面具有可移植性,但无法决定组件的颜色、字体和外观。
􀁺 低级API(Canvas):编写相对复杂,但对画面的控制具有完全的控制权。由于在不同的机器上有不同的特性(控制方式、屏幕颜色等),不能保证不同种类机器上可以得到相同的执行结果。
由于手机一次只能显示出一个画面,因此每个画面只能在高级API或者API之间择一使用。
高级API和低级API可以在同一个MIDlet中混合使用,组成应用程序中的每个画面。但是同一个画面中,就只能使用高级或者低级API中的一个。
2. LCDUI的包体系结构
能够显示在屏幕上的组件都是继承自抽象类Displayable。
Displayable
|
-------------Screen(高级API——高级类库)
|
-------------Canvas(低级API——低级类库)
LCDUI包全部定义在java.microedition.lcdui中。
3. Displayable类
是一个抽象类。其子类都具有显示于屏幕上的能力。
提供的方法:
getTicker()/setTicker()设定/获取跑马灯
setTitle()/getTitle()设定/获取画面标题
注意:上述方法在MIDP1.0中用于Screen,而在MIDP2.0中可用于Displayable中。
getHeight()取得屏幕上应用程序区的高度
getWidth()取得屏幕上应用程序区的宽度
上述2个方法,对低级API来说非常有用。因为每款手机的屏幕大小不同,而跑马灯与标题区存在与否,会影响这两个方法的返回值。
应用程序区:除去标题、跑马灯区域以及Command显示区以外,屏幕上剩下的那部分区域。
Displayable的子类可以通过isShow()判断目前这个画面是否正被Display显示在屏幕上。
Displayable类中定义了一个名为sizeChanged()的方法。可以被Canvas或Form的子类所重写(Override)。例如,Canvas的setFullScreenMode()方法就会导致sizeChanged()被调用。
第四章 高级界面开发
目标:
􀁺 了解Screen的基本概念
􀁺 了解基本屏幕类的开发
MIDP用户界面设计开发不同于一般的桌面程序,受限于屏幕大小、颜色、内存和处理能力。好的界面应该根据设备具体情况有针对性地设计。
4.1 MIDP高级界面开发
高级API提供了常用的控件,强调可移植性,只能有限控制控件外观,事件的使用也很有限。
4.1.1 Display类的开发
MIDP的程序界面是通过屏幕显示出来的。在屏幕上显示一幅画面就是Display对象要实现的功能。
每个MIDP程序都是由Displayable对象来具体处理在屏幕上显示的内容。MIDP程序可以根据手机使用者与程序的交互情况,把每次操作后的画面通过Displayable对象显示在当前屏幕上。
Displayable是Display的一个继承类,主要包括两个具体实现类:
􀁺 高级界面开发类Screen
􀁺 低级界面开发类Canvas
MIDP1.0中Displayable定义的方法有:
boolean isShown()
void addCommand(Command cmd)
void removeCommand(Command cmd)
void setCommandListener(CommandListener l)
MIDP2.0中Displayable新添加的方法有:
String getTitle()
public void setTitle(String s)
Ticker getTicker()
public void setTicker(Ticker ticker)
public int getWidth()
public int getHeight()
protected void sizeChanged(int w, int h)
上面的方法均可在Screen和Canvas中使用。但要注意在MIDP1.0下开发,MIDP2.0的方法不能够使用。
类Screen共有四个继承它的屏幕类,而Form屏幕类可以添加八个继承自Item类的控件类。
Screen
List
TextBox
Form
DateField
TextField
ImageItem
Gauge
ChoiceGroup
StringItem
CustomItem(MIDP2.0)
Spacer(MIDP2.)
Alert
4.1.2 基本控件开发简介
Screen共有4个子类:Alert Form List和TextBox。这四个子类本身就是屏幕类,可以直接在屏幕上显示。
Alert:用于显示提示信息的屏幕类。
List: 用来显示列表的屏幕类。
TextBox:用来输入文字信息。
一个复杂的程序界面往往需要很多类型的输入方式和显示方式。
Form类被设计成可以包含多个不同类型的控件,使用Form类可以管理屏幕上的Item控件,基本的Item控件有DateField TextField ImageItem Gauge ChoiceGroup StringItem等。
4.2 事件处理
Java程序中,实现与用户的交互功能都是需要通过事件来处理的,需要指定控件所使用的时间监听器。
事件就是用户与GUI(图形界面)交互时候所触发的事情。例如按键就是事件。
J2ME中,事件会被传送到事件处理器,一般由J2ME中的监听器来实现。监听器是能够检测并且能够相应事件的代码。
需要注意的是每个事件的处理总是在前一个事件处理完成以后程序才会接着处理,意味着事件不能够同时被处理,它们是串行处理的。
4.2.1Command编程基础
高级屏幕类TextBox、List和Form都可以在屏幕上添加Command(菜单项)。javax.microedition.lcdui.Command就是一般应用程序中使用的系统菜单中的菜单项的概念。由于Displayable对象中定义了addCommand()/removeCommand()两个方法,意味着Command类适用于高级API(Screen)与低级API(Canvas)。
API:
new Command(Labels, Type, Priority);
方法:
getLabel()
getLongLabel()
getCommandType()
getPriority()
第二个参数是Command的类型:共有八种类型。注意Command并不会因为设定成某一种类型就具有该类型“名称”的功能。例,某个Command不会因为设置为Command.EXIT,选择后就真的会终止程序。但每种类型都有其隐含的意义。
类型 默认数值 作用
BACK 2 逻辑上返回前一个屏幕
CANCEL 3 取消当前屏幕的操作和提示
EXIT 7 退出程序
HELP 5 请求帮助
ITEM 8 提示实现指定屏幕上的某一项
OK 4 肯定当前屏幕的操作或指示
SCREEN 1 应用到当前屏幕
STOP 6 停止当前运行的操作
在不同的机器上,Command的位置会因为类型不同而有所不同。有些机器会以抬头菜单的形式出现(Nokia 9210),有些机器会根据类型自动修改按钮在屏幕上的名称(Nokia 3300)。只能确定的是,Command会以以用户熟悉的操作方式来呈现。并根据类型,将Command放置到该设备最合适的位置上。
第三个参数是优先权,号码越低优先权越高,优先权越高,代表用户越能够方便的找到它们。数值相同时,使用方法本身默认的数值。
例:
Form f = new Form(“test”);
Command c = new Command(“menu1”, Command.Screen, 1);
f.addCommand(c );
display.setCurrent(f);
另外,Command类有另外构造方法,共4个参数:
Command(“short name”, “long name”, commandType, priority)
其中第二个参数是相对于第一个参数而来的。系统在屏幕上显示长名或者短名,不同产
家的实现不同。如果没有指定长名,就一定会使用短名。标准MIDP模拟器中,如果Command对应到软件按钮(例如:Command.Back),就会使用短名,如果用到菜单显示,就会自动使用长名。建议,尽量短名不超过四个字,长名在四个字以上。
练习:在屏幕上添加Command,要求使用Command的8种命令类型。
4.2.2通用事件处理CommandListener
Command必须和javax.microedition.lcdui.CommandListener事件处理接口一起使用才能反映用户的动作。Displayable类中定义了setCommandListener(CommandListener)方法,所以高级API和低级API都可以使用CommandListener。
使用步骤:
􀁺 implements CommandListener
􀁺 添加菜单项 addCommand(Command)
􀁺 setCommandListener(CommandListener)
􀁺 实现接口CommandListener的方法:
commandAction(Command c, Displayable s)
其中,c是被选定的系统菜单项的引用,s是发生事件的来源,也就是包含了此Command对象的Displayable实例。
完成上述步骤,在点选菜单项时,实现了CommandListener接口的类中的commandAction(Command, Displayable)方法就会被调用。这种向事件来源注册,然后等待通知的事件处理模型在Java中称为委托模型(Delegation Model)。
4.2.3 处理高级别事件
每一个高级界面的Displayable对象都有一个相应的监听器,该监听器用来监听控件是否已经被触发了相关的事件。
步骤同4.2.2。
练习:编写exitCommand,并实现按键后退出程序的功能。
4.3 Ticker类
是一个类似跑马灯的类,在所有的Displayable的子类上都可以加入Ticker。
API:
Ticker(String s)
方法:
setString(String s) 设置显示内容。
使用方法:
displayable.setTicker(ticker);
displayable.getTicker();
利用定义在Displayable中的setTicker()方法设定画面上的Ticker,或者getTicker()获取画面内包含的Ticker对象。
注意:MIDP1.0中Ticker只能用于Screen的子类。MIDP2.0可以用在Displayable子类了。
4.4 基本屏幕控件
屏幕控件就是屏幕显示的控件,目前主要有4种:
􀁺 List
􀁺 TextBox
􀁺 Alert
􀁺 Form
4.4.1 TextBox
API:
TextBox(String title, String text, int maxSize, int Constraints)
title:标题
text:初始化内容
maxSize:可输入的最大字符数
Constrains:输入限制
􀁺 TextField.ANY 允许输入任何字符或者数字
􀁺 TextField.EMAILADDR 允许输入电子邮件地址
􀁺 TextField.NUMERIC:整数 只允许输入数字,整型数
􀁺 TextField.PHONENUMBER 只允许输入电话号码的格式
􀁺 TextField.URL 允许用户输入URL形式的字符串
􀁺 TextField.DECIMAL 允许输入浮点型数
􀁺 TextField.PASSWORD 所有输入以星号表示
􀁺 TextField.UNEDITABLE 不允许修改
方法:
setString/getString() 设置/取得TextBox中的内容
setMaxSize()/getMaxSize() 设置/取得最大长度
size() 返回TextBox中文字的长度
delete() 删除TextBox实际内容
setChar()/getChar() 将TextBox存放的内容以一个char数组来存取
getCaretPosition() 取得目前输入光标所在位置
insert() 在特定位置加入内容
setConstraints(int constraints)设定输入限制
例:
TextBox tb = new TextBox(“number”, “123”, 5, TextField.NUMERIC);
注意:
设备一般都会自行限定TextBox所能存放的内容的最大值。构造方法中指定的最大值不能超过设备本身所限制的最大值。TextBox支持多行输入。
避免指定初始内容长度大于最大长度所引发的IllegalArgumentException。
练习:使用TextBox输入数据,按键后清空TextBox内容。
4.4.2 List
API:
List(String title, int listType)
List(String title, int listType, String[] stringElements, Image[] imageElements);
1. 单选方式Choice.Exclusive
2. 多选方式Choice.MULTPLE
3. 隐含方式Choice.IMPLICIT(简易式的单选)
Choice.EXCLUSIVE
Choice.IMPLICIT
Choice.MULTIPLE
比较三种不同的Choice型态
方法:
append(String, Image icon)若不需要图标,将第二项设置为null。
getSelectedIndex()
多选框的List事件,类似单选框的事件处理方法,不同的是需要通过getSelectedFlags(boolean[] arr)获得哪几个List的列表项被选择了,选择的结果放在一个布尔数组中。
getString(int index)获取指定索引的值。
insert()在指定项目后插入下一个项目。
set()重新设置某个项目的内容。
size()返回List中的项目数。
getImage()取得项目图标
getFont()/setFont()取得/设定系统显示项目使用的字体。
delete(int idx)删除特定选项
deleteAll()删除所有选项
isSelected(int idx)判断指定项目是否被选择。
(1)单选类型的List:
List list = new List("List test", Choice.EXCLUSIVE);
注意:Choice.EXCLUSIVE类型的List并不会在用户选择之后立刻引发事件,通常
通过系统菜单项来完成。
(2)多选类型的List
List list = new List("List test", Choice.MULTIPLE);
􀁺 通过遍历List项目的方式,判断哪项被选中:
int size = l.size();
for (int i=0; i<size; i++)
{
    if (l.isSelected(i))
    {
        String value = l.getString(i);
        System.out.println("第" + (i+1) + "项: " + value);
    }
}
􀁺 利用getSelectedFlags()方法传回boolean数组,判断哪项被选中。
setSelectedFlags()设定List之中的选项。
(3)简易式单选
List list = new List("List test", Choice.IMPLICIT);
与单选和多选不同,Choice.IMPLICIT类型的List会在用户选择之后立刻引发事件,并将List.SELECT_COMMAND通过commandAction()方法的第一个参数传入。判断commandAction()的第一个参数是否为List.SELECT_COMMAND,可以知道事件是否为List引发。因为这种类型的List同时间只有一个选项会被选择,所以我们可以利用List的getSelectedIndex()来判别是哪一个选项被选择。
例子:
public void commandAction(Command c, Displayable s)
{
    if (c == List.SELECT_COMMAND)
    {
        List l = (List)s;
        int index = l.getSelectedIndex();
        String value = l.getString(index);
        System.out.println("第" + (index+1) + "项: " + value);
    }
}
4.4.3 AlertType
AlertType是一个工具类,不能实例化。但它提供了几种定义好的AlertType用以辅助Alert类的使用:
AlertType.ALARM 警报
AlertType.CONFIRMATION确认
AlertType.ERROR 错误
AlertType.INFO 提示信息
AlertType.WARNING 警告
AlertType提供的唯一的方法:
playSound(),可以用来发出几种类型的声音。
4.4.4 Alert
Alert是比较特殊的屏幕对象。利用Display显示于屏幕时将Alert显示于屏幕上,过一段时间后,自动调回之前的画面。
注意:将Alert显示之前,系统应存在一个画面,这样才能让Alert有地方可以跳回。因此,如果一启动就将Alert第一个显示于屏幕,会出现错误。
Alert的特性,使得它可以用作启动画面(Splash Screen)。
API:
Alert(String title)
Alert(String title, String alertText, Image alertImage, AlertType alertType)
方法:
setType()/getType() 设置获取Alert类型
setString()/getString() 设置/获取内含文字
setImage()/getImage() 设置/获取内含图像
setTimeOut() 设置显示时间
可以利用Alert类的setTimeOut()方法,传入Alert.Forever作为参数,此时Alert只有在用户按下解除按钮(Dismiss Command)时,才会跳回之前画面。
类型:
AlertType提供的几种类型。
Alert不允许使用Command对象
MIDP2.0新添加了setIndicator(Gauge indicator)方法。
4.4.5 Form与Item
Form是容器类型,可以配合Item类的子类产生丰富效果。
API:
Form(String title)
方法:
append(Item)
append(String)
set(int) 可以重新设定某个位置上的Item
get(int index) 可以取得指定位置Item的引用
size() 取得Form中Item的数量
getHeight()/getWidth() 可以返回Form用来摆放Item的区域的高和宽
delete(int pos) 删除指定Item
deleteAll() 删除Form上所有Item
Item
DateField
TextField
ImageItem
Gauge
ChoiceGroup
StringItem
CustomItem(MIDP2.0)
Spacer(MIDP2.)
注意:每一个Item子类同时只能属于一个容器,否则在加入其他容器时会产生IllegalStateException。如果某个Item想要加入其他容器中,必须在加入前从原来的容器中删除。
每个Form都被逻辑划分成多个区域,每个区域都有可能被一个以上Item占据。逻辑区域可能是自上而下划分,也有可能自左而右划分,取决于设备。例如,较长的屏幕,就有可能自上而下画出许多不等高的逻辑区域。
了解一下Item的布局方式:
􀁺 Item.LAYOUT_LEFT
􀁺 Item.LAYOUT_CENTER
􀁺 Item.LAYOUT_RIGHT
上述三种方式互斥,其他布局参考手册。
Item一般依照缺省布局绘制Item.LAYOUT_DEFAULT。可以利用setLayout()/getLayout()设置/取得目前布局。
尽管Form会被逻辑划分成多个区域,但并不是每个逻辑区域中只有一个Item。Form默认情况下,尽可能让不同Item出现在同一个逻辑区域中。
在下面情形下,Form将会自动将新的Item放到下一个逻辑区域中。
Item之后换行的情形:
1. StringItem内容后有换行符;
2. 具有LAYOUT_NEWLINE_AFTER设定的Item;
3. 如果是ChoiceGroup、DateField、Gauge、TextField,而且其布局并未设定为LAYOUT_2。
Item之前换行的情形:
1. 前一个Item之后有换行;
2. 具有LAYOUT_NEWLINE_BEFORE设定的Item;
3. StringItem内容开头有换行符;
4. 如果是ChoiceGroup、DateField、Gauge、TextField,而且其布局并未设定为LAYOUT_2;
5. Item布局设定为LAYOUT_LEFT、LAYOUT_CENTER、LAYOUT_RIGHT。
4.4.5.1 StringItem
在屏幕上显示只读信息的Item控件,用户不能更改控件的提示信息。可以按钮或者超级链接形式呈现。
API:
StringItem(String label, String text);
StringItem(String label, String text, int appearanceMode)
参数appearanceMode指定控件显示类型:
1. Item.PLAIN 默认类型
2. Item.HYPERLINK 超级链接
3. Item.BUTTON 图像按钮类型
方法:
getAppearanceMode() 取得StringItem所用的外观
getFont()/setFont() 用来取得/设定字体
getText()/setText() 用来取得/设定内容
getLable()/setLable 存取Label
在Form中加入StringItem,可以使用append(Item)方法。form.append(String)等同于调用:
form.append(new StringItem(null, String));
如果StringItem没有和Command关联起来,即使使用不同的外观设定,外观也是相同的。
4.4.5.2 Item与Command——ItemCommandListener
每个Item子类中,至少有三种东西:
1. Command数组;
2. 名为DefaultCommand的变量,引用到Command数组中的一个Command;
3. 一个指向ItemCommandListener的引用。
默认情况下,这些内部结构都是null。
addCommand()/removeCommand() 添加/删除Command
setDefaultCommand() 设定DefaultCommand
setItemCommandListener() 设定ItemCommandListener
使用removeCommand()删除的Command如果是DefaultCommand,那么系统会同时调用setDefaultCommand(null)。调用setDefaultCommand()时,如果传入的Command不在Command数组中,则系统会先调用addCommand()将其加入内部的Command数组中。自己调用setDefaultCommand(null),只会断开DefaultCommand与Command数组的引用,并不会将DefaultCommand所引用的Command从数组中删除。
Item一旦加入到Form中,用户选择到该Item时,那么该Item内部的Command数组就会变成系统菜单项。任何菜单项被选定之后,实现了ItemCommandListener接口的类中的commandAction()方法就会被调用(传入Command与Item的引用)。
StringItem一旦加入Command,其外观(Button、HYPERLINK)就会产生和PLAIN不同的样式。
设定Item的DefaultCommand的好处是,可以容易的让用户使用。用户只要直接在Item上按下按钮就可以产生默认执行效果,而不必通过选单选择后按确认再执行。DefaultCommand可以方便用户的使用。
基本使用步骤:
1) import javax.microedition.lcdui.*;
2) implements ItemCommandListener
3) 重写commandAction(Comand c, Item i)
4) displayable.addCommand()
5) displayable.setItemConmandListener()
4.4.5.3 ImageItem
图形显示控件,可以把图像作为Form的一个控件显示于屏幕。MIDP2.0中,增加了将图片作为按钮或者超级链接的功能。
API:
ImageItem(String label, Image img, int layout, String altText)
ImageItem(String label, Image img, int layout, String altText, int appearanceMode)
参数label:控件标题
参数layout:控件的布局
参数altText:如果不能够显示图片或图片不存在,则使用一个字符串替代图片
参数appearanceMode指定控件显示类型:
1. Item.PLAIN 默认类型
2. Item.HYPERLINK 超级链接
3. Item.BUTTON 图像按钮类型
方法:
setLayout()/getLayout() 设置/获取布局
setImage()/getImage() 设置/获取ImageItem中的Image
setAltText()/getAltText() 设置/获取取代文字
getAppearanceMode() 取得外观设定
Form的append(Image img)方法等同于:
form.append(new ImageItem(null, image, Item.LAYOUT_DEFAULT, null));
4.4.5.4 Spacer
用来在Form上加入一些空白间隔。功能特殊,不能与用户交互(不能使用Command)。
API:
Spacer(int minWidth, int minHeight)
4.4.5.5 ChoiceGroup
类似List。同List一样也实现了Choice接口。
API:
ChoiceGroup(String label, int choiceType);
ChoiceGroup(String label, int choiceType, String[] stringElements, Image[] imageElements)
参数choiceType指定控件的显示类型共3种:
􀁺 ChoiceEXCLUSIVE(单选)
􀁺 Choice.MULTIPLE(多选)
􀁺 Choice.POPUP(弹出式菜单)——MIDP2.0提供
注意,ChoiceGroup无法使用Choice.IMPLICIT类型。
ChoiceGroup与List的最大不同在于,ChoiceGroup必须在Form中才有用。
4.4.5.6 ItemStateListener
可以看到,Displayable的子类,可以使用addCommand()配合setCommandListener()做事件处理。Item类本身也有addCommand()方法,可以配合setItemCommandListener()做事件处理。
当Form组件内部的Item组件内部的状态发生改变时,Form组件会对所有使用setItemStateListener()向它注册的ItemStateListener的itemStateChanged()方法发出状态改变的消息。
以下几种情况会使得Form发出此消息:
1、 ChoiceGroup的状态改变了;
2、 Gauge的状态改变了
3、 TextField的状态改变了
4、 DateField的状态改变了
5、 Item组件的notifyStateChanged()被调用。
根据MIDP规范之中的定义,如果Form之中同时有CommandListener与ItemStateListener的话,那么itemStateChanged()会比commandAction()还要先被调用。
注意:ItemStateListener只有在与用户交互时,组件的状态真的被改变时,其itemStateChanged()方法才会被调用。如果是程序修改组件的状态,则不会触发该事件。除非在改变完某个组件状态后,调用notifyStateChanged()。
使用步骤:
1) import javax.microedition.lcdui.*
2) implements ItemStateListener
3) 重写itemStateChanged(Item i)
4) item.setItemStateListener(itemStateListener)
示例:
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

/**
 * 
 * 
@author Allan
 * 
@version
 
*/

public class ItemStateListenerTextMidlet extends MIDlet implements
        ItemStateListener 
{
    
private Display display;

    
private Image img1;

    
private Image img2;

    
private ChoiceGroup cg1;

    
private ChoiceGroup cg2;

    
public ItemStateListenerTextMidlet() {
        display 
= Display.getDisplay(this);
        
try {
            img1 
= Image.createImage("/f1.png");
            img2 
= Image.createImage("/f2.png");
        }
 catch (Exception e) {
        }

    }


    
public void startApp() {
        Form f 
= new Form("ChoiceGroup test");
        cg1 
= new ChoiceGroup("名称", Choice.EXCLUSIVE);
        cg1.append(
"水果A", img1);
        cg1.append(
"水果B", img2);
        cg2 
= new ChoiceGroup("价格", Choice.MULTIPLE);
        cg2.append(
"10.2", img1);
        cg2.append(
"0.85", img2);
        f.setItemStateListener(
this);
        f.append(cg1);
        f.append(cg2);
        display.setCurrent(f);
    }


    
public void pauseApp() {
    }


    
public void destroyApp(boolean unconditional) {
    }


    
public void itemStateChanged(Item item) {
        String label 
= item.getLabel();
        
if (label.equals("名称")) {
            System.out.println(
"名称的状态改变了");
            
int i = cg1.getSelectedIndex();
            System.out.println(cg1.getString(i));
        }
 else if (label.equals("价格")) {
            System.out.println(
"价格的状态改变了");
            
boolean[] c = new boolean[cg2.size()];
            cg2.getSelectedFlags(c);
            
for (int i = 0; i < c.length; i++{
                
if (cg2.isSelected(i)) {
                    System.out.println(
"" + cg2.getString(i));
                }

            }

        }

    }

}



4.4.5.7 TextField
同前面讲过的TextBox,请参考前面关于TextBox的使用。
示例:
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

/**
 * 
 * 
@author Allan
 * 
@version
 
*/

public class TextFieldTestMidlet extends MIDlet implements ItemStateListener {
    
private Display display;

    
private TextField uid;

    
private TextField name;

    
private TextField password;

    
private TextField summary;

    
public TextFieldTestMidlet() {
        display 
= Display.getDisplay(this);
    }


    
public void startApp() {
        Form f 
= new Form("TextField test");
        uid 
= new TextField("UID"""5, TextField.NUMERIC);
        name 
= new TextField("姓名"""12, TextField.ANY);
        password 
= new TextField("密码"""8, TextField.PASSWORD);
        summary 
= new TextField("结果"""30, TextField.ANY);
        f.append(uid);
        f.append(name);
        f.append(password);
        f.append(summary);
        f.setItemStateListener(
this);
        display.setCurrent(f);
    }


    
public void pauseApp() {
    }


    
public void destroyApp(boolean unconditional) {
    }


    
public void itemStateChanged(Item i) {
        
if (i == name) {
            summary.setString(
"您输入的用户名为:" + name.getString());
        }

    }

}



4.4.5.8 Gauge
一般让用户做大小的调整,或是用作进度条使用。
API:
Gauge(String label, boolean interactive, int maxValue, int initialValue);
参数interactive指定控件的类型:
􀁺 交互类型(interactive设为true),可以通过手机键盘控制进度条进度;
􀁺 非交互类型(interactive设为false),只能通过程序控制进度条。
参数maxValue指定控件最大数值
参数initialValue指明初始数值。
方法:
setMaxValue()/getMaxValue() 设定/取得允许的最大值
setValue()/getValue() 设定/取得初始值
isInteractive() 判断Gauge是否可与用户交互
规范中还定义了一种无范围Gauge。要求:
Gauge属于非交互类型(第二个参数设置为false),第三个参数传入Gauge.INDEFINITE就可以产生没有范围的Gauge。此时,第四个参数只能有四种选择:
􀁺 Gauge.CONTINUOUS_IDLE 目前程序停止
􀁺 Gauge.CONTINUOUS_RUNNING 以动画显示
􀁺 Gauge.INCREMENTAL_IDLE 目前程序停止,所以是一个静态的图
􀁺 Gauge.INCREMENTAL_UPDATING 以动画显示,只有每次重新调用setValue()画面才会慢慢更新。
示例一:
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

/**
 * 
 * 
@author Allan
 * 
@version
 
*/

public class GaugeTestMidlet extends MIDlet implements ItemStateListener {
    
private Display display;

    
private Gauge g1;

    
private Gauge g2;

    
public GaugeTestMidlet() {
        display 
= Display.getDisplay(this);
    }


    
public void startApp() {
        Form f 
= new Form("Gauge test");
        g1 
= new Gauge("进度条一"true102);
        g2 
= new Gauge("进度条二"false104);
        f.append(g1);
        f.append(g2);
        f.setItemStateListener(
this);
        display.setCurrent(f);
    }


    
public void pauseApp() {
    }


    
public void destroyApp(boolean unconditional) {
    }


    
public void itemStateChanged(Item i) {
        
if (i == g1) {
            g2.setValue(g1.getValue());
        }

    }

}



示例二:
/*
 * GaugeTestMidlet.java
 *
 * Created on 2008年9月2日, AM: 8:40
 
*/

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

/**
 * 
 * 
@author Allan
 * 
@version
 
*/

public class GaugleIndefiniteMidlet extends MIDlet implements CommandListener {
    
private Display display;

    
private Gauge g1;

    
private Command c1;

    
private Command c2;

    
private Command c3;

    
private Command c4;

    
public GaugleIndefiniteMidlet() {
        display 
= Display.getDisplay(this);
        c1 
= new Command("CONTINUOUS_IDLE", Command.SCREEN, 1);
        c2 
= new Command("CONTINUOUS_RUNNING", Command.SCREEN, 1);
        c3 
= new Command("INCREMENTAL_IDLE", Command.SCREEN, 1);
        c4 
= new Command("INCREMENTAL_UPDATING", Command.SCREEN, 1);
    }


    
public void startApp() {
        Form f 
= new Form("Gauge test");
        f.addCommand(c1);
        f.addCommand(c2);
        f.addCommand(c3);
        f.addCommand(c4);
        g1 
= new Gauge("进度条一"false, Gauge.INDEFINITE, Gauge.CONTINUOUS_IDLE);
        
// g1 = new Gauge("进度条一", false, Gauge.INDEFINITE,
        
// Gauge.CONTINUOUS_RUNNING);
        
// g1 = new Gauge("进度条一", false, Gauge.INDEFINITE,
        
// Gauge.INCREMENTAL_IDLE);
        
// g1 = new Gauge("进度条一", false, Gauge.INDEFINITE,
        
// Gauge.INCREMENTAL_UPDATING);
        
// f.setCommandListener(this);
        f.append(g1);
        display.setCurrent(f);
    }


    
public void pauseApp() {
    }


    
public void destroyApp(boolean unconditional) {
    }


    
public void commandAction(Command c, Displayable s) {
        
if (c == c1) {
            g1.setValue(Gauge.CONTINUOUS_IDLE);
        }
 else if (c == c2) {
            g1.setValue(Gauge.CONTINUOUS_RUNNING);
        }
 else if (c == c3) {
            g1.setValue(Gauge.INCREMENTAL_IDLE);
        }
 else if (c == c4) {
            g1.setValue(Gauge.INCREMENTAL_UPDATING);
        }

    }

}


4.4.5.9 DateField
可以让用户方便地输入日期和时间。
API:
DateField(String label, int mode)
DateField(String label, int mode, TimeZone timeZone)
参数mode指定控件类型(3种):
􀁺 DateField.DATE 输入日期
􀁺 DateField.TIME 输入时间
􀁺 DateField.DATE_TIME 输入日期时间
方法:
setInputMode()/getInputMode() 设置/取得输入模式
setDate()/getDate() 设置/取得时间(Dateu需要和Calendar类配合)
示例:

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.util.*;

/**
 * 
 * 
@author DCF
 * 
@version
 
*/

public class DateFieldTestMidlet extends MIDlet {
    
private Display display;

    
private DateField df1;

    
private DateField df2;

    
private DateField df3;

    
public DateFieldTestMidlet() {
        display 
= Display.getDisplay(this);
    }


    
public void startApp() {
        Form f 
= new Form("DateField test");
        TimeZone tz 
= TimeZone.getDefault();
        System.out.println(
"系统默认时区是:" + tz.getID());
        Date now 
= new Date();
        df1 
= new DateField("日期", DateField.DATE);
        df1.setDate(now);
        df2 
= new DateField("日期", DateField.TIME, tz);
        df2.setDate(now);
        df3 
= new DateField("日期", DateField.DATE_TIME, TimeZone
                .getTimeZone(
"CCT"));
        df3.setDate(now);
        f.append(df1);
        f.append(df2);
        f.append(df3);
        display.setCurrentItem(df1);
    }


    
public void pauseApp() {
    }


    
public void destroyApp(boolean unconditional) {
    }

}



4.4.5.9 Alert与Gauge
利用Alert的方法setIndicator()/getIndicator(),可以将Alert当作显示进度的画面。用Gauge做进度显示,但它必须满足以下条件:
1) 不能与用户交互,即第二个参数为false.
2) 不能已经被其他Form或是Alert使用(Item的子类同时间只能属于一个容器)
3) 不能利用addCommand加入任何Command
4) 不能有ItemCommandListener
5) 不能有Label,即构造函数的第一个参数必须给定null
6) 不能使用setLayout()指定Item.LAYOUT_DEFAULT以外的layout
7) 不能使用setPreferSize()指定期望的组件尺寸
示例:

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

/**
 * 
 * 
@author DCF
 * 
@version
 
*/

public class AlertWithIndicatorMidlet extends MIDlet implements
        CommandListener, Runnable 
{
    
private Display display;

    
private Gauge g;

    
private boolean exit = false;

    
public AlertWithIndicatorMidlet() {
        display 
= Display.getDisplay(this);
    }


    
public void startApp() {
        Alert a 
= new Alert("处理中");
        a.setType(AlertType.INFO);
        a.setTimeout(Alert.FOREVER);
        a.setString(
"系统正在处理中");
        g 
= new Gauge(nullfalse100);
        a.setIndicator(g);
        Command start 
= new Command("Start", Command.OK, 1);
        Command stop 
= new Command("Stop", Command.STOP, 1);
        a.addCommand(start);
        a.addCommand(stop);
        a.setCommandListener(
this);
        display.setCurrent(a);
        System.out.println(Thread.currentThread().getName());
    }


    
public void pauseApp() {
    }


    
public void destroyApp(boolean unconditional) {
    }


    
public void run() {
        
if (!exit) {
            
for (int i = 0; i < 11; i++{
                g.setValue(i);
                System.out.println(Thread.currentThread().getName());
                
try {
                    Thread.sleep(
1000);
                }
 catch (Exception e) {
                }

            }

        }

    }


    
public void commandAction(Command c, Displayable s) {
        System.out.println(Thread.currentThread().getName());
        String cmd 
= c.getLabel();
        
if (cmd.equals("Start")) {
            
new Thread(this).start();
        }
 else if (cmd.equals("Stop")) {
            exit 
= true;
            destroyApp(
false);
            notifyDestroyed();
        }

    }

}



注意:所有UI相关的回调函数都是由同一个Thread完成,具有依序执行的特性。 

posted on 2008-09-01 19:48 骑猪闯天下 阅读(3111) 评论(3)  编辑  收藏

评论

# re: [J2ME] MIDP高级界面开发 2008-09-01 19:57 ∪∩BUG

建议格式化一下代码,方便学习交流.  回复  更多评论   

# re: [J2ME] MIDP高级界面开发 2008-09-02 08:46 骑猪闯天下

@∪∩BUG
接受建议,已格式化  回复  更多评论   

# re: [J2ME] MIDP高级界面开发 2009-05-23 11:25

真的很不错  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航: