我在一个 SWT 应用程序中,可以Composite
通过拖放重新排列 shell(或任何其他)内的控件。这基本上没有问题,DragSource
s和DropTarget
s都到位并相应地附加了听众。Transfer
为了练习,我什至实现了一个自定义类型。很简单。
但是现在的要求是只有在执行拖动手势时按下 ALT 键才应该启动拖动,否则什么都不应该做。(ALT 键是一个示例,也可以是 CTRL。)
到目前为止,我看到或考虑过以下方法。所有这些要么不起作用,要么很丑陋。
\1。拦截并取消DragDetect
事件
这个想法是在没有按下 ALT 键的情况下取消事件event.doit = false
。
lblPos.addListener(SWT.DragDetect, new Listener() {
public @Override void handleEvent(Event event) {
if ((event.stateMask & SWT.ALT) == 0)
event.doit = false; // XXX: doit will not be evaluated
}
});
但是,这是行不通的。该doit
标志显然没有被评估。
\2。拦截并取消DND.DragStart
事件。
class RowDragListener implements DragSourceListener {
public @Override void dragStart(DragSourceEvent event) {
if (/* ALT key not pressed */)
event.doit = false;
}
...
}
这与方法 1 有相反的问题。虽然doit
标志被正确评估并因此适合取消拖动,但stateMask
在事件中没有可以检查修饰键的情况。那么问题来了,如何直接查询键盘(无需安装 KeyUp/Down 事件处理程序)?ALT 键的当前向上/向下状态是什么?
\3。结合 1 和 2
检查事件,将结果存储在某处,然后在事件中做出相应的stateMask
反应。这不应该太难,但我认为它很难看,不应该这样做。代替,可以捕获 KeyUp/Down 事件并存储 ALT 键的最后一个已知状态。DragDetect
DND.DragStart
DragDetect
\4。覆盖Control.dragDetect(Event)
或Control.dragDetect(MouseEvent)
DragDetect
如果这些方法看到满足它的条件,它们最终会创建事件。
仅当发出所需的修饰键信号时,才检查事件stateMask
并从超类调用重写的方法。这里的问题是,从文档中不清楚这是否是唯一踩在拖动手势上的代码路径。事实上,这两个方法是相互独立的(它们不相互调用),所以甚至不清楚要覆盖哪一个。这些方法已经是启动拖动手势的两种不同方式。谁知道还有多少种方式?如果可能的话,全部覆盖它们很容易出错,而且肯定不干净。
所以我的问题是: 1. 你会怎么做?还有其他想法吗?2. 如果方法 2 看起来最合理,如何在不借助事件处理程序的情况下查询键盘?
(抱歉这篇文章的格式,我似乎无法掌握语法。或者也许这不是我的错,谁知道。)
更新:有一点需要注意,我在实施过程中注意到了这一点。在 Windows 上,ALT-Drag&Drop 具有链接操作的特定含义(与移动或复制相反;cmp.DND.DROP_* 常量)。这就是为什么,如果您选择以类似方式使用 ALT 键,建议您在DropTargetListener
.
if (event.detail == DND.DROP_LINK) event.detail = DND.DROP_MOVE;
我在dragEnter
,dragOver
和dragOperationChanged
listener 方法中有这个,这很好用。