最近,在些一个SWT的Diglog因为觉得里面的Button不好用,所以自己手动编写了一个Button类继承Cavas,但是发现对于键盘的Tab按钮并没有什么反应,为了想做到与SWT自带的Button一样对Tab事件的监听,就顺带研究了一下这个Tab按钮是如何实现的,先说说SWT是如何对Tab事件的监听,和如何推论出下一个tab移动的组件
在SWT中,键盘的TAB键是在display里面做了监听,还包括一些其他移动性按钮(上下按钮等)
所以当按Tab键的时候,控件里面的translateTraversal()方法被触发了,大概的流程如下:
- 首先寻找到当前组件的顶层组件容器shell
- 推算出当前的组件是否tab组件,如果不是tab组件,寻找它的子类
- 寻找到它的下一个组件进行推算
- 假如下一个组件为Tab组件,或者它添加了按钮监听事件,侧被视为下一个跳转按钮组件
根据上面的讲解,找到了所有组件的根类Widget,然后发现,Widget的组件,默认调用setTabItemFocus ()这个方法,返回false,被视为非tab跳转组件,既然Button被视为下一个Tab组件,说明setTabItemFocus ()这个方法被重写了,不难找到control重写了setTabItemFocus()方法,所以继承他的Button类会被视为Tab的组件,继承widget下的Scrollable没有重新setTabItemFocus()方法,所以往下的所有组件都不视为Tab组件,包括Composite,按照这样的推论,假如自定义一个继承至widget的类都能重写setTabItemFocus()这个方法就可以了,但是,setTabItemFocus()这个方法,在Widget里面被视为只有同包才能重写此方法,所以不能往这个方向着手了。
然后发现了Canvas类下,有两个子类,一个是CLabel,另外一个是FormText,CLabel不视为Tab组件,但FormText居然视为Tab组件,而FormText跟Widget既不同包也不同插件,所以它根本没有重写setTabItemFocus ()这个方法,怎么可能会被视为Tab组件呢。看了看代码,发现记得之前的SWT校验Tab组件的其中一个条件是,当组件有按钮下按监听事件的时候,就会被视为Tab组件。果然发现了FormText类的构造函数中,添加了几个按钮监听事件,那一切都好办了,只要能在自定义的Button组件中,添加按钮的监听事件,那键盘Tab转移聚焦组件的功能就不难实现了