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);
}