首页 > 代码库 > 6.17 实现大纲视图Outline,并且提供鹰眼功能(eagle eye)

6.17 实现大纲视图Outline,并且提供鹰眼功能(eagle eye)

1.创建outline

创建图形模型的 Outline 是通过 getAdapter 实现的,如果类型是 IContentOutlinePage,则返回一个大纲视图页面。因此要创建一个 MyContentOutlinePage 类。注意,这里的MyContentOutlinePage 类不是从 org.eclipse.ui.views.contentoutline.ContentOutlinePage 派生的,而是从 org.eclipse.gef.ui.parts.ContentOutlinePage 派生的。这样,MyContentOutlinePage类中使用的 TreeViewer 也是使用的 GEF 的 Editpart Viewer,所以可以保证大纲视图的内容和 Graphical Editor 的内容同步。

(1)在DiagramEditor中创建一个ContentOutlinePage的内部类,用于显示大纲视图:

 1 class EditorContentOutlinePage extends ContentOutlinePage { 2         private SashForm sash;//使用 SashForm 把 Outline 视图分为两部分:显示大纲和显示鹰眼
 4         private ScrollableThumbnail thumbnail; 5         private DisposeListener disposeListener; 6  7         public EditorContentOutlinePage() { 8             super(new TreeViewer()); 9             // 使用GEF的TreeViewer10         }11 12         @Override13         public void init(IPageSite pageSite) {14             // TODO Auto-generated method stub15             super.init(pageSite);16 17             ActionRegistry registry = getActionRegistry();18             IActionBars bars = pageSite.getActionBars();19 20             String id = ActionFactory.UNDO.getId();21             bars.setGlobalActionHandler(id, registry.getAction(id));22             id = ActionFactory.REDO.getId();23             bars.setGlobalActionHandler(id, registry.getAction(id));24             id = ActionFactory.DELETE.getId();25             bars.setGlobalActionHandler(id, registry.getAction(id));26             id = ActionFactory.SAVE.getId();27             bars.setGlobalActionHandler(id, registry.getAction(id));28             id = ActionFactory.SAVE_ALL.getId();29             bars.setGlobalActionHandler(id, registry.getAction(id));30 31             bars.updateActionBars();32         }33 34         @Override35         public void createControl(Composite parent) {36             // TODO Auto-generated method stub37 38             sash = new SashForm(parent, SWT.VERTICAL);39 40             getViewer().createControl(sash);41 42             getViewer().setEditDomain(getEditDomain());43             getViewer().setEditPartFactory(new TreePartFactory());44 45             getViewer().setContents(diagram);46             getSelectionSynchronizer().addViewer(getViewer());47 48             Canvas canvas = new Canvas(sash, SWT.BORDER);49             LightweightSystem lws = new LightweightSystem(canvas);50 51             thumbnail = new ScrollableThumbnail(52                     (Viewport) ((ScalableRootEditPart) getGraphicalViewer()53                             .getRootEditPart()).getFigure());54             thumbnail.setSource(((ScalableRootEditPart) getGraphicalViewer()55                     .getRootEditPart())56                     .getLayer(LayerConstants.PRINTABLE_LAYERS));57 58             lws.setContents(thumbnail);59 60             disposeListener = new DisposeListener() {61 62                 @Override63                 public void widgetDisposed(DisposeEvent e) {64                     // TODO Auto-generated method stub65                     if (thumbnail != null) {66                         thumbnail.deactivate();67                         thumbnail = null;68                     }69                 }70 71             };72 73             getGraphicalViewer().getControl().addDisposeListener(74                     disposeListener);75         }76 77         @Override78         public Control getControl() {79             // 当大纲视图是当前(active)视图时,返回聚焦的控件。80             return sash;81         }82 83         @Override84         public void dispose() {85             // TODO Auto-generated method stub86             getSelectionSynchronizer().removeViewer(getViewer());87 88             if (getGraphicalViewer().getControl() != null89                     && !getGraphicalViewer().getControl().isDisposed()) {90                 getGraphicalViewer().getControl().removeDisposeListener(91                         disposeListener);92 93             }94             super.dispose();95         }96 97     }

(2)在Perspective类中加入大纲视图

public class Perspective implements IPerspectiveFactory {    public void createInitialLayout(IPageLayout layout) {        final String editorArea=layout.getEditorArea();                IFolderLayout leftTopFolder=layout.createFolder("leftTopOutline", IPageLayout.LEFT, 0.35f, editorArea);        leftTopFolder.addView(TTCNView.VIEW_PROJECT);        leftTopFolder.addView(TTCNView.VIEW_EOUTLINE);                                IFolderLayout midBottomFolder=layout.createFolder("BottomProperty", IPageLayout.BOTTOM, 0.35f,editorArea );        midBottomFolder.addView(TTCNView.VIEW_DPROPERTY);        midBottomFolder.addView(TTCNView.VIEW_CORELANG);        midBottomFolder.addView(TTCNView.VIEW_TODOITEM);        midBottomFolder.addView(IPageLayout.ID_PROBLEM_VIEW);                        layout.addFastView(TTCNView.VIEW_DEFINE);                layout.setEditorAreaVisible(true);        }}

(3)让大纲视图显示当前GraphicalEditor中的图形信息。

 1 public class CustomTreeEditPart extends AbstractTreeEditPart implements 2         PropertyChangeListener { 3  4     @Override 5     public void propertyChange(PropertyChangeEvent arg0) { 6         // TODO Auto-generated method stub 7  8     } 9 10     @Override11     public void activate() {12         // TODO Auto-generated method stub13         super.activate();14         ((AbstractModel) getModel()).addPropertyChangeListener(this);15     }16 17     @Override18     public void deactivate() {19         // TODO Auto-generated method stub20         ((AbstractModel) getModel()).removePropertyChangeListener(this);21         super.deactivate();22     }23     24     25 }

(4)对应于某个类如contentsModel,创建相应的类ContentsTreeEditPart。

 1 public class ContainerTreeEditPart extends CustomTreeEditPart { 2  3     @Override 4     public void propertyChange(PropertyChangeEvent arg0) { 5         // TODO Auto-generated method stub 6         if (arg0.getPropertyName().equals( 7                 ModelStringConstant.P_CONTAINER_CHILDREN_ADD)) { 8             refreshChildren(); 9         } else if (arg0.getPropertyName().equals(10                 ModelStringConstant.P_CONTAINER_CHILDREN_REM)) {11             refreshChildren();12         }13     }14 15     @Override16     public List<Object> getModelChildren() {17         return ((ContainerElementModel) getModel()).getChildren();18 19     }20 21     @Override22     protected void refreshVisuals() {23         // TODO Auto-generated method stub24         ContainerElementModel model = (ContainerElementModel) getModel();25         setWidgetText(model.getLabel());26         setWidgetImage(TreeEditorPartDescriptorFactory.getContainerImage(model));27     }28 29 }

(5)对应于 DiagramModel 类,创建的相应类DiagramTreeEditPart 如下:

 1 public class DiagramTreeEditPart extends CustomTreeEditPart { 2  3     @Override 4     public void propertyChange(PropertyChangeEvent arg0) { 5         // TODO Auto-generated method stub 6  7         if (arg0.getPropertyName().equals( 8                 ModelStringConstant.P_DIAGRAM_PORTS_INC)) { 9             refreshChildren();10         } else if (arg0.getPropertyName().equals(11                 ModelStringConstant.P_DIAGRAM_PORTS_DEC)) {12             refreshChildren();13         }14     }15 16     @Override17     public List<Object> getModelChildren() {18         // TODO Auto-generated method stub19         List<Object> list = ((DiagramModel) getModel()).getChildren();20         List<Object> children = new ArrayList<Object>();21         Object model;22         for (int i = 0; i < list.size(); i++) {23             model = list.get(i);24             if (model instanceof PortElementModel) {25                 children.add(model);26             }27         }28 29         return children;30     }31 32 }

(6)和图形的绘制一样,我们同样要有一个工厂把这些 Tree Editpart 和相应的模型联系起来。

  1 public class TreeEditorPartDescriptorFactory不用继承自EditPartFactory么? {  2   3   4     public static Image getLiteralImage(AbstractModel model) {  5         if (model instanceof ActionModel) {  6             return IImageKey.getImage(IImageKey.KEY_ACTION);  7         }  8   9         else if (model instanceof ConditionModel) { 10             return IImageKey.getImage(IImageKey.KEY_CONDITION); 11         } 12         else if (model instanceof CreateModel) { 13             return IImageKey.getImage(IImageKey.KEY_CREATE); 14         } 15  16         else if (model instanceof DefaultModel) { 17             return IImageKey.getImage(IImageKey.KEY_DEFAULT); 18         } 19  20         else if (model instanceof EventCommentModel) { 21             return IImageKey.getImage(IImageKey.KEY_EVENTCOMMENT); 22         } 23  24         else if (model instanceof ExecuteModel) { 25             return IImageKey.getImage(IImageKey.KEY_EXECUTE); 26         } 27  28         else if (model instanceof LabelModel) { 29             return IImageKey.getImage(IImageKey.KEY_LABEL); 30         } 31          32         else if (model instanceof GotoModel) { 33             return IImageKey.getImage(IImageKey.KEY_GOTO); 34         } 35  36         else if (model instanceof ReferenceModel) { 37             return IImageKey.getImage(IImageKey.KEY_REFERENCE); 38         } 39  40         else if (model instanceof StartModel) { 41             return IImageKey.getImage(IImageKey.KEY_START); 42         } 43  44         else if (model instanceof TextModel) { 45             return IImageKey.getImage(IImageKey.KEY_TEXT); 46         } 47  48         return null; 49     } 50  51     public static Image getContainerImage(AbstractModel model) { 52         if (model instanceof ContainerElementModel) { 53             return IImageKey.getImage(IImageKey.KEY_INLINE); 54         } 55         return null; 56     } 57  58     public static Image getFigureImage(AbstractModel model) { 59         if (model instanceof StartTimerModel) { 60             return IImageKey.getImage(IImageKey.KEY_STARTTIMER); 61         } 62  63         else if (model instanceof StopComponentModel) { 64             return IImageKey.getImage(IImageKey.KEY_STOP); 65         } 66  67         else if (model instanceof StopTimerModel) { 68             return IImageKey.getImage(IImageKey.KEY_STOPTIMER); 69         } 70  71         else if (model instanceof TimeoutTimerModel) { 72             return IImageKey.getImage(IImageKey.KEY_TIMEOUTTIMER); 73         } 74          75         else if (model instanceof StartImplicitTimerModel) { 76             return IImageKey.getImage(IImageKey.KEY_STARTIMPLICITTIMER); 77         } 78          79         else if (model instanceof TimeoutImplicitTimerModel) { 80             return IImageKey.getImage(IImageKey.KEY_TIMEOUTIMPLICITTIMER); 81         } 82  83         else if (model instanceof StopModel) { 84             return IImageKey.getImage(IImageKey.KEY_STOP); 85         } 86  87         else if (model instanceof ReturnModel) { 88             return IImageKey.getImage(IImageKey.KEY_RETURN); 89         } 90          91         else if (model instanceof RepeatModel) { 92             return IImageKey.getImage(IImageKey.KEY_REPEAT); 93         } 94          95         else if (model instanceof SuspensionRegionModel) { 96             return IImageKey.getImage(IImageKey.KEY_SUSPENSIONREGION); 97         } 98          99         else if (model instanceof InstanceEndModel) {100             return IImageKey.getImage(IImageKey.KEY_INSTANCEEND);101         }102 103 104         return null;105     }106 107     public static Image getConnectionImage(AbstractModel model) {108         String id = ((ElementModel)model).getModelID();109         110         if (id.equals(ConstantResourceFactory.ID_FOUND_MODEL)111                 || id.equals(ConstantResourceFactory.ID_FOUNDCHECK_MODEL)){112             return IImageKey.getImage(IImageKey.KEY_FOUND);113         }114         115         else if(model instanceof MessageFromModel){116             return IImageKey.getImage(IImageKey.KEY_MESSAGEFROM);117         }118         119         else if(model instanceof MessageToModel){120             return IImageKey.getImage(IImageKey.KEY_MESSAGETO);121         }122         return null;123     }124 125     public static Image getPortImage(AbstractModel model) {126         if (model instanceof PortInstanceModel) {127             return IImageKey.getImage(IImageKey.KEY_PORT);128         }129         130         else if (model instanceof ComponentInstanceModel) {131             return IImageKey.getImage(IImageKey.KEY_COMPONENT);132         }133 134         return null;135     }136 137     138 }

而教程中的例子是这样的:

 1 public class TreeEditPartFactory implements EditPartFactory { 2         public EditPart createEditPart(EditPart context, Object model) { 3             EditPart part=null; 4             if(model instanceof ContentsModel) 5                    part=new ContentsTreeEditPart(); 6             else if(model instanceof HelloModel) 7                    part=new HelloTreeEditPart(); 8             if(part!=null) 9                    part.setModel(model);10             return part;11 }12 }

(7)我们再回到 DiagramEditor 中把图形绘制在大纲视图中,过程和绘制图形差不多。

 1 class EditorContentOutlinePage extends ContentOutlinePage { 2         private SashForm sash; 3  4         private ScrollableThumbnail thumbnail; 5         private DisposeListener disposeListener; 6  7         public EditorContentOutlinePage() { 8             super(new TreeViewer()); 9             // TODO Auto-generated constructor stub10         }11 12         @Override13         public void init(IPageSite pageSite) {14             // TODO Auto-generated method stub15             super.init(pageSite);16 17             ActionRegistry registry = getActionRegistry();18             IActionBars bars = pageSite.getActionBars();19 20             String id = ActionFactory.UNDO.getId();21             bars.setGlobalActionHandler(id, registry.getAction(id));22             id = ActionFactory.REDO.getId();23             bars.setGlobalActionHandler(id, registry.getAction(id));24             id = ActionFactory.DELETE.getId();25             bars.setGlobalActionHandler(id, registry.getAction(id));26             id = ActionFactory.SAVE.getId();27             bars.setGlobalActionHandler(id, registry.getAction(id));28             id = ActionFactory.SAVE_ALL.getId();29             bars.setGlobalActionHandler(id, registry.getAction(id));30 31             bars.updateActionBars();32         }33 34         @Override35         public void createControl(Composite parent) {36             // TODO Auto-generated method stub37 38             sash = new SashForm(parent, SWT.VERTICAL);39 40             getViewer().createControl(sash);41 42             getViewer().setEditDomain(getEditDomain());43             getViewer().setEditPartFactory(new TreePartFactory());44 45             getViewer().setContents(diagram);46             getSelectionSynchronizer().addViewer(getViewer());47 48             Canvas canvas = new Canvas(sash, SWT.BORDER);49             LightweightSystem lws = new LightweightSystem(canvas);50 51             thumbnail = new ScrollableThumbnail(52                     (Viewport) ((ScalableRootEditPart) getGraphicalViewer()53                             .getRootEditPart()).getFigure());54             thumbnail.setSource(((ScalableRootEditPart) getGraphicalViewer()55                     .getRootEditPart())56                     .getLayer(LayerConstants.PRINTABLE_LAYERS));57 58             lws.setContents(thumbnail);59 60             disposeListener = new DisposeListener() {61 62                 @Override63                 public void widgetDisposed(DisposeEvent e) {64                     // TODO Auto-generated method stub65                     if (thumbnail != null) {66                         thumbnail.deactivate();67                         thumbnail = null;68                     }69                 }70 71             };72 73             getGraphicalViewer().getControl().addDisposeListener(74                     disposeListener);75         }76 77         @Override78         public Control getControl() {79             // TODO Auto-generated method stub80             return sash;81         }