Constructing a GEF application is usually divided into such steps: design model, design EditPart and Figure, design EditPolicy and Command, where EditPart is the most important part, because it is inevitable to use the editpolicy, while the latter It also involves Command.
Now let's look at an example, its function is very simple, users can add the node (Node) and node on the canvas, directly edit the name of the node and change the position of the node, the user can undo / re-do anything, There is a tree-like view and a property page. Click here to download, this is an eclipse project package file, running Run-Time Workbench after Eclipse, and newly built a file that extension "gefpractice" will open this editor.
Figure 1 Usage of Practice Editor
You can refer to the code to see the next content, let us start from the model. The model is designed according to the application needs, so our model includes these objects that represent the Diagram, representative node, and representative connections that represent the Node and representative connections. We know that the model is to be responsible for notifying your changes to EditPart. In order to separate this function, we use the abstract class named Element to implement the notification mechanism, and then let other model classes inherit it. The ELEMENT class includes a member variable of a PropertyChangeSupport type and provides addPropertyChangeListener (), RemovePropertyChangeListener (), and Firexxx () methods to register the listener and notification listener model change events. In GEF, the model's listener is Editpart, and we will register it as a listener into the model as a listener in the an active () method of Editpart. So, there are four classes that make up our model part.
In the previous post, most GEF applications are implemented as Editor, this example is no exception, the corresponding Editor is called PracticeEditor. This editor inherits the GraphicaleditorWithPalette class, indicating that it is a graphic editor with a palette. The most important way is ConfigureGraphicalViewer () and InitializeGraphicalViewer (), which are used to customize and initialize EditPartViewer (see the previous post), simply check the GEF code. You will find that in the Graphicaleditor class. Calling these two methods, just inserting a hookgraphicalViewer () method, its role is synchronized to select and put EditPartViewer as a SelectionProvider to register to the Site (Site is the concept of Workbench, please check the Eclipse Help). Therefore, the initialization operation with the selection should be completed in the former, otherwise it is done in the latter. In the example, in these two methods we configure RooteditPart, used to create an editpart's editpartFactory, Contents, Diagram object, and add drag and drop support, drag the target is the current editpartviewer, then see the drag source is a palette .
This Editor is a palette, so what tools are to tell Gef in our palette, which is implemented by overriding the getPaletterOot () method. In this method, we use your own tool class PaletteFactory to construct a PaletterOot object and return. There are three tools that need to be selected: Select Tools, Node Tools and Connections. In GEF, there can be a drawer (PalettedRawer) to classify various tools, each tool is a toolntry, select Tool (ConnectionToolEntry and Connection Tool (ConnectionCreentry "is a predefined tool Two, so you can use it directly. For node tools, you want to use CombinedTemplatencentry, and pass the node type as one of the parameters to it, the code for creating the node tool is as follows. Toolentry Tool
=
New
CombinedTemplateCreationntry
"
Node
"
,
"
Create a new node
"
Node.class,
New
SimpleFactory (node.class),
NULL
,
NULL
);
In the new version 3.0, GEF also provides an editor GRAPHICALEDITORWITHFLYOUTPALETTE that automatically hides the palette, and more options for the appearance of the palette can be selected. How to use it later.
The initialization operation of the palette should be done in InitializePaletteViewer (). The main task is to add drag source support for the editpartViewer in which the palette is located. We have added drag the target event to the eDitpartViewer in which the canvas is located, so now You can achieve a complete drag and drop operation. Here is a slight explanation of the implementation principle of drag and drop to create a node tool for the node object as an example. It is a CombinedTemplateCreation throughntry in the palette. When you create this PaletteEntry (see the code above) We specify the object to correspond to a Node .CLASS, so when the user drags this tool from the palette, there is a TemplateTransfer single case object to record node.class (called template), when the user releases the mouse on the canvas, dragging and drop Events are triggered, and the DiagramTLATRANSFERDROPTARGETLISTENER object that will be registered by the canvas is to process the template object (now node.class). In the example, our processing method is to use a object called ElementFactory to create a corresponding type of corresponding type according to this template.
We have established models and Editor for implementing views because the changes in the model are modified directly by the Command object, so let's see what kind of Command will be seen first. It can be seen from demand, we have an increase / delete node to the model's operation, modify the node name, change the node location, and add / delete connections, so there is CreatenodeCommand, DELETENODECMMAND, RENAMENODECOMMAND, MOVENODECOMMAND, CreateConnectionCommand, and DeleteConnectionCommand These objects, they all put Category in the Commands package. The most important thing in a Command object is of course the execute () method, that is, the method of executing the command. In addition, since the undo / redo function is to be revoked, there are undo () and redo () methods in the Command object, while in the Command object, there must be a member variable in the Command object to be responsible for reserving the relevant state when executing the command, such as RenameNodeCommand. There are two variables in OldName and NewName, so that the undo () and redo () methods can be implemented correctly, remember, each executed Command object instance is saved in the CommandStack of EditDomain. EDITPOLICY in the example is placed in a policies package, associated with graphic (graphicaleditpart subclass) has DiagramLayouteditPolicy, NodeDirecteditPolicy and NodeGraphicalnodeEditPolicy, and two are independent of the graphic. It can be seen that in two types of two classes (ConnectionEditPolicy and NodeEditPolic), we only cover the createDeleteCommand () method, which is used to create a Command object responsible for "Delete" and return, to make this method. It seems that Create and Delete are different objects in the seemingly contradictory name.
With Command and EditPolicy, you can now take a look at the EditPart section. Each model object corresponds to an editpart, so our three model objects (Element is not counted) corresponding to Diagrampart, ConnectionPart, and NodePart. For EDITPARs containing sub-elements, you must override a list of sub-objects, such as the method of DiagramPart, which is included in Diagram object.
Each editpart has both Active () and deACTIVE (). Generally, we register your listener in the former (because the PropertyChangeListener interface is implemented, the EditPart itself is the listener) to the model object, and the listener will be from the lasers Remove it in the list. In the PropertyChange () method that triggers the listener event, it is generally based on "event name" to determine how to use the way to refresh the view, for example for NodePart, if it is a node itself, the refreshvisuals () method is called, if it is It calls refreshTargetConnections () or refreshsourceConnections () or RefreshSourceConnections (). The name of the event used here is our own, in the example, such as node.prop_name represents the name property of the node, node.prop_location represents the location attribute of the node, and so on.
Editpart (exactly what is AbstractGraphicaleditpart) Another important way to implement is CreateFigure (), which should return the model representation representation in the view, is an iFigure type object. These graphics are usually placed in the frame, only Nodefigure a custom graphics, and the Diagram object corresponds to the graphic of the GEF comes with FreeformLayer, which is a layer graphic that can be extended in the northwest direction of southeast. And the connection corresponding to the GEF comes with the PolylineConnection. This graphic default is a straight line used to connect the other two graphics. In the example, we will display an arrow with the setTargetDecoration () method. Finally, you have to increase the appropriate editpolicy for editpart, which is implemented by overwriting EditPart's CreateEtPolicies () method, each of which is "Install" to EditPart, and each of the strings used to represent the role (Role). For editparts with children with children in the model, an editpolicy.Layout_Role role will generally install EditPolicy (see below), the latter is more LayouteditPolicy subclass; for the connection type EditPart, you generally install the editpolicy.connection_endpoints_role role EditPolicy, the latter is more connectionndpointeditpolicy or its subclasses, and so on.