騎豬闖天下

          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 騎豬闖天下 閱讀(3125) 評論(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

          真的很不錯  回復  更多評論   


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 龙门县| 怀集县| 铅山县| 汶上县| 石阡县| 镇坪县| 弋阳县| 永嘉县| 延津县| 佳木斯市| 汉源县| 安吉县| 洛南县| 济阳县| 隆尧县| 卓尼县| 临澧县| 达拉特旗| 石屏县| 晋州市| 潢川县| 册亨县| 乌鲁木齐市| 乳源| 高淳县| 德庆县| 仁化县| 涿州市| 万荣县| 邹平县| 荆州市| 海盐县| 紫金县| 南乐县| 乳山市| 方山县| 清涧县| 凤山县| 五常市| 灵台县| 韶关市|