GEF (Graphical Editing Framework) 是 Eclipse 圖形化編輯器的核心框架,掌握 EditPolicy、EditPart 協作機制是構建專業建模工具的關鍵。本文匯總六大高頻實戰技巧,附代碼模式可直接應用。
菜單項 (如「刪除」) 是否顯示,取決於對應 EditPart 是否安裝了相關 EditPolicy。
// TreeEditPart 中
protected void createEditPolicies() {
super.createEditPolicies();
// 安裝 ComponentEditPolicy 才會在右鍵菜單顯示「刪除」
installEditPolicy(EditPolicy.COMPONENT_ROLE, new ComponentEditPolicy());
}
原則:功能啟用 = 安裝對應 Policy,而非硬編碼菜單可見性。
覆寫 LayoutEditPolicy.createChangeConstraintCommand 返回 null 即可阻止容器被選中 (無法拖拽、調整大小)。
// EditPart
public class BoardPart extends ContainerPart {
protected void createEditPolicies() {
super.createEditPolicies();
installEditPolicy(EditPolicy.LAYOUT_ROLE, new BoardLayoutEditPolicy());
}
}
// Policy
public class BoardLayoutEditPolicy extends XYLayoutEditPolicy {
@Override
protected Command createChangeConstraintCommand(EditPart child, Object constraint) {
return null; // 禁止任何佈局變更命令 → 容器不可選
}
}
批量驗證後,程式化選中錯誤元素並聚焦最後一個。
private void selectErrors(ArrayList<ElementView> errorEls) {
EditPartViewer viewer = getGraphicalViewer();
viewer.deselectAll();
EditPart last = null;
for (ElementView el : errorEls) {
EditPart ep = (EditPart) viewer.getEditPartRegistry().get(el);
viewer.appendSelection(ep);
last = ep;
}
if (last != null) viewer.reveal(last); // 滾動到可視區
}
覆寫 dispose() 無效,需實現 ISaveablePart2 介面。
@Override
public int promptToSaveOnClose() {
if (isDirty && !UIHelper.confirm("關閉提示", getTitle() + " 尚未保存,確定退出?")) {
return ISaveablePart2.CANCEL; // 取消關閉
}
return ISaveablePart2.NO; // 允許關閉 (NO 表示無需保存或用戶確認放棄)
}
兩步配合:
createFigure() 設置 fig.setOpaque(true) (接收鼠標事件)。getDragTracker() 返回 MarqueeDragTracker。protected IFigure createFigure() {
Figure fig = new Figure();
fig.setOpaque(true); // 關鍵:不透明才能接收拖拽事件
return fig;
}
public DragTracker getDragTracker(Request request) {
if (request instanceof SelectionRequest &&
((SelectionRequest) request).getLastButtonPressed() == 3) { // 右鍵
return new DeselectAllTracker(this);
}
return new MarqueeDragTracker(); // 左鍵拖拽 → 橡皮筋選擇框
}
利用命令堆棧執行空命令即可標記髒狀態。
public void commit() {
getViewer().getEditDomain().getCommandStack().execute(new Command() {});
}
適用場景:連線拖拽、屬性面板修改等無法直接調用 editor.setDirty(true) 的情況。
GEF 核心哲學:「Policy 封裝行為,Part 組合 Policy」。靈活運用
EditPolicy組合 (Component, Layout, Connection, Selection 等) 即可實現豐富交互邏輯,避免在 EditPart 中硬編碼行為。