posts - 28, comments - 27, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理
          需要以下的對象:
          LoginDialog,用于展示狀態,
          LoginListener,用于監聽登錄狀態,并根據不同的情況改變LoginDialog的顯示
          LoginAction,用于執行登錄的業務邏輯,并且根據不同的結果來fire不同的動作。

          狀態一共有以下幾種:
          1。登錄中
          2。登錄成功
          3。登錄失敗
          ? 3.1 連接失敗
          ? 3.2 用戶名密碼錯誤
          ? 3.3 .....
          4。用戶取消登錄

          下面是代碼片段:

          Application;

          public?class?Application?implements?IPlatformRunnable?{
          ?
          ???
          ????
          /*
          ?????*?(non-Javadoc)
          ?????*?
          ?????*?@see?org.eclipse.core.runtime.IPlatformRunnable#run(java.lang.Object)
          ?????
          */
          ????
          public?Object?run(Object?args)?throws?Exception?{

          ????????
          try?{

          ????????????TestLoginDialog?dialog?=?new?TestLoginDialog(Display.getCurrent()
          ????????????????????.getActiveShell());
          ????????????LoginListener?loginListener?
          =?new?LoginListenerImpl(dialog);
          ????????????LoginAction?action?
          =?new?LoginAction("login");
          ????????????action.addLoginListener(loginListener);
          ????????????dialog.setLoginAction(action);

          ????????????
          if?(dialog.open()?!=?Window.OK)?{
          ????????????????
          return?IPlatformRunnable.EXIT_OK;
          ????????????}
          ????????????
          int?returnCode?=?PlatformUI.createAndRunWorkbench(display,
          ????????????????????
          new?ApplicationWorkbenchAdvisor());

          ????????????
          if?(returnCode?==?PlatformUI.RETURN_RESTART)?{
          ????????????????
          return?IPlatformRunnable.EXIT_RESTART;
          ????????????}
          ????????????
          return?IPlatformRunnable.EXIT_OK;
          ????????}?
          finally?{
          ????????????display.dispose();
          ????????}
          ????}
          }


          LoginListener:

          public?interface?LoginListener?extends?EventListener{
          ????
          public?void?loginError(String?message);

          ????
          public?void?loginComplete();

          ????
          public?void?loginCanceled();
          ????
          ????
          public?void?loginStarted();
          ????
          }


          LoginAction:這里要用到Job,因為登錄的邏輯處理必須要在異步線程中來做,否則UI就會停住的。

          public?class?LoginAction?extends?Job?{
          ????
          private?LoginListener?loginListener;
          ????
          private?Session?session?=?Session.getInstance();

          ????
          public?LoginAction(String?name)?{
          ????????
          super(name);
          ????}

          ????
          public?void?addLoginListener(LoginListener?listener)?{
          ????????
          this.loginListener?=?listener;
          ????}

          ????
          public?void?fireLoginComplete()?{
          ????????loginListener.loginComplete();
          ????}

          ????
          public?void?fireLoginStarted()?{
          ????????loginListener.loginStarted();
          ????}

          ????
          public?void?fireLoginError(String?message)?{
          ????????loginListener.loginError(message);
          ????}

          ????
          public?void?fireLoginCanceled()?{
          ??? ??? //write cancel login logic here
          ????????loginListener.loginCanceled();
          ????}

          ????@Override
          ????
          protected?IStatus?run(IProgressMonitor?monitor)?{
          ????????login();
          ????????
          return?Status.OK_STATUS;
          ????}

          ????
          public?boolean?login()?{
          ????????fireLoginStarted();

          ????????if?(//網絡連接失敗)?{
          ???????????
          fireLoginError(Messages.getString("Session.connectionFailed"));
          ????????}?
          else?{
          ????????????
          if?(//登錄失敗)?{
          ???????????
          fireLoginError(Messages.getString("Session.loginFailed"));
          ????????????}?
          else?{
          ????????????????session.setAuthenticated(
          true);
          ????????????????fireLoginComplete();
          ??? ??? ??? ??? //處理登錄動作
          ????????????}
          ????????}
          ????????
          return?session.isAuthenticated();
          ????}

          }


          LoginDialog:

          這里用到了StackLayout,因為在登錄的過程中,需要在顯示用戶名/密碼的位置上,顯示gif動畫,所以在createDialogArea的時候,要創建一個主Composite,然后將其layout設置為StackLayout,然后創建兩個Composite,將其parent都設置為主Composite,新創建的兩個我將其命名為loginInfoComposite和loginAnimaComposite,顧名思義,一個用來顯示登錄信息,一個用來顯示登錄動畫。

          關于如何顯示gif,我在這里就不多說了,因為SWT Snippet和Eclipse的SWT Example里面都有對應的例子,我在這里推薦大家去參考一下SWT Example,因為那里面是用Canvas來繪圖的,這也是我們所需要的。

          在使用StackLayout的時候要注意,當我們使用stackLayout.topControl = xxx的時候,還要調用stackLayout.layout()方法,否則會不起作用。

          還有就是因為在登錄的過程中,按鈕欄應該是不可見的,但是Dialog的getButtonBar方法是protected的,所以就重寫了這個方法,聲明為public,返回super.getButtonBar(),雖然源碼的注釋中寫著這個方法不應該重寫,但是我想,這樣子應該沒問題吧。

          另外,在繪制gif的下方添加一個按鈕,并且addSelectionListener,當SelectionEvent發生的時候,就去觸發loginAction的fireCancel方法就可以了。

          細節就不描述了,下面是一些個人認為比較關鍵的代碼片段:

          ????/*
          ?????*?to?create?login?button?
          ?????
          */
          ????
          public?static?int?LOGIN_ID?=?9527;


          ????protected?void?createButtonsForButtonBar(Composite?parent)?{
          ????????createButton(parent,?LOGIN_ID,?Messages
          ????????????????.getString(
          "LoginDialog.loginbutton"),?true);?]
          ????????createButton(parent,?IDialogConstants.CANCEL_ID,?Messages
          ????????????????.getString(
          "LoginDialog.cancelbutton"),?false);
          ????}


          ????@Override
          ????
          protected?void?buttonPressed(int?buttonId)?{
          ????????
          if?(buttonId?==?LOGIN_ID)?{
          ????????????loginPressed();
          ????????}
          ????????
          super.buttonPressed(buttonId);
          ????}


          ??? protected?void?loginPressed()?{
          ??? ??? //...
          ????????loginAction.schedule();
          ????}

          然后是LoginListener的實現類:

          public?class?LoginListenerImpl?implements?LoginListener?{
          ????
          private?Display?display;
          ????
          //login?dialog
          ????private?TestLoginDialog?dialog;
          ????
          //image?to?show?on?login?failed
          ????private?Image?errorMessageImage?=?AbstractUIPlugin
          ????????????.imageDescriptorFromPlugin(Application.PLUGIN_ID,
          ????????????????????IImageKeys.crodoTitleImage).createImage();
          ????
          //error?message?area?background
          ????private?Color?errorMessageBackground?=?new?Color(null,?255,?255,?0);

          ????
          public?LoginListenerImpl(TestLoginDialog?dialog)?{
          ????????
          this.dialog?=?dialog;
          ????????display?
          =?Display.getCurrent();
          ????}

          ??? //因為這里需要在非UI線程中更新UI,所以要用display.syncExec()方法。
          ????public?void?loginCanceled()?{
          ????????display.syncExec(
          new?Runnable()?{
          ????????????
          public?void?run()?{
          ????????????????dialog.getStackLayout().topControl?
          =?dialog
          ????????????????????????.getLoginInfoComposite();
          ????????????????dialog.getStackLayoutComposite().layout();
          ????????????????dialog.animate();
          ????????????????dialog.getButtonBar().setVisible(
          true);
          ????????????}
          ????????});
          ????}

          ????
          public?void?loginComplete()?{
          ????????display.syncExec(
          new?Runnable()?{
          ????????????@SuppressWarnings(
          "deprecation")
          ????????????
          public?void?run()?{
          ??? ??? ??? ??? //我知道Thread.stop()方法已經被廢棄,但是暫時沒想到什么方法來中止
          ??? ??? ??? ??? //就暫時這樣子用了,還請大家指教!
          ????????????????dialog.getAnimateThread().stop();
          ????????????????dialog.okPressed();
          ????????????}
          ????????});
          ????}

          ????
          public?void?loginError(final?String?message)?{
          ????????display.syncExec(
          new?Runnable()?{
          ????????????
          public?void?run()?{
          ????????????????dialog.getErrorMessageLabel().setText(message);
          ????????????????dialog.getErrorMessageLabel().setImage(errorMessageImage);
          ????????????????dialog.getErrorMessageLabel().setBackground(
          ????????????????????????errorMessageBackground);
          ????????????????dialog.getStackLayout().topControl?
          =?dialog
          ????????????????????????.getLoginInfoComposite();
          ????????????????dialog.getStackLayoutComposite().layout();
          ????????????????dialog.animate();
          ????????????????dialog.getButtonBar().setVisible(
          true);
          ????????????}
          ????????});
          ????}

          ????
          public?void?loginStarted()?{
          ????????display.syncExec(
          new?Runnable()?{
          ????????????
          public?void?run()?{
          ????????????????dialog.getStackLayout().topControl?
          =?dialog
          ????????????????????????.getLoginAnimaComposite();
          ????????????????dialog.getStackLayoutComposite().layout();
          ????????????????dialog.animate();
          ????????????????dialog.getButtonBar().setVisible(
          false);
          ????????????}
          ????????});
          ????}


          評論

          # re: [rcp系列]用RCP實現MSN風格的登錄窗口  回復  更多評論   

          2006-09-27 10:15 by 123bingbing
          想學編程?來www.mylinux.com吧,這里將成為你成長的新起點!

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


          網站導航:
           
          主站蜘蛛池模板: 海安县| 甘泉县| 莱阳市| 清远市| 寿阳县| 华坪县| 尼勒克县| 杭锦后旗| 钦州市| 那坡县| 茂名市| 湘阴县| 双峰县| 右玉县| 甘肃省| 石首市| 航空| 云安县| 古交市| 时尚| 金门县| 彰化市| 闽清县| 禄丰县| 武川县| 蒙城县| 曲周县| 广德县| 洞口县| 吉首市| 吴堡县| 庆阳市| 浦江县| 广饶县| 南岸区| 于都县| 登封市| 仙居县| 前郭尔| 都匀市| 平顶山市|