Polish gui 编程:
1. 使用正确的import语句:正确并且非全限定的类名
a) 错误用法:
public class MyForm
extends javax.microedition.lcdui.Form
{
private javax.microedition.lcdui.StringItem textItem;
public MyForm( String title ) {
//#style myForm, default
super( title );
this.textItem =
new javax.microedition.lcdui.StringItem( null, "Hello World" );
append( this.textItem );
}
}
b) 正确用法
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.StringItem;
public class MyForm
extends Form
{
private StringItem textItem;
public MyForm( String title ) {
//#style myForm, default
super( title );
this.textItem = new StringItem( null, "Hello World" );
append( this.textItem );
}
}
c) 如果你更倾向于使用原生的J2ME实现而不是polish的,可以通过给出全限定的类名来限制这种行为
2. 设置style
a) 当有多个style,使用第一个有效的style
b) 实例:
import javax.microedition.lcdui.Form;
public class MainMenu extends Form {
public MainMenu( String title ) {
//#style mainMenu, default
super( title );
[...]
}
}
c) 你总要在resources/polish.css定义 .mainMenu 样式,当没有找到时,polish会报错,并退出处理。Default样式很特别,即使你没有明确定义,它仍能使用。
i. 定义.mainMenu
.mainMenu {
background-image: url( bg.png );
columns: 2;
}
d) 在哪里插入#style语句?
i. Item contructor :#style可以放在任何item的构造器前
例子:
//#style cool, frosty,
StringItem url = new StringItem ( null, "http://192.168.101.101" );
//#style cool
ImageItem img = new ImageItem
( null, iconImage,
ImageItem.LAYOUT_DEFAULT, null );
ii. Item.setApperanceMode() #style指令能够防止调用setApperanceMode()之前,这个方法仅仅在J2ME polish内有效
例子
//#style openLink
url.setApperanceMode(Item.HYPERLINK);
iii. List.append #style指令能够放在添加一个list元素之前
//#style choice
list.append (“Start”,null);
iv. List.insert 同上
//#style choice
list.insert (2,“Start”,null);
v. List.set 同上
//#style choice
list.set (2,“Start”,null);
vi. Form.append
//#style text
form.append (textItem);
vii. ChoiceGroup.append
//#style text
group.append (“Choice 1”,null);
viii. ChoiceGroup.insert()
//#style text
group.insert (2,“Choice 3”,null);
ix. ChoiceGroup.set()
//#style text
group.set (2,“Choice 3”,null);
x. Screen Constructor
//#style mainScreen
Form form = new Form(“Menu”);
//in subclasses of Screens
//#style mainScreen
super(“Menu”);
3. 使用动态和预定义的类型
如果你使用动态类型 ,你甚至不用#style指令,这时设计基于类,例如所有form根据form样式设计,使用动态类型,可以最快的查找现有程序的GUI,但需要额外的内存和时间。所以你要为最后的程序使用正常的“静态”的样式
有的元素默认使用预先定义的样式,例如Screen标题的表现由title样式负责。
4. 从MIDP 2.0 移植到 MIDP 1.0
当你使用polish gui 你可以使用MIDP 2.0的组件,如popup choicegroup或CustomItem., 完全没有任何限制
当使用MIDP2.0特有的,超出polish gui范畴的属性时候要修改源码,如Display.flashBacklight(int)
当一个特定的call不被目标设备支持,build会因为compile error停止。通常,error要被#if预处理指令包围,如下例子:
#ifdef polish.midp2
this.display.flashBacklight(1000);
#endif
5. 特定的Item和Screen
a) TabbedForm : de.enough.polish.ui.TabbedForm , 在不同的tab上维护gui元素,你可以使用任何的Form方法在她上面。
实例:
package com.apress.ui;
import javax.microedition.lcdui.Choice;
import javax.microedition.lcdui.ChoiceGroup;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.DateField;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.StringItem;
import javax.microedition.lcdui.TextField;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.ItemStateListener;
import de.enough.polish.ui.TabbedForm;
public class TabbedFormDemo implements ItemStateListener {
private final TextField nameField;
public TabbedFormDemo( CommandListener commandListener,
Display display, Command returnCmd )
{
String[] tabNames = new String[]{ "Input", "Choice",
"Connection" };
//#style tabbedScreen
TabbedForm form = new TabbedForm( "TabbedDemo", tabNames, null );
//#style label
StringItem label = new StringItem( null, "name:" );
form.append( 0, label );
//#style input
this.nameField = new TextField( null, "Robert", 30,
TextField.ANY | TextField.INITIAL_CAPS_WORD );
form.append( 0, this.nameField );
//#style label
label = new StringItem( null, "birthday:" );
form.append( 0, label );
//#style input
DateField birthdate = new DateField( null, DateField.DATE );
form.append( 0, birthdate );
//#style label
label = new StringItem( null, "What kind of animals do you like:" );
form.append( 1, label );
//#style multipleChoice
ChoiceGroup choice = new ChoiceGroup( null, Choice.MULTIPLE );
//#style choiceItem
choice.append( "dogs", null );
//#style choiceItem
choice.append( "cats", null );
//#style choiceItem
choice.append( "birds", null );
form.append( 1, choice );
//#style label
label = new StringItem( null, "Connection:" );
form.append( 2, label );
//#style multipleChoice
choice = new ChoiceGroup( null, Choice.MULTIPLE );
//#style choiceItem
choice.append( "ISDN", null );
//#style choiceItem
choice.append( "DSL", null );
//#style choiceItem
choice.append( "Cable", null );
form.append( 2, choice );
form.addCommand( returnCmd );
form.setCommandListener( commandListener );
form.setItemStateListener( this );
display.setCurrentItem( choice );
}
public void itemStateChanged( Item item ) {
System.out.println( "Item State Changed: " + item );
}
}
TabbedForm实例图片:
b) FramedForm: de.enough.polish.ui.FramedForm 将屏幕划分为一个主区域和四个可能的frame:上下左右。只有主区域是可以滚动的。
实例:
package com.apress.ui;
import javax.microedition.lcdui.Choice;
import javax.microedition.lcdui.ChoiceGroup;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.DateField;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.TextField;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.ItemStateListener;
import de.enough.polish.ui.FramedForm;
public class FramedFormDemo implements ItemStateListener {
private final TextField inputField;
private final Item[] items;
public FramedFormDemo( CommandListener commandListener,
Display display, Command returnCmd, Item[] items )
{
//#style framedScreen
FramedForm form = new FramedForm( "TabbedDemo" );
// add all normal items:
for ( int i = 0; i < items.length; i ++ ) {
form.append( items[i] );
}
//#style inputFilter
this.inputField = new TextField( "Filter: ", "", 30, TextField.ANY );
form.append( Graphics.BOTTOM, this.inputField );
form.addCommand( returnCmd );
form.setCommandListener( commandListener );
display.setCurrentItem( this.inputField );
}
public void itemStateChanged( Item item ) {
// the TextField has been changed, now filter
// the item accordingly...
}
FramedForm实例图片:
c) SpriteItem:de.enough.polish.ui.SpriteItem将动画包含在你的form里面,这个item内嵌一个正常的javax.microedtion.lcdui.game.Sprite,当item聚焦时候能够产生动画。
i. SpriteItem的构造参数:
1. Strig label :标签
2. Sprite sprite:内嵌的Sprite,在动画过程中播放Sprite的帧序列
3. long animationInterval:帧之间切换的间隔,这需要是100的倍数,触发你在build.xml设置polish.animationInterval
4. int defaultFrameIndex 当SpriteItem没有聚焦时候的帧号
5. boolean repeatAnimation 是否重复播放
实例:
package com.apress.ui;
import java.io.IOException;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.ItemCommandListener;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
import de.enough.polish.ui.SpriteItem;
public class AnimatedMenuMidlet
extends MIDlet
implements ItemCommandListener
{
private Display display;
private Form mainForm;
private final Command startCmd;
private final Command loadCmd;
private final Command aboutCmd;
private final Command exitCmd;
public AnimatedMenuMidlet() {
super();
this.startCmd = new Command( "Start Game", Command.ITEM, 1 );
this.loadCmd = new Command( "Load Game", Command.ITEM, 1 );
this.aboutCmd = new Command( "About", Command.ITEM, 1 );
this.exitCmd = new Command( "Exit", Command.ITEM, 1 );
try {
this.mainForm = new Form( "Main Menu" );
int frameWidth = 30;
int frameHeight = 30;
// create the start game menu item:
Image image = Image.createImage( "/player.png");
Sprite sprite = new Sprite( image, frameWidth, frameHeight );
sprite.setFrameSequence( new int[]{ 2, 5, 5, 6, 3, 7, 1 } );
//#style mainScreenItem
SpriteItem spriteItem = new SpriteItem( null, sprite, 200, 0, false );
spriteItem.setDefaultCommand( this.startCmd );
spriteItem.setItemCommandListener( this );
this.mainForm.append( spriteItem );
// create the load game menu item:
image = Image.createImage( "/load.png");
sprite = new Sprite( image, frameWidth, frameHeight );
// use default frame sequence
//#style mainScreenItem
spriteItem = new SpriteItem( null, sprite, 200, 0, false );
spriteItem.setDefaultCommand( this.loadCmd );
spriteItem.setItemCommandListener( this );
this.mainForm.append( spriteItem );
// create the about menu item:
image = Image.createImage( "/about.png");
sprite = new Sprite( image, frameWidth, frameHeight );
//#style mainScreenItem
spriteItem = new SpriteItem( null, sprite, 200, 0, false );
spriteItem.setDefaultCommand( this.aboutCmd );
spriteItem.setItemCommandListener( this );
this.mainForm.append( spriteItem );
// create the exit menu item:
image = Image.createImage( "/exit.png");
sprite = new Sprite( image, frameWidth, frameHeight );
//#style mainScreenItem
spriteItem = new SpriteItem( null, sprite, 200, 0, false );
spriteItem.setDefaultCommand( this.exitCmd );
spriteItem.setItemCommandListener( this );
this.mainForm.append( spriteItem );
catch ( IOException e ) {
//#debug error
System.out.println( "Unable to create menu screen" + e );
this.mainForm = null;
}
}
protected void startApp() throws MIDletStateChangeException {
this.display = Display.getDisplay( this );
if ( this.mainForm == null ) {
throw new MIDletStateChangeException();
}
this.display.setCurrent( this.mainForm );
}
protected void pauseApp() {
// just pause
}
protected void destroyApp( boolean unconditional )
throws MIDletStateChangeException
{
// just quit
}
public void commandAction( Command cmd, Item item ) {
if ( cmd == this.startCmd ) {
// start game...
} else if ( cmd == this.loadCmd ) {
/// load game...
} else if ( cmd == this.aboutCmd ) {
// about this game...
} else if ( cmd == this.exitCmd ) {
notifyDestroyed();
}
}
}