java SWT:TraverseEvent的理解塈添加TraverseListener实现Composite之间TAB键切换焦点

24 篇文章 0 订阅

TraverseEvent遍历事件

从英文直译的话,org.eclipse.swt.events.TraverseEvent是指widget中组件遍历(切换焦点)动作发生时产生的事件
举例来说,就是当我们使用光标键,TAB/shift-TAB键,PAGE-UP/DOWN等键在按钮(Button)之间切换焦点的时候,就会产生TraverseEvent事件。

关于TraverseEven的原文说明,参见官网《org.eclipse.swt.events.TraverseEvent》

为什么Canvas下TAB不起作用?

当在Canvas中按下TAB键时, TraverseEvent#detail字段的值是SWT.TRAVERSE_TAB_NEXT ,TraverseEvent#doit 字段的值是false,这时系统的默认行为不会将这个TAB键理解为用户是想将焦点设置到下一个widget,这就意味着在Canvas中的按键侦听器(key Listener)将会收到用户敲的TAB键(SWT.TAB)—所以默认情况下,用TAB键是无法在widget之间切换焦点的。

如果要想让Composite对象支持TAB键在组件间移动焦点,就要改变系统对TAB键的行为,修改TraverseEvent#doit 字段的值为true

下面是org.eclipse.swt.widget.Control类中的traverse 方法代码,可以看到,当TraverseEvent#doittrue就会执行后续的遍历动作。

boolean traverse (Event event) {
    /*
    * It is possible (but unlikely), that application
    * code could have disposed the widget in the traverse
    * event.  If this happens, return true to stop further
    * event processing.
    */
    //将TraverseEvent事件发送给所有组件
    sendEvent (SWT.Traverse, event);    
    if (isDisposed ()) return true;
    if (!event.doit) return false;
    //如果有组件将响应TraverseEvent事件并将doit置为true,就执行遍历动作。
    switch (event.detail) {
        case SWT.TRAVERSE_NONE:         return true;
        case SWT.TRAVERSE_ESCAPE:           return traverseEscape ();
        case SWT.TRAVERSE_RETURN:           return traverseReturn ();
        case SWT.TRAVERSE_TAB_NEXT:     return traverseGroup (true);
        case SWT.TRAVERSE_TAB_PREVIOUS: return traverseGroup (false);
        case SWT.TRAVERSE_ARROW_NEXT:       return traverseItem (true);
        case SWT.TRAVERSE_ARROW_PREVIOUS:   return traverseItem (false);
        case SWT.TRAVERSE_MNEMONIC:     return traverseMnemonic (event.character);
        case SWT.TRAVERSE_PAGE_NEXT:        return traversePage (true);
        case SWT.TRAVERSE_PAGE_PREVIOUS:    return traversePage (false);
    }
    return false;
}

TraverseListener侦听器

如何将doit置为true呢?
SWT提供了一个TraverseListener接口(遍历事件侦听器),在组件上加上这个侦听器,就可以收到并处理TraverseEvent事件。

在WindowBuilder下添加TraverseListener侦听器很方便,可以如下图在组件上右键点击,找到Add event handler\traverse\keyTraversed,就可以为组件添加一个TraverseListener了。

这里写图片描述
然后在侦听器中添加如下处理代码(是参照org.eclipse.ui.forms.widgets.FormText的TraverseListener代码改的):

        addTraverseListener(new TraverseListener() {
            @Override
            public void keyTraversed(TraverseEvent e) {
                switch (e.detail) {
                case SWT.TRAVERSE_TAB_NEXT:
                case SWT.TRAVERSE_TAB_PREVIOUS:
                    // TAB/shift-TAB键时将doit置为true
                    e.doit = true;
                    return;
                }
            }
        });

上面的代码也可以写成这样

        addListener(SWT.Traverse, new Listener() {
            @Override
            public void handleEvent(Event e) {
                switch (e.detail) {
                case SWT.TRAVERSE_TAB_NEXT:
                case SWT.TRAVERSE_TAB_PREVIOUS:
                    e.doit = true;
                    return;
                }
            }
        });

注意:不要忘记在父类中调用setTabList设置TAB list

参考资料

《SWT对于监听Tab键的理解》
《org.eclipse.swt.events.TraverseEvent》
《SWT/JFace 按键、事件、监听》

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10km

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值