有很多学习SWT的同志遇到过一类需求,为某些控件添加了诸如MouseListener、KeyListener之类的监听,然后呢,希望使用代码模拟鼠标、键盘来执行点击、按键等操作。
首先说明一点,这是可以实现的,但是99%的需求都不应该这样实现。
在继续往下看之前,请你考虑一点,你是不是可以把监听中的逻辑代码抽离出来,做成单独的可供调用的功能块,在你希望“模拟”的地方调用它。
如果实在考虑不出更好的方式,请往下看。
解决方案很简单:
Event ex = new Event(); ex.widget = targetWidget; ex.type = SWT.KeyDown; ex.button = 1; Display.getCurrent().post(ex);
自己构建一个事件,为该事件指定一个控件目标,然后发起它。
那么,如此简单的代码,为什么你还需要搜索呢?
这里说说,在对发起事件无甚了解又不想看API的情况下的解决思路。
1、为任意控件添加一个监听,打断点,触发它
通过这个步骤,我们可以看出,事件Event都是通过Display的readAndDispatch方法进行调度分发的。
2、读到runDeferredEvents方法中,可以观察到eventQueue事件队列,你应该能敏感的察觉到你需要往这里面添加Event,才有可能发起事件
3、ctrl+shift+G搜索eventQueue在Display里的使用,可以观察到sentEvent、postEvent等等方法,先不要看源码,ctrl+o,可以看出,Display对外提供了一个post(Event)方法
4、那么,调用post就可以了么?我们再来看看步骤2位置,阅读以下源码:
/* Run the event */ Widget widget = event.widget; if (widget != null && !widget.isDisposed ()) { Widget item = event.item; if (item == null || !item.isDisposed ()) { run = true; widget.sendEvent (event); } }
可以看出,充要条件是event必须具备一个未被disposed的widget。
以上,即可得出早前的解决方案。