騎豬闖天下

          J2ME隨筆,記錄成長(zhǎng)的腳步

          統(tǒng)計(jì)

          留言簿(3)

          閱讀排行榜

          評(píng)論排行榜

          [J2ME] MIDP高級(jí)界面開(kāi)發(fā)

          MIDP高低級(jí)界面開(kāi)發(fā)


          LCDUI——Limited Configuration Device UI。

          1. LCDUI包的設(shè)計(jì):
          兩種API:
          ?? 高級(jí)API(Screen):畫(huà)面具有可移植性,但無(wú)法決定組件的顏色、字體和外觀。
          ?? 低級(jí)API(Canvas):編寫(xiě)相對(duì)復(fù)雜,但對(duì)畫(huà)面的控制具有完全的控制權(quán)。由于在不同的機(jī)器上有不同的特性(控制方式、屏幕顏色等),不能保證不同種類(lèi)機(jī)器上可以得到相同的執(zhí)行結(jié)果。
          由于手機(jī)一次只能顯示出一個(gè)畫(huà)面,因此每個(gè)畫(huà)面只能在高級(jí)API或者API之間擇一使用。
          高級(jí)API和低級(jí)API可以在同一個(gè)MIDlet中混合使用,組成應(yīng)用程序中的每個(gè)畫(huà)面。但是同一個(gè)畫(huà)面中,就只能使用高級(jí)或者低級(jí)API中的一個(gè)。
          2. LCDUI的包體系結(jié)構(gòu)
          能夠顯示在屏幕上的組件都是繼承自抽象類(lèi)Displayable。
          Displayable
          |
          -------------Screen(高級(jí)API——高級(jí)類(lèi)庫(kù))
          |
          -------------Canvas(低級(jí)API——低級(jí)類(lèi)庫(kù))
          LCDUI包全部定義在java.microedition.lcdui中。
          3. Displayable類(lèi)
          是一個(gè)抽象類(lèi)。其子類(lèi)都具有顯示于屏幕上的能力。
          提供的方法:
          getTicker()/setTicker()設(shè)定/獲取跑馬燈
          setTitle()/getTitle()設(shè)定/獲取畫(huà)面標(biāo)題
          注意:上述方法在MIDP1.0中用于Screen,而在MIDP2.0中可用于Displayable中。
          getHeight()取得屏幕上應(yīng)用程序區(qū)的高度
          getWidth()取得屏幕上應(yīng)用程序區(qū)的寬度
          上述2個(gè)方法,對(duì)低級(jí)API來(lái)說(shuō)非常有用。因?yàn)槊靠钍謾C(jī)的屏幕大小不同,而跑馬燈與標(biāo)題區(qū)存在與否,會(huì)影響這兩個(gè)方法的返回值。
          應(yīng)用程序區(qū):除去標(biāo)題、跑馬燈區(qū)域以及Command顯示區(qū)以外,屏幕上剩下的那部分區(qū)域。
          Displayable的子類(lèi)可以通過(guò)isShow()判斷目前這個(gè)畫(huà)面是否正被Display顯示在屏幕上。
          Displayable類(lèi)中定義了一個(gè)名為sizeChanged()的方法。可以被Canvas或Form的子類(lèi)所重寫(xiě)(Override)。例如,Canvas的setFullScreenMode()方法就會(huì)導(dǎo)致sizeChanged()被調(diào)用。
          第四章 高級(jí)界面開(kāi)發(fā)
          目標(biāo):
          ?? 了解Screen的基本概念
          ?? 了解基本屏幕類(lèi)的開(kāi)發(fā)
          MIDP用戶(hù)界面設(shè)計(jì)開(kāi)發(fā)不同于一般的桌面程序,受限于屏幕大小、顏色、內(nèi)存和處理能力。好的界面應(yīng)該根據(jù)設(shè)備具體情況有針對(duì)性地設(shè)計(jì)。
          4.1 MIDP高級(jí)界面開(kāi)發(fā)
          高級(jí)API提供了常用的控件,強(qiáng)調(diào)可移植性,只能有限控制控件外觀,事件的使用也很有限。
          4.1.1 Display類(lèi)的開(kāi)發(fā)
          MIDP的程序界面是通過(guò)屏幕顯示出來(lái)的。在屏幕上顯示一幅畫(huà)面就是Display對(duì)象要實(shí)現(xiàn)的功能。
          每個(gè)MIDP程序都是由Displayable對(duì)象來(lái)具體處理在屏幕上顯示的內(nèi)容。MIDP程序可以根據(jù)手機(jī)使用者與程序的交互情況,把每次操作后的畫(huà)面通過(guò)Displayable對(duì)象顯示在當(dāng)前屏幕上。
          Displayable是Display的一個(gè)繼承類(lèi),主要包括兩個(gè)具體實(shí)現(xiàn)類(lèi):
          ?? 高級(jí)界面開(kāi)發(fā)類(lèi)Screen
          ?? 低級(jí)界面開(kāi)發(fā)類(lèi)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下開(kāi)發(fā),MIDP2.0的方法不能夠使用。
          類(lèi)Screen共有四個(gè)繼承它的屏幕類(lèi),而Form屏幕類(lèi)可以添加八個(gè)繼承自Item類(lèi)的控件類(lèi)。
          Screen
          List
          TextBox
          Form
          DateField
          TextField
          ImageItem
          Gauge
          ChoiceGroup
          StringItem
          CustomItem(MIDP2.0)
          Spacer(MIDP2.)
          Alert
          4.1.2 基本控件開(kāi)發(fā)簡(jiǎn)介
          Screen共有4個(gè)子類(lèi):Alert Form List和TextBox。這四個(gè)子類(lèi)本身就是屏幕類(lèi),可以直接在屏幕上顯示。
          Alert:用于顯示提示信息的屏幕類(lèi)。
          List: 用來(lái)顯示列表的屏幕類(lèi)。
          TextBox:用來(lái)輸入文字信息。
          一個(gè)復(fù)雜的程序界面往往需要很多類(lèi)型的輸入方式和顯示方式。
          Form類(lèi)被設(shè)計(jì)成可以包含多個(gè)不同類(lèi)型的控件,使用Form類(lèi)可以管理屏幕上的Item控件,基本的Item控件有DateField TextField ImageItem Gauge ChoiceGroup StringItem等。
          4.2 事件處理
          Java程序中,實(shí)現(xiàn)與用戶(hù)的交互功能都是需要通過(guò)事件來(lái)處理的,需要指定控件所使用的時(shí)間監(jiān)聽(tīng)器。
          事件就是用戶(hù)與GUI(圖形界面)交互時(shí)候所觸發(fā)的事情。例如按鍵就是事件。
          J2ME中,事件會(huì)被傳送到事件處理器,一般由J2ME中的監(jiān)聽(tīng)器來(lái)實(shí)現(xiàn)。監(jiān)聽(tīng)器是能夠檢測(cè)并且能夠相應(yīng)事件的代碼。
          需要注意的是每個(gè)事件的處理總是在前一個(gè)事件處理完成以后程序才會(huì)接著處理,意味著事件不能夠同時(shí)被處理,它們是串行處理的。
          4.2.1Command編程基礎(chǔ)
          高級(jí)屏幕類(lèi)TextBox、List和Form都可以在屏幕上添加Command(菜單項(xiàng))。javax.microedition.lcdui.Command就是一般應(yīng)用程序中使用的系統(tǒng)菜單中的菜單項(xiàng)的概念。由于Displayable對(duì)象中定義了addCommand()/removeCommand()兩個(gè)方法,意味著Command類(lèi)適用于高級(jí)API(Screen)與低級(jí)API(Canvas)。
          API:
          new Command(Labels, Type, Priority);
          方法:
          getLabel()
          getLongLabel()
          getCommandType()
          getPriority()
          第二個(gè)參數(shù)是Command的類(lèi)型:共有八種類(lèi)型。注意Command并不會(huì)因?yàn)樵O(shè)定成某一種類(lèi)型就具有該類(lèi)型“名稱(chēng)”的功能。例,某個(gè)Command不會(huì)因?yàn)樵O(shè)置為Command.EXIT,選擇后就真的會(huì)終止程序。但每種類(lèi)型都有其隱含的意義。
          類(lèi)型 默認(rèn)數(shù)值 作用
          BACK 2 邏輯上返回前一個(gè)屏幕
          CANCEL 3 取消當(dāng)前屏幕的操作和提示
          EXIT 7 退出程序
          HELP 5 請(qǐng)求幫助
          ITEM 8 提示實(shí)現(xiàn)指定屏幕上的某一項(xiàng)
          OK 4 肯定當(dāng)前屏幕的操作或指示
          SCREEN 1 應(yīng)用到當(dāng)前屏幕
          STOP 6 停止當(dāng)前運(yùn)行的操作
          在不同的機(jī)器上,Command的位置會(huì)因?yàn)轭?lèi)型不同而有所不同。有些機(jī)器會(huì)以抬頭菜單的形式出現(xiàn)(Nokia 9210),有些機(jī)器會(huì)根據(jù)類(lèi)型自動(dòng)修改按鈕在屏幕上的名稱(chēng)(Nokia 3300)。只能確定的是,Command會(huì)以以用戶(hù)熟悉的操作方式來(lái)呈現(xiàn)。并根據(jù)類(lèi)型,將Command放置到該設(shè)備最合適的位置上。
          第三個(gè)參數(shù)是優(yōu)先權(quán),號(hào)碼越低優(yōu)先權(quán)越高,優(yōu)先權(quán)越高,代表用戶(hù)越能夠方便的找到它們。數(shù)值相同時(shí),使用方法本身默認(rèn)的數(shù)值。
          例:
          Form f = new Form(“test”);
          Command c = new Command(“menu1”, Command.Screen, 1);
          f.addCommand(c );
          display.setCurrent(f);
          另外,Command類(lèi)有另外構(gòu)造方法,共4個(gè)參數(shù):
          Command(“short name”, “long name”, commandType, priority)
          其中第二個(gè)參數(shù)是相對(duì)于第一個(gè)參數(shù)而來(lái)的。系統(tǒng)在屏幕上顯示長(zhǎng)名或者短名,不同產(chǎn)
          家的實(shí)現(xiàn)不同。如果沒(méi)有指定長(zhǎng)名,就一定會(huì)使用短名。標(biāo)準(zhǔn)MIDP模擬器中,如果Command對(duì)應(yīng)到軟件按鈕(例如:Command.Back),就會(huì)使用短名,如果用到菜單顯示,就會(huì)自動(dòng)使用長(zhǎng)名。建議,盡量短名不超過(guò)四個(gè)字,長(zhǎng)名在四個(gè)字以上。
          練習(xí):在屏幕上添加Command,要求使用Command的8種命令類(lèi)型。
          4.2.2通用事件處理CommandListener
          Command必須和javax.microedition.lcdui.CommandListener事件處理接口一起使用才能反映用戶(hù)的動(dòng)作。Displayable類(lèi)中定義了setCommandListener(CommandListener)方法,所以高級(jí)API和低級(jí)API都可以使用CommandListener。
          使用步驟:
          ?? implements CommandListener
          ?? 添加菜單項(xiàng) addCommand(Command)
          ?? setCommandListener(CommandListener)
          ?? 實(shí)現(xiàn)接口CommandListener的方法:
          commandAction(Command c, Displayable s)
          其中,c是被選定的系統(tǒng)菜單項(xiàng)的引用,s是發(fā)生事件的來(lái)源,也就是包含了此Command對(duì)象的Displayable實(shí)例。
          完成上述步驟,在點(diǎn)選菜單項(xiàng)時(shí),實(shí)現(xiàn)了CommandListener接口的類(lèi)中的commandAction(Command, Displayable)方法就會(huì)被調(diào)用。這種向事件來(lái)源注冊(cè),然后等待通知的事件處理模型在Java中稱(chēng)為委托模型(Delegation Model)。
          4.2.3 處理高級(jí)別事件
          每一個(gè)高級(jí)界面的Displayable對(duì)象都有一個(gè)相應(yīng)的監(jiān)聽(tīng)器,該監(jiān)聽(tīng)器用來(lái)監(jiān)聽(tīng)控件是否已經(jīng)被觸發(fā)了相關(guān)的事件。
          步驟同4.2.2。
          練習(xí):編寫(xiě)exitCommand,并實(shí)現(xiàn)按鍵后退出程序的功能。
          4.3 Ticker類(lèi)
          是一個(gè)類(lèi)似跑馬燈的類(lèi),在所有的Displayable的子類(lèi)上都可以加入Ticker。
          API:
          Ticker(String s)
          方法:
          setString(String s) 設(shè)置顯示內(nèi)容。
          使用方法:
          displayable.setTicker(ticker);
          displayable.getTicker();
          利用定義在Displayable中的setTicker()方法設(shè)定畫(huà)面上的Ticker,或者getTicker()獲取畫(huà)面內(nèi)包含的Ticker對(duì)象。
          注意:MIDP1.0中Ticker只能用于Screen的子類(lèi)。MIDP2.0可以用在Displayable子類(lèi)了。
          4.4 基本屏幕控件
          屏幕控件就是屏幕顯示的控件,目前主要有4種:
          ?? List
          ?? TextBox
          ?? Alert
          ?? Form
          4.4.1 TextBox
          API:
          TextBox(String title, String text, int maxSize, int Constraints)
          title:標(biāo)題
          text:初始化內(nèi)容
          maxSize:可輸入的最大字符數(shù)
          Constrains:輸入限制
          ?? TextField.ANY 允許輸入任何字符或者數(shù)字
          ?? TextField.EMAILADDR 允許輸入電子郵件地址
          ?? TextField.NUMERIC:整數(shù) 只允許輸入數(shù)字,整型數(shù)
          ?? TextField.PHONENUMBER 只允許輸入電話號(hào)碼的格式
          ?? TextField.URL 允許用戶(hù)輸入U(xiǎn)RL形式的字符串
          ?? TextField.DECIMAL 允許輸入浮點(diǎn)型數(shù)
          ?? TextField.PASSWORD 所有輸入以星號(hào)表示
          ?? TextField.UNEDITABLE 不允許修改
          方法:
          setString/getString() 設(shè)置/取得TextBox中的內(nèi)容
          setMaxSize()/getMaxSize() 設(shè)置/取得最大長(zhǎng)度
          size() 返回TextBox中文字的長(zhǎng)度
          delete() 刪除TextBox實(shí)際內(nèi)容
          setChar()/getChar() 將TextBox存放的內(nèi)容以一個(gè)char數(shù)組來(lái)存取
          getCaretPosition() 取得目前輸入光標(biāo)所在位置
          insert() 在特定位置加入內(nèi)容
          setConstraints(int constraints)設(shè)定輸入限制
          例:
          TextBox tb = new TextBox(“number”, “123”, 5, TextField.NUMERIC);
          注意:
          設(shè)備一般都會(huì)自行限定TextBox所能存放的內(nèi)容的最大值。構(gòu)造方法中指定的最大值不能超過(guò)設(shè)備本身所限制的最大值。TextBox支持多行輸入。
          避免指定初始內(nèi)容長(zhǎng)度大于最大長(zhǎng)度所引發(fā)的IllegalArgumentException。
          練習(xí):使用TextBox輸入數(shù)據(jù),按鍵后清空TextBox內(nèi)容。
          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(簡(jiǎn)易式的單選)
          Choice.EXCLUSIVE
          Choice.IMPLICIT
          Choice.MULTIPLE
          比較三種不同的Choice型態(tài)
          方法:
          append(String, Image icon)若不需要圖標(biāo),將第二項(xiàng)設(shè)置為null。
          getSelectedIndex()
          多選框的List事件,類(lèi)似單選框的事件處理方法,不同的是需要通過(guò)getSelectedFlags(boolean[] arr)獲得哪幾個(gè)List的列表項(xiàng)被選擇了,選擇的結(jié)果放在一個(gè)布爾數(shù)組中。
          getString(int index)獲取指定索引的值。
          insert()在指定項(xiàng)目后插入下一個(gè)項(xiàng)目。
          set()重新設(shè)置某個(gè)項(xiàng)目的內(nèi)容。
          size()返回List中的項(xiàng)目數(shù)。
          getImage()取得項(xiàng)目圖標(biāo)
          getFont()/setFont()取得/設(shè)定系統(tǒng)顯示項(xiàng)目使用的字體。
          delete(int idx)刪除特定選項(xiàng)
          deleteAll()刪除所有選項(xiàng)
          isSelected(int idx)判斷指定項(xiàng)目是否被選擇。
          (1)單選類(lèi)型的List:
          List list = new List("List test", Choice.EXCLUSIVE);
          注意:Choice.EXCLUSIVE類(lèi)型的List并不會(huì)在用戶(hù)選擇之后立刻引發(fā)事件,通常
          通過(guò)系統(tǒng)菜單項(xiàng)來(lái)完成。
          (2)多選類(lèi)型的List
          List list = new List("List test", Choice.MULTIPLE);
          ?? 通過(guò)遍歷List項(xiàng)目的方式,判斷哪項(xiàng)被選中:
          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) + "項(xiàng): " + value);
              }
          }
          ?? 利用getSelectedFlags()方法傳回boolean數(shù)組,判斷哪項(xiàng)被選中。
          setSelectedFlags()設(shè)定List之中的選項(xiàng)。
          (3)簡(jiǎn)易式單選
          List list = new List("List test", Choice.IMPLICIT);
          與單選和多選不同,Choice.IMPLICIT類(lèi)型的List會(huì)在用戶(hù)選擇之后立刻引發(fā)事件,并將List.SELECT_COMMAND通過(guò)commandAction()方法的第一個(gè)參數(shù)傳入。判斷commandAction()的第一個(gè)參數(shù)是否為L(zhǎng)ist.SELECT_COMMAND,可以知道事件是否為L(zhǎng)ist引發(fā)。因?yàn)檫@種類(lèi)型的List同時(shí)間只有一個(gè)選項(xiàng)會(huì)被選擇,所以我們可以利用List的getSelectedIndex()來(lái)判別是哪一個(gè)選項(xiàng)被選擇。
          例子:
          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) + "項(xiàng): " + value);
              }
          }
          4.4.3 AlertType
          AlertType是一個(gè)工具類(lèi),不能實(shí)例化。但它提供了幾種定義好的AlertType用以輔助Alert類(lèi)的使用:
          AlertType.ALARM 警報(bào)
          AlertType.CONFIRMATION確認(rèn)
          AlertType.ERROR 錯(cuò)誤
          AlertType.INFO 提示信息
          AlertType.WARNING 警告
          AlertType提供的唯一的方法:
          playSound(),可以用來(lái)發(fā)出幾種類(lèi)型的聲音。
          4.4.4 Alert
          Alert是比較特殊的屏幕對(duì)象。利用Display顯示于屏幕時(shí)將Alert顯示于屏幕上,過(guò)一段時(shí)間后,自動(dòng)調(diào)回之前的畫(huà)面。
          注意:將Alert顯示之前,系統(tǒng)應(yīng)存在一個(gè)畫(huà)面,這樣才能讓Alert有地方可以跳回。因此,如果一啟動(dòng)就將Alert第一個(gè)顯示于屏幕,會(huì)出現(xiàn)錯(cuò)誤。
          Alert的特性,使得它可以用作啟動(dòng)畫(huà)面(Splash Screen)。
          API:
          Alert(String title)
          Alert(String title, String alertText, Image alertImage, AlertType alertType)
          方法:
          setType()/getType() 設(shè)置獲取Alert類(lèi)型
          setString()/getString() 設(shè)置/獲取內(nèi)含文字
          setImage()/getImage() 設(shè)置/獲取內(nèi)含圖像
          setTimeOut() 設(shè)置顯示時(shí)間
          可以利用Alert類(lèi)的setTimeOut()方法,傳入Alert.Forever作為參數(shù),此時(shí)Alert只有在用戶(hù)按下解除按鈕(Dismiss Command)時(shí),才會(huì)跳回之前畫(huà)面。
          類(lèi)型:
          AlertType提供的幾種類(lèi)型。
          Alert不允許使用Command對(duì)象
          MIDP2.0新添加了setIndicator(Gauge indicator)方法。
          4.4.5 Form與Item
          Form是容器類(lèi)型,可以配合Item類(lèi)的子類(lèi)產(chǎn)生豐富效果。
          API:
          Form(String title)
          方法:
          append(Item)
          append(String)
          set(int) 可以重新設(shè)定某個(gè)位置上的Item
          get(int index) 可以取得指定位置Item的引用
          size() 取得Form中Item的數(shù)量
          getHeight()/getWidth() 可以返回Form用來(lái)擺放Item的區(qū)域的高和寬
          delete(int pos) 刪除指定Item
          deleteAll() 刪除Form上所有Item
          Item
          DateField
          TextField
          ImageItem
          Gauge
          ChoiceGroup
          StringItem
          CustomItem(MIDP2.0)
          Spacer(MIDP2.)
          注意:每一個(gè)Item子類(lèi)同時(shí)只能屬于一個(gè)容器,否則在加入其他容器時(shí)會(huì)產(chǎn)生IllegalStateException。如果某個(gè)Item想要加入其他容器中,必須在加入前從原來(lái)的容器中刪除。
          每個(gè)Form都被邏輯劃分成多個(gè)區(qū)域,每個(gè)區(qū)域都有可能被一個(gè)以上Item占據(jù)。邏輯區(qū)域可能是自上而下劃分,也有可能自左而右劃分,取決于設(shè)備。例如,較長(zhǎng)的屏幕,就有可能自上而下畫(huà)出許多不等高的邏輯區(qū)域。
          了解一下Item的布局方式:
          ?? Item.LAYOUT_LEFT
          ?? Item.LAYOUT_CENTER
          ?? Item.LAYOUT_RIGHT
          上述三種方式互斥,其他布局參考手冊(cè)。
          Item一般依照缺省布局繪制Item.LAYOUT_DEFAULT。可以利用setLayout()/getLayout()設(shè)置/取得目前布局。
          盡管Form會(huì)被邏輯劃分成多個(gè)區(qū)域,但并不是每個(gè)邏輯區(qū)域中只有一個(gè)Item。Form默認(rèn)情況下,盡可能讓不同Item出現(xiàn)在同一個(gè)邏輯區(qū)域中。
          在下面情形下,F(xiàn)orm將會(huì)自動(dòng)將新的Item放到下一個(gè)邏輯區(qū)域中。
          Item之后換行的情形:
          1. StringItem內(nèi)容后有換行符;
          2. 具有LAYOUT_NEWLINE_AFTER設(shè)定的Item;
          3. 如果是ChoiceGroup、DateField、Gauge、TextField,而且其布局并未設(shè)定為L(zhǎng)AYOUT_2。
          Item之前換行的情形:
          1. 前一個(gè)Item之后有換行;
          2. 具有LAYOUT_NEWLINE_BEFORE設(shè)定的Item;
          3. StringItem內(nèi)容開(kāi)頭有換行符;
          4. 如果是ChoiceGroup、DateField、Gauge、TextField,而且其布局并未設(shè)定為L(zhǎng)AYOUT_2;
          5. Item布局設(shè)定為L(zhǎng)AYOUT_LEFT、LAYOUT_CENTER、LAYOUT_RIGHT。
          4.4.5.1 StringItem
          在屏幕上顯示只讀信息的Item控件,用戶(hù)不能更改控件的提示信息。可以按鈕或者超級(jí)鏈接形式呈現(xiàn)。
          API:
          StringItem(String label, String text);
          StringItem(String label, String text, int appearanceMode)
          參數(shù)appearanceMode指定控件顯示類(lèi)型:
          1. Item.PLAIN 默認(rèn)類(lèi)型
          2. Item.HYPERLINK 超級(jí)鏈接
          3. Item.BUTTON 圖像按鈕類(lèi)型
          方法:
          getAppearanceMode() 取得StringItem所用的外觀
          getFont()/setFont() 用來(lái)取得/設(shè)定字體
          getText()/setText() 用來(lái)取得/設(shè)定內(nèi)容
          getLable()/setLable 存取Label
          在Form中加入StringItem,可以使用append(Item)方法。form.append(String)等同于調(diào)用:
          form.append(new StringItem(null, String));
          如果StringItem沒(méi)有和Command關(guān)聯(lián)起來(lái),即使使用不同的外觀設(shè)定,外觀也是相同的。
          4.4.5.2 Item與Command——ItemCommandListener
          每個(gè)Item子類(lèi)中,至少有三種東西:
          1. Command數(shù)組;
          2. 名為DefaultCommand的變量,引用到Command數(shù)組中的一個(gè)Command;
          3. 一個(gè)指向ItemCommandListener的引用。
          默認(rèn)情況下,這些內(nèi)部結(jié)構(gòu)都是null。
          addCommand()/removeCommand() 添加/刪除Command
          setDefaultCommand() 設(shè)定DefaultCommand
          setItemCommandListener() 設(shè)定ItemCommandListener
          使用removeCommand()刪除的Command如果是DefaultCommand,那么系統(tǒng)會(huì)同時(shí)調(diào)用setDefaultCommand(null)。調(diào)用setDefaultCommand()時(shí),如果傳入的Command不在Command數(shù)組中,則系統(tǒng)會(huì)先調(diào)用addCommand()將其加入內(nèi)部的Command數(shù)組中。自己調(diào)用setDefaultCommand(null),只會(huì)斷開(kāi)DefaultCommand與Command數(shù)組的引用,并不會(huì)將DefaultCommand所引用的Command從數(shù)組中刪除。
          Item一旦加入到Form中,用戶(hù)選擇到該Item時(shí),那么該Item內(nèi)部的Command數(shù)組就會(huì)變成系統(tǒng)菜單項(xiàng)。任何菜單項(xiàng)被選定之后,實(shí)現(xiàn)了ItemCommandListener接口的類(lèi)中的commandAction()方法就會(huì)被調(diào)用(傳入Command與Item的引用)。
          StringItem一旦加入Command,其外觀(Button、HYPERLINK)就會(huì)產(chǎn)生和PLAIN不同的樣式。
          設(shè)定Item的DefaultCommand的好處是,可以容易的讓用戶(hù)使用。用戶(hù)只要直接在Item上按下按鈕就可以產(chǎn)生默認(rèn)執(zhí)行效果,而不必通過(guò)選單選擇后按確認(rèn)再執(zhí)行。DefaultCommand可以方便用戶(hù)的使用。
          基本使用步驟:
          1) import javax.microedition.lcdui.*;
          2) implements ItemCommandListener
          3) 重寫(xiě)commandAction(Comand c, Item i)
          4) displayable.addCommand()
          5) displayable.setItemConmandListener()
          4.4.5.3 ImageItem
          圖形顯示控件,可以把圖像作為Form的一個(gè)控件顯示于屏幕。MIDP2.0中,增加了將圖片作為按鈕或者超級(jí)鏈接的功能。
          API:
          ImageItem(String label, Image img, int layout, String altText)
          ImageItem(String label, Image img, int layout, String altText, int appearanceMode)
          參數(shù)label:控件標(biāo)題
          參數(shù)layout:控件的布局
          參數(shù)altText:如果不能夠顯示圖片或圖片不存在,則使用一個(gè)字符串替代圖片
          參數(shù)appearanceMode指定控件顯示類(lèi)型:
          1. Item.PLAIN 默認(rèn)類(lèi)型
          2. Item.HYPERLINK 超級(jí)鏈接
          3. Item.BUTTON 圖像按鈕類(lèi)型
          方法:
          setLayout()/getLayout() 設(shè)置/獲取布局
          setImage()/getImage() 設(shè)置/獲取ImageItem中的Image
          setAltText()/getAltText() 設(shè)置/獲取取代文字
          getAppearanceMode() 取得外觀設(shè)定
          Form的append(Image img)方法等同于:
          form.append(new ImageItem(null, image, Item.LAYOUT_DEFAULT, null));
          4.4.5.4 Spacer
          用來(lái)在Form上加入一些空白間隔。功能特殊,不能與用戶(hù)交互(不能使用Command)。
          API:
          Spacer(int minWidth, int minHeight)
          4.4.5.5 ChoiceGroup
          類(lèi)似List。同List一樣也實(shí)現(xiàn)了Choice接口。
          API:
          ChoiceGroup(String label, int choiceType);
          ChoiceGroup(String label, int choiceType, String[] stringElements, Image[] imageElements)
          參數(shù)choiceType指定控件的顯示類(lèi)型共3種:
          ?? ChoiceEXCLUSIVE(單選)
          ?? Choice.MULTIPLE(多選)
          ?? Choice.POPUP(彈出式菜單)——MIDP2.0提供
          注意,ChoiceGroup無(wú)法使用Choice.IMPLICIT類(lèi)型。
          ChoiceGroup與List的最大不同在于,ChoiceGroup必須在Form中才有用。
          4.4.5.6 ItemStateListener
          可以看到,Displayable的子類(lèi),可以使用addCommand()配合setCommandListener()做事件處理。Item類(lèi)本身也有addCommand()方法,可以配合setItemCommandListener()做事件處理。
          當(dāng)Form組件內(nèi)部的Item組件內(nèi)部的狀態(tài)發(fā)生改變時(shí),F(xiàn)orm組件會(huì)對(duì)所有使用setItemStateListener()向它注冊(cè)的ItemStateListener的itemStateChanged()方法發(fā)出狀態(tài)改變的消息。
          以下幾種情況會(huì)使得Form發(fā)出此消息:
          1、 ChoiceGroup的狀態(tài)改變了;
          2、 Gauge的狀態(tài)改變了
          3、 TextField的狀態(tài)改變了
          4、 DateField的狀態(tài)改變了
          5、 Item組件的notifyStateChanged()被調(diào)用。
          根據(jù)MIDP規(guī)范之中的定義,如果Form之中同時(shí)有CommandListener與ItemStateListener的話,那么itemStateChanged()會(huì)比commandAction()還要先被調(diào)用。
          注意:ItemStateListener只有在與用戶(hù)交互時(shí),組件的狀態(tài)真的被改變時(shí),其itemStateChanged()方法才會(huì)被調(diào)用。如果是程序修改組件的狀態(tài),則不會(huì)觸發(fā)該事件。除非在改變完某個(gè)組件狀態(tài)后,調(diào)用notifyStateChanged()。
          使用步驟:
          1) import javax.microedition.lcdui.*
          2) implements ItemStateListener
          3) 重寫(xiě)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("名稱(chēng)", Choice.EXCLUSIVE);
                  cg1.append(
          "水果A", img1);
                  cg1.append(
          "水果B", img2);
                  cg2 
          = new ChoiceGroup("價(jià)格", 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("名稱(chēng)")) {
                      System.out.println(
          "名稱(chēng)的狀態(tài)改變了");
                      
          int i = cg1.getSelectedIndex();
                      System.out.println(cg1.getString(i));
                  }
           else if (label.equals("價(jià)格")) {
                      System.out.println(
          "價(jià)格的狀態(tài)改變了");
                      
          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
          同前面講過(guò)的TextBox,請(qǐng)參考前面關(guān)于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("結(jié)果"""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(
          "您輸入的用戶(hù)名為:" + name.getString());
                  }

              }

          }



          4.4.5.8 Gauge
          一般讓用戶(hù)做大小的調(diào)整,或是用作進(jìn)度條使用。
          API:
          Gauge(String label, boolean interactive, int maxValue, int initialValue);
          參數(shù)interactive指定控件的類(lèi)型:
          ?? 交互類(lèi)型(interactive設(shè)為true),可以通過(guò)手機(jī)鍵盤(pán)控制進(jìn)度條進(jìn)度;
          ?? 非交互類(lèi)型(interactive設(shè)為false),只能通過(guò)程序控制進(jìn)度條。
          參數(shù)maxValue指定控件最大數(shù)值
          參數(shù)initialValue指明初始數(shù)值。
          方法:
          setMaxValue()/getMaxValue() 設(shè)定/取得允許的最大值
          setValue()/getValue() 設(shè)定/取得初始值
          isInteractive() 判斷Gauge是否可與用戶(hù)交互
          規(guī)范中還定義了一種無(wú)范圍Gauge。要求:
          Gauge屬于非交互類(lèi)型(第二個(gè)參數(shù)設(shè)置為false),第三個(gè)參數(shù)傳入Gauge.INDEFINITE就可以產(chǎn)生沒(méi)有范圍的Gauge。此時(shí),第四個(gè)參數(shù)只能有四種選擇:
          ?? Gauge.CONTINUOUS_IDLE 目前程序停止
          ?? Gauge.CONTINUOUS_RUNNING 以動(dòng)畫(huà)顯示
          ?? Gauge.INCREMENTAL_IDLE 目前程序停止,所以是一個(gè)靜態(tài)的圖
          ?? Gauge.INCREMENTAL_UPDATING 以動(dòng)畫(huà)顯示,只有每次重新調(diào)用setValue()畫(huà)面才會(huì)慢慢更新。
          示例一:
          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("進(jìn)度條一"true102);
                  g2 
          = new Gauge("進(jìn)度條二"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("進(jìn)度條一"false, Gauge.INDEFINITE, Gauge.CONTINUOUS_IDLE);
                  
          // g1 = new Gauge("進(jìn)度條一", false, Gauge.INDEFINITE,
                  
          // Gauge.CONTINUOUS_RUNNING);
                  
          // g1 = new Gauge("進(jìn)度條一", false, Gauge.INDEFINITE,
                  
          // Gauge.INCREMENTAL_IDLE);
                  
          // g1 = new Gauge("進(jìn)度條一", 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
          可以讓用戶(hù)方便地輸入日期和時(shí)間。
          API:
          DateField(String label, int mode)
          DateField(String label, int mode, TimeZone timeZone)
          參數(shù)mode指定控件類(lèi)型(3種):
          ?? DateField.DATE 輸入日期
          ?? DateField.TIME 輸入時(shí)間
          ?? DateField.DATE_TIME 輸入日期時(shí)間
          方法:
          setInputMode()/getInputMode() 設(shè)置/取得輸入模式
          setDate()/getDate() 設(shè)置/取得時(shí)間(Dateu需要和Calendar類(lèi)配合)
          示例:

          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(
          "系統(tǒng)默認(rèn)時(shí)區(qū)是:" + 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當(dāng)作顯示進(jìn)度的畫(huà)面。用Gauge做進(jìn)度顯示,但它必須滿足以下條件:
          1) 不能與用戶(hù)交互,即第二個(gè)參數(shù)為false.
          2) 不能已經(jīng)被其他Form或是Alert使用(Item的子類(lèi)同時(shí)間只能屬于一個(gè)容器)
          3) 不能利用addCommand加入任何Command
          4) 不能有ItemCommandListener
          5) 不能有Label,即構(gòu)造函數(shù)的第一個(gè)參數(shù)必須給定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(
          "系統(tǒng)正在處理中");
                  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相關(guān)的回調(diào)函數(shù)都是由同一個(gè)Thread完成,具有依序執(zhí)行的特性。 

          posted on 2008-09-01 19:48 騎豬闖天下 閱讀(3127) 評(píng)論(3)  編輯  收藏

          評(píng)論

          # re: [J2ME] MIDP高級(jí)界面開(kāi)發(fā) 2008-09-01 19:57 ∪∩BUG

          建議格式化一下代碼,方便學(xué)習(xí)交流.  回復(fù)  更多評(píng)論   

          # re: [J2ME] MIDP高級(jí)界面開(kāi)發(fā) 2008-09-02 08:46 騎豬闖天下

          @∪∩BUG
          接受建議,已格式化  回復(fù)  更多評(píng)論   

          # re: [J2ME] MIDP高級(jí)界面開(kāi)發(fā) 2009-05-23 11:25

          真的很不錯(cuò)  回復(fù)  更多評(píng)論   


          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 吉木萨尔县| 南汇区| 上饶市| 延安市| 长葛市| 汨罗市| 东辽县| 万源市| 昌平区| 东明县| 沁阳市| 双峰县| 万州区| 丰都县| 留坝县| 武功县| 绵阳市| 自贡市| 临沭县| 涡阳县| 肃宁县| 论坛| 曲麻莱县| 定边县| 招远市| 西乌珠穆沁旗| 武平县| 板桥市| 罗山县| 昭苏县| 安龙县| 广灵县| 古蔺县| 白山市| 怀集县| 志丹县| 苗栗县| 克拉玛依市| 株洲县| 湖北省| 大田县|