版权声明:本文为博主原创文章,转载请注明源地址。 https://cloud.tencent.com/developer/article/1433531
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#doit
为true
就会执行后续的遍历动作。
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 handlertraversekeyTraversed,就可以为组件添加一个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;
}
}
});
上面的代码也可以写成这样
代码语言:javascript复制 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 按键、事件、监听》