乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Eclipse RCP 開發(fā):從登錄對話框說開去 - 海邊沫沫 - BlogJava

       gyb98 2010-12-08

      以前我寫過一系列的關(guān)于Eclipse RCP編程的文章,內(nèi)容包含了從RCP入門到高級的OpenGL編程。而且我堅信,RCP編程會越來越流行。如果大家需要從頭了解RCP,可以看我以前的文章:
      使用Eclipse RCP進行桌面程序開發(fā)(一):快速起步
      使用Eclipse RCP進行桌面程序開發(fā)(二):菜單、工具欄和對話框
      使用Eclipse RCP進行桌面程序開發(fā)(三):視圖和透視圖
      使用Eclipse RCP進行桌面程序開發(fā)(四):在Windows中使用Active X控件
      使用Eclipse RCP進行桌面程序開發(fā)(五):2D繪圖
      使用Eclipse RCP進行桌面程序開發(fā)(六):向OpenGL進軍

      在今天的這篇文章里,我要和大家探討的是登錄對話框,不要小看這個對話框,雖然SWT和JFace里面提供了很好用的對話框基類,但是如果你不理解SWT中GUI線程和非GUI線程的概念,那么你依然難以達到你想要的效果。具體什么情況呢?這要從我最近接的一個項目說起。

      有人委托我做一個藥店管理系統(tǒng),這種系統(tǒng)屬于進銷存管理系統(tǒng)的范疇,理論上講沒有什么難度,可供選擇的開發(fā)工具有很多,最主流的當(dāng)然要數(shù)Visual C++和VB、Delphi,如果偷一點懶,選擇Office中的Access開發(fā)也很簡單,但是為了挑戰(zhàn)自己,我決定選擇Eclipse RCP來寫這個程序,Eclipse RCP開發(fā)的程序界面很漂亮,但是Eclipse RCP很復(fù)雜,稍有不慎就會陷入Bug的泥沼,嚴重延誤工期。這不,一開始就碰到了對話框的難題。

      我的本意是在打開工作臺窗口前,先打開一個用戶登錄的對話框,如果用戶登錄成功,則關(guān)閉對話框,打開工作臺窗口。使用Eclipse的向?qū)?chuàng)建了項目之后,很快我就決定在Application類中實現(xiàn)該功能。我的代碼如下,只列出Application類中的start方法:

      public  Object start(IApplicationContext context) {
              Display display 
      =  PlatformUI.createDisplay();
              
              
      // 下面是我的代碼
              LoginDialog loginDialog  =   new  LoginDialog();
              
      // 我的代碼結(jié)束
              
              
      try  {
                  
      int  returnCode  =  PlatformUI.createAndRunWorkbench(display,  new  ApplicationWorkbenchAdvisor());
                  
      if  (returnCode  ==  PlatformUI.RETURN_RESTART) {
                      
      return  IApplication.EXIT_RESTART;
                  }
                  
      return  IApplication.EXIT_OK;
              } 
      finally  {
                  display.dispose();
              }
          }

      我的本意是只彈出登錄對話框,登錄對話框關(guān)閉后才出現(xiàn)工作臺窗口,可是事實證明,即使登錄等話框不關(guān)閉,也不會影響工作臺窗口的創(chuàng)建,效果如下圖:
      001.jpg

      即使我自己加入阻塞代碼也不行,我先加入的代碼如下:

      public  Object start(IApplicationContext context) {
              Display display 
      =  PlatformUI.createDisplay();
              
              
      // 下面是我的代碼
              LoginDialog loginDialog  =   new  LoginDialog();
              
      while ( ! loginDialog.getSShell().isDisposed()){
                  
      try {
                      Thread.sleep(
      100 );
                  }
      catch (Exception e){
                      
                  }
              }
              
      // 我的代碼結(jié)束
              
              
      try  {
                  
      int  returnCode  =  PlatformUI.createAndRunWorkbench(display,  new  ApplicationWorkbenchAdvisor());
                  
      if  (returnCode  ==  PlatformUI.RETURN_RESTART) {
                      
      return  IApplication.EXIT_RESTART;
                  }
                  
      return  IApplication.EXIT_OK;
              } 
      finally  {
                  display.dispose();
              }
          }

      這個時候雖然可以阻止工作臺窗口的產(chǎn)生,但是程序會失去響應(yīng),Splash Screen也不消失,關(guān)閉程序時會出錯,如下圖:
      002.jpg

      這個問題難就難在我們既需要阻止工作臺窗口的創(chuàng)建,又要不讓程序失去響應(yīng)。下面我們就來討論其中隱藏的秘密。

      在SWT程序中,一般都會存在兩種線程,一種是GUI線程,一種是非GUI線程,GUI線程就是用來生成窗口和控件的,生成窗口和控件之后一般都有一個事件循環(huán),用來處理GUI中產(chǎn)生的事件。在我上面的例子中,我自己加入的阻塞代碼不僅阻塞了工作臺窗口的創(chuàng)建,同時也阻塞了事件循環(huán),使得窗口事件得不到處理,所以出現(xiàn)了應(yīng)用程序沒有響應(yīng)。

      那有了上面的知識,就可以解決我們的這個問題了,我們不能用暴力的方法(即Thread的sleep方法)來阻塞GUI線程,但是我們可以在GUI線程里面構(gòu)建一個事件循環(huán),只要這個事件循環(huán)不退出,那后面的工作臺窗口當(dāng)然就不會創(chuàng)建了。構(gòu)建事件循環(huán),需要用到Display類的一些方法。

      所以,正確的代碼如下:

      public  Object start(IApplicationContext context) {
              Display display 
      =  PlatformUI.createDisplay();
              
              
      // 下面是我的代碼
              LoginDialog loginDialog  =   new  LoginDialog();
              
      while ( ! loginDialog.getSShell().isDisposed()){
                  
      if  ( ! display.readAndDispatch ())
                      display.sleep ();
              }
              
      // 我的代碼結(jié)束
              
              
      try  {
                  
      int  returnCode  =  PlatformUI.createAndRunWorkbench(display,  new  ApplicationWorkbenchAdvisor());
                  
      if  (returnCode  ==  PlatformUI.RETURN_RESTART) {
                      
      return  IApplication.EXIT_RESTART;
                  }
                  
      return  IApplication.EXIT_OK;
              } 
      finally  {
                  display.dispose();
              }
          }

      這個時候,我們可以想到模式對話框,我想模式對話框的實現(xiàn)原理也是一樣的,就是在Dialog類中自己加入了一個事件循環(huán),只有當(dāng)對話框關(guān)閉的時候,對話框的事件循環(huán)才退出,這樣工作臺窗口才能繼續(xù)出處理事件。

      另外需要說明的是,在Eclispe中實現(xiàn)對話框有幾種方法,可以繼承自SWT中的Dialog類,也可以繼承自JFace里的Dialog類,當(dāng)然,也可以什么類都不繼承而自己創(chuàng)建一個簡單的Shell。在上面的例子中,我的LoginDialog類沒有繼承自org.eclipse.jface.dialogs.Dialog,就是使用的一個普通Shell,其代碼如下:

      package  opengsp;

      import  org.eclipse.swt.layout.GridLayout;
      import  org.eclipse.swt.graphics.Point;
      import  org.eclipse.swt.widgets.Shell;
      import  org.eclipse.swt.widgets.Label;
      import  org.eclipse.swt.SWT;
      import  org.eclipse.swt.widgets.Text;
      import  org.eclipse.swt.widgets.Button;
      import  org.eclipse.swt.layout.GridData;

      public   class  LoginDialog {

          
      private  Shell sShell  =   null ;  
          
      private  Label lbUserName  =   null ;
          
      private  Text txtUserName  =   null ;
          
      private  Label lbPassword  =   null ;
          
      private  Text txtPassword  =   null ;
          
      private  Button btnOK  =   null ;
          
      private  Button btnCancel  =   null ;

          
      public  LoginDialog() {
              
      //  TODO Auto-generated constructor stub
              createSShell();
              sShell.open();
          }

          
      public  Shell getSShell() {
              
      return  sShell;
          }

          
      /**
           * This method initializes sShell
           
      */
          
      private   void  createSShell() {
              sShell 
      =   new  Shell();
              
              GridData gridData 
      =   new  GridData();
              gridData.horizontalSpan 
      =   2 ;
              GridLayout gridLayout 
      =   new  GridLayout();
              gridLayout.numColumns 
      =   3 ;    
              sShell.setText(
      " 用戶登錄 " );
              sShell.setLayout(gridLayout);
              sShell.setSize(
      new  Point( 300 200 ));
              sShell.addShellListener(
      new  org.eclipse.swt.events.ShellAdapter() {
                  
      public   void  shellClosed(org.eclipse.swt.events.ShellEvent e) {
                      sShell.dispose(); 
      //  TODO Auto-generated Event stub shellClosed()
                  }
              });
              lbUserName 
      =   new  Label(sShell, SWT.NONE);
              lbUserName.setText(
      " 用戶名: " );
              txtUserName 
      =   new  Text(sShell, SWT.BORDER);
              txtUserName.setLayoutData(gridData);
              lbPassword 
      =   new  Label(sShell, SWT.NONE);
              lbPassword.setText(
      " 密碼: " );
              txtPassword 
      =   new  Text(sShell, SWT.BORDER);
              Label filler1 
      =   new  Label(getSShell(), SWT.NONE);
              btnOK 
      =   new  Button(getSShell(), SWT.NONE);
              btnOK.setText(
      " 確定 " );
              btnCancel 
      =   new  Button(getSShell(), SWT.NONE);
              btnCancel.setText(
      " 取消 " );
          }

      }

      在上面的代碼中,我們需要自己設(shè)計OK按鈕和Cancel按鈕,需要自己處理事件,需要模式對話框的時候,還需要自己構(gòu)建事件循環(huán)。

      其實,我們可以使用JFace提供的Dialog基類來簡化我們的開發(fā),使用JFace的Dialog類時,只需要重寫幾個方法就行了,重寫createDialogArea來添加控件,而且不需要我們自己設(shè)計OK按鈕和Cancel按鈕,重寫okPressed來處理事件。所以,我寫了了另外一個LoginDialog2類,其代碼如下:
      package opengsp;

      import org.eclipse.jface.dialogs.Dialog;
      import org.eclipse.jface.window.IShellProvider;
      import org.eclipse.swt.SWT;
      import org.eclipse.swt.widgets.Composite;
      import org.eclipse.swt.widgets.Control;
      import org.eclipse.swt.widgets.Label;
      import org.eclipse.swt.widgets.Shell;
      import org.eclipse.swt.widgets.Text;

      public class LoginDialog2 extends Dialog {
          
      private Label lbUserName = null;
          
      private Text txtUserName = null;
          
      private Label lbPassword = null;
          
      private Text txtPassword = null;

          
      public LoginDialog2(IShellProvider parentShell) {
              
      super(parentShell);
              
      // TODO Auto-generated constructor stub
          }

          
      public LoginDialog2(Shell parentShell) {
              
      super(parentShell);
              
      // TODO Auto-generated constructor stub
          }

          @Override
          
      protected Control createDialogArea(Composite parent) {
              
      // TODO Auto-generated method stub
              Composite composite = (Composite) super.createDialogArea(parent);
              lbUserName 
      = new Label(composite, SWT.NONE);
              lbUserName.setText(
      "用戶名:");
              txtUserName 
      = new Text(composite, SWT.BORDER);
              lbPassword 
      = new Label(composite, SWT.NONE);
              lbPassword.setText(
      "密碼:");
              txtPassword 
      = new Text(composite, SWT.BORDER);
              
      return composite;
          }

      }

      而這個時候,在Application類中的代碼如下:
      public Object start(IApplicationContext context) {
              Display display 
      = PlatformUI.createDisplay();
              
              
      //下面是我的代碼
              LoginDialog2 loginDialog = new LoginDialog2(new Shell());
              loginDialog.open();
              
      //我的代碼結(jié)束
              
              
      try {
                  
      int returnCode = PlatformUI.createAndRunWorkbench(display, new ApplicationWorkbenchAdvisor());
                  
      if (returnCode == PlatformUI.RETURN_RESTART) {
                      
      return IApplication.EXIT_RESTART;
                  }
                  
      return IApplication.EXIT_OK;
              } 
      finally {
                  display.dispose();
              }
          }

      最后說一點,關(guān)于可是化編輯環(huán)境的。VE是在是太不能讓人滿意了,根本沒有辦法對Dialog進行可視化編輯,而且用于Eclispe 3.4的VE 1.4非官方版也不能對ViewPart進行編輯。建議打擊使用SWT Designer。

      還有,我覺得不應(yīng)該把這個對話框插入到Application類中,而是應(yīng)該放到ApplicationWorkbenchWindowAdvisor類的preWindowOpen方法中。

      評論

      # re: 談一談 Eclipse RCP 中的對話框  回復(fù)  更多評論   

      2009-05-20 12:24 by 陽衡鋒
      // 下面是我的代碼
      LoginDialog loginDialog = new LoginDialog();
      while ( ! loginDialog.getSShell().isDisposed()){
      if ( ! display.readAndDispatch ())
      display.sleep ();
      }
      // 我的代碼結(jié)束
      寫一個 模態(tài)框都這么麻煩。在我看來,用java做c/s麻煩是真的。不如用別的平臺了。

      # re: 談一談 Eclipse RCP 中的對話框  回復(fù)  更多評論   

      2009-05-20 12:39 by 陽衡鋒
      不過lz寫的這個系列確實寫的很好。

      # re: 談一談 Eclipse RCP 中的對話框  回復(fù)  更多評論   

      2009-05-20 13:14 by 隔葉黃鶯
      @陽衡鋒
      這樣寫法比起 Windows SDK 寫窗口程序還是簡單些。

      # re: Eclipse RCP 開發(fā):從登錄對話框說開去  回復(fù)  更多評論   

      2010-01-25 12:09 by 初學(xué)
      修改了一下LZ的程序,JFACE的DLG返回結(jié)果沒有起到作用,不知道改成這樣對不對,還請lZ指教1、2.
      Display display = PlatformUI.createDisplay();

      UserLogin userdlg=new UserLogin(new Shell());
      try
      {
      int rescode=userdlg.open();
      if (rescode!=IDialogConstants.OK_ID) return IApplication.EXIT_OK;
      else {
      try {

      int returnCode = PlatformUI.createAndRunWorkbench(display, new ApplicationWorkbenchAdvisor());
      if (returnCode == PlatformUI.RETURN_RESTART) {
      return IApplication.EXIT_RESTART;
      }
      return IApplication.EXIT_OK;
      } finally
      {
      display.dispose();
      }
      }
      }
      finally
      {
      display.dispose();
      }

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多