<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    好好生活,努力工作,天天向上!

    BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
      46 Posts :: 1 Stories :: 178 Comments :: 0 Trackbacks

      是不是覺得Windows的倒計(jì)時(shí)關(guān)機(jī)對(duì)話框很酷?
                           

       其實(shí)你也可以通過SWT的對(duì)話框來實(shí)現(xiàn)這個(gè)功能,如果你真的夠無聊的話,可以用來嚇唬一下你的用戶,當(dāng)然你的確定你的人緣很好才行.

       好了,開場(chǎng)白到此為止,下面進(jìn)入正題:

        我設(shè)計(jì)這個(gè)倒計(jì)時(shí)對(duì)話框主要是為了讓我們系統(tǒng)在自動(dòng)更新完成后自動(dòng)重啟,我們的系統(tǒng)提供了自動(dòng)更新的功能,而且有個(gè)數(shù)據(jù)傳輸模塊,數(shù)據(jù)傳輸模塊是使用Wrapper這個(gè)工具封裝Java程序成服務(wù),數(shù)據(jù)傳輸模塊會(huì)共享RCP客戶端的插件Jar包,由于Eclipse插件的特殊性,自動(dòng)更新完成后可能會(huì)在安裝目錄中存在同名稱但不同版本號(hào)的插件,具體細(xì)節(jié)省去7443個(gè)字節(jié)。

       想實(shí)現(xiàn)倒計(jì)時(shí)對(duì)話框,我們可以使用Timer這個(gè)定時(shí)工具類,這主要考慮到倒計(jì)時(shí)對(duì)話框要和RCP項(xiàng)目的主線程區(qū)分開來,對(duì)話框彈出不能夠影響用戶的操作,至少得讓他們的有時(shí)間保存信息不至于丟失,我們把這個(gè)類命名為 TimerMessageDialog .java, 根據(jù)MessageDialog中提供的方法,我們無法動(dòng)態(tài)顯示提示信息,比如還剩下多少時(shí)間.你可以重載MessageDialog的 createMessageArea(Composite composite) 方法,可以再TimerMessageDialog中新增一個(gè)字段引用 messageLabel ,比如 localMessageLabel ,然后對(duì) localMessageLabel 的值進(jìn)行修改,下面是我的實(shí)現(xiàn),可以參考一下:

     
    protected Control createMessageArea(Composite composite) {
        
    // create composite
        
    // create image
        Image image = getImage();
        
    if (image != null) {
          imageLabel 
    = new Label(composite, SWT.NULL);
          image.setBackground(imageLabel.getBackground());
          imageLabel.setImage(image);
    //      addAccessibleListeners(imageLabel, image);
          GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.BEGINNING)
              .applyTo(imageLabel);
        }
        
    // create message
        if (message != null) {
          messageLabel 
    = new Label(composite, getMessageLabelStyle());
          TimerMessageDialog.localMessageLabel 
    = messageLabel;
          messageLabel.setText(message);
          GridDataFactory
              .fillDefaults()
              .align(SWT.FILL, SWT.BEGINNING)
              .grab(
    truefalse)
              .hint(
                  convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH),
                  SWT.DEFAULT).applyTo(messageLabel);
        }
        
    return composite;
      }

       然后我們添加一個(gè)打開對(duì)話框的方法:  open(final int second,final String message) ,second表示倒計(jì)時(shí)時(shí)間,message表示提示信息,在open方法中新建一個(gè) Timer 對(duì)象。對(duì)了,為了讓MessageDialog彈出后不阻塞線程的執(zhí)行,需要在調(diào)用對(duì)話框的open方法之前調(diào)用 setBlockOnOpen(false); 方法,下面是我的實(shí)現(xiàn),大家可以參考一下:

    /**
       * 打開定時(shí)關(guān)閉對(duì)話框,顧名思義,就是在指定的時(shí)間自動(dòng)關(guān)閉  。
       * 
    @author 劉堯興
       * 
    @param second
       * 
    @param message 
       
    */
      
    public void open(final int second,final String message) {
        setBlockOnOpen(
    false);
        open();
        
    //    final MessageFormat format = new MessageFormat("系統(tǒng)檢查到重要插件的更新,系統(tǒng)將會(huì)在 {0} 秒后自動(dòng)重啟,請(qǐng)注意保存文件");
        
        timer 
    = new Timer("檢查更新");
        
    final TimerTask task = new TimerTask() {
          
    int count = second;
          
    public void run() {
            Display display 
    = Display.getDefault();
            
    if (display == null) {
              
    return;
            }
            display.asyncExec(
    new Runnable() {
              
    public void run() {
                
    try {

                  
    if (count == 0) {
                    cancel();
                    buttonPressed(Window.OK);
                  } 
    else {
                    count 
    -= 1;
                    
    if (!localMessageLabel.isDisposed()&&localMessageLabel != null) {
                      localMessageLabel.setText(message
    +"系統(tǒng)將在:" + count + "秒后自動(dòng)重啟");
    //                localMessageLabel.setText(format.format(new Object[]{new Integer(count)}));
                    }
                  }
                
                }
    catch (Exception e) {
                  e.printStackTrace();
                }
              }
            });
          }
        };
        timer.schedule(task, 
    10001000);
      }

       這里的Timer是每一秒鐘執(zhí)行一次,在定時(shí)器執(zhí)行完成后應(yīng)該讓對(duì)話框自動(dòng)關(guān)閉,然后可以通知事件發(fā)起人來執(zhí)行對(duì)應(yīng)的操作,從這樣設(shè)計(jì)的角度上看,我們的需要在用戶點(diǎn)擊確認(rèn)或者取消或者關(guān)閉對(duì)話框時(shí)響應(yīng)用戶的操作,這樣我們的重載父類的 buttonPressed(int buttonId) 方法,在這個(gè)方法中執(zhí)行對(duì)應(yīng)的操作.比如這樣:

     
    protected void buttonPressed(int buttonId) {
        
    if(buttonId == Window.OK) {
          timer.cancel();
          firePropertyChange(IPropery.RESTART_OK_PRESSED, 
    falsetrue);
        } 
    else if(buttonId == Window.CANCEL) {
          close();
        }
      }

       這里我使用了java.util包中的 PropertyChangeListener 來監(jiān)聽屬性值的修改。這里的對(duì)話框應(yīng)該算是事件源,由這個(gè)發(fā)起屬性事件的修改通知,其他監(jiān)聽類根據(jù)接收到的信息作出相應(yīng)的響應(yīng)。我在TimerMessageDialog實(shí)現(xiàn)了一個(gè)內(nèi)部類: PropertyChangeSupportImpl ,這個(gè)類管理通知的對(duì)象: 
     

    /**
       * 屬性修改支持實(shí)現(xiàn)類  。 
       * 
    @author 劉堯興
       * <p>2009-8-18</p>
       
    */
      
    public class PropertyChangeSupportImpl {
        
        
    /** 屬性修改支持     */
        PropertyChangeSupport listeners 
    = new PropertyChangeSupport(this);

        
    /**
         * 添加屬性修改事件  。
         * 
    @author 劉堯興
         * 
    @param l
         
    */
        
    public void addPropertyChangeListener(PropertyChangeListener l) {
          listeners.addPropertyChangeListener(l);
        }

        
    /**
         * 通知修改事件發(fā)生  。
         * 
    @author 劉堯興
         * 
    @param prop
         * 
    @param old
         * 
    @param newValue
         
    */
        
    public void firePropertyChange(String prop, Object old, Object newValue) {
          listeners.firePropertyChange(prop, old, newValue);
        }

        
    /**
         * 通知事件修改  。
         * 
    @author 劉堯興
         * 
    @param prop
         * 
    @param child
         
    */
        
    protected void fireStructureChange(String prop, Object child) {
          listeners.firePropertyChange(prop, 
    null, child);
        }

        
    /**
         * 刪除屬性修改事件  。
         * 
    @author 劉堯興
         * 
    @param l
         
    */
        
    public void removePropertyChangeListener(PropertyChangeListener l) {
          listeners.removePropertyChangeListener(l);
        }
      }

       在完成這些之后,在監(jiān)聽類中注冊(cè)一個(gè)屬性修改的事件,比如在UpdatePlan這個(gè)類中執(zhí)行TimerMessageDialog的打開操作,那就的讓UpdatePlan這個(gè)類實(shí)現(xiàn) PropertyChangeListener 這個(gè)接口并實(shí)現(xiàn) propertyChange(final PropertyChangeEvent evt) 這個(gè)方法,這個(gè)方法可以根據(jù)傳過來的屬性名稱和屬性值執(zhí)行相應(yīng)的操作。UpdatePlan屬性注冊(cè)方式是:

    Display.getDefault().asyncExec(new Runnable() {
          @Override
          
    public void run() {
            
    try {
              TimerMessageDialog dialog 
    = new TimerMessageDialog(Display.getDefault().getActiveShell(),"系統(tǒng)信息","系統(tǒng)將要自動(dòng)重啟");
              dialog.addPropertyChangeListener(
    this);
              dialog.open(
    30,"");
            }
            
    catch (Exception e) {
              e.printStackTrace();
            }
          }
        });
      因?yàn)槲沂窃赗CP的非UI現(xiàn)在調(diào)用這個(gè)對(duì)話框,所以需要在Display的asyncExec方法啟用一個(gè)新的異步線程.這樣就不會(huì)拋出非法的線程訪問異常了。

      看下效果:
       
      
      下面是完整的類
     
        package com.cnex.oss.managerupdate.tools;
        
        
    import java.beans.PropertyChangeListener;
        
    import java.beans.PropertyChangeSupport;
        
    import java.util.Timer;
        
    import java.util.TimerTask;
        
        
    import org.eclipse.jface.dialogs.IDialogConstants;
        
    import org.eclipse.jface.layout.GridDataFactory;
        
    import org.eclipse.jface.window.Window;
        
    import org.eclipse.swt.SWT;
        
    import org.eclipse.swt.graphics.Image;
        
    import org.eclipse.swt.widgets.Composite;
        
    import org.eclipse.swt.widgets.Control;
        
    import org.eclipse.swt.widgets.Display;
        
    import org.eclipse.swt.widgets.Label;
        
    import org.eclipse.swt.widgets.Shell;
        
        
    /**
         * 定時(shí)執(zhí)行對(duì)話框 。 
         * 
    @author 劉堯興
         * <p>2009-12-7</p>
         
    */
        
    public class TimerMessageDialog extends MessageDialog2 {
        
          
    /** 標(biāo)簽文本     */
          
    protected static Label localMessageLabel;
          
          
    /** 屬性修改支持實(shí)現(xiàn)類     */
          
    private PropertyChangeSupportImpl instance = new PropertyChangeSupportImpl();
        
          
    /** 定時(shí)器     */
          
    private Timer timer;
          
          
    /**
           * 構(gòu)造函數(shù)。
           * 
    @param parentShell
           * 
    @param dialogTitle
           * 
    @param dialogMessage
           
    */
          
    public TimerMessageDialog(Shell parentShell, String dialogTitle, String dialogMessage) {
            
    super(parentShell, dialogTitle, null, dialogMessage, INFORMATION, new String[] {"立即重啟","隱藏"}, 0);
            setShellStyle(SWT.BORDER 
    | SWT.MIN);
          }
        
          
    protected Control createMessageArea(Composite composite) {
            
    // create composite
            
    // create image
            Image image = getImage();
            
    if (image != null) {
              imageLabel 
    = new Label(composite, SWT.NULL);
              image.setBackground(imageLabel.getBackground());
              imageLabel.setImage(image);
        
    //      addAccessibleListeners(imageLabel, image);
              GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.BEGINNING)
                  .applyTo(imageLabel);
            }
            
    // create message
            if (message != null) {
              messageLabel 
    = new Label(composite, getMessageLabelStyle());
              TimerMessageDialog.localMessageLabel 
    = messageLabel;
              messageLabel.setText(message);
              GridDataFactory
                  .fillDefaults()
                  .align(SWT.FILL, SWT.BEGINNING)
                  .grab(
    truefalse)
                  .hint(
                      convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH),
                      SWT.DEFAULT).applyTo(messageLabel);
            }
            
    return composite;
          }
          
          
    /**
           * 打開定時(shí)關(guān)閉對(duì)話框,顧名思義,就是在指定的時(shí)間自動(dòng)關(guān)閉  。
           * 
    @author 劉堯興
           * 
    @param second
           * 
    @param message 
           
    */
          
    public void open(final int second,final String message) {
            setBlockOnOpen(
    false);
            open();
            
        
    //    final MessageFormat format = new MessageFormat("系統(tǒng)檢查到重要插件的更新,系統(tǒng)將會(huì)在 {0} 秒后自動(dòng)重啟,請(qǐng)注意保存文件");
            
            timer 
    = new Timer("檢查更新");
            
    final TimerTask task = new TimerTask() {
              
    int count = second;
              
    public void run() {
                Display display 
    = Display.getDefault();
                
    if (display == null) {
                  
    return;
                }
                display.asyncExec(
    new Runnable() {
                  
    public void run() {
                    
    try {
        
                      
    if (count == 0) {
                        cancel();
                        buttonPressed(Window.OK);
                      } 
    else {
                        count 
    -= 1;
                        
    if (!localMessageLabel.isDisposed()&&localMessageLabel != null) {
                          localMessageLabel.setText(message
    +"系統(tǒng)將在:" + count + "秒后自動(dòng)重啟");
        
    //                localMessageLabel.setText(format.format(new Object[]{new Integer(count)}));
                        }
                      }
                    
                    }
    catch (Exception e) {
                      e.printStackTrace();
                    }
                  }
                });
              }
            };
            timer.schedule(task, 
    10001000);
          }
          
          
    protected void buttonPressed(int buttonId) {
            
    if(buttonId == Window.OK) {
              timer.cancel();
              firePropertyChange(IPropery.RESTART_OK_PRESSED, 
    falsetrue);
            } 
    else if(buttonId == Window.CANCEL) {
              close();
            }
          }
          
          
    /**
           * 添加屬性事件  。
           * 
    @author 劉堯興
           * 
    @param l
           
    */
          
    public void addPropertyChangeListener(PropertyChangeListener l) {
            instance.addPropertyChangeListener(l);
          }
          
          
    /**
           * 刪除屬性修改事件  。
           * 
    @author 劉堯興
           * 
    @param l
           
    */
          
    public void removePropertyChangeListener(PropertyChangeListener l) {
            instance.removePropertyChangeListener(l);
          }
          
          
    /**
           * 通知屬性修改事件(通知前臺(tái)代碼修改)  。
           * 
    @author 劉堯興
           * 
    @param prop
           * 
    @param old
           * 
    @param newValue
           
    */
          
    public void firePropertyChange(String prop, Object old, Object newValue) {
            instance.firePropertyChange(prop, old, newValue);
          }
          
          
    /**
           * 屬性修改支持實(shí)現(xiàn)類  。 
           * 
    @author 劉堯興
           * <p>2009-8-18</p>
           
    */
          
    public class PropertyChangeSupportImpl {
            
            
    /** 屬性修改支持     */
            PropertyChangeSupport listeners 
    = new PropertyChangeSupport(this);
        
            
    /**
             * 添加屬性修改事件  。
             * 
    @author 劉堯興
             * 
    @param l
             
    */
            
    public void addPropertyChangeListener(PropertyChangeListener l) {
              listeners.addPropertyChangeListener(l);
            }
        
            
    /**
             * 通知修改事件發(fā)生  。
             * 
    @author 劉堯興
             * 
    @param prop
             * 
    @param old
             * 
    @param newValue
             
    */
            
    public void firePropertyChange(String prop, Object old, Object newValue) {
              listeners.firePropertyChange(prop, old, newValue);
            }
        
            
    /**
             * 通知事件修改  。
             * 
    @author 劉堯興
             * 
    @param prop
             * 
    @param child
             
    */
            
    protected void fireStructureChange(String prop, Object child) {
              listeners.firePropertyChange(prop, 
    null, child);
            }
        
            
    /**
             * 刪除屬性修改事件  。
             * 
    @author 劉堯興
             * 
    @param l
             
    */
            
    public void removePropertyChangeListener(PropertyChangeListener l) {
              listeners.removePropertyChangeListener(l);
            }
          }
        
        }
    posted on 2009-12-09 08:32 VWPOLO 閱讀(2407) 評(píng)論(4)  編輯  收藏

    Feedback

    # re: SWT對(duì)話框系列:倒計(jì)時(shí)關(guān)閉對(duì)話框.doc 2009-12-09 10:24 20G高壓鍋爐管
    說的挺好  回復(fù)  更多評(píng)論
      

    # re: SWT對(duì)話框系列:倒計(jì)時(shí)關(guān)閉對(duì)話框.doc 2009-12-09 11:48 feenn
    中間在說PropertyChangeListener的時(shí)候說錯(cuò)了吧,PropertyChangeListener是java.beans中的接口,代碼中都寫正確了的  回復(fù)  更多評(píng)論
      

    # re: SWT對(duì)話框系列:倒計(jì)時(shí)關(guān)閉對(duì)話框.doc 2009-12-10 10:45 夢(mèng)芭莎內(nèi)衣
    的大方廣闊的風(fēng)格  回復(fù)  更多評(píng)論
      

    # re: SWT對(duì)話框系列:倒計(jì)時(shí)關(guān)閉對(duì)話框.doc 2009-12-11 16:20 av
    很好的小功能,收藏了!  回復(fù)  更多評(píng)論
      


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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲国产成人精品女人久久久| 成人亚洲网站www在线观看 | 亚洲性线免费观看视频成熟 | 中文字幕一区二区免费| 亚洲中文字幕视频国产| 久青草国产免费观看| 亚洲国产精品毛片av不卡在线| 无忧传媒视频免费观看入口| 四虎永久免费网站免费观看| 无码色偷偷亚洲国内自拍| 人人狠狠综合久久亚洲高清| 成人a毛片免费视频观看| 亚洲一区二区三区影院| 亚洲另类精品xxxx人妖| 91香蕉国产线观看免费全集| 亚洲高清资源在线观看| 青青久在线视频免费观看| 亚洲精品又粗又大又爽A片| 国产免费牲交视频| 91av免费在线视频| 无码专区—VA亚洲V天堂| 无码人妻精品中文字幕免费东京热| 亚洲videos| 亚洲?V无码乱码国产精品| igao激情在线视频免费| 久久亚洲AV成人无码软件| 成年女人18级毛片毛片免费| 十八禁的黄污污免费网站| 亚洲乱亚洲乱妇无码麻豆| 69av免费观看| 老司机福利在线免费观看| 国产亚洲真人做受在线观看| 免费专区丝袜脚调教视频| 国产偷国产偷亚洲清高APP| 国产亚洲成AV人片在线观黄桃| 青青视频观看免费99| 成年免费大片黄在线观看com| 亚洲精品视频久久| 亚洲AV网站在线观看| 亚洲高清视频免费| 亚欧国产一级在线免费|