S-JIS[2013-03-09/2013-09-27] 変更履歴

Eclipse GEF GraphicalEditor

Eclipseプラグイン開発GEFのGraphicalEditorについて。


概要

GraphicalEditorは、GUIで絵(図形や線)を描画する為のエディター。

クラス名 説明
GraphicalEditor 基本的なエディター
GraphicalEditorWithPalette パレット付きのエディター
GraphicalEditorWithFlyoutPalette フローティングパレット(ユーザーが移動可能なパレット)付きのエディター

パレットは図形の一覧(メニュー)で、そこから図形を選択してエディター上に図形を置くことが出来るようにするもの。


最小限動作するGUIエディターの例。

まず、GraphicalEditorクラスを作成する。

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.gef.DefaultEditDomain;
import org.eclipse.gef.palette.PaletteRoot;
import org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette;
public class MyEditor extends GraphicalEditorWithFlyoutPalette {
	public MyEditor() {
		DefaultEditDomain domain = new DefaultEditDomain(this);
		setEditDomain(domain);
	}

コンストラクターでEditDomainを設定する。イベント通知や操作履歴を保持するものらしい。
とりあえずはデフォルトのものをそのまま使用する。

	@Override
	protected PaletteRoot getPaletteRoot() {
		// TODO 自動生成されたメソッド・スタブ
		return null;
	}
	@Override
	public void doSave(IProgressMonitor monitor) {
		// TODO 自動生成されたメソッド・スタブ
	}
}

そして、ファイルの拡張子とエディタークラスを連動させる。

拡張にorg.eclipse.ui.editorsを追加する。

plugin.xml:

   <extension
         point="org.eclipse.ui.editors">
      <editor
            class="com.example.MyEditor"
            default="false"
            filenames="*.mygui"
            id="plugin.my-gui-editor"
            name="My GUI Editor">
      </editor>
   </extension>

これで、Eclipseプラグインを実行して拡張子「mygui」というファイルを作って開けば、自分のエディターが起動する。
(まだ何も表示されないけど^^;)

ActionBarContributor


図形の表示

エディター上に図形を表示するには色々なクラスを準備する必要がある。
ほとんどの単なる写経になってしまうし量も多いので詳細は割愛するが、以下の様なクラスが必要となる。

種類 親クラス 備考
Model なし データを保持するクラス。
ファイルにはこのクラスのオブジェクトを保存する。(ファイルを読み込んでこのオブジェクトを復元する)
ほぼ単なるJavaBeansだが、値セット時はPropertyChangeイベントを発生させるようにする。
Figure org.eclipse.draw2d
IFigure
エディター上に表示する図形を描画するクラス。
org.eclipse.draw2dのクラスを使用して描画する。
EditPart org.eclipse.gef.editparts
AbstractGraphicalEditPart
Figureインスタンスを生成するクラス。
また、ModelのPropertyChangeイベントを受け取ってFigureの再描画を行う。
EditPartFactory org.eclipse.gef
EditPartFactory
EditPartインスタンスを生成するクラス。
Model毎に対応するEditPartを生成するようにする。

これらのクラスは、MVC(Model-View-Controller)に従っている。
すなわち、Modelがモデル、Figureがビュー、EditPartがコントローラーとなる。
→linuxtopiaのEclipse GEF and Draw2d Plug-in Developer Guide

ModelFigureEditPartは1つの図形につき1つずつ存在することになる。
EditPartFactoryはエディターにつき1つあればよい。

また、Modelクラス類は、エディター内の全図形を管理するルートとなるクラス(では「Diagramクラス」)と、各図形のクラスが必要となる。


GraphicalEditorクラス:

import org.eclipse.gef.GraphicalViewer;
public class MyEditor extends GraphicalEditorWithFlyoutPalette {
〜
	@Override
	protected void configureGraphicalViewer() {
		super.configureGraphicalViewer();

		GraphicalViewer viewer = getGraphicalViewer();
		viewer.setEditPartFactory(new MyEditPartFactory());
	}

configureGraphicalViewer()でEditPartFactoryを設定する。

	@Override
	protected void initializeGraphicalViewer() {
		super.initializeGraphicalViewer();

		GraphicalViewer viewer = getGraphicalViewer();

		Diagram diagram = new Diagram();
		{
			// 初期表示
			MyModel model = new MyModel();
			model.setName("zzz");
			model.setX(16);
			model.setY(16);
			diagram.addContents(model);
		}

		viewer.setContents(diagram);
	}

initializeGraphicalViewer()でエディター内に表示するデータ(Modelインスタンス)を生成する。
(上記の例では図形を1個表示しているが、初期状態を空で表示するには、Diagramだけあればいい)

contentsにセットしたModelから、EditPartFactoryによってEditPartが作られ、EditPartでFigureが生成される。


EditorからModelやEditPartを取得する方法

EditorからEditPartを取得するのは簡単。[2013-09-27]

GraphicalEditorクラス:

		EditPart editPart = getGraphicalViewer().getContents();
		DiagramEditPart diagramEditPart = (DiagramEditPart) editPart;

そもそも最初にviewerに対してDiagram(Model)をセットしているので、それを取り出しているだけと言える。
ただしsetContents()の引数はModelだったが、内部ではEditPartとして保持しているので、取り出せるのはEditPart。


EditorからEditPartが取得できるので、Modelはそこから取ればよい。

GraphicalEditorクラス:

		EditPart editPart = getGraphicalViewer().getContents();
		Diagram diagram = (Diagram) editPart.getModel();

EditPartからEditorを取得する方法

EditPartからEditorを取得する例。[2013-09-27]

MyEditPart.java:

import org.eclipse.gef.DefaultEditDomain;
import org.eclipse.gef.EditPartViewer;
		EditPartViewer viewer = getViewer();
		DefaultEditDomain domain = (DefaultEditDomain) viewer.getEditDomain();
		MyEditor editor = (MyEditor) domain.getEditorPart();

ただし、EditPartとEditorが必ずしも1:1対応するとは限らないらしい?

参考: Eclipse Community ForumsのHow to get from an EditPart to its Editor in Eclipse?


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