S-JIS[2013-04-29/2013-09-24] 変更履歴

Eclipse GEF ドロップ

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のエディター(ダイアグラム)の場合は、新しい図形を作るコマンドになると思う。


そして、エディタークラスにこのリスナーを登録する。

GraphicalEditorクラス:

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

GEFへ戻る / Eclipseプラグインへ戻る / Eclipseへ戻る / 技術メモへ戻る
メールの送信先:ひしだま