圖標閃爍和顯示時間的通用類

 

本文轉自http://www.eclipseworld.org/bbs/read-cec-tid-3840.html

 圖標閃爍和顯示時間的通用類

        TDD有一個基本思想:拒絕代碼的複製/粘帖。也就是說一段相同的代碼,在項目中應該只存在一處。同理,從更高處來說,幾個項目中常用的類也應該只存在於一處。其實,我們平時編程就已經發現很多類和代碼是通用的,不過我們依然習慣於去老項目中翻看代碼,然後複製粘貼於新項目中來。這樣的做法是違反TDD “拒絕代碼的複製/粘帖”原則的,所以在平時我們就應該注意提煉自己的公共代碼庫,說不定幾年後我們就能形成自己的一個框架,很多框架和類庫不就是這樣形成的嗎,比如 appache 的commons系列,比如Struts、比如Spring。
今天我抽取的公共類是一個圖標閃爍類,和一個時間顯示Label。
如下圖
        圖中上部左邊的“郵件圖標”和右邊的“時間顯示”,可以抽取出來做成公共類,在各種SWT項目中使用。特別是郵件圖標的閃爍顯示,因爲SWT還不支持動態 GIF,所以只能用多線程輪換圖片的方式來實現圖標閃爍,我想這樣的類提取出來,用作還是挺大的。
一、FlashImage類
       這裏沒有讓FlashImage 繼承自Label,而是內嵌了一個Label。這是應用於組合優先於繼承的原則,並且Label是不可繼承的,雖然SWT中並沒有把它定義成Final ,但卻會在其內部做一個子類檢查,如果是繼承自Label則會報出異常。和Label一樣的還是Shell,雖然沒有final 修飾符,但也是不可繼承的。
       這裏還涉及SWT的多線程編程,在停止線程時不能用Thead#stop方法的,這個方法已經禁用了。另外,線程要在label#dispose後也關閃掉,所以在label加了一個disponse的事件監聽。
package  cn.com.chengang.myswt;

import  org.eclipse.core.runtime.Assert;
import  org.eclipse.swt.events.DisposeEvent;
import  org.eclipse.swt.events.DisposeListener;
import  org.eclipse.swt.events.MouseListener;
import  org.eclipse.swt.graphics.Image;
import  org.eclipse.swt.widgets.Composite;
import  org.eclipse.swt.widgets.Display;
import  org.eclipse.swt.widgets.Label;

import  cn.com.chengang.common.util.CommonUtil;

public   class  FlashImage  ... {
  
private  Label flashLabel;
  
private  Image stopImage;
  
private  Image[] flashImages;
  
private   long  flashSpaceTime  =   100 // 閃動間隔時間

  
private   boolean  progressStop  =   true // 處理是否停止的標誌

  
/** */ /**
  * 
@param  comp
  * 
@param  style 與Label的style相同
  * 
@param  flashImages 閃動的圖像
  * 
@param  stopImage 停止時的圖像
  
*/

  
public  FlashImage(Composite comp,  int  style, Image[] flashImages, Image stopImage)  ... {
    Assert.isTrue(flashImages 
!=   null   &&  flashImages.length  !=   0 );
    flashLabel 
=   new  Label(comp, style);
    
this .flashImages  =  flashImages;
    
this .stopImage  =  stopImage;
    flashLabel.setImage(stopImage);
    
// 監聽Dispose事件,在其銷燬時停掉線程
    flashLabel.addDisposeListener( new  DisposeListener()  ... {
        
public   void  widgetDisposed(DisposeEvent e)  ... {
          progressStop 
=   true ;
        }

    }
);
  }


  
/** */ /**
  * 開始閃動
  
*/

  
public   void  flash()  ... {
    
if  ( ! progressStop)
        
return ;

    progressStop 
=   false ;
    
new  ImageFlashThread().start();
  }


  
/** */ /**
  * 停止閃動
  
*/

  
public   void  flashStop()  ... {
    progressStop 
=   true ;
  }


  
/** */ /**
  * 設置閃動間隔的時間
  * 
@param  time 默認100(100毫秒)
  
*/

  
public   void  setFlashSpaceTime( long  time)  ... {
    
this .flashSpaceTime  =  time;
  }


  
private  Display getDisplay()  ... {
    
return  Display.getDefault();
  }


  
public   void  addMouseListener(MouseListener listener)  ... {
    flashLabel.addMouseListener(listener);
  }


  
/** */ /**
  * 閃動圖像線程
  
*/

  
private   class  ImageFlashThread  extends  Thread  ... {
    
public   void  run()  ... {
        
int  i  =   0 ;
        
while  ( ! progressStop)  ... {
          
if  (i  ==  flashImages.length) // 到頭循環
            i  =   0 ;
          setCurrentImage(flashImages[i]);
          CommonUtil.sleep(flashSpaceTime);
// 閃動間隔
          i ++ ;
        }

        setCurrentImage(stopImage);
    }


    
private   void  setCurrentImage( final  Image image)  ... {
        getDisplay().asyncExec(
new  Runnable()  ... {
          
public   void  run()  ... {
            flashLabel.setImage(image);
          }

        }
);
    }

  }


}

給出一個客戶端使用的示例:

  Image[] flashs  =   new  Image[]  ... {
                ImagesContext.getImage(ImagesContext.MAIL),   
// ImagesContext是我自己寫的一個管理Image的類
                ImagesContext.getImage(ImagesContext.MAIL_GRAY) }
;
          Image stopImage 
=  ImagesContext.getImage(ImagesContext.MAIL);

          flashImage 
=   new  FlashImage(c, SWT.NONE, flashs, stopImage);
          flashImage.setFlashSpaceTime(
800 );
          flashImage.addMouseListener(
new  MouseAdapter()  ... {
            
public   void  mouseDown(MouseEvent e)  ... {
                  
// do something......
            }

          }
);

二、TimeLabel類
        時間顯示Label則和FlashImage類似,可以說是它的一個簡化版

package  cn.com.chengang.myswt;

import  java.text.DateFormat;
import  java.text.SimpleDateFormat;
import  java.util.Date;

import  org.eclipse.swt.events.DisposeEvent;
import  org.eclipse.swt.events.DisposeListener;
import  org.eclipse.swt.layout.GridData;
import  org.eclipse.swt.widgets.Composite;
import  org.eclipse.swt.widgets.Display;
import  org.eclipse.swt.widgets.Label;

import  cn.com.chengang.common.util.CommonUtil;

/** */ /**
@author  chengang 2006-4-19
*/

public   class  TimeLabel  ... {
  
private  Label timeLabel;
  
private   long  flashSpaceTime  =   480 // 閃動間隔時間
   private   boolean  progressStop  =   false // 處理是否停止的標誌
   private  DateFormat dateFormat  =   new  SimpleDateFormat( " HH:mm:ss " );

  
public  TimeLabel(Composite comp,  int  style)  ... {
    timeLabel 
=   new  Label(comp, style);
    timeLabel.setText(
" sssssssssssssssssss " );
    
// 監聽Dispose事件,在其銷燬時停掉線程
    timeLabel.addDisposeListener( new  DisposeListener()  ... {
        
public   void  widgetDisposed(DisposeEvent e)  ... {
          progressStop
= true ;
        }

    }
);
    
new  ShowTimeThread().start();
  }


  
public   void  dispose()  ... {
    progressStop 
=   true ;
  }


  
private  Display getDisplay()  ... {
    
return  Display.getDefault();
  }


  
private   class  ShowTimeThread  extends  Thread  ... {
    
public   void  run()  ... {
        
while  ( ! progressStop)  ... {
          String str 
=  dateFormat.format( new  Date());
          setText(str);
          CommonUtil.sleep(flashSpaceTime);
// 閃動間隔
              
// CommonUtil是我自己寫的一個常用工具方法類,sleep的代碼如下
              
// public class CommonUtil {
              
//    public static void sleep(long millis) {
              
//      try {
              
//          Thread.sleep(millis);
              
//      } catch (InterruptedException e) {
              
//          e.printStackTrace();
              
//      }
              
//    }
        }

    }


    
private   void  setText( final  String time)  ... {
        getDisplay().asyncExec(
new  Runnable()  ... {
          
public   void  run()  ... {
            timeLabel.setText(time);
          }

        }
);
    }

  }


  
public   void  setLayoutData(GridData data)  ... {
    timeLabel.setLayoutData(data);
  }


  
public   void  setDateFormate(DateFormat format)  ... {
    dateFormat 
=  format;
  }


}

客戶端的使用代碼示例: 

 TimeLabel timeLabel  =   new  TimeLabel(topComp, SWT.NONE);
//            timeLabel.setDateFormate(new SimpleDateFormat("HH:mm:ss"));
          timeLabel.setLayoutData( new  GridData(GridData.END, GridData.CENTER,  true true ));
發佈了10 篇原創文章 · 獲贊 13 · 訪問量 34萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章