图标闪烁和显示时间的通用类

来源:互联网 发布:美味香蕉网络柠檬tv 编辑:程序博客网 时间:2024/06/06 19:21
 

本文转自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 ));