- J2ME手機游戲設計與開發
- 劉暢 張旭輝編著
- 128字
- 2019-01-01 07:08:57
3.5 Form類及其組件
3.5.1 Form類介紹
TextBox、List、Alert類只能實現單一的功能,手機屏幕在某一時刻只能顯示一個對象,所以很多時候無法滿足人們對界面的設計,例如,【例3-5】中為了實現用戶名和密碼的校驗不得不切換界面,如果可以在一個界面中同時輸入用戶名和密碼就會使程序和界面都簡化很多,Form類的提出很大程度上解決了這個問題。Form為屏幕表單類,本身是高級屏幕類Screen的子類,可以作為setCurrent()方法的參數直接被使用,但是Form中并沒有提供與用戶進行交互的界面,它是通過在其中添加其他組件完成交互的,所添加的組件即是Item的子類,包括文本域、日期域、進度條等共計8種。首先介紹Form類本身所提供的常用方法,如表3-11所示。
表3-11 Form類的常用方法
創建并使用Form對象:
Display display; Form mainForm; display=Display.getDisplay(this); mainForm=new Form("屏幕表單及其組件"); display.setCurrent(mainForm);
執行效果如圖3-14所示。
3.5.2 StringItem字符串顯示類
StringItem類是包含一個字符串的表單組件,只用做顯示而不能編輯內容,但通過程序代碼可以更改它的標簽和文本內容。StringItem類的常用方法如表3-12所示。
表3-12 StringItem類的常用方法
創建并使用StringItem對象:
StringItem si1=new StringItem("StringItem組件","顯示字符串信息"); mainForm.append(si1);
執行效果如圖3-15所示。

圖3-14 Form屏幕表單效果圖

圖3-15 StringItem組件效果
StringItem類有兩個構造函數,第2個構造函數需要3個參數,除了標題和內容外還要給出外觀模式,在StringItem中一共定義了3種外觀模式。
Item.PLAIN:值為0,無特殊模式。
Item.HYPERLINK:值為1,顯示為超級鏈接。
Item.BUTTON:值為2,顯示為按鈕。
【例3-8】 添加和修改StringItem對象。
import javax.microedition.lcdui.*; import javax.microedition.midlet.MIDlet; import javax.microedition.midlet.MIDletStateChangeException; public class mainMidlet extends MIDlet implements CommandListener { Display disp; Form form; StringItem si; Command cmd; public mainMidlet() { disp=Display.getDisplay(this); form=new Form("StringItem實例"); si=new StringItem("內容:","修改前"); cmd=new Command("修改文本",Command.OK,1); form.append(si); form.addCommand(cmd); form.setCommandListener(this); } protected void destroyApp(boolean arg0) throws MIDletStateChangeException { } protected void pauseApp() { } protected void startApp() throws MIDletStateChangeException { disp.setCurrent(form); } public void commandAction(Command arg0, Displayable arg1) { if(cmd==arg0) { si.setText("修改后"); } } }
執行效果如圖3-16所示。

圖3-16 StringItem實例效果圖
3.5.3 ImageItem圖像顯示類
ImageItem類能夠在Form中顯示圖片,從而實現比較豐富而復雜的顯示界面,其常用方法如表3-13所示。
表3-13 ImageItem類的常用方法
創建和使用ImageItem對象,要想創建ImageItem,首先需要創建Image對象。代碼格式為Image img=Image.createImage(“/xm.png”);其中參數為圖像的路徑。導入圖像時要做異常處理,具體代碼如下:
Image img; try { img=Image.createImage("/xm.png"); } catch (Exception e) { } ImageItem ii=new ImageItem("圖像",img,ImageItem.LAYOUT_CENTER,"文本"); mainForm.append(ii);
執行效果如圖3-17所示。

圖3-17 ImageItem 組件效果
構造函數中的第3個參數為ImageItem的布局樣式,ImageItem中共定義了6種布局樣式。
ImageItem.LAYOUT_DEFAULT:值為0,使用系統默認的圖像布局。
ImageItem.LAYOUT_LEFT:值為1,圖像靠近繪圖區域的左邊緣。
ImageItem.LAYOUT_RIGHT:值為2,圖像靠近繪圖邊緣的右邊緣。
ImageItem.LAYOUT_CENTER:值為3,圖像位于繪圖區域的水平中間。
ImageItem.LAYOUT_NEWLINE_BEFORE:值為4,繪制圖像前開始新的一行。
ImageItem.LAYOUT_NEWLINE_AFTER:值為5,繪制圖像后開始新的一行。
【例3-9】 ImageItem實例。
import javax.microedition.lcdui.*; import javax.microedition.midlet.MIDlet; import javax.microedition.midlet.MIDletStateChangeException; public class ImageItemTest extends MIDlet { Display disp; Form form; ImageItem ii1,ii2,ii3; Image img; public ImageItemTest() { disp=Display.getDisplay(this); form=new Form("ImageItem實例"); try { img=Image.createImage("/_ack_8.png"); } catch (Exception e) { } ii1=new ImageItem("左對齊",img,ImageItem.LAYOUT_LEFT,""); ii2=new ImageItem("居中對齊",img,ImageItem.LAYOUT_CENTER,""); ii3=new ImageItem("右對齊",img,ImageItem.LAYOUT_RIGHT,""); form.append(ii1); form.append(ii2); form.append(ii3); } protected void destroyApp(boolean arg0) throws MIDletStateChangeException { } protected void pauseApp() { } protected void startApp() throws MIDletStateChangeException { disp.setCurrent(form); } }
執行效果如圖3-18所示。

圖3-18 ImageItem實例效果圖
3.5.4 TextField文本域類
TextField為文本域類,主要用來輸入和顯示文本內容,TextField類的常用方法如表3-14所示。
表3-14 TextField類的常用方法
創建并使用TextField對象:
TextField tf=new TextField ("任意字符", "初始字符",20,TextField.ANY);
TextField的構造函數與TextBox非常類似,第1個參數是標簽文本,第2參數是初始時顯示的字符,第3個參數是能夠容納的最大字符數,最后一個參數是輸入的文本約束。
TextField和TextBox的區別是前者是Item的子類,不能直接被setCurrent方法調用,只能被添加到Form上才能被顯示在手機屏幕上,后者則是Screen類的子類,可以直接被setCurrent()方法調用顯示,但是某一時刻只可以顯示一個TextBox對象。
這里首先利用TextField對象的特點修改一下【例3-5】,修改后的結果參見【例3-10】。
【例3-10】 TextField的用戶名和密碼驗證。
import javax.microedition.lcdui.*; import javax.microedition.midlet.*; public class mainMidlet extends MIDlet implements CommandListener { Display display; Form form; TextField tfName,tfPwd; StringItem si; Command cmdEnter; public mainMidlet() { display=Display.getDisplay(this); form=new Form("登錄界面"); tfName=new TextField("請輸入用戶名","",12,TextField.ANY); tfPwd=new TextField("請輸入密碼","",6,TextField.NUMERIC); cmdEnter=new Command("確定",Command.OK,1); si=new StringItem("",""); form.append(tfName); form.append(tfPwd); form.addCommand(cmdEnter); form.setCommandListener(this); } protected void destroyApp(boolean arg0)throws MIDletStateChangeException{ } protected void pauseApp() { } protected void startApp() throws MIDletStateChangeException { display.setCurrent(form); } public void commandAction(Command c, Displayable d) { if(c==cmdEnter ) { if(tfName.getString().equals("abc")&&tfPwd.getString(). equals("123")) si.setText("輸入正確"); else si.setText("輸入錯誤"); form.deleteAll(); form.append(si); } } }
執行效果如圖3-19所示。

圖3-19 TextField用戶名和密碼驗證效果圖
3.5.5 DateField日期域類
DateField為日期域類,主要用來輸入和顯示日期和時間。DateField類的常用方法如表3-15所示。
表3-15 DateField類的常用方法
創建并使用DateField對象:
DateField df=new DateField("出生日期", DateField.DATE);
DateField有兩個構造函數,第1個構造函數DateField(String label,int mode)使用指定的標簽和輸入模式來構建DateField對象,第2個構造函數DateField(String label,int mode,TimeZone timeZone)則需要在指定標簽和輸入模式的同時還指定時區,如果TimeZone的值為null,則使用系統默認時區。
DateField類中共定義了3種輸入模式:DateField.DATE(日期)、DateField.TIME(時間)和DateField.DATE_TIME(日期加時間)。
構造完成后,DateField還處于未初始化狀態,沒有具體的日期時間,可以使用setDate(Date date)方法為其設置初始值。
將DateField對象添加到Form對象中:
mainForm.append(df);
執行效果如圖3-20所示。

圖3-20 DateField對象效果
下面運用DateField類來看看不同的輸入模式的表現有何不同,具體實現參見【例3-11】。
【例3-11】 DateField類的不同輸入模式。
import javax.microedition.midlet.*; import javax.microedition.lcdui.*; import java.util.Date; public class DateFieldTest extends MIDlet implements CommandListener{ private Form form; private List startmenu; private long date, time; //計算一天有多少毫秒 private long dayInMillis=24*60*60*1000; private String choices[]={"DATE mode","TIME mode", "DATE_TIME mode"}; private Command backCommand = new Command("Back", Command.BACK, 1); private Command okCommand = new Command("OK", Command.OK, 1); private Command exitCommand = new Command("EXIT", Command.EXIT, 1); private Display display; public DateFieldTest() { //創建List對象作為起始菜單 startmenu= new List("Chooise a input mode",List.IMPLICIT,choices,null); startmenu.addCommand(exitCommand); startmenu.setCommandListener(this); //創建Form對象 form= new Form("DateField Test"); DateField df=new DateField("",DateField.DATE_TIME); //System.currentTimeMillis()表示系統的當前時間 time=System.currentTimeMillis()%dayInMillis; date=System.currentTimeMillis()-time; df.setDate(new Date(date+time)); form.append(df); form.addCommand(okCommand); form.addCommand(backCommand); form.setCommandListener(this); display=Display.getDisplay(this); } public void startApp() throws MIDletStateChangeException { display.setCurrent(startmenu); } public void pauseApp() { } public void destroyApp(boolean unconditional) { form=null; startmenu=null; backCommand = null; okCommand=null; exitCommand = null; display=null; } public void commandAction(Command c, Displayable d) { if(d==startmenu && c==List.SELECT_COMMAND) { //form.get(0)表示獲取form界面中的第一個組件 DateField df= (DateField) form.get(0); //保存設置的日期或時間 if(df.getInputMode()==DateField.DATE) { date=df.getDate().getTime(); } else if(df.getInputMode() == DateField.TIME) { time=df.getDate().getTime(); } else { time=df.getDate().getTime()%dayInMillis; date=df.getDate().getTime()-time; } //設置時間和輸入模式 df.setLabel(choices[startmenu.getSelectedIndex()]); switch(startmenu.getSelectedIndex()) { case 0: df.setInputMode(DateField.DATE); df.setDate(new Date(date)); break; case 1: df.setInputMode(DateField.TIME); df.setDate(new Date(time)); break; case 2: df.setInputMode(DateField.DATE_TIME); df.setDate(new Date(date+time)); break; } display.setCurrent(form); } else if(d==form && c==okCommand) { DateField df= (DateField) form.get(0); System.out.println("Time set in millis: "+df.getDate().getTime()); } else if(c==backCommand) { display.setCurrent(startmenu); } else if(c==exitCommand) { destroyApp(true); notifyDestroyed(); } } }
執行效果如圖3-21所示。

圖3-21 DateField類的不同輸入模式效果
3.5.6 Gauge類圖形標尺
Gauge類實現了一個圖像標尺,通常被用來表示一個過程的進展情況,例如進度條、音量調節界面等。Gauge類的常用方法如表3-16所示。
表3-16 Gauge類的常用方法
創建并使用Gauge對象:
Gauge gauge=new Gauge("圖形標尺",true,5,0);
Gauge只有一個構造方法,其中第1個參數為圖形標尺的標簽,可以設置為null,第2個參數表示是否允許用戶交互,第3個參數表示標尺的最大值,必須大于0,第4個參數表示標尺的初始值。
將Gauge對象添加到Form界面中:
gauge.setLayout(Item.LAYOUT_CENTER);//設置布局模式居中 mainForm.append(gauge);
如果是否允許交互值為true,則執行效果如圖3-22(a)所示;如果為false,則效果如圖3-22(b)所示。

圖3-22 Gauge對象效果
Gauge類的完整實例程序參見【例3-12】。
【例3-12】 Gauge類對象的應用。
import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class GaugeTest extends MIDlet implements CommandListener{ private Form form; private List startmenu; private String choices[]={"Interactive Gauge","Non-interactive Gauge"}; private Command backCommand = new Command("Back", Command.BACK, 1); private Command exitCommand = new Command("EXIT", Command.EXIT, 1); private Display display; public GaugeTest() { startmenu= new List("Chooise a Gauge type",List.IMPLICIT,choices,null); startmenu.addCommand(exitCommand); startmenu.setCommandListener(this); form= new Form("Gauge Test"); form.addCommand(backCommand); form.setCommandListener(this); display=Display.getDisplay(this); } public void startApp() throws MIDletStateChangeException { display.setCurrent(startmenu); } public void pauseApp() { } public void destroyApp(boolean unconditional) { form=null; startmenu=null; backCommand = null; exitCommand = null; display=null; } public void commandAction(Command c, Displayable d) { if(d==startmenu && c==List.SELECT_COMMAND) { if(form.size()>0) form.delete(0); if(startmenu.getSelectedIndex()==0) { form.append(new Gauge("Interactive Gauge",true,10,4)); } else { form.append(new Gauge("Non-interactive Gauge",false,10,4)); } display.setCurrent(form); } else if(c==backCommand) { display.setCurrent(startmenu); } else if(c==exitCommand) { destroyApp(true); notifyDestroyed(); } } }
執行效果如圖3-23所示。

圖3-23 Gauge中的交互模式和非交互模式效果圖
3.5.7 Spacer類
Spacer類是MIDP 2.0中特有的不可見組件,通常是提供其他組件之間的垂直和水平間隔,用于定位。Spacer類的常用方法如表3-17所示。
表3-17 Spacer類的常用方法
創建和使用Spacer對象:
Spacer sp=new Spacer(30,30); mainForm.append(sp);
效果如圖3-24所示,其中(a)為未使用Spacer組件效果,(b)為使用Spacer組件效果。

圖3-24 Spacer對象效果
3.5.8 CustomItem類自定義組件
已有的高級屏幕類組件并不能滿足開發者對界面的要求,所以在MIDP 2.0中引入了CustomItem自定義組件類實現像素級別的繪制和內部事件的處理。
CustomItem類為抽象類,在實際運用時需要派生一個CustomItem的子類,在子類中通過實現CustomItem的抽象方法及定義自己的方法來完善實際的功能,從而繪制較復雜的畫面,這些與普通的Item類略有不同。CustomItem類的常用方法如表3-18所示。
表3-18 CustomItem類的常用方法
CustomItem的功能介于高級和低級之間的用戶界面,它既可以添加到Form中,也可以擴展為圖像用戶界面,通過實現一系列抽象方來繪制具體的圖形。實現自定義界面的代碼參見【例3-13】。
【例3-13】 利用CustomItem類繪制自定義表格。
(1)建立MIDlet類。
import javax.microedition.lcdui.*; import javax.microedition.midlet.*; public class CustomMidlet extends MIDlet { Display display; Form mainForm; MyCustomItem custom; public CustomMidlet() { display=Display.getDisplay(this); mainForm=new Form("自定義組件"); custom=new MyCustomItem("表格"); mainForm.append(custom); } protected void destroyApp(boolean arg0) throws MIDletStateChange Exception { } protected void pauseApp() { } protected void startApp() throws MIDletStateChangeException { display.setCurrent(mainForm); } }
(2)MyCustomItem類的基本框架。
import javax.microedition.lcdui.*; public class MyCustomItem extends CustomItem { public MyCustomItem(String label) { super(label); } protected int getMinContentHeight() { return 0; } protected int getMinContentWidth() { return 0; } protected int getPrefContentHeight(int arg0) { return 200; } protected int getPrefContentWidth(int arg0) { return 200; } protected void paint(Graphics arg0, int arg1, int arg2) { for(int i=0;i<=5;i++) { arg0.drawLine(0, i*20, 100, i*20); arg0.drawLine(i*20, 0, i*20, 100); } } }
(3)執行效果如圖3-25所示。

圖3-25 自定義表格效果
- Mastering Hadoop 3
- 21天學通JavaScript
- Learning Apache Spark 2
- 手把手教你玩轉RPA:基于UiPath和Blue Prism
- 輕松學Java
- 大數據時代的數據挖掘
- Hadoop Real-World Solutions Cookbook(Second Edition)
- Enterprise PowerShell Scripting Bootcamp
- Lightning Fast Animation in Element 3D
- Troubleshooting OpenVPN
- Machine Learning with the Elastic Stack
- Python:Data Analytics and Visualization
- FPGA/CPLD應用技術(Verilog語言版)
- Learning Apache Apex
- AVR單片機工程師是怎樣煉成的