拖放 Eclipse Workbench 标签
http://tech.ddvip.com 2006年11月20日 社区交流
本文详细介绍拖放 Eclipse Workbench 标签
正如上面介绍的一样,编辑器标签有一种默认的拖放行为,它将进行重新排列和平铺操作,这可以使用拖放检测、鼠标移动 和鼠标释放 类型的事件的监听器实现。这些鼠标移动和鼠标释放的事件监听器的行为可能会与我们正在对编辑器实现的拖放行为冲突。例如,在将编辑器标签拖放到 Drop Window 上之后,如 图 2 所示,编辑器标签的重新排列和平铺会重新出现,这会导致在执行定制行为中产生意料不到的操作。(我们可以认为这是另外一次操作。)因此,限制默认监听器的行为是非常有必要的。
我们的想法是取消或忽略所发生的其他拖放操作。Eclipse 用户可以通过使用 Esc 键或右键点击鼠标来轻松实现这种功能。通过编程可以很容易实现这种功能:使用 event.button 值而不是 1 来执行触发鼠标释放事件,如下所示:
清单 5. 取消其他拖放操作
public void dragFinished(DragSourceEvent dsEvent)
{
dragSource.dispose();
// inhibit the action of CTabFolder's default drag-drop-listeners
draggedFolder.notifyListeners(SWT.MouseUp, null);
}对视图标签的拖放行为进行定制
由于视图通常都存放在 CTabFolder 容器中,因此上面用来定制编辑器的拖放行为的方法也可以用来定制视图的拖放行为。要像上面的 图 1 和 图 2 中所显示的那样对视图的拖放行为进行定制,则需要执行以下操作:当用户拖动一个视图标签时,捕获底层视图的 view-id,并将其设置为拖放过程中正在转移的对象。下面黑色字体表示的代码是应该在上面 清单 3 和 清单 4 的基础上添加的代码。
清单 6. 定制编辑器和视图标签的拖放行为
PlatformUI.getWorkbench().getDisplay().addFilter(SWT.DragDetect, new Listener()
{
public void handleEvent(Event event)
{
//ignore drag of widgets other than tab-folders (which host
//editor and view tabs)
if(!(event.widget instanceof CTabFolder))
return;
final CTabFolder draggedFolder = (CTabFolder)event.widget;
//Handle special case where no editors are open but editor area
//(and hence containing tab-folder) are still visible. Now try
//dragging the tab-folder. This drag should be ignored.
if( draggedFolder.getItemCount() < 1 )
return;
int operations = DND.DROP_COPY | DND.DROP_DEFAULT;
final DragSource dragSource = new DragSource(draggedFolder, operations);
//get a reference to the workbench-part that is being dragged
IWorkbenchWindow workbenchWindow =
PlatformUI.getWorkbench().getActiveWorkbenchWindow();
final IWorkbenchPart workbenchPartBeingDragged =
workbenchWindow.getActivePage().getActivePart();
Transfer[] transferTypes = null;
if(workbenchPartBeingDragged instanceof IEditorPart)
transferTypes = new Transfer[] {EditorInputTransfer.getInstance()};
else
transferTypes = new Transfer[] {TextTransfer.getInstance()};
dragSource.setTransfer(transferTypes);
dragSource.addDragListener(new DragSourceListener()
{
public void dragStart(DragSourceEvent dsEvent) { }
public void dragSetData(DragSourceEvent dsEvent)
{
if(workbenchPartBeingDragged instanceof IEditorPart)
{
String editorId = workbenchPartBeingDragged.getSite().getId();
IEditorInput editorInput =
((IEditorPart)workbenchPartBeingDragged).getEditorInput();
EditorInputTransfer.EditorInputData data =
EditorInputTransfer.createEditorInputData(editorId, editorInput);
dsEvent.data = new EditorInputTransfer.EditorInputData[] { data };
}
else if(workbenchPartBeingDragged instanceof IViewPart)
{
String viewId = workbenchPartBeingDragged.getSite().getId();
dsEvent.data = viewId;
}
}
public void dragFinished(DragSourceEvent dsEvent)
{
dragSource.dispose();
// inhibit the action of CTabFolder's default drag-detect-listeners
draggedFolder.notifyListeners(SWT.MouseUp, null);
}
});
}
});运行这个示例
这个 DragDropWorkbenchParts 插件在 Window 菜单中增加了一个菜单项 Enable Drag-n-Drop of Editor/View Parts。它在工具条中添加了一个相应的触发按钮。当用户选择这个菜单项或触发按钮时,就会有一个如 清单 6 所示的过滤器 被添加到 Display 中,从而启用编辑器和视图标签的拖放操作。当没有选择这个操作时,就会从 Display 中删除这个过滤器,恢复编辑器和视图标签的默认拖放行为(这意味着又可以进行重新排列和平铺操作了)。
该插件还定义了一个标题为 Drop Window 的视图,它有一个支持 EditorInputTransfer 和 TextTransfer 的拖放目标,允许将编辑器和视图标签拖放到此窗口中。
来源:IBM 作者:Shiva Kumar H.R. 责编:豆豆技术应用