SWT小部件中的自定义拖动检测

时间:2011-07-15 11:31:50

标签: java drag-and-drop swt

在我的基于SWT的应用程序中,我有一个Canvas派生的自定义Widget,它显示了一堆“项目”。这些项目的全部目的是让用户将它们拖出窗口小部件。我没有遇到实现DragSource,DragDetectListener以及使DND工作的所有东西都没有问题。我试图解决的问题是我希望更早地检测到拖动,即在比默认平台行为短得多的鼠标拖动距离之后。

我知道我可以覆盖Widget类的dragDetect()。但是,这只允许我否决超类的实现,而不是通知在超级类认为它之前已经发生拖拽。

基本上,如果我可以自己生成拖动事件,就像我可以使用Widget.postEvent(SWT.DragDetect,eventWhichIAllocatedAndFilledOut)(这是包私有),这看起来像我的解决方案。我已经看过Widget中的拖拽检测代码了,它似乎并不是为这个用例设计的。有没有解决方法,让我随时随地启动拖动?

1 个答案:

答案 0 :(得分:3)

我已经弄清楚了。可以生成自定义事件并将其分发给DragDetect侦听器机制。下面的代码与内部实现相同,但可以从Widget实现中随意调用,例如从MouseMoveListener的mouseMove(MouseEvent e)钩子中调用:

Event event = new Event();
event.type = SWT.DragDetect;
event.display = getDisplay();
event.widget = this;
event.button = e.button;
event.stateMask = e.stateMask;
event.time = e.time;
event.x = e.x;
event.y = e.y;

notifyListeners(SWT.DragDetect, event);

值得注意的是,必须禁用内置拖动检测才能使其按预期工作。默认实现是通过dragDetect(MouseEvent e)方法公开的,该方法可以从mouseDown()处理程序调用(如dragDetect()文档中所述)。它通过事件线程中的繁忙循环来工作,直到检测到拖动。它只是至少从GTK后端的本机事件队列中消耗鼠标移动事件。当向Widget注册DragDetectListener时,这将自动完成,因此除非通过setDragDetect(false)禁用该机制,否则自定义拖动检测仅在内置检测之后运行,因为它阻止了事件线程,当然,除了第二次检测拖动之外。