Eclipseのプラグイン開発のGEFの(ドラッグ&ドロップの)ドロップについて。
|
|
GEFでは、ファイル等をドラッグしてエディター(ダイアグラム)上にドロップすることが出来る。
AbstractTransferDropTargetListenerクラスを継承したリスナーを作ってエディターに登録すると、ドロップ処理が行える。
このリスナークラスを作る際は、どの種類のドロップに対応できるかを指定する。
例えばFileTransferを指定すると、ファイルがドロップできるようになる。
クラス名 | ドロップできる内容 | データの型 | |
---|---|---|---|
FileTransfer | ファイルやフォルダー | String[] | ファイルのフルパス(複数ファイル可) |
EditorInputTransfer | ワークスペース内のファイル | EditorInputData[] | EditorInputDataの中にIEditorInputが入っている |
LocalSelectionTransfer | パッケージエクスプローラーの要素 | TreeSelection | パッケージエクスプローラーの場合 |
もう少し具体的には、以下の様な内容がドロップできる(受け付けることが出来る)。
ドラッグ要素 | F | EI | LS | |
---|---|---|---|---|
パッケージエクスプローラー | プロジェクト | × | × | ○ |
フォルダー | ○ | × | ○ | |
ファイル | ○ | ○ | ○ | |
javaファイル内のクラス | ○ | ○ | ○ | |
javaファイル内のフィールド・メソッド | × | ○ | ○ | |
Javaライブラリー | × | × | ○ | |
ワークスペース外のファイル・フォルダー | ○ | × | × |
FileTransferの例。
import org.eclipse.gef.EditPartViewer; import org.eclipse.gef.Request; import org.eclipse.gef.commands.Command; import org.eclipse.gef.dnd.AbstractTransferDropTargetListener; import org.eclipse.gef.dnd.SimpleObjectTransfer; import org.eclipse.gef.requests.CreateRequest; import org.eclipse.swt.dnd.DropTargetEvent; import org.eclipse.swt.dnd.FileTransfer;
public class ExampleDropTargetListener extends AbstractTransferDropTargetListener {
public ExampleDropTargetListener(EditPartViewer viewer) { super(viewer, FileTransfer.getInstance()); }
コンストラクターの第2引数で受け付けるドロップの種類(ここではFileTransfer)を指定する。
@Override protected void updateTargetRequest() { }
@Override protected Request createTargetRequest() { return new CreateRequest(); }
ドロップしたときにどういうRequestを発行するかを指定する。
GEFのエディター(ダイアグラム)の場合は、新しい図形を作ることが多いと思う。
@Override protected Command getCommand() { DropTargetEvent event = getCurrentEvent(); String[] files = (String[]) event.data; 〜 return new MyCreateCommand(〜); } }
処理を行うコマンドを返す。
GEFのエディター(ダイアグラム)の場合は、新しい図形を作るコマンドになると思う。
そして、エディタークラスにこのリスナーを登録する。
public class MyEditor extends GraphicalEditorWithFlyoutPalette { 〜
@Override protected void configureGraphicalViewer() { super.configureGraphicalViewer(); GraphicalViewer viewer = getGraphicalViewer(); 〜 viewer.addDropTargetListener(new ExampleDropTargetListener(viewer)); }
ドロップされた座標はgetLocation()で取得することが出来る。[2013-09-24]
import org.eclipse.draw2d.geometry.Point;
public class ExampleDropTargetListener extends AbstractTransferDropTargetListener { @Override protected Command getCommand() { 〜 Point location = getDropLocation(); int x = location.x; int y = location.y; return new MyCreateCommand(〜, x, y); }
ただしこれだと、表示されている領域(ドロップ先)がスクロールされている場合、その分が反映されない。
スクロールされている分も反映させるには、以下のようにすればよい。
import org.eclipse.draw2d.FigureCanvas; import org.eclipse.draw2d.geometry.Point; import org.eclipse.gef.EditPartViewer;
@Override protected Command getCommand() { 〜 EditPartViewer viewer = getViewer(); FigureCanvas c = (FigureCanvas) viewer.getControl(); Point base = c.getViewport().getViewLocation(); Point location = getDropLocation(); int x = base.x + location.x; int y = base.y + location.y; return new MyCreateCommand(〜, x, y); }
参考: Eclipse Community ForumsのHow to calculate the cursor Position in a Eclipse graphical editor ??
もしくは、Viewport#translateFromParent()を使って変換しても良さそう。
@Override protected Command getCommand() { 〜 EditPartViewer viewer = getViewer(); FigureCanvas c = (FigureCanvas) viewer.getControl(); Point location = getDropLocation(); c.getViewport().translateFromParent(location); int x = location.x; int y = location.y; return new MyCreateCommand(〜, x, y); }