SWT可变Link颜色的Link控件的实现
程序员文章站
2024-03-24 12:16:40
...
package study.swt;
import org.apache.commons.lang.StringUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.ACC;
import org.eclipse.swt.accessibility.Accessible;
import org.eclipse.swt.accessibility.AccessibleControlAdapter;
import org.eclipse.swt.accessibility.AccessibleControlEvent;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.TextLayout;
import org.eclipse.swt.graphics.TextStyle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.TypedListener;
/**
* <b>系统名称:</b>Digital Cinema 心得--SWT 学习与使用<br>
* <b>技能名称:</b>可变 Link 颜色的 Link 控件<br>
* <b>处理说明:</b> SWT 中的 Link 控件的 link 颜色只能为蓝色,如果 Link 的背景是深色的话,就会导致 Link 看起来比较费劲。本控件提供了一个 setLinkColor()方法设置 Link 的颜色。<br>
* <b>变更履历:</b>2007/10/16 MuChunYu Create<br>
* <br>
*
* @author Mu ChunYu
* @version 1.0 2007/07/04 初版
* <p>
*/
public class ColoredLink extends Canvas {
/** Link 文字 */
private String text = null;
/** Link 文字与边框的距离 */
private static final int INDENT = 3;
/** 画 Link 的TextLayout */
private TextLayout layout = null;
/** Link的颜色 */
private Color linkColor = null;
/** 横向的边框 */
private int hIndent = INDENT;
/** 纵向的边框 */
private int vIndent = INDENT;
/** Link的范围 */
private Rectangle rect = null;
/**
* <b>机能概要:</b> 构造函数。<br>
* <br>
* <b>处理流程:</b> <br>
* <ul>
* <li>调用父类的构造函数
* <li>初始化TextLayout
* <li>添加鼠标移动监听器
* <li>添加鼠标点击监听器
* </ul>
*
* @param parent 父容器
* @param style 分格
* @since 1.0
* <p>
*/
public ColoredLink(Composite parent, int style) {
super(parent, style);
// 初始化TextLayout
layout = new TextLayout(getDisplay());
layout.setOrientation(SWT.RIGHT_TO_LEFT | SWT.CENTER);
// 添加描画监听器
addPaintListener(new PaintListener() {
public void paintControl(PaintEvent event) {
// 重画
onPaint(event);
}
});
// 添加鼠标移动监听器
addMouseMoveListener(new MouseMoveListener() {
@Override
public void mouseMove(MouseEvent event) {
if (rect != null && rect.contains(event.x, event.y)) {
setCursor(new Cursor(null, SWT.CURSOR_HAND));
} else {
setCursor(new Cursor(null, SWT.NONE));
}
}
});
// 添加鼠标点击监听器
addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent event) {
if (rect != null && rect.contains(event.x, event.y)) {
Event e = new Event();
e.widget = ColoredLink.this;
notifyListeners(SWT.Selection, e);
redraw();
}
}
});
// 添加改变大小监听器
addControlListener(new ControlAdapter() {
@Override
public void controlResized(ControlEvent e) {
redraw();
}
});
// 添加焦点监听器
addFocusListener(new FocusListener() {
public void focusGained(FocusEvent e) {
((Canvas) e.getSource()).redraw();
}
public void focusLost(FocusEvent e) {
((Canvas) e.getSource()).redraw();
}
});
// 添加Tab监听器,处理Tab键
addTraverseListener(new TraverseListener() {
public void keyTraversed(TraverseEvent e) {
if (e.detail == SWT.TRAVERSE_TAB_NEXT || e.detail == SWT.TRAVERSE_TAB_PREVIOUS) {
e.doit = true;
}
}
});
// 添加键盘监听器,不添加的话控件不能取得焦点
addListener(SWT.KeyDown, new Listener() {
public void handleEvent(Event event) {
}
});
// 设定辅助信息
addAccessibility();
}
/**
* <b>机能概要:</b> 添加鼠标点击监听器。<br>
* <br>
* <b>处理流程:</b> <br>
* <ul>
* <li>添加鼠标点击监听器
* </ul>
*
* @param listener 监听器
* @since 1.0
* <p>
*/
public void addSelectionListener(SelectionListener listener) {
checkWidget();
if (listener == null) {
SWT.error(SWT.ERROR_NULL_ARGUMENT);
}
TypedListener typedListener = new TypedListener(listener);
addListener(SWT.Selection, typedListener);
addListener(SWT.DefaultSelection, typedListener);
}
/**
* <b>机能概要:</b> 删除鼠标点击监听器。<br>
* <br>
* <b>处理流程:</b> <br>
* <ul>
* <li>删除鼠标点击监听器
* </ul>
*
* @param listener 监听器
* @since 1.0
* <p>
*/
public void removeSelectionListener(SelectionListener listener) {
checkWidget();
if (listener == null) {
SWT.error(SWT.ERROR_NULL_ARGUMENT);
}
removeListener(SWT.Selection, listener);
}
/**
* <b>机能概要:</b> 设定辅助信息。<br>
* 不知道具体干吗的,可以不作<br>
* <b>处理流程:</b> <br>
* <ul>
* <li>设定辅助信息
* </ul>
*
* @param listener 监听器
* @since 1.0
* <p>
*/
private void addAccessibility() {
Accessible accessible = getAccessible();
accessible.addAccessibleControlListener(new AccessibleControlAdapter() {
@Override
public void getChildAtPoint(AccessibleControlEvent e) {
e.childID = ACC.CHILDID_SELF;
}
@Override
public void getChildCount(AccessibleControlEvent e) {
e.detail = 0;
}
@Override
public void getRole(AccessibleControlEvent e) {
e.detail = ACC.ROLE_LINK;
}
@Override
public void getLocation(AccessibleControlEvent e) {
Rectangle location = getBounds();
if (location != null) {
Point pt = toDisplay(new Point(location.x, location.y));
e.x = pt.x;
e.y = pt.y;
e.width = location.width;
e.height = location.height;
}
}
@Override
public void getState(AccessibleControlEvent e) {
e.detail = ACC.STATE_FOCUSABLE;
if (isFocusControl()) {
e.detail |= ACC.STATE_FOCUSED;
}
}
@Override
public void getSelection(AccessibleControlEvent e) {
if (isFocusControl()) {
e.childID = ACC.CHILDID_SELF;
}
}
@Override
public void getFocus(AccessibleControlEvent e) {
if (isFocusControl()) {
e.childID = ACC.CHILDID_SELF;
}
}
@Override
public void getDefaultAction(AccessibleControlEvent e) {
e.result = SWT.getMessage("SWT_Press");
}
});
}
/**
* <b>机能概要:</b> 画Link。<br>
* <br>
* <b>处理流程:</b> <br>
* <ul>
* <li>计算Link文字的位置
* <li>画Link
* <li>保存link文字的位置
* <li>画取得Focus的虚线
* </ul>
*
* @param event イベント
* <p>
*/
void onPaint(PaintEvent event) {
// 计算Link文字的位置
Rectangle txtRect = layout.getBounds();
Rectangle ctlRect = getBounds();
hIndent = 0;
vIndent = ctlRect.height - txtRect.height;
vIndent = (vIndent > 0 ? vIndent : 0) / 2;
// 画
layout.draw(event.gc, hIndent, vIndent);
// 保存link文字的位置
rect = new Rectangle(hIndent, vIndent, txtRect.width, txtRect.height);
// 画取得Focus的虚线
if (isFocusControl()) {
event.gc.drawFocus(hIndent, vIndent, txtRect.width, txtRect.height);
}
}
/**
* <b>机能概要:</b> 取得Link的文字。<br>
* <br>
* <b>处理流程:</b> <br>
* <ul>
* <li>取得Link的文字
* </ul>
*
* @return text Link的文字
* <p>
*/
public String getText() {
return text;
}
/**
* <b>机能概要:</b> 设定Link的文字。<br>
* <br>
* <b>处理流程:</b> <br>
* <ul>
* <li>设定 Link 的文字
* <li>设定 Link 的文字的风格,下划线和颜色
* </ul>
*
* @param text Link 的文字
* <p>
*/
public void setText(String text) {
this.text = text;
layout.setText(this.text);
TextStyle txtStyle = new TextStyle(null, linkColor, null);
txtStyle.underline = true;
layout.setStyle(txtStyle, 0, StringUtils.isEmpty(text) ? 0 : text.length());
}
/**
* <b>机能概要:</b> 设置 Link 的颜色。<br>
* <br>
* <b>处理流程:</b> <br>
* <ul>
* <li>设置 Link 的颜色
* </ul>
*
* @param linkColor Link 的颜色
* <p>
*/
public void setLinkColor(Color linkColor) {
this.linkColor = linkColor;
}
/**
* <b>机能概要:</b> 计算 Link 的位置。<br>
* <br>
* <b>处理流程:</b> <br>
* <ul>
* <li>计算Link的位置
* </ul>
*
* @param wHint 设定大小
* @param hHint 设定大小
* @param changed 变更标志
* @return Point Link 的位置
* <p>
*/
@Override
public Point computeSize(int wHint, int hHint, boolean changed) {
Rectangle txtRect = getBounds();
int width = wHint;
int height = hHint;
if (wHint != SWT.DEFAULT) {
width = txtRect.width;
}
if (hHint != SWT.DEFAULT) {
height = txtRect.height;
}
return new Point(width + 2, height + 2);
}
}
三、使用方式
1、添加 Link
ColoredLink lnkColumn1 = new ColoredLink(cmpColumn1, SWT.NONE);
lnkColumn1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
lnkColumn1.setForeground(StyleUtils.getDetailForeground());
lnkColumn1.setLinkColor(StyleUtils.getLinkForeground());
lnkColumn1.setText(column);
lblCert.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
// TODO
}