|
パレットは図形の一覧(メニュー)で、そこから図形を選択してエディター上に図形を置くことが出来るようにするもの。
パレットを使う場合は、GraphicalEditorとしてGraphicalEditorWithPaletteあるいはGraphicalEditorWithFlyoutPaletteを使用する。
パレットに図形の選択肢を表示しておき、そこからエディター上に図形を生成する例。
import org.eclipse.gef.palette.CreationToolEntry; import org.eclipse.gef.palette.PaletteDrawer; import org.eclipse.gef.palette.PaletteRoot; import org.eclipse.gef.requests.SimpleFactory;
public class MyEditor extends GraphicalEditorWithFlyoutPalette { 〜
@Override protected PaletteRoot getPaletteRoot() { PaletteRoot root = new PaletteRoot(); PaletteDrawer drawer = new PaletteDrawer("描画ツール"); drawer.add(new CreationToolEntry("モデル名", "モデルの説明", new SimpleFactory(MyModel.class), null, null)); root.add(drawer); return root; }
CreationToolEntryにより、パレットにモデル(図形)の行が表示される。
(パレット上でその行を選択してからエディター上で置きたい場所をクリックすると図形が配置される。ドラッグ&ドロップではないので注意。
→ドラッグ&ドロップで配置する方法)
CreationToolEntryは、EditPartのポリシーに書かれている図形生成コマンドを使って図形を生成する。
わざわざコマンドになっているのは、Ctrl+ZによるUNDO(取り消し)やCtrl+YにとるREDOが出来るようにする為。
(とは言っても、Ctrl+ZやCtrl+Yの処理は自前で書かないと駄目だが^^;)
「drawer.add(new PaletteSeparator());
」でセパレーターを追加することも出来る。[2013-12-29]
import org.eclipse.gef.EditPolicy;
public class DiagramEditPart extends AbstractModelEditPart { 〜
@Override protected void createEditPolicies() { installEditPolicy(EditPolicy.LAYOUT_ROLE, new DiagramLayoutEditPolicy()); }
import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.gef.EditPart; import org.eclipse.gef.commands.Command; import org.eclipse.gef.editpolicies.XYLayoutEditPolicy; import org.eclipse.gef.requests.ChangeBoundsRequest; import org.eclipse.gef.requests.CreateRequest;
public class DiagramLayoutEditPolicy extends XYLayoutEditPolicy {
@Override protected Command getCreateCommand(CreateRequest request) { Point point = request.getLocation(); MyModel element = (MyModel) request.getNewObject(); Diagram diagram = (Diagram) getHost().getModel(); return new CreateElementCommand(diagram, element, point.x, point.y); } }
import org.eclipse.gef.commands.Command;
public class CreateElementCommand extends Command {
private Diagram parent; private MyModel element; private int x; private int y;
public CreateElementCommand(Diagram parent, MyModel element, int x, int y) { this.parent = parent; this.element = element; this.x = x; this.y = y; }
@Override public void execute() { element.setX(x); element.setY(y); parent.addContent(element); }
@Override public void undo() { parent.removeContent(element); } }
上記の方法では、図形を配置するには、パレットで図形を選択し、エディター上で配置したい場所をクリックする。
よくある操作では、パレットから図形をドラッグして、配置したい場所にドロップする。これを実現してみる。[2013-03-12]
参考: stackoverflowのHow to drag and drop figures from palette into GEF editor?
import org.eclipse.gef.dnd.TemplateTransferDragSourceListener; import org.eclipse.gef.dnd.TemplateTransferDropTargetListener; import org.eclipse.gef.palette.CombinedTemplateCreationEntry; import org.eclipse.gef.ui.palette.PaletteViewer;
public class MyEditor extends GraphicalEditorWithFlyoutPalette { 〜
@Override
protected void initializeGraphicalViewer() {
super.initializeGraphicalViewer();
GraphicalViewer viewer = getGraphicalViewer();
Diagram diagram = new Diagram();
viewer.setContents(diagram);
// パレットのドラッグのリスナーを登録
PaletteViewer paletteViewer = getPaletteViewerProvider().getEditDomain().getPaletteViewer();
paletteViewer.addDragSourceListener(new TemplateTransferDragSourceListener(paletteViewer));
// エディターのドロップのリスナーを登録
viewer.addDropTargetListener(new TemplateTransferDropTargetListener(viewer));
}
@Override protected PaletteRoot getPaletteRoot() { PaletteRoot root = new PaletteRoot(); PaletteDrawer drawer = new PaletteDrawer("描画ツール"); drawer.add(new CombinedTemplateCreationEntry("モデル名", "モデルの説明", new SimpleFactory(MyModel.class), null, null)); root.add(drawer); return root; }
これで、パレットからドラッグ&ドロップで図形を配置できるようになる。
(クリックによる配置も従来通り出来る)
パレット上の図形を選んでCtrl+Cでコピーし、エディター上にCtrl+Vで貼り付けて新しい図形を作ることが出来る。[2013-12-04]
参考: LogicEditor
CopyTemplateActionは、パレット上で図形を選択すると、その図形のテンプレート(CombinedTemplateCreationEntryから取得する)をAction内部に保持する。
そこでCtrl+Cが押されると、そのテンプレートをクリップボードにコピーする。
Ctrl+Vが押されるとPasteTemplateActionが呼ばれ、クリップボードからテンプレートを取得してそれを使って新しい図形を生成する。
なお、PasteTemplateActionでは貼り付け先の座標は(10,10)になっている。つまりエディター上で選択中の図形内の左上に配置される。
その図形内に新しい図形を生成できない場合は、何も生成されない。
図形の生成は、エディター上で選択されている図形のEditPartに対してCREATEイベントが送られることによって実現されている。
つまり、通常の図形生成と同じ仕組みが使われている。
import org.eclipse.gef.ui.actions.CopyTemplateAction; import org.eclipse.gef.ui.actions.PasteTemplateAction; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.ui.actions.ActionFactory;
public class MyEditor extends GraphicalEditorWithFlyoutPalette { 〜
@SuppressWarnings("unchecked")
@Override
protected void createActions() {
super.createActions();
ActionRegistry registry = getActionRegistry();
{
IAction action = new CopyTemplateAction(this);
registry.registerAction(action);
//PaletterViewerに登録するので、selectionActionsには登録しない
}
{
IAction action = new PasteTemplateAction(this);
registry.registerAction(action);
getSelectionActions().add(action.getId());
}
〜
}
@Override
protected void initializeGraphicalViewer() {
super.initializeGraphicalViewer();
〜
// palette drag
PaletteViewer paletteViewer = getPaletteViewerProvider().getEditDomain().getPaletteViewer();
paletteViewer.addDragSourceListener(new TemplateTransferDragSourceListener(paletteViewer));
// palette copy
final CopyTemplateAction copy = (CopyTemplateAction) getActionRegistry().getAction(ActionFactory.COPY.getId());
paletteViewer.addSelectionChangedListener(copy);
// palette context-menu
paletteViewer.getContextMenu().addMenuListener(new IMenuListener() {
@Override
public void menuAboutToShow(IMenuManager manager) {
manager.appendToGroup(GEFActionConstants.GROUP_COPY, copy);
}
});
// editor drop
viewer.addDropTargetListener(new TemplateTransferDropTargetListener(viewer));
}
import org.eclipse.ui.actions.ActionFactory;
public class MyActionBarContributor extends ActionBarContributor { 〜
@Override protected void declareGlobalActionKeys() { addGlobalActionKey(ActionFactory.COPY.getId()); addGlobalActionKey(ActionFactory.PASTE.getId()); } }
ちなみに、Eclipse4.3で開発してEclipse3.7にインストールすると、PasteTemplateActionが存在しないので例外が発生する。[2013-03-10]
java.lang.NoClassDefFoundError: org/eclipse/gef/ui/actions/PasteTemplateAction 〜 Caused by: java.lang.ClassNotFoundException: org.eclipse.gef.ui.actions.PasteTemplateAction 〜
CopyTemplateActionはGEF3.7に存在しているが、PasteTemplateActionは何故かGEF3.8で追加されたらしい。
したがってPasteTemplateActionはGEF3.7に存在しないのでエラーになる。
デフォルトでは、エディターを開いた直後はパレットが閉じた状態になっている。[2013-12-29]
そういった初期状態(初期値)(パレットの開閉有無やパレットの幅、配置場所(エディターの右か左か))を変更する例。
import org.eclipse.draw2d.PositionConstants; import org.eclipse.gef.ui.palette.FlyoutPaletteComposite; import org.eclipse.gef.ui.palette.FlyoutPaletteComposite.FlyoutPreferences;
public class MyEditor extends GraphicalEditorWithFlyoutPalette { 〜
@Override protected FlyoutPreferences getPalettePreferences() { FlyoutPreferences pref = super.getPalettePreferences(); if (pref.getPaletteWidth() <= 0) { pref.setDockLocation(PositionConstants.EAST); pref.setPaletteState(FlyoutPaletteComposite.STATE_PINNED_OPEN); pref.setPaletteWidth(160); } return pref; }
メソッド名を見れば分かる通り、preferences(設定)で状態(値)を保持している。