Eclipseのプラグイン開発のGEFの図形の直接編集について。
|
エディター上の図形をクリックして、図形内の文字列を直接編集することが出来る。
図形を直接編集する為に、DirectEditPolicyとDirectEditManagerを用意する必要がある。
import org.eclipse.draw2d.Label; import org.eclipse.gef.EditPolicy; import org.eclipse.gef.Request; import org.eclipse.gef.RequestConstants;
public class MyEditPart extends AbstractModelEditPart implements NodeEditPart { 〜
@Override protected void createEditPolicies() { 〜 installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new MyModelDirectEditPolicy()); }
@Override public void performRequest(Request request) { if (request.getType() == RequestConstants.REQ_DIRECT_EDIT) { performDirectEdit(); } } private void performDirectEdit() { MyFigure figure = (MyFigure)getFigure(); Label label = figure.getMyValueLabel(); MyModelDirectEditManager manager = new MyModelDirectEditManager(this, label); manager.show(); }
DirectEditPolicyを指定することで、図形をクリックしたときにREQ_DIRECT_EDITのリクエストが来るようになる。
そこでDirectEditManagerで編集用のTextを用意する。編集用のTextのサイズや初期文字列を決める為に、Figureに表示しているLabelを使う。
DirectEditPolicyで、Textに入力された文字列をモデルへ移送するコマンドを用意する。
import org.eclipse.gef.commands.Command; import org.eclipse.gef.editpolicies.DirectEditPolicy; import org.eclipse.gef.requests.DirectEditRequest;
public class MyModelDirectEditPolicy extends DirectEditPolicy {
@Override protected Command getDirectEditCommand(DirectEditRequest request) { MyModel model = (MyModel) getHost().getModel(); String value = (String) request.getCellEditor().getValue(); MyModelDirectEditCommand command = new MyModelDirectEditCommand(model, value); return command; }
@Override protected void showCurrentEditValue(DirectEditRequest request) { MyFigure figure = (MyFigure) getHostFigure(); String value = (String) request.getCellEditor().getValue(); figure.setMyValue(value); } }
import org.eclipse.gef.commands.Command;
public class MyModelDirectEditCommand extends Command { private MyModel model; private String value, old_value;
public MyModelDirectEditCommand(MyModel model, String value) { this.model = model; this.value = value; }
@Override public void execute() { old_value = model.getMyValue(); model.setMyValue(value); }
@Override public void undo() { model.setMyValue(old_value); } }
import org.eclipse.draw2d.Label; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.gef.GraphicalEditPart; import org.eclipse.gef.tools.CellEditorLocator; import org.eclipse.gef.tools.DirectEditManager; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Text;
public class MyModelDirectEditManager extends DirectEditManager {
public MyModelDirectEditManager(GraphicalEditPart source, Label label) { super(source, TextCellEditor.class, new Locator(label), label); }
@Override protected void initCellEditor() { Label label = (Label) getDirectEditFeature(); String initialLabelText = label.getText(); getCellEditor().setValue(initialLabelText); }
public static class Locator implements CellEditorLocator { private Label label; public Locator(Label label) { this.label = label; } @Override public void relocate(CellEditor celleditor) { Text text = (Text) celleditor.getControl(); Point pref = text.computeSize(SWT.DEFAULT, SWT.DEFAULT); Rectangle rect = label.getTextBounds().getCopy(); label.translateToAbsolute(rect); text.setBounds(rect.x - 1, rect.y - 1, pref.x + 1, pref.y + 1); } } }
F2キーを押したときに直接編集を始めるようにする方法。
import org.eclipse.gef.KeyHandler; import org.eclipse.gef.KeyStroke; import org.eclipse.gef.ui.actions.DirectEditAction; import org.eclipse.gef.ui.actions.GEFActionConstants; import org.eclipse.gef.ui.parts.GraphicalViewerKeyHandler; import org.eclipse.jface.action.IAction; import org.eclipse.swt.SWT;
public class MyEditor extends GraphicalEditorWithFlyoutPalette { 〜
@Override
protected void configureGraphicalViewer() {
〜
ActionRegistry registry = getActionRegistry();
KeyHandler handler = new GraphicalViewerKeyHandler(viewer);
viewer.setKeyHandler(handler);
handler.put(KeyStroke.getPressed(SWT.F2, 0), registry.getAction(GEFActionConstants.DIRECT_EDIT));
}
KeyHandlerを用意し、F2キーを押したときのアクションを指定する。
そのアクションは、createActions()で定義しておく。
@SuppressWarnings("unchecked") @Override protected void createActions() { super.createActions(); ActionRegistry registry = getActionRegistry(); IAction action = new DirectEditAction(this); registry.registerAction(action); getSelectionActions().add(action.getId()); }
vainoloさんのサイトによるとKeyHandlerだけ定義すれば良さそうに見えるが、どこかでDirectEditActionをActionRegistryに登録しておく必要があるようだ。
また、図形の様に、選択したオブジェクトに対して直接編集を行いたい場合は、selectionActionsにActionのIDを登録しておく必要があるらしい。
(selectionActionsは、選択された図形に対するアクションを登録しておくもの。デフォルトではDeleteActionが登録されている。
図形を選択する度に、選択した図形がselectionActionsに登録されたアクションに設定される)