package amarsoft.rcp.base.widgets;
![](/Images/OutliningIndicators/None.gif)
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
![](/Images/OutliningIndicators/None.gif)
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.accessibility.*;
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/** *//**
* 该类是对{@link org.eclipse.swt.custom.CLabel CLabel}的改写,使之能够显示动画GIF。
* 由于各种浏览器对于Gif图片的中每一帧的驻留时间的解析不尽相同,所以用本类实现的Gif动画展示有可能和在非IE核心的浏览器中看到的不一致。
*
* @author ggfan@amarsoft
*
*/
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
public class GifCLabel extends Canvas
{
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//** 图片和文本之间的间隔 */
private static final int GAP = 5;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//** 默认空白距离,以像素为单位 */
private static final int DEFAULT_MARGIN = 3;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//** 当文本太长显示不全时,截断文本并在后面追加显示一个省略号,在某些操作系统上有一个符号专门用于此目的——\u2026 */
private static final String ELLIPSIS = "
";
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//** 对齐方式,默认左对齐 */
private int align = SWT.LEFT;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//** 左边空白 */
private int leftMargin = DEFAULT_MARGIN;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//** 顶部空白 */
private int topMargin = DEFAULT_MARGIN;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//** 右边空白 */
private int rightMargin = DEFAULT_MARGIN;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//** 底部空白 */
private int bottomMargin = DEFAULT_MARGIN;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//** 当前文本 */
private String text;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//** 当前图片 */
private Image image;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//** 提示信息,鼠标悬停时弹出 */
private String appToolTipText;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//** 是否忽略销毁方法调用 */
private boolean ignoreDispose;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//** 背景图片 */
private Image backgroundImage;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//** 渐变颜色 */
private Color[] gradientColors;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//** 渐变百分比 */
private int[] gradientPercents;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//** 是否在垂直方向渐变 */
private boolean gradientVertical;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//** 背景色 */
private Color background;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
* 线程,用于切换图片帧
*/
private GifThread thread = null;
![](/Images/OutliningIndicators/InBlock.gif)
private static int DRAW_FLAGS = SWT.DRAW_MNEMONIC | SWT.DRAW_TAB
| SWT.DRAW_TRANSPARENT | SWT.DRAW_DELIMITER;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
* 构造函数
* @param parent
* @param style
*/
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
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;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
addPaintListener(new PaintListener()
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void paintControl(PaintEvent event)
{
onPaint(event);
}
});
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
addTraverseListener(new TraverseListener()
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void keyTraversed(TraverseEvent event)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (event.detail == SWT.TRAVERSE_MNEMONIC)
{
onMnemonic(event);
}
}
});
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
addListener(SWT.Dispose, new Listener()
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void handleEvent(Event event)
{
onDispose(event);
}
});
![](/Images/OutliningIndicators/InBlock.gif)
initAccessible();
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
*检查Style参数,去掉无效参数
*/
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
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;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public Point computeSize(int wHint, int hHint, boolean changed)
{
checkWidget();
Point e = getTotalSize(image, text);
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (wHint == SWT.DEFAULT)
{
e.x += leftMargin + rightMargin;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} else
{
e.x = wHint;
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (hHint == SWT.DEFAULT)
{
e.y += topMargin + bottomMargin;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} else
{
e.y = hHint;
}
return e;
}
![](/Images/OutliningIndicators/InBlock.gif)
private void drawBevelRect(GC gc, int x, int y, int w, int h,
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
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);
![](/Images/OutliningIndicators/InBlock.gif)
gc.setForeground(topleft);
gc.drawLine(x, y, x + w - 1, y);
gc.drawLine(x, y, x, y + h - 1);
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
char _findMnemonic(String string)
{
if (string == null)
return '\0';
int index = 0;
int length = string.length();
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
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';
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public int getAlignment()
{
return align;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public int getBottomMargin()
{
return bottomMargin;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public Image getImage()
{
return image;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public int getLeftMargin()
{
return leftMargin;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public int getRightMargin()
{
return rightMargin;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private Point getTotalSize(Image image, String text)
{
Point size = new Point(0, 0);
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (image != null)
{
Rectangle r = image.getBounds();
size.x += r.width;
size.y += r.height;
}
![](/Images/OutliningIndicators/InBlock.gif)
GC gc = new GC(this);
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
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;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} else
{
size.y = Math.max(size.y, gc.getFontMetrics().getHeight());
}
gc.dispose();
![](/Images/OutliningIndicators/InBlock.gif)
return size;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public int getStyle()
{
int style = super.getStyle();
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
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;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public String getText()
{
return text;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public String getToolTipText()
{
checkWidget();
return appToolTipText;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public int getTopMargin()
{
return topMargin;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private void initAccessible()
{
Accessible accessible = getAccessible();
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
accessible.addAccessibleListener(new AccessibleAdapter()
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void getName(AccessibleEvent e)
{
e.result = getText();
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void getHelp(AccessibleEvent e)
{
e.result = getToolTipText();
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void getKeyboardShortcut(AccessibleEvent e)
{
char mnemonic = _findMnemonic(GifCLabel.this.text);
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (mnemonic != '\0')
{
e.result = "Alt+" + mnemonic;
}
}
});
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
accessible.addAccessibleControlListener(new AccessibleControlAdapter()
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void getChildAtPoint(AccessibleControlEvent e)
{
e.childID = ACC.CHILDID_SELF;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
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;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void getChildCount(AccessibleControlEvent e)
{
e.detail = 0;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void getRole(AccessibleControlEvent e)
{
e.detail = ACC.ROLE_LABEL;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void getState(AccessibleControlEvent e)
{
e.detail = ACC.STATE_READONLY;
}
});
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
void onDispose(Event event)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (ignoreDispose)
{
ignoreDispose = false;
return;
}
ignoreDispose = true;
notifyListeners(event.type, event);
event.type = SWT.NONE;
![](/Images/OutliningIndicators/InBlock.gif)
gradientColors = null;
gradientPercents = null;
backgroundImage = null;
text = null;
image = null;
appToolTipText = null;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
void onMnemonic(TraverseEvent event)
{
char mnemonic = _findMnemonic(text);
if (mnemonic == '\0')
return;
if (Character.toLowerCase(event.character) != mnemonic)
return;
Composite control = this.getParent();
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while (control != null)
{
Control[] children = control.getChildren();
int index = 0;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while (index < children.length)
{
if (children[index] == this)
break;
index++;
}
index++;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (index < children.length)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (children[index].setFocus())
{
event.doit = true;
event.detail = SWT.TRAVERSE_NONE;
}
}
control = control.getParent();
}
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
void onPaint(PaintEvent event)
{
Rectangle rect = getClientArea();
if (rect.width == 0 || rect.height == 0)
return;
![](/Images/OutliningIndicators/InBlock.gif)
boolean shortenText = false;
String t = text;
Image img = image;
int availableWidth = Math.max(0, rect.width
- (leftMargin + rightMargin));
Point extent = getTotalSize(img, t);
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (extent.x > availableWidth)
{
img = null;
extent = getTotalSize(img, t);
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (extent.x > availableWidth)
{
shortenText = true;
}
}
![](/Images/OutliningIndicators/InBlock.gif)
GC gc = event.gc;
String[] lines = text == null ? null : splitString(text);
![](/Images/OutliningIndicators/InBlock.gif)
// 截断过长文本
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (shortenText)
{
extent.x = 0;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
for (int i = 0; i < lines.length; i++)
{
Point e = gc.textExtent(lines[i], DRAW_FLAGS);
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (e.x > availableWidth)
{
lines[i] = shortenText(gc, lines[i], availableWidth);
extent.x = Math.max(extent.x,
getTotalSize(null, lines[i]).x);
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} else
{
extent.x = Math.max(extent.x, e.x);
}
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (appToolTipText == null)
{
super.setToolTipText(text);
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} else
{
super.setToolTipText(appToolTipText);
}
![](/Images/OutliningIndicators/InBlock.gif)
// 计算水平位置
int x = rect.x + leftMargin;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (align == SWT.CENTER)
{
x = (rect.width - extent.x) / 2;
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (align == SWT.RIGHT)
{
x = rect.width - rightMargin - extent.x;
}
![](/Images/OutliningIndicators/InBlock.gif)
// 绘制背景图片,如果设置了背景图片的话
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
try
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (backgroundImage != null)
{
Rectangle imageRect = backgroundImage.getBounds();
gc.setBackground(getBackground());
gc.fillRectangle(rect);
int xPos = 0;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while (xPos < rect.width)
{
int yPos = 0;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while (yPos < rect.height)
{
gc.drawImage(backgroundImage, xPos, yPos);
yPos += imageRect.height;
}
xPos += imageRect.width;
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} else if (gradientColors != null)
{
// 绘制渐变效果
final Color oldBackground = gc.getBackground();
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (gradientColors.length == 1)
{
if (gradientColors[0] != null)
gc.setBackground(gradientColors[0]);
gc.fillRectangle(0, 0, rect.width, rect.height);
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} else
{
final Color oldForeground = gc.getForeground();
Color lastColor = gradientColors[0];
if (lastColor == null)
lastColor = oldBackground;
int pos = 0;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
for (int i = 0; i < gradientPercents.length; ++i)
{
gc.setForeground(lastColor);
lastColor = gradientColors[i + 1];
if (lastColor == null)
lastColor = oldBackground;
gc.setBackground(lastColor);
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (gradientVertical)
{
final int gradientHeight = (gradientPercents[i]
* rect.height / 100)
- pos;
gc.fillGradientRectangle(0, pos, rect.width,
gradientHeight, true);
pos += gradientHeight;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} else
{
final int gradientWidth = (gradientPercents[i] * rect.width / 100) - pos;
gc.fillGradientRectangle(pos, 0, gradientWidth,
rect.height, false);
pos += gradientWidth;
}
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (gradientVertical && pos < rect.height)
{
gc.setBackground(getBackground());
gc.fillRectangle(0, pos, rect.width, rect.height - pos);
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (!gradientVertical && pos < rect.width)
{
gc.setBackground(getBackground());
gc.fillRectangle(pos, 0, rect.width - pos, rect.height);
}
gc.setForeground(oldForeground);
}
gc.setBackground(oldBackground);
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} else
{
if (background != null
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
|| (getStyle() & SWT.DOUBLE_BUFFERED) == 0)
{
gc.setBackground(getBackground());
gc.fillRectangle(rect);
}
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} catch (SWTException e)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if ((getStyle() & SWT.DOUBLE_BUFFERED) == 0)
{
gc.setBackground(getBackground());
gc.fillRectangle(rect);
}
}
![](/Images/OutliningIndicators/InBlock.gif)
// 绘制边框
int style = getStyle();
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if ((style & SWT.SHADOW_IN) != 0 || (style & SWT.SHADOW_OUT) != 0)
{
paintBorder(gc, rect);
}
![](/Images/OutliningIndicators/InBlock.gif)
// 如果文本高度高于图片高度,则从最高点(不包括顶部空白)开始绘制文本,否则绘制图片
Rectangle imageRect = null;
int lineHeight = 0, textHeight = 0, imageHeight = 0;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (img != null)
{
imageRect = img.getBounds();
imageHeight = imageRect.height;
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (lines != null)
{
lineHeight = gc.getFontMetrics().getHeight();
textHeight = lines.length * lineHeight;
}
![](/Images/OutliningIndicators/InBlock.gif)
int imageY = 0, midPoint = 0, lineY = 0;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
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;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} 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;
}
![](/Images/OutliningIndicators/InBlock.gif)
// 绘制图片
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (img != null)
{
![](/Images/OutliningIndicators/InBlock.gif)
gc.drawImage(img, 0, 0, imageRect.width, imageHeight, x, imageY,
imageRect.width, imageHeight);
x += imageRect.width + GAP;
extent.x -= imageRect.width + GAP;
}
![](/Images/OutliningIndicators/InBlock.gif)
// 绘制文本
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (lines != null)
{
gc.setForeground(getForeground());
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
for (int i = 0; i < lines.length; i++)
{
int lineX = x;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (lines.length > 1)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (align == SWT.CENTER)
{
int lineWidth = gc.textExtent(lines[i], DRAW_FLAGS).x;
lineX = x + Math.max(0, (extent.x - lineWidth) / 2);
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
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;
}
}
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
* 绘制边框
*/
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private void paintBorder(GC gc, Rectangle r)
{
Display disp = getDisplay();
![](/Images/OutliningIndicators/InBlock.gif)
Color c1 = null;
Color c2 = null;
![](/Images/OutliningIndicators/InBlock.gif)
int style = getStyle();
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if ((style & SWT.SHADOW_IN) != 0)
{
c1 = disp.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
c2 = disp.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW);
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if ((style & SWT.SHADOW_OUT) != 0)
{
c1 = disp.getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW);
c2 = disp.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (c1 != null && c2 != null)
{
gc.setLineWidth(1);
drawBevelRect(gc, r.x, r.y, r.width - 1, r.height - 1, c1, c2);
}
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
* 设置对齐方式
* @param align
*/
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void setAlignment(int align)
{
checkWidget();
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (align != SWT.LEFT && align != SWT.RIGHT && align != SWT.CENTER)
{
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (this.align != align)
{
this.align = align;
redraw();
}
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void setBackground(Color color)
{
super.setBackground(color);
if (backgroundImage == null && gradientColors == null
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
&& gradientPercents == null)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (color == null)
{
if (background == null)
return;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} else
{
if (color.equals(background))
return;
}
}
background = color;
backgroundImage = null;
gradientColors = null;
gradientPercents = null;
redraw();
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void setBackground(Color[] colors, int[] percents)
{
setBackground(colors, percents, false);
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void setBackground(Color[] colors, int[] percents, boolean vertical)
{
checkWidget();
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (colors != null)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (percents == null || percents.length != colors.length - 1)
{
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (getDisplay().getDepth() < 15)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
colors = new Color[]
{ colors[colors.length - 1] };
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
percents = new int[]
{};
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
for (int i = 0; i < percents.length; i++)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (percents[i] < 0 || percents[i] > 100)
{
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (i > 0 && percents[i] < percents[i - 1])
{
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
}
}
![](/Images/OutliningIndicators/InBlock.gif)
final Color background = getBackground();
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (backgroundImage == null)
{
if ((gradientColors != null) && (colors != null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
&& (gradientColors.length == colors.length))
{
boolean same = false;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
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;
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (same)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
for (int i = 0; i < gradientPercents.length; i++)
{
same = gradientPercents[i] == percents[i];
if (!same)
break;
}
}
if (same && this.gradientVertical == vertical)
return;
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} else
{
backgroundImage = null;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (colors == null)
{
gradientColors = null;
gradientPercents = null;
gradientVertical = false;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} 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();
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void setBackground(Image image)
{
checkWidget();
if (image == backgroundImage)
return;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (image != null)
{
gradientColors = null;
gradientPercents = null;
}
backgroundImage = image;
redraw();
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void setBottomMargin(int bottomMargin)
{
checkWidget();
if (this.bottomMargin == bottomMargin || bottomMargin < 0)
return;
this.bottomMargin = bottomMargin;
redraw();
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void setFont(Font font)
{
super.setFont(font);
redraw();
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void setImage(Image image)
{
checkWidget();
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (thread != null)
{
thread.stopRunning();
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
try
{
thread.join();
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (image != this.image)
{
this.image = image;
redraw();
}
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void setGifImage(String path)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
try
{
this.setGifImage(new FileInputStream(new File(path)));
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} catch (FileNotFoundException e)
{
this.image = null;
return;
}
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void setGifImage(InputStream inputStream)
{
checkWidget();
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (thread != null)
{
thread.stopRunning();
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
try
{
thread.join();
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
![](/Images/OutliningIndicators/InBlock.gif)
ImageLoader loader = new ImageLoader();
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
try
{
loader.load(inputStream);
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} catch (Exception e)
{
this.image = null;
return;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (loader.data[0] != null)
{
this.image = new Image(this.getDisplay(), loader.data[0]);
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (loader.data.length > 1)
{
thread = new GifThread(loader);
thread.start();
}
![](/Images/OutliningIndicators/InBlock.gif)
redraw();
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
* Dispose方法被调用时,停止动画线程
*/
@Override
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void dispose()
{
super.dispose();
if (thread != null)
thread.stopRunning();
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
* 动画线程,支持一般GIF动画,没有考虑一些特殊情况。
*
* @author ggfan@amarsoft
*/
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private class GifThread extends Thread
{
![](/Images/OutliningIndicators/InBlock.gif)
private int imageNumber = 0;
private ImageLoader loader = null;
private boolean run = true;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public GifThread(ImageLoader loader)
{
this.loader = loader;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void run()
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while (run)
{
int delayTime = loader.data[imageNumber].delayTime;
// 采用IE的策略,当延迟时间小于60毫秒时,转换为100毫秒
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if(delayTime < 6)
{
delayTime = 10;
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
try
{
Thread.sleep(delayTime * 10);
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} catch (InterruptedException e)
{
e.printStackTrace();
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (!GifCLabel.this.isDisposed())
{
// this new runnable will just be queued
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
GifCLabel.this.getDisplay().asyncExec(new Runnable()
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void run()
{
// 当这个Runnable获得执行机会的时候,外围的线程可能已经调用过stopRunning()方法了,因此要检查一下。
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if(!run)
{
return;
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
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();
}
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void stopRunning()
{
run = false;
}
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void setLeftMargin(int leftMargin)
{
checkWidget();
if (this.leftMargin == leftMargin || leftMargin < 0)
return;
this.leftMargin = leftMargin;
redraw();
}
![](/Images/OutliningIndicators/InBlock.gif)
public void setMargins(int leftMargin, int topMargin, int rightMargin,
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
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();
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void setRightMargin(int rightMargin)
{
checkWidget();
if (this.rightMargin == rightMargin || rightMargin < 0)
return;
this.rightMargin = rightMargin;
redraw();
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void setText(String text)
{
checkWidget();
if (text == null)
text = "";
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (!text.equals(this.text))
{
this.text = text;
redraw();
}
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void setToolTipText(String string)
{
super.setToolTipText(string);
appToolTipText = super.getToolTipText();
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void setTopMargin(int topMargin)
{
checkWidget();
if (this.topMargin == topMargin || topMargin < 0)
return;
this.topMargin = topMargin;
redraw();
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
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);
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
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;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (l1 + w + l2 > width)
{
max = mid;
mid = validateOffset(layout, (max + min) / 2);
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} else if (l1 + w + l2 < width)
{
min = mid;
mid = validateOffset(layout, (max + min) / 2);
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} else
{
min = max;
}
}
String result = mid == 0 ? t : t.substring(0, mid) + ELLIPSIS + t.substring(validateOffset(layout, l - mid), l);
layout.dispose();
return result;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
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;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private String[] splitString(String text)
{
String[] lines = new String[1];
int start = 0, pos;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
do
{
pos = text.indexOf('\n', start);
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (pos == -1)
{
lines[lines.length - 1] = text.substring(start);
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} 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 阅读(1531)
评论(2) 编辑 收藏 所属分类:
Eclipse-RCP