GEF七天之第五天
今天写两篇,后天去北京,所以近期可能很少来园子里了,呵呵!!!
之前我们以一个小DEMO的形式介绍了GEF的model,Controller的实现,今天我们就来介绍gef中MVC的最后一个----view,即视图.由于我们这个DEMO是一个eclipse plug-in程序.所以他视图部分用的知识大部分是eclipse plug-in的相关知识(涉及的eclipse plug-in的相关知识我们将不作说明).
通常我们用eclipse 的Editor作为主要视图,我们必须扩展org.eclipse.ui.editors这个扩展点,这个可以在plugin.xm 定义,定义后的文件如下:
<point="org.eclipse.ui.editors">
<editor
class="hya.gef.demo.shapes.ui.ShapesEditor"
default="true"
extensions="Demo"
icon="shapes.gif"
contributorClass="hya.gef.demo.shapes.ui.ShapesEditorActionBarContributor"
id="hya.gef.demo.shapes"
name="GEF Demo"/>
</extension>
其中,class属性指定我们编辑器对应的类;
Extensions属性指定编辑器打开文件的扩展名为workflow;
Default属性指出该编辑器是扩展名为workflow文件的默认打开方式;
Icon为扩展名为workflow的文件和编辑器的图标;
Id属性为编辑器的唯一标识
Name为编辑器显示的名称
然后我们定义编辑器的主界面类ShapesEditor,他继承GraphicalEditorWithFlyoutPalette,GraphicalEditorWithFlyoutPalette是带有面板的图形化编辑器.我们先来看看ShapesEditor的代码
ackage hya.gef.demo.shapes.ui;
import hya.gef.demo.shapes.Activator;
import hya.gef.demo.shapes.models.DiagramModel;
import hya.gef.demo.shapes.models.RadioModel;
import hya.gef.demo.shapes.models.RectangularModel;
import hya.gef.demo.shapes.models.TriangleModel;
import hya.gef.demo.shapes.parts.ShapesEditPartFactory;
import hya.gef.demo.shapes.parts.tree.ShapesTreeEditPartFactory;
import java.util.EventObject;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.gef.ContextMenuProvider;
import org.eclipse.gef.DefaultEditDomain;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.dnd.TemplateTransferDragSourceListener;
import org.eclipse.gef.dnd.TemplateTransferDropTargetListener;
import org.eclipse.gef.editparts.ScalableFreeformRootEditPart;
import org.eclipse.gef.palette.CombinedTemplateCreationEntry;
import org.eclipse.gef.palette.ConnectionCreationToolEntry;
import org.eclipse.gef.palette.MarqueeToolEntry;
import org.eclipse.gef.palette.PaletteContainer;
import org.eclipse.gef.palette.PaletteDrawer;
import org.eclipse.gef.palette.PaletteGroup;
import org.eclipse.gef.palette.PaletteRoot;
import org.eclipse.gef.palette.PaletteSeparator;
import org.eclipse.gef.palette.PanningSelectionToolEntry;
import org.eclipse.gef.palette.ToolEntry;
import org.eclipse.gef.requests.CreationFactory;
import org.eclipse.gef.requests.SimpleFactory;
import org.eclipse.gef.ui.actions.ActionRegistry;
import org.eclipse.gef.ui.palette.PaletteViewer;
import org.eclipse.gef.ui.palette.PaletteViewerProvider;
import org.eclipse.gef.ui.parts.ContentOutlinePage;
import org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette;
import org.eclipse.gef.ui.parts.TreeViewer;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.TransferDropTargetListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
public class ShapesEditor extends GraphicalEditorWithFlyoutPalette {
private static PaletteRoot PALETTE_MODEL;
// 顶层模型类
private DiagramModel diagram;
public ShapesEditor() {
setEditDomain(new DefaultEditDomain(this));
}
/**
* @Override 创建创建调色板
*/
protected PaletteRoot getPaletteRoot() {
if (PALETTE_MODEL == null)
PALETTE_MODEL = createPalette();
return PALETTE_MODEL;
}
// 在编辑器的GraphicalViewer加监听
protected void initializeGraphicalViewer() {
super.initializeGraphicalViewer();
GraphicalViewer viewer = getGraphicalViewer();
viewer.setContents(getModel());
// 增加监听,用于监听用户动作
viewer.addDropTargetListener(createTransferDropTargetListener());
}
// 建立监听
private TransferDropTargetListener createTransferDropTargetListener() {
return new TemplateTransferDropTargetListener(getGraphicalViewer()) {
protected CreationFactory getFactory(Object template) {
return new SimpleFactory((Class) template);
}
};
}
// 给面板增加监听
protected PaletteViewerProvider createPaletteViewerProvider() {
return new PaletteViewerProvider(getEditDomain()) {
protected void configurePaletteViewer(PaletteViewer viewer) {
super.configurePaletteViewer(viewer);
viewer.addDragSourceListener(new TemplateTransferDragSourceListener(
viewer));
}
};
}
public void commandStackChanged(EventObject event) {
firePropertyChange(IEditorPart.PROP_DIRTY);
super.commandStackChanged(event);
}
@Override
public void doSave(IProgressMonitor arg0) {
// TODO Auto-generated method stub
}
public DiagramModel getModel() {
return diagram;
}
protected void configureGraphicalViewer() {
super.configureGraphicalViewer();
GraphicalViewer viewer = getGraphicalViewer();
viewer.setEditPartFactory(new ShapesEditPartFactory());
viewer.setRootEditPart(new ScalableFreeformRootEditPart());
// 添加右键菜单
ContextMenuProvider cmProvider = new EditorContextMenuProvider(viewer,
getActionRegistry());
viewer.setContextMenu(cmProvider);
getSite().registerContextMenu(cmProvider, viewer);
}
protected void setInput(IEditorInput input) {
super.setInput(input);
diagram = new DiagramModel();
}
public Object getAdapter(Class type) {
if (type == IContentOutlinePage.class)
return new OutlinePage(new TreeViewer());
return super.getAdapter(type);
}
/***************************************************************************
* 提供建立调色板(及工具箱)的方法
**************************************************************************/
// 建立工具箱
private PaletteRoot createPalette() {
PaletteRoot palette = new PaletteRoot();
palette.add(createToolsGroup(palette));
palette.add(createShapesDrawer());
return palette;
}
// 建立图形工具
private PaletteContainer createShapesDrawer() {
PaletteDrawer componentsDrawer = new PaletteDrawer("Shapes");
CombinedTemplateCreationEntry component = new CombinedTemplateCreationEntry(
"圆形", "Create an elliptical shape", RadioModel.class,
new SimpleFactory(RadioModel.class), ImageDescriptor
.createFromFile(Activator.class, "icons/redio.gif"),
ImageDescriptor.createFromFile(Activator.class,
"icons/redio2.gif"));
componentsDrawer.add(component);
component = new CombinedTemplateCreationEntry("矩形",
"Create a rectangular shape", RectangularModel.class,
new SimpleFactory(RectangularModel.class),
ImageDescriptor.createFromFile(Activator.class,
"icons/rectangle.gif"), ImageDescriptor.createFromFile(
Activator.class, "icons/rectangle2.gif"));
componentsDrawer.add(component);
component = new CombinedTemplateCreationEntry("三角形",
"Create a Triangle shape", TriangleModel.class,
new SimpleFactory(TriangleModel.class), ImageDescriptor
.createFromFile(Activator.class, "icons/triangle.gif"),
ImageDescriptor.createFromFile(Activator.class,
"icons/triangle.gif"));
componentsDrawer.add(component);
return componentsDrawer;
}
private static PaletteContainer createToolsGroup(PaletteRoot palette) {
PaletteGroup toolGroup = new PaletteGroup("Tools");
ToolEntry tool = new PanningSelectionToolEntry();
toolGroup.add(tool);
palette.setDefaultEntry(tool);
toolGroup.add(new MarqueeToolEntry());
toolGroup.add(new PaletteSeparator());
tool = new ConnectionCreationToolEntry("连线", "连接两个图形", null,
ImageDescriptor.createFromFile(Activator.class,
"icons/connection.gif"), ImageDescriptor
.createFromFile(Activator.class,
"icons/connection2.gif"));
toolGroup.add(tool);
return toolGroup;
}
/***************************************************************************
* 建立大纲视图对应类,以内部类的形式
**************************************************************************/
public class OutlinePage extends ContentOutlinePage {
/**
* 为editor建立一个新的大纲 使用树结构显示大纲
*/
public OutlinePage(EditPartViewer viewer) {
super(viewer);
}
public void createControl(Composite parent) {
// create outline viewer page
getViewer().createControl(parent);
// configure outline viewer
getViewer().setEditDomain(getEditDomain());
getViewer().setEditPartFactory(new ShapesTreeEditPartFactory());
// 让大纲视图和编辑器的GraphicalViewer视图同步选择
getSelectionSynchronizer().addViewer(getViewer());
// 设置大纲视图的根内容为DiagramModel
getViewer().setContents(getModel());
}
public void dispose() {
// unhook outline viewer
getSelectionSynchronizer().removeViewer(getViewer());
// dispose
super.dispose();
}
// 返回我们的outline成员变量,也就是指定让这个控件出现在大纲视图中
public Control getControl() {
return getViewer().getControl();
}
/**
* 绑定UNDO/REDO/DELETE等命令到Eclipse主窗口 方法必须
* 否则将否则当大纲视图处于活动状态时,主工具条上的这些命令就会变为不可用状态
*
*/
public void init(IPageSite pageSite) {
super.init(pageSite);
ActionRegistry registry = getActionRegistry();
IActionBars bars = pageSite.getActionBars();
String id = ActionFactory.UNDO.getId();
bars.setGlobalActionHandler(id, registry.getAction(id));
id = ActionFactory.REDO.getId();
bars.setGlobalActionHandler(id, registry.getAction(id));
id = ActionFactory.DELETE.getId();
bars.setGlobalActionHandler(id, registry.getAction(id));
}
}
}
在这个类getPaletteRoot()方法中,创建了面板。
在setInput方法中,定义了一个DiagramModel对象;
在构造函数中setEditDomain(new DefaultEditDomain(this));就是给当前编辑器设置一个默认编辑域,这个域跟命令堆栈有关。
initializeGraphicalViewer()方法,把GraphicalViewer的内容设计为DiagramModel,说明后编辑的是一个DiagramModel,并且添加了监听以监听用户的请求(用createTransferDropTargetListener方法建立监听)
在configureGraphicalViewer(),注册控制器工厂,并通过ContextMenuProvider来创建右肩菜单。
getAdapter(Class type)在此方法中创建大纲视图,大纲视图的相关创建我们以后再说明.
建立大纲和建立面板以后我们会做详细说明
这是视图界面截图: