weidagang2046的專欄

          物格而后知致
          隨筆 - 8, 文章 - 409, 評(píng)論 - 101, 引用 - 0
          數(shù)據(jù)加載中……

          JFace 開發(fā)向?qū)?/a>

          使用 JFace 工具箱

          級(jí)別: 中級(jí)

          Jeff Gunther
          總經(jīng)理, Intalgent Technologies
          2003 年 9 月 09 日

          無(wú)論您使用什么語(yǔ)言開發(fā) GUI 應(yīng)用程序,收集用戶輸入的交互式機(jī)制都是不可或缺的。屬于開發(fā)中的 Eclipse 項(xiàng)目的 JFace 工具箱提供了一組功能強(qiáng)大的用戶界面組件,開發(fā)人員可以輕松地在獨(dú)立應(yīng)用程序中利用這些組件。JFace 工具箱中比較有趣的組件之一是對(duì)向?qū)У闹С帧Face 向?qū)Ш蜆?biāo)準(zhǔn)窗口小部件工具箱(Standard Widget Toolkit,SWT)內(nèi)的其它用戶界面組件結(jié)合起來(lái)提供了靈活的機(jī)制,以便系統(tǒng)化地收集用戶輸入和執(zhí)行數(shù)據(jù)驗(yàn)證。

          過(guò)去,用 Java 開發(fā)高度交互式的客戶機(jī)端應(yīng)用程序,使這些應(yīng)用程序看起來(lái)就象本機(jī)應(yīng)用程序并且能象本機(jī)應(yīng)用程序那樣操作,這樣的想法就象圣杯(Holy Grail)一樣難以捉摸。隨著 Eclipse 項(xiàng)目的出現(xiàn),開發(fā)人員開始創(chuàng)建模擬原汁原味的本機(jī)應(yīng)用程序的 Java 應(yīng)用程序。雖然傳統(tǒng)意義上認(rèn)為 Eclipse 項(xiàng)目是 Java 的開放源碼集成開發(fā)環(huán)境(IDE),但是該項(xiàng)目涉及的范圍要廣得多。事實(shí)上,在 eclipse.org 網(wǎng)站首頁(yè)上,Eclipse 被描述為“…一種通用工具平臺(tái) - 是一種開放的可擴(kuò)展 IDE,它可以做任何事,而不是特別用于某個(gè)方面。”

          在 Eclipse 平臺(tái)開發(fā)期間,該項(xiàng)目產(chǎn)生了兩個(gè)用戶界面工具箱:SWT 和 JFace。SWT 提供了一個(gè)與平臺(tái)無(wú)關(guān)的 API,該 API 與操作系統(tǒng)的本機(jī)窗口環(huán)境緊密地集成在一起。該工具箱使開發(fā)人員不必面對(duì)在使用 Java 的抽象窗口工具箱(Abstract Window Toolkit,AWT)或 Java 基礎(chǔ)類(Java Foundation Classes,JFC)時(shí)在許多設(shè)計(jì)和實(shí)現(xiàn)方面所要作的權(quán)衡。JFace 工具箱是與平臺(tái)無(wú)關(guān)的 API,可與 SWT 進(jìn)行互操作。該庫(kù)提供了一組組件和助手實(shí)用程序,它們使開發(fā) SWT 用戶界面中的許多常見任務(wù)得以簡(jiǎn)化。

          盡管在開發(fā)本文中的樣本代碼時(shí)使用了 Eclipse,但文章本身演示如何在獨(dú)立應(yīng)用程序的上下文內(nèi)使用 JFace 向?qū)АS嘘P(guān) Eclipse 項(xiàng)目的更多信息或背景知識(shí),請(qǐng)參閱本文后面的 參考資料

          地址簿應(yīng)用程序
          在查看如何使用 JFace 工具箱的代碼和實(shí)現(xiàn)細(xì)節(jié)之前,讓我們查看一下這個(gè)示例應(yīng)用程序的用途和結(jié)構(gòu)。本文所包含的應(yīng)用程序是一個(gè)簡(jiǎn)單的內(nèi)存中的地址簿,它允許用戶添加個(gè)人地址簿聯(lián)系人。該應(yīng)用程序包含了一個(gè)由兩頁(yè)組成的 JFace 向?qū)В恳豁?yè)都包含了描述特定聯(lián)系人的域。用戶可以使用 圖 1中所示的表來(lái)瀏覽聯(lián)系人列表。

          圖 1. 在 Red Hat Linux 8 上運(yùn)行的地址簿應(yīng)用程序
          地址簿應(yīng)用程序

          圖 2所示,New Contact 向?qū)Ч┯脩魟?chuàng)建新的聯(lián)系人。

          圖 2. 用 Microsoft Windows XP 上的 New Contact 向?qū)?lái)說(shuō)明數(shù)據(jù)驗(yàn)證
          New Contact 向?qū)? src=

          就象 Eclipse 項(xiàng)目一樣,SWT 和 JFace 庫(kù)一開始就設(shè)計(jì)成支持各種各樣的操作系統(tǒng)和環(huán)境。為演示這些庫(kù)的跨平臺(tái)能力,已經(jīng)將所包含的示例獨(dú)立應(yīng)用程序打包,以便能在 Microsoft Windows 和 Linux 上運(yùn)行。

          環(huán)境需求
          您可以在 參考資料一節(jié)中查找并下載本文中所用的代碼。要測(cè)試地址簿應(yīng)用程序,您的環(huán)境必須滿足下列最低需求:

          • Microsoft Windows XP 或 Red Hat Linux 8 操作系統(tǒng)
          • Java 2 SDK,標(biāo)準(zhǔn)版 1.4 或更高版本
          • Apache Ant 1.5.2 或更高版本

          雖然已經(jīng)很小心地使 Ant 構(gòu)建腳本可以跨平臺(tái)使用,但是仍然只在 Microsoft Windows XP 和 Red Hat Linux 8 操作系統(tǒng)上測(cè)試和驗(yàn)證了個(gè)人地址簿應(yīng)用程序。讓我們從安裝和設(shè)置樣本代碼開始吧。

          安裝和構(gòu)建地址簿應(yīng)用程序
          要安裝和構(gòu)建地址簿應(yīng)用程序,請(qǐng)完成下列步驟:

          1. 下載源代碼軟件包。請(qǐng)參閱 參考資料中的鏈接。
          2. addressbook.zip 文件解壓縮到臨時(shí)目錄中。
          3. 在新創(chuàng)建的目錄中運(yùn)行下面這個(gè)命令: ant clean
          4. 在新創(chuàng)建的目錄中運(yùn)行下面這個(gè)命令: ant

          如果您的環(huán)境滿足需求并且配置正確,那么您應(yīng)當(dāng)會(huì)看到類似于下面這樣的內(nèi)容:

          清單 1. 構(gòu)建地址簿應(yīng)用程序
          
          Buildfile: build.xml
          
          init:
              [mkdir] Created dir: D:\Address Book\dist
          
          compile-common:
          
          compile-module:
              [echo] Compiling ...
              [mkdir] Created dir: D:\Address Book\build
              [mkdir] Created dir: D:\Address Book\build\classes
              [javac] Compiling 8 source files to D:\Address Book\build\classes
          
          package-common:
                [jar] Building jar: D:\Address Book\dist\addressbook.jar
          
          default:
          
          BUILD SUCCESSFUL
          

          使用 JFace 向?qū)?/SPAN>
          既然我們已經(jīng)介紹了 SWT 和 JFace 的基礎(chǔ)知識(shí)以及地址簿應(yīng)用程序的行為,讓我們研究一下如何使用 JFace 向?qū)АS捎诒疚牡哪康脑谟诮榻B JFace 向?qū)В虼瞬](méi)有提供有關(guān)如何創(chuàng)建獨(dú)立應(yīng)用程序的更多背景信息。有關(guān)如何在 Eclipse 工作臺(tái)之外使用 SWT/JFace 組件的更多信息和背景知識(shí),請(qǐng)參閱 Adrian Van Emmenis 的由三部分所組成的文章系列(請(qǐng)參閱 參考資料以獲取鏈接)。

          在地址簿應(yīng)用程序中, NewContactAction 類處理用戶從 File 菜單選擇 New Contact這一操作(請(qǐng)參閱 圖 3)。

          圖 3. New Contact 菜單項(xiàng)
          New Contact 向?qū)? src=

          清單 2中的代碼說(shuō)明了為用戶打開一個(gè)向?qū)璧膶?duì)象和方法。


          清單 2. NewContactAction 類
          
          1    public class NewContactAction extends Action
          2    {
          3       ApplicationWindow window;
          4
          5        publicNewContactAction(ApplicationWindow w)
          6        {
          7           window = w;
          8           this.setText("New Contact");
          9           this.setToolTipText("Create new contact");
          10        }
          11
          12        public void run()
          13        {
          14           ContactWizard wizard = new ContactWizard();
          15
          16           WizardDialog dialog = new WizardDialog(window.getShell(), wizard);
          17           dialog.open();
          18        }
          19    }
          

          讓我們逐步研究這段代碼:

          1. 無(wú)論用戶何時(shí)從菜單欄選擇 New Contact,都要執(zhí)行第 12 行中的 run 方法。
          2. 如第 14 行所示,在向用戶顯示 GUI 向?qū)е靶枰獎(jiǎng)?chuàng)建 ContactWizard 類的新實(shí)例。該類設(shè)置向?qū)У母鱾€(gè)頁(yè)面,允許用戶向各個(gè)域提供輸入。我們稍后將更加詳細(xì)地介紹 ContactWizard 類。
          3. 第 16 行用兩個(gè)變量對(duì) WizardDialog 類進(jìn)行實(shí)例化:第一個(gè)變量包含了對(duì) shell 的引用,第二個(gè)變量包含了對(duì)第 14 行中所創(chuàng)建的 ContactWizard 的引用。 WizardDialog 類負(fù)責(zé)為用戶顯示實(shí)際向?qū)б约敖M織每個(gè)頁(yè)面的表現(xiàn)形式。
          4. 圖 4所示,第 17 行打開了向?qū)?duì)話框。

          圖 4. 在 Microsoft Windows XP 上運(yùn)行的 Contact 向?qū)?/B>
          Contact 向?qū)? src=

          實(shí)現(xiàn) JFace 向?qū)?/SPAN>
          要在地址簿應(yīng)用程序中創(chuàng)建 ContactWizard 類,我們需要?jiǎng)?chuàng)建繼承向?qū)Щ緦?shí)現(xiàn)的子類并覆蓋下列方法:

          • public void addPages() - 該方法提供了一個(gè)掛鉤,以便在向最終用戶顯示向?qū)е敖o向?qū)砑悠渌?yè)面。要給向?qū)砑有碌捻?yè)面,只要如 清單 3 所示的那樣調(diào)用 addPage 方法即可。在 ContactWizard 類中定義了兩個(gè)頁(yè)面。我們將在下一節(jié)中研究如何創(chuàng)建新的頁(yè)面。
          清單 3. ContactWizard 類中的 addPages 方法
          
          public void addPages()
          {
          page1 = new BasicContactPage(selection);
              page2 = new AddressContactPage(selection);
              addPage(page1);
          addPage(page2);
          }
          
          • public boolean performFinish() - 當(dāng)用戶點(diǎn)擊 Finish 按鈕時(shí)執(zhí)行這個(gè)方法。在 ContactWizard 中,用這個(gè)方法收集向?qū)У拿總€(gè)頁(yè)面上每個(gè)域中的數(shù)據(jù)并把它們填充到一個(gè)域?qū)ο笾小U?qǐng)參閱 清單 4
          清單 4. ContactWizard 類中的 performFinish 方法
          
          public boolean performFinish()
          {
          Contact contact = new Contact();
             contact.setFamilyName(page1.getFamilyName());
             contact.setGivenName(page1.getGivenName());
             contact.setBusinessPhone(page1.getBusinessPhone());
             contact.setHomePhone(page1.getHomePhone());
             contact.setEmailAddress(page1.getEmail());
                 
             AddressBook.addContact(contact);
                 
              return true;
          }

          清單 5 顯示了具有 addPagesperformFinish 方法的完整類。

          清單 5. ContactWizard 類
          
          ...
          public class ContactWizard extends Wizard
          {
              private BasicContactPage page1;
              private AddressContactPage page2;
              private ISelection selection;
          
              public ContactWizard()
              {
                  super();
                  setNeedsProgressMonitor(true);
              }
          
              public void addPages()
              {
                  page1 = new BasicContactPage(selection);
                  page2 = new AddressContactPage(selection);
                  addPage(page1);
                  addPage(page2);
              }
          
              public boolean performFinish()
              {
                  Contact contact = new Contact();
                  contact.setFamilyName(page1.getFamilyName());
                  contact.setGivenName(page1.getGivenName());
                  contact.setBusinessPhone(page1.getBusinessPhone());
                  contact.setHomePhone(page1.getHomePhone());
                  contact.setEmailAddress(page1.getEmail());
          
                  AddressBook.addContact(contact);
          
                  return true;
              }
          }
          

          實(shí)現(xiàn) JFace WizardPage
          沒(méi)有實(shí)現(xiàn) WizardPage 的類, ContactWizard 就不會(huì)有任何行為。您可以將向?qū)Э闯墒且欢芽ㄆ恳粡埧ㄆ加凶约旱牟季趾驮O(shè)計(jì)。每個(gè) WizardPage 負(fù)責(zé)向?qū)е袉蝹€(gè)頁(yè)面(即卡片)的布局和行為。要?jiǎng)?chuàng)建 WizardPage ,我們需要?jiǎng)?chuàng)建繼承 WizardPage 基本實(shí)現(xiàn)的子類并實(shí)現(xiàn) createControl 方法,從而為向?qū)ы?yè)面創(chuàng)建特定的 GUI 控件。

          開發(fā) WizardPage 時(shí),需要完成下列各項(xiàng):

          1. 使用指定父項(xiàng)創(chuàng)建一個(gè)組合。
          2. 創(chuàng)建窗口小部件的布局。對(duì)于 BasicContactPage 類,使用 GridLayout。
          3. 在第 2 步創(chuàng)建的布局中構(gòu)造并布置窗口小部件。有關(guān) SWT 窗口小部件的更詳盡的文檔,請(qǐng)參閱 參考資料中的鏈接。 清單 6 演示了在 ContactWizard 類中構(gòu)造和布置 BasicContactPage 所需的代碼。請(qǐng)參閱 圖 1中該向?qū)ы?yè)面的抓屏。
          清單 6. BasicContactPage 類中的 createControl 方法
          
          ...
          public void createControl(Composite parent)
          {
             Compositecontainer = new Composite(parent, SWT.NULL);
             GridLayoutlayout = new GridLayout();
             container.setLayout(layout);
             layout.numColumns = 2;
             layout.verticalSpacing = 9;
                 
             Label label= new Label(container, SWT.NULL);
             label.setText("&Given Name:");
                 
             givenNameText = new Text(container, SWT.BORDER | SWT.SINGLE);
                 
             GridData gd= new GridData(GridData.FILL_HORIZONTAL);
             givenNameText.setLayoutData(gd);
             givenNameText.addModifyListener(new ModifyListener()
                  {
                     public void modifyText(ModifyEvent e)
                      {
                         dialogChanged();
                      }
                  });
                 
             label = newLabel(container, SWT.NULL);
             label.setText("&Family Name:");
                 
             familyNameText = new Text(container, SWT.BORDER | SWT.SINGLE);
             gd = newGridData(GridData.FILL_HORIZONTAL);
             familyNameText.setLayoutData(gd);
             familyNameText.addModifyListener(new ModifyListener()
                  {
                     public void modifyText(ModifyEvent e)
                      {
                         dialogChanged();
                      }
                  });
                 
             label = newLabel(container, SWT.NULL);
             label.setText("&Nickname:");
                 
             nickNameText= new Text(container, SWT.BORDER | SWT.SINGLE);
             gd = newGridData(GridData.FILL_HORIZONTAL);
             nickNameText.setLayoutData(gd);
                 
             createLine(container, layout.numColumns);
                 
             label = newLabel(container, SWT.NULL);
             label.setText("&Business Phone:");
                 
             businessPhoneText = new Text(container, SWT.BORDER | SWT.SINGLE);
             gd = newGridData(GridData.FILL_HORIZONTAL);
             businessPhoneText.setLayoutData(gd);
                 
             label = new Label(container, SWT.NULL);
             label.setText("&Home Phone:");
                 
             homePhoneText = new Text(container, SWT.BORDER | SWT.SINGLE);
             gd = newGridData(GridData.FILL_HORIZONTAL);
             homePhoneText.setLayoutData(gd);
                 
             createLine(container, layout.numColumns);
                 
             label = newLabel(container, SWT.NULL);
             label.setText("&E-Mail Address:");
                 
             emailText =new Text(container, SWT.BORDER | SWT.SINGLE);
             gd = newGridData(GridData.FILL_HORIZONTAL);
             emailText.setLayoutData(gd);
             emailText.addModifyListener(newModifyListener()
                  {
                     public void modifyText(ModifyEvent e)
                      {
                         dialogChanged();
                      }
                  });
                 
             //dialogChanged();
             setControl(container);
          }
          ...
          
          1. 為任何可能需要輸入驗(yàn)證或轉(zhuǎn)換的窗口小部件創(chuàng)建偵聽器。對(duì)于 BasicContactPage 類,創(chuàng)建了幾個(gè) ModifyListeners 對(duì)特定數(shù)據(jù)域執(zhí)行輸入驗(yàn)證。無(wú)論何時(shí)修改文本域中的文本,都要執(zhí)行 dialogChanged 方法。該方法負(fù)責(zé)處理錯(cuò)誤并將錯(cuò)誤報(bào)告給向?qū)А?清單 7演示了處理輸入驗(yàn)證和將任何錯(cuò)誤通知向?qū)璧拇a。
          清單 7. 處理輸入驗(yàn)證類的 dialogChanged 和 updateStatus 方法
          
          ...
          private void dialogChanged()
          {
              if (this.getGivenName().length() == 0)
              {
                  updateStatus("Given name must be specified.");
          
                  return;
              }
          
              if (this.getFamilyName().length() == 0)
              {
                  updateStatus("Family name must be specified.");
          
                  return;
              }
          
              if (this.getEmail().length() > 0)
              {
                  if (this.getEmail().indexOf("@") < 0)
                  {
                      updateStatus("Enter your email address as yourname@yourdomain.com");
          
                  return;
                  }
              }
          
              updateStatus(null);
          }
          
          private void updateStatus(String message)
          {
              setErrorMessage(message);
              setPageComplete(message == null);
          ...
          

          運(yùn)行地址簿應(yīng)用程序
          要測(cè)試和運(yùn)行地址簿應(yīng)用程序,請(qǐng)完成下列步驟:

          1. 在解包源代碼的目錄中運(yùn)行下面這個(gè)命令: ant run
          2. 執(zhí)行 Ant 腳本之后,應(yīng)當(dāng)會(huì)出現(xiàn)地址簿應(yīng)用程序。
          3. 從 File 菜單選擇 New Contact 以啟動(dòng) JFace Contact 向?qū)АU?qǐng)參閱 圖 5

          圖 5. Microsoft Windows XP 上 Contact 向?qū)У膬蓚€(gè)頁(yè)面
          Contact 向?qū)? src=

          結(jié)束語(yǔ)
          通過(guò)引入 SWT/JFace 用戶界面工具箱,Eclipse 項(xiàng)目最終為 Java 開發(fā)人員提供了一種創(chuàng)建高度交互式客戶機(jī)端應(yīng)用程序的方法。使用象 JFace 向?qū)н@樣的組件來(lái)研究如何用最少的代碼來(lái)創(chuàng)建收集用戶輸入的靈活機(jī)制,確實(shí)令人興奮。示例地址簿應(yīng)用程序提供了一個(gè)構(gòu)建和打包框架,您可以用該框架來(lái)創(chuàng)建自己的獨(dú)立 SWT/JFace 應(yīng)用程序。

          參考資料

          關(guān)于作者
          Jeff Gunther 是 Intalgent Technologies的總經(jīng)理和創(chuàng)始人,這家公司是新興的軟件產(chǎn)品和解決方案供應(yīng)商,其產(chǎn)品和解決方案采用 Java 2 企業(yè)版和 Lotus Notes/Domino 平臺(tái)。Jeff 從早期的“Mosaic”(最早的 Internet Web 瀏覽器)出現(xiàn)之前的時(shí)代就投身于因特網(wǎng)行業(yè)。他擁有軟件生命周期所有方面的專業(yè)經(jīng)驗(yàn),包括 Java/J2EE、DHTML、XML/XSLT、數(shù)據(jù)庫(kù)設(shè)計(jì)和手持設(shè)備方面的特殊軟件開發(fā)專業(yè)經(jīng)驗(yàn)。可以通過(guò) jeff.gunther@intalgent.com與他聯(lián)系。


          轉(zhuǎn)自:http://www-128.ibm.com/developerworks/cn/linux/opensource/os-ecjfw/

          posted on 2005-05-26 11:12 weidagang2046 閱讀(1153) 評(píng)論(0)  編輯  收藏 所屬分類: Java

          主站蜘蛛池模板: 湟中县| 宁化县| 田林县| 马公市| 奈曼旗| 景谷| 连江县| 桐柏县| 雷波县| 融水| 太原市| 平潭县| 宜兴市| 宁南县| 新源县| 林芝县| 潼关县| 嘉义县| 太谷县| 宁城县| 榆林市| 荣昌县| 依安县| 景宁| 诸城市| 达拉特旗| 平陆县| 东丽区| 茶陵县| 山西省| 保靖县| 阿克陶县| 永善县| 和龙市| 紫金县| 习水县| 高台县| 扶风县| 论坛| 涞水县| 吉木萨尔县|