West Farm
吾本布衣,生于川北,躬耕于代码的田地上。
posts - 16,  comments - 15,  trackbacks - 0
package amarsoft.rcp.base.widgets;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.accessibility.*;

/**
 * 该类是对{
@link org.eclipse.swt.custom.CLabel CLabel}的改写,使之能够显示动画GIF。
 * 由于各种浏览器对于Gif图片的中每一帧的驻留时间的解析不尽相同,所以用本类实现的Gif动画展示有可能和在非IE核心的浏览器中看到的不一致。
 * 
 * 
@author ggfan@amarsoft
 * 
 
*/

public class GifCLabel extends Canvas {

    
/** 图片和文本之间的间隔 */
    
private static final int GAP = 5;

    
/** 默认空白距离,以像素为单位 */
    
private static final int DEFAULT_MARGIN = 3;

    
/** 当文本太长显示不全时,截断文本并在后面追加显示一个省略号,在某些操作系统上有一个符号专门用于此目的——\u2026 */
    
private static final String ELLIPSIS = "";

    
/** 对齐方式,默认左对齐 */
    
private int align = SWT.LEFT;

    
/** 左边空白 */
    
private int leftMargin = DEFAULT_MARGIN;

    
/** 顶部空白 */
    
private int topMargin = DEFAULT_MARGIN;

    
/** 右边空白 */
    
private int rightMargin = DEFAULT_MARGIN;
    
    
/** 底部空白 */
    
private int bottomMargin = DEFAULT_MARGIN;

    
/** 当前文本 */
    
private String text;

    
/** 当前图片 */
    
private Image image;

    
/** 提示信息,鼠标悬停时弹出 */
    
private String appToolTipText;

    
/** 是否忽略销毁方法调用 */
    
private boolean ignoreDispose;

    
/** 背景图片 */
    
private Image backgroundImage;

    
/** 渐变颜色 */
    
private Color[] gradientColors;

    
/** 渐变百分比 */
    
private int[] gradientPercents;

    
/** 是否在垂直方向渐变 */
    
private boolean gradientVertical;

    
/** 背景色 */
    
private Color background;

    
/**
     * 线程,用于切换图片帧
     
*/

    
private GifThread thread = null;

    
private static int DRAW_FLAGS = SWT.DRAW_MNEMONIC | SWT.DRAW_TAB
            
| SWT.DRAW_TRANSPARENT | SWT.DRAW_DELIMITER;

    
/**
     * 构造函数
     * 
@param parent
     * 
@param style
     
*/

    
public GifCLabel(Composite parent, int style) {
        
super(parent, checkStyle(style));
        
if ((style & (SWT.CENTER | SWT.RIGHT)) == 0)
            style 
|= SWT.LEFT;
        
if ((style & SWT.CENTER) != 0)
            align 
= SWT.CENTER;
        
if ((style & SWT.RIGHT) != 0)
            align 
= SWT.RIGHT;
        
if ((style & SWT.LEFT) != 0)
            align 
= SWT.LEFT;

        addPaintListener(
new PaintListener() {
            
public void paintControl(PaintEvent event) {
                onPaint(event);
            }

        }
);

        addTraverseListener(
new TraverseListener() {
            
public void keyTraversed(TraverseEvent event) {
                
if (event.detail == SWT.TRAVERSE_MNEMONIC) {
                    onMnemonic(event);
                }

            }

        }
);

        addListener(SWT.Dispose, 
new Listener() {
            
public void handleEvent(Event event) {
                onDispose(event);
            }

        }
);

        initAccessible();

    }


    
/**
     *检查Style参数,去掉无效参数
     
*/

    
private static int checkStyle(int style) {
        
if ((style & SWT.BORDER) != 0)
            style 
|= SWT.SHADOW_IN;
        
int mask = SWT.SHADOW_IN | SWT.SHADOW_OUT | SWT.SHADOW_NONE
                
| SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
        style 
= style & mask;
        
return style |= SWT.NO_FOCUS | SWT.DOUBLE_BUFFERED;
    }


    
public Point computeSize(int wHint, int hHint, boolean changed) {
        checkWidget();
        Point e 
= getTotalSize(image, text);
        
if (wHint == SWT.DEFAULT) {
            e.x 
+= leftMargin + rightMargin;
        }
 else {
            e.x 
= wHint;
        }

        
if (hHint == SWT.DEFAULT) {
            e.y 
+= topMargin + bottomMargin;
        }
 else {
            e.y 
= hHint;
        }

        
return e;
    }


    
private void drawBevelRect(GC gc, int x, int y, int w, int h,
            Color topleft, Color bottomright) 
{
        gc.setForeground(bottomright);
        gc.drawLine(x 
+ w, y, x + w, y + h);
        gc.drawLine(x, y 
+ h, x + w, y + h);

        gc.setForeground(topleft);
        gc.drawLine(x, y, x 
+ w - 1, y);
        gc.drawLine(x, y, x, y 
+ h - 1);
    }


    
char _findMnemonic(String string) {
        
if (string == null)
            
return '\0';
        
int index = 0;
        
int length = string.length();
        
do {
            
while (index < length && string.charAt(index) != '&')
                index
++;
            
if (++index >= length)
                
return '\0';
            
if (string.charAt(index) != '&')
                
return Character.toLowerCase(string.charAt(index));
            index
++;
        }
 while (index < length);
        
return '\0';
    }


    
public int getAlignment() {
        
return align;
    }


    
public int getBottomMargin() {
        
return bottomMargin;
    }


    
public Image getImage() {
        
return image;
    }


    
public int getLeftMargin() {
        
return leftMargin;
    }


    
public int getRightMargin() {
        
return rightMargin;
    }


    
private Point getTotalSize(Image image, String text) {
        Point size 
= new Point(00);

        
if (image != null{
            Rectangle r 
= image.getBounds();
            size.x 
+= r.width;
            size.y 
+= r.height;
        }


        GC gc 
= new GC(this);
        
if (text != null && text.length() > 0{
            Point e 
= gc.textExtent(text, DRAW_FLAGS);
            size.x 
+= e.x;
            size.y 
= Math.max(size.y, e.y);
            
if (image != null)
                size.x 
+= GAP;
        }
 else {
            size.y 
= Math.max(size.y, gc.getFontMetrics().getHeight());
        }

        gc.dispose();

        
return size;
    }


    
public int getStyle() {
        
int style = super.getStyle();
        
switch (align) {
        
case SWT.RIGHT:
            style 
|= SWT.RIGHT;
            
break;
        
case SWT.CENTER:
            style 
|= SWT.CENTER;
            
break;
        
case SWT.LEFT:
            style 
|= SWT.LEFT;
            
break;
        }

        
return style;
    }


    
public String getText() {
        
return text;
    }


    
public String getToolTipText() {
        checkWidget();
        
return appToolTipText;
    }


    
public int getTopMargin() {
        
return topMargin;
    }


    
private void initAccessible() {
        Accessible accessible 
= getAccessible();
        accessible.addAccessibleListener(
new AccessibleAdapter() {
            
public void getName(AccessibleEvent e) {
                e.result 
= getText();
            }


            
public void getHelp(AccessibleEvent e) {
                e.result 
= getToolTipText();
            }


            
public void getKeyboardShortcut(AccessibleEvent e) {
                
char mnemonic = _findMnemonic(GifCLabel.this.text);
                
if (mnemonic != '\0'{
                    e.result 
= "Alt+" + mnemonic;
                }

            }

        }
);

        accessible.addAccessibleControlListener(
new AccessibleControlAdapter() {
            
public void getChildAtPoint(AccessibleControlEvent e) {
                e.childID 
= ACC.CHILDID_SELF;
            }


            
public void getLocation(AccessibleControlEvent e) {
                Rectangle rect 
= getDisplay().map(getParent(), null,
                        getBounds());
                e.x 
= rect.x;
                e.y 
= rect.y;
                e.width 
= rect.width;
                e.height 
= rect.height;
            }


            
public void getChildCount(AccessibleControlEvent e) {
                e.detail 
= 0;
            }


            
public void getRole(AccessibleControlEvent e) {
                e.detail 
= ACC.ROLE_LABEL;
            }


            
public void getState(AccessibleControlEvent e) {
                e.detail 
= ACC.STATE_READONLY;
            }

        }
);
    }


    
void onDispose(Event event) {
        
if (ignoreDispose) {
            ignoreDispose 
= false;
            
return;
        }

        ignoreDispose 
= true;
        notifyListeners(event.type, event);
        event.type 
= SWT.NONE;

        gradientColors 
= null;
        gradientPercents 
= null;
        backgroundImage 
= null;
        text 
= null;
        image 
= null;
        appToolTipText 
= null;
    }


    
void onMnemonic(TraverseEvent event) {
        
char mnemonic = _findMnemonic(text);
        
if (mnemonic == '\0')
            
return;
        
if (Character.toLowerCase(event.character) != mnemonic)
            
return;
        Composite control 
= this.getParent();
        
while (control != null{
            Control[] children 
= control.getChildren();
            
int index = 0;
            
while (index < children.length) {
                
if (children[index] == this)
                    
break;
                index
++;
            }

            index
++;
            
if (index < children.length) {
                
if (children[index].setFocus()) {
                    event.doit 
= true;
                    event.detail 
= SWT.TRAVERSE_NONE;
                }

            }

            control 
= control.getParent();
        }

    }


    
void onPaint(PaintEvent event) {
        Rectangle rect 
= getClientArea();
        
if (rect.width == 0 || rect.height == 0)
            
return;

        
boolean shortenText = false;
        String t 
= text;
        Image img 
= image;
        
int availableWidth = Math.max(0, rect.width
                
- (leftMargin + rightMargin));
        Point extent 
= getTotalSize(img, t);
        
if (extent.x > availableWidth) {
            img 
= null;
            extent 
= getTotalSize(img, t);
            
if (extent.x > availableWidth) {
                shortenText 
= true;
            }

        }


        GC gc 
= event.gc;
        String[] lines 
= text == null ? null : splitString(text);

        
// 截断过长文本
        if (shortenText) {
            extent.x 
= 0;
            
for (int i = 0; i < lines.length; i++{
                Point e 
= gc.textExtent(lines[i], DRAW_FLAGS);
                
if (e.x > availableWidth) {
                    lines[i] 
= shortenText(gc, lines[i], availableWidth);
                    extent.x 
= Math.max(extent.x,
                            getTotalSize(
null, lines[i]).x);
                }
 else {
                    extent.x 
= Math.max(extent.x, e.x);
                }

            }

            
if (appToolTipText == null{
                
super.setToolTipText(text);
            }

        }
 else {
            
super.setToolTipText(appToolTipText);
        }


        
// 计算水平位置
        int x = rect.x + leftMargin;
        
if (align == SWT.CENTER) {
            x 
= (rect.width - extent.x) / 2;
        }

        
if (align == SWT.RIGHT) {
            x 
= rect.width - rightMargin - extent.x;
        }


        
// 绘制背景图片,如果设置了背景图片的话
        try {
            
if (backgroundImage != null{
                Rectangle imageRect 
= backgroundImage.getBounds();
                gc.setBackground(getBackground());
                gc.fillRectangle(rect);
                
int xPos = 0;
                
while (xPos < rect.width) {
                    
int yPos = 0;
                    
while (yPos < rect.height) {
                        gc.drawImage(backgroundImage, xPos, yPos);
                        yPos 
+= imageRect.height;
                    }

                    xPos 
+= imageRect.width;
                }

            }
 else if (gradientColors != null{
                
// 绘制渐变效果
                final Color oldBackground = gc.getBackground();
                
if (gradientColors.length == 1{
                    
if (gradientColors[0!= null)
                        gc.setBackground(gradientColors[
0]);
                    gc.fillRectangle(
00, rect.width, rect.height);
                }
 else {
                    
final Color oldForeground = gc.getForeground();
                    Color lastColor 
= gradientColors[0];
                    
if (lastColor == null)
                        lastColor 
= oldBackground;
                    
int pos = 0;
                    
for (int i = 0; i < gradientPercents.length; ++i) {
                        gc.setForeground(lastColor);
                        lastColor 
= gradientColors[i + 1];
                        
if (lastColor == null)
                            lastColor 
= oldBackground;
                        gc.setBackground(lastColor);
                        
if (gradientVertical) {
                            
final int gradientHeight = (gradientPercents[i]
                                    
* rect.height / 100)
                                    
- pos;
                            gc.fillGradientRectangle(
0, pos, rect.width,
                                    gradientHeight, 
true);
                            pos 
+= gradientHeight;
                        }
 else {
                            
final int gradientWidth = (gradientPercents[i] * rect.width / 100- pos;
                            gc.fillGradientRectangle(pos, 
0, gradientWidth,
                                    rect.height, 
false);
                            pos 
+= gradientWidth;
                        }

                    }

                    
if (gradientVertical && pos < rect.height) {
                        gc.setBackground(getBackground());
                        gc.fillRectangle(
0, pos, rect.width, rect.height - pos);
                    }

                    
if (!gradientVertical && pos < rect.width) {
                        gc.setBackground(getBackground());
                        gc.fillRectangle(pos, 
0, rect.width - pos, rect.height);
                    }

                    gc.setForeground(oldForeground);
                }

                gc.setBackground(oldBackground);
            }
 else {
                
if (background != null
                        
|| (getStyle() & SWT.DOUBLE_BUFFERED) == 0{
                    gc.setBackground(getBackground());
                    gc.fillRectangle(rect);
                }

            }

        }
 catch (SWTException e) {
            
if ((getStyle() & SWT.DOUBLE_BUFFERED) == 0{
                gc.setBackground(getBackground());
                gc.fillRectangle(rect);
            }

        }


        
// 绘制边框
        int style = getStyle();
        
if ((style & SWT.SHADOW_IN) != 0 || (style & SWT.SHADOW_OUT) != 0{
            paintBorder(gc, rect);
        }


        
// 如果文本高度高于图片高度,则从最高点(不包括顶部空白)开始绘制文本,否则绘制图片
        Rectangle imageRect = null;
        
int lineHeight = 0, textHeight = 0, imageHeight = 0;

        
if (img != null{
            imageRect 
= img.getBounds();
            imageHeight 
= imageRect.height;
        }

        
if (lines != null{
            lineHeight 
= gc.getFontMetrics().getHeight();
            textHeight 
= lines.length * lineHeight;
        }


        
int imageY = 0, midPoint = 0, lineY = 0;
        
if (imageHeight > textHeight) {
            
if (topMargin == DEFAULT_MARGIN && bottomMargin == DEFAULT_MARGIN)
                imageY 
= rect.y + (rect.height - imageHeight) / 2;
            
else
                imageY 
= topMargin;
            midPoint 
= imageY + imageHeight / 2;
            lineY 
= midPoint - textHeight / 2;
        }
 else {
            
if (topMargin == DEFAULT_MARGIN && bottomMargin == DEFAULT_MARGIN)
                lineY 
= rect.y + (rect.height - textHeight) / 2;
            
else
                lineY 
= topMargin;
            midPoint 
= lineY + textHeight / 2;
            imageY 
= midPoint - imageHeight / 2;
        }


        
// 绘制图片
        if (img != null{

            gc.drawImage(img, 
00, imageRect.width, imageHeight, x, imageY,
                    imageRect.width, imageHeight);
            x 
+= imageRect.width + GAP;
            extent.x 
-= imageRect.width + GAP;
        }


        
// 绘制文本
        if (lines != null{
            gc.setForeground(getForeground());
            
for (int i = 0; i < lines.length; i++{
                
int lineX = x;
                
if (lines.length > 1{
                    
if (align == SWT.CENTER) {
                        
int lineWidth = gc.textExtent(lines[i], DRAW_FLAGS).x;
                        lineX 
= x + Math.max(0, (extent.x - lineWidth) / 2);
                    }

                    
if (align == SWT.RIGHT) {
                        
int lineWidth = gc.textExtent(lines[i], DRAW_FLAGS).x;
                        lineX 
= Math.max(x, rect.x + rect.width - rightMargin
                                
- lineWidth);
                    }

                }

                gc.drawText(lines[i], lineX, lineY, DRAW_FLAGS);
                lineY 
+= lineHeight;
            }

        }

    }


    
/**
     * 绘制边框
     
*/

    
private void paintBorder(GC gc, Rectangle r) {
        Display disp 
= getDisplay();

        Color c1 
= null;
        Color c2 
= null;

        
int style = getStyle();
        
if ((style & SWT.SHADOW_IN) != 0{
            c1 
= disp.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
            c2 
= disp.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW);
        }

        
if ((style & SWT.SHADOW_OUT) != 0{
            c1 
= disp.getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW);
            c2 
= disp.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
        }


        
if (c1 != null && c2 != null{
            gc.setLineWidth(
1);
            drawBevelRect(gc, r.x, r.y, r.width 
- 1, r.height - 1, c1, c2);
        }

    }


    
/**
     * 设置对齐方式
     * 
@param align
     
*/

    
public void setAlignment(int align) {
        checkWidget();
        
if (align != SWT.LEFT && align != SWT.RIGHT && align != SWT.CENTER) {
            SWT.error(SWT.ERROR_INVALID_ARGUMENT);
        }

        
if (this.align != align) {
            
this.align = align;
            redraw();
        }

    }


    
public void setBackground(Color color) {
        
super.setBackground(color);
        
if (backgroundImage == null && gradientColors == null
                
&& gradientPercents == null{
            
if (color == null{
                
if (background == null)
                    
return;
            }
 else {
                
if (color.equals(background))
                    
return;
            }

        }

        background 
= color;
        backgroundImage 
= null;
        gradientColors 
= null;
        gradientPercents 
= null;
        redraw();
    }



    
public void setBackground(Color[] colors, int[] percents) {
        setBackground(colors, percents, 
false);
    }


    
public void setBackground(Color[] colors, int[] percents, boolean vertical) {
        checkWidget();
        
if (colors != null{
            
if (percents == null || percents.length != colors.length - 1{
                SWT.error(SWT.ERROR_INVALID_ARGUMENT);
            }

            
if (getDisplay().getDepth() < 15{
                colors 
= new Color[] { colors[colors.length - 1] };
                percents 
= new int[] {};
            }

            
for (int i = 0; i < percents.length; i++{
                
if (percents[i] < 0 || percents[i] > 100{
                    SWT.error(SWT.ERROR_INVALID_ARGUMENT);
                }

                
if (i > 0 && percents[i] < percents[i - 1]) {
                    SWT.error(SWT.ERROR_INVALID_ARGUMENT);
                }

            }

        }


        
final Color background = getBackground();
        
if (backgroundImage == null{
            
if ((gradientColors != null&& (colors != null)
                    
&& (gradientColors.length == colors.length)) {
                
boolean same = false;
                
for (int i = 0; i < gradientColors.length; i++{
                    same 
= (gradientColors[i] == colors[i])
                            
|| ((gradientColors[i] == null&& (colors[i] == background))
                            
|| ((gradientColors[i] == background) && (colors[i] == null));
                    
if (!same)
                        
break;
                }

                
if (same) {
                    
for (int i = 0; i < gradientPercents.length; i++{
                        same 
= gradientPercents[i] == percents[i];
                        
if (!same)
                            
break;
                    }

                }

                
if (same && this.gradientVertical == vertical)
                    
return;
            }

        }
 else {
            backgroundImage 
= null;
        }


        
if (colors == null{
            gradientColors 
= null;
            gradientPercents 
= null;
            gradientVertical 
= false;
        }
 else {
            gradientColors 
= new Color[colors.length];
            
for (int i = 0; i < colors.length; ++i)
                gradientColors[i] 
= (colors[i] != null? colors[i]
                        : background;
            gradientPercents 
= new int[percents.length];
            
for (int i = 0; i < percents.length; ++i)
                gradientPercents[i] 
= percents[i];
            gradientVertical 
= vertical;
        }

        redraw();
    }


    
public void setBackground(Image image) {
        checkWidget();
        
if (image == backgroundImage)
            
return;
        
if (image != null{
            gradientColors 
= null;
            gradientPercents 
= null;
        }

        backgroundImage 
= image;
        redraw();

    }


    
public void setBottomMargin(int bottomMargin) {
        checkWidget();
        
if (this.bottomMargin == bottomMargin || bottomMargin < 0)
            
return;
        
this.bottomMargin = bottomMargin;
        redraw();
    }


    
public void setFont(Font font) {
        
super.setFont(font);
        redraw();
    }


    
public void setImage(Image image) {
        checkWidget();
        
if (thread != null{
            thread.stopRunning();
            
try {
                thread.join();
            }
 catch (InterruptedException e) {
                e.printStackTrace();
            }

        }

        
if (image != this.image) {
            
this.image = image;
            redraw();
        }

    }


    
public void setGifImage(String path) {
        
try {
            
this.setGifImage(new FileInputStream(new File(path)));
        }
 catch (FileNotFoundException e) {
            
this.image = null;
            
return;
        }

    }


    
public void setGifImage(InputStream inputStream) {
        checkWidget();
        
if (thread != null{
            thread.stopRunning();
            
try {
                thread.join();
            }
 catch (InterruptedException e) {
                e.printStackTrace();
            }

        }


        ImageLoader loader 
= new ImageLoader();

        
try {
            loader.load(inputStream);
        }
 catch (Exception e) {
            
this.image = null;
            
return;
        }


        
if (loader.data[0!= null){
            
this.image = new Image(this.getDisplay(), loader.data[0]);
        }


        
if (loader.data.length > 1{
            thread 
= new GifThread(loader);
            thread.start();
        }


        redraw();
    }


    
/**
     * Dispose方法被调用时,停止动画线程
     
*/

    @Override
    
public void dispose() {
        
super.dispose();
        
if (thread != null)
            thread.stopRunning();
    }


    
/**
     * 动画线程,支持一般GIF动画,没有考虑一些特殊情况。
     * 
     * 
@author ggfan@amarsoft
     
*/

    
private class GifThread extends Thread {

        
private int imageNumber = 0;
        
private ImageLoader loader = null;
        
private boolean run = true;

        
public GifThread(ImageLoader loader) {
            
this.loader = loader;
        }


        
public void run() {
            
while (run) {
                
int delayTime = loader.data[imageNumber].delayTime;
                
// 采用IE的策略,当延迟时间小于60毫秒时,转换为100毫秒
                if(delayTime < 6){
                    delayTime 
= 10;
                }

                
try {
                    Thread.sleep(delayTime 
* 10);
                }
 catch (InterruptedException e) {
                    e.printStackTrace();
                }

                
if (!GifCLabel.this.isDisposed()) {
                    
// this new runnable will just be queued
                    GifCLabel.this.getDisplay().asyncExec(new Runnable() {
                        
public void run() {
                            
// 当这个Runnable获得执行机会的时候,外围的线程可能已经调用过stopRunning()方法了,因此要检查一下。
                            if(!run){
                                
return;
                            }

                            
if (!GifCLabel.this.isDisposed()) {
                                imageNumber 
= imageNumber == loader.data.length - 1 ? 0 : imageNumber + 1;
                                
if (!GifCLabel.this.image.isDisposed())
                                    GifCLabel.
this.image.dispose();
                                ImageData nextFrameData 
= loader.data[imageNumber];
                                GifCLabel.
this.image = new Image(GifCLabel.this.getDisplay(), nextFrameData);
                                GifCLabel.
this.redraw();
                            }
 else
                                stopRunning();
                        }

                    }
);
                }
 else
                    stopRunning();
            }

        }


        
public void stopRunning() {
            run 
= false;
        }

        
    }


    
public void setLeftMargin(int leftMargin) {
        checkWidget();
        
if (this.leftMargin == leftMargin || leftMargin < 0)
            
return;
        
this.leftMargin = leftMargin;
        redraw();
    }


    
public void setMargins(int leftMargin, int topMargin, int rightMargin,
            
int bottomMargin) {
        checkWidget();
        
this.leftMargin = Math.max(0, leftMargin);
        
this.topMargin = Math.max(0, topMargin);
        
this.rightMargin = Math.max(0, rightMargin);
        
this.bottomMargin = Math.max(0, bottomMargin);
        redraw();
    }


    
public void setRightMargin(int rightMargin) {
        checkWidget();
        
if (this.rightMargin == rightMargin || rightMargin < 0)
            
return;
        
this.rightMargin = rightMargin;
        redraw();
    }


    
public void setText(String text) {
        checkWidget();
        
if (text == null)
            text 
= ""
        
if (!text.equals(this.text)) {
            
this.text = text;
            redraw();
        }

    }


    
public void setToolTipText(String string) {
        
super.setToolTipText(string);
        appToolTipText 
= super.getToolTipText();
    }


    
public void setTopMargin(int topMargin) {
        checkWidget();
        
if (this.topMargin == topMargin || topMargin < 0)
            
return;
        
this.topMargin = topMargin;
        redraw();
    }


    
protected String shortenText(GC gc, String t, int width) {
        
if (t == null)
            
return null;
        
int w = gc.textExtent(ELLIPSIS, DRAW_FLAGS).x;
        
if (width <= w)
            
return t;
        
int l = t.length();
        
int max = l / 2;
        
int min = 0;
        
int mid = (max + min) / 2 - 1;
        
if (mid <= 0)
            
return t;
        TextLayout layout 
= new TextLayout(getDisplay());
        layout.setText(t);
        mid 
= validateOffset(layout, mid);
        
while (min < mid && mid < max) {
            String s1 
= t.substring(0, mid);
            String s2 
= t.substring(validateOffset(layout, l - mid), l);
            
int l1 = gc.textExtent(s1, DRAW_FLAGS).x;
            
int l2 = gc.textExtent(s2, DRAW_FLAGS).x;
            
if (l1 + w + l2 > width) {
                max 
= mid;
                mid 
= validateOffset(layout, (max + min) / 2);
            }
 else if (l1 + w + l2 < width) {
                min 
= mid;
                mid 
= validateOffset(layout, (max + min) / 2);
            }
 else {
                min 
= max;
            }

        }

        String result 
= mid == 0 ? t : t.substring(0, mid) + ELLIPSIS + t.substring(validateOffset(layout, l - mid), l);
        layout.dispose();
        
return result;
    }


    
int validateOffset(TextLayout layout, int offset) {
        
int nextOffset = layout.getNextOffset(offset, SWT.MOVEMENT_CLUSTER);
        
if (nextOffset != offset)
            
return layout.getPreviousOffset(nextOffset, SWT.MOVEMENT_CLUSTER);
        
return offset;
    }


    
private String[] splitString(String text) {
        String[] lines 
= new String[1];
        
int start = 0, pos;
        
do {
            pos 
= text.indexOf('\n', start);
            
if (pos == -1{
                lines[lines.length 
- 1= text.substring(start);
            }
 else {
                
boolean crlf = (pos > 0&& (text.charAt(pos - 1== '\r');
                lines[lines.length 
- 1= text.substring(start, pos - (crlf ? 1 : 0));
                start 
= pos + 1;
                String[] newLines 
= new String[lines.length + 1];
                System.arraycopy(lines, 
0, newLines, 0, lines.length);
                lines 
= newLines;
            }

        }
 while (pos != -1);
        
return lines;
    }

}

不同浏览器对于Gif动画帧延迟的处理方式:
浏览器类型 区间 转换值
Mozila <=1 10
IE <6 10
Opera <10 10
Safari <3

3

posted on 2011-10-11 16:28 West Farmer 阅读(1538) 评论(2)  编辑  收藏 所属分类: Eclipse-RCP

FeedBack:
# re: SWT: 改写CLabel使其支持Gif动画
2011-12-27 11:37 | [西部农民]
该类并未对GIF帧转换未作妥善处理,请谨慎使用。  回复  更多评论
  
# re: SWT: 改写CLabel使其支持Gif动画
2013-03-13 17:15 | pjq
太感谢了!  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 

<2013年3月>
242526272812
3456789
10111213141516
17181920212223
24252627282930
31123456

常用链接

留言簿

随笔分类

随笔档案

相册

搜索

  •  

最新评论

阅读排行榜

评论排行榜