SWT可变Link颜色的Link控件的实现

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
        }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值