Up to this point, GEF (Graphical Editing Framework) has referred to the Eclipse GEF project, which is made up of the Draw2D, Zest, and GEF plugins. Naturally, this plug-in name is the source of the Eclipse project name and is what most developers think of when they see GEF referenced. The remaining chapters in the book use GEF to refer to the org.eclipse.gef
plug-in rather than the Eclipse project.
Both Zest (see Chapter 9 on page 129) and GEF (the org.eclipse.gef
plug-in) are built on top of Draw2D (see Chapter 3 on page 21), but Zest is a simpler framework. With Zest, the model must fit into one of the four content providers (see Section 9.3 on page 132), and because of this, there is an underlying assumption that the model is a graph. Zest requires fewer lines of code than are required to construct the same program using GEF. If Zest has all the functionality required for your product, then there is no reason for you to use GEF.
In contrast, GEF provides more customization and flexibility for both rendering a model and interacting with a model. GEF enables developers to design a visual representation of each model component using Draw2D figures (see Section 4.2 on page 29). GEF can be used to visually display graphs, text, flow diagrams, WYSIWYG GUI editors, SWT trees, or any other kind of graphics provided by Draw2D. Developers can easily add editing rules, listeners, and business logic to a GEF diagram. Because GEF provides so much functionality, the number of concepts and definitions can be overwhelming at first. This chapter aims to take a step back from source code to give a high-level overview of how a GEF application is architected.
Like other frameworks that display graphical information, GEF is designed using the Model-View-Controller (MVC) architecture. MVC architectures have three components: the model, view, and controller (see Figure 10–1). The model is the data portion of the architecture, containing business logic and information that persists across application sessions. Listeners attached to model objects are notified when state changes occur. The view is responsible for drawing the diagram and passing user events to any attached listeners. The control binds model to view, updating the view when the model changes, and updating the model based upon user events from the view.
Figure 10–1. The elements of a Model-View-Controller (MVC) architecture.
GEF can display many different types of models from Plain Old Java Object (POJO) models to Eclipse Modeling Framework (EMF)-based models. However, missing functionality in a model will lead to missed opportunities when it comes to functionality in your GEF-based product. Before starting development of your first GEF interface, ensure that your model follows these rules:
• Ensure that all data editable by the user is contained in the model. No user-editable data should be in the controller or view.
• The model should be persistable so that changes made by the user will be preserved across application sessions.
• Only domain data and business logic should be contained within the model. Set up a separate model project that does not have any references to GEF so that no controller or view code can creep into the model code base.
• The model should broadcast all state changes via listeners so that the view can be updated without the model having any direct knowledge of the controller or view.
GEF supports representing a model as nodes in a graph or items in a tree. In a graph, the view is a collection of Draw2D figures (see Chapter 4 on page 27) displayed in an SWT canvas. Alternatively, GEF can represent model elements as SWT tree items displayed in an SWT tree. Many applications have both a GEF Editor displaying Draw2D figures with an outline view to one side constructed using a GEF tree viewer. Figures and tree items should not have direct knowledge or references to any model or controller objects.
EditParts
bind model elements to GEF figures. Each model object has a corresponding EditPart
(see Section 11.3 on page 188), which is responsible for several things:
• Constructing a figure to represent the model object
• Listening for model changes and updating the view accordingly
• Providing a collection of child model objects to be displayed
Similar to Draw2D, which provides many different types of figures used in building complex views, GEF provides various EditPart
classes used to observe and update model objects and manage the associated figures.
At the core of every GEF view is an instance of EditPartViewer
, which orchestrates the interaction of the model, the edit parts, and the view (Figure 10–2). There are four main elements of each EditPartViewer
:
• setContents(
...)
—call this method to set the top-level model element for the model being displayed (see Section 10.2.3 on page 180 and Section 11.2.2 on page 187).
• EditPartFactory
—the factory used to construct all EditParts
except for the root edit part (see Section 10.2.1 on page 179 and Section 11.3 on page 188).
• RootEditPart
—the top level edit part for the graph or tree that directly or indirectly contains all other edit parts (see Section 10.2.2 on page 179 and Section 11.2 on page 186).
• EditDomain
—responsible for directing user input and managing command stack and tool palette (see Section 10.2.4 on page 180).
Figure 10–2. EditPartViewer components.
As mentioned earlier, GEF supports representing a model as nodes in a graph or items in a tree. The EditPartViewer
to use depends upon how you want to visually represent your model:
• GraphicalViewerImpl
—used to display model elements as figures in a graph.
• ScrollingGraphicalViewer
—used to display model elements as figures in a scrollable graph (see Section 11.2 on page 186).
• TreeViewer
—used to represent model elements as items in a tree. This is the org.eclipse.gef.ui.parts.TreeViewer
class and not the JFace TreeViewer
.
When the EditPartViewer
needs to display a model element but does not have an EditPart
associated with that model element already cached, it calls the EditPartFactory
to construct a new EditPart
for that model element (see Section 11.3 on page 188). All EditParts
except for the RootEditPart
are instantiated using this technique. Each EditPart
is then called to construct the figures or tree item used to represent its associated model object in the view (see Section 11.3.2 on page 189).
The RootEditPart
is the top level EditPart
for the graph and directly or indirectly contains all other EditParts
in the graph. TreeViewer
provides its own RootEditPart
, but there are several different RootEditParts
that can be used with GraphicalViewerImpl
depending the desired graph:
• SimpleRootEditPart
—constructs a simple non-scrolling layered view using StackLayout
(see Section 5.3.5 on page 61).
• FreeformGraphicalRootEditPart
—constructs a layered view using FreeformViewport
for use with a ScrollingGraphicalViewport
(see Section 11.2 on page 186) for displaying FreeformFigures
(see Section 7.2.3 on page 98).
• ScalableFreeformRootEditPart
—constructs a layered view similar to FreeformGraphicalRootEditPart
, but that can be zoomed (see Section 11.2 on page 186).
Call EditPartViewer
’s setContents(
...)
method to set the top-level model element displayed by the viewer (see Section 11.2.2 on page 187). This method calls the EditPartFactory
to construct an EditPart
for the top-level model. This does not quite follow Java’s typical get/set method paradigm because to retrieve the top-level model element from an EditPartViewer
, you must first call getContents()
to get the top-level EditPart
, and then call getModel()
to retrieve the top-level model element from the top-level EditPart
.
EditPart topLevelEditPart = myEditPartViewer.getContent();
Object topLevelModelElement = topLevelEditPart.getModel();
The EditDomain
is responsible for directing all user input and managing both the command stack (see Section 13.2.1 on page 227) and the tools palette (see Section 13.5.3 on page 251). The EditDomain
class provides for the general case, and the DefaultEditDomain
subclass is for use with an Eclipse IEditorPart
(see Section 12.2 on page 201). Typically there is one EditDomain
for each EditPartViewer
, but the architecture allows for the more general case of having one EditDomain
associated with multiple EditPartViewers
.
The GEF architecture provides an extendable framework to associate user actions with changes in the model and view (Figure 10–3). Tools
and Actions
convert low-level user input into higher-level Requests
. EditPolicies
attached to EditParts
translate these higher-level Requests
into Commands
that encapsulate changes to the model. These Commands
are executed and placed on the command stack so that the user may choose to undo the operation at a later time.
Figure 10–3. User actions and the GEF architecture.
Typically, a GEF Editor has an associated palette of tools (see Section 13.5.1 on page 250). When the user selects a tool, it becomes the active tool for that editor’s EditDomain
. When the user interacts with the canvas, low-level user input passes from the EditPartViewer
and EditDomain
to the active tool. This tool is then responsible for turning the lower-level action into a request (see Section 10.3.3 on page 182). Many different types of tools are used to facilitate user interaction with the displayed information, such as
• SelectionTool
—translates mouse click and drag events into background selection, figure selection, and handle manipulation requests (see Section 13.3.2 on page 235)
• CreationTool
—translates mouse click and drag events into requests to create new model elements (see Section 13.5.3 on page 251)
• DragEditPartsTracker
—translates mouse drag events into requests to move figures to a new location (see Section 13.3.2 on page 235)
• ConnectionDragCreationTool
—translates mouse click and drag events into connection creation requests (see Section 13.3.6.3 on page 244)
Many user interactions such as saving, printing, deleting, and undoing aren’t included on the GEF palette. Users expect these operations to be placed in their standard Eclipse locations, such as menus or toolbars. Each of these actions is a subclass of the JFace Action
class. GEF provides several action classes, such as
• AlignmentAction
—aligns the selected figures
• DeleteAction
—removes the currently selected elements from the model
• PrintAction
—prints the current figure canvas
• SelectAllAction
—selects all figures in the canvas
• UndoAction
—pops the top command off the command stack and performs the inverse operation to change the model to a prior state
Similarly to tools, some of these actions, such as AlignmentAction
and DeleteAction
, modify the application state and thus translate user input into requests and commands. Other actions, such as PrintAction
, do not change the application state and thus do not create requests or commands.
Requests
are higher-level user operations containing all the information needed to make an application state change. Requests
can be changes to the underlying model content, such as a creation or direct edit request, or requests may change visual characteristics of the graph, such as selection requests (see Section 12.3.2 on page 209).
Multiple EditPolicies
can be associated with each EditPart
(see Section 12.3.2 on page 209) to translate requests into commands. If multiple EditPolicies
return a command for the same request, then those commands are chained together and performed or reversed as a unit.
Commands
returned by EditPolicy
methods contain the information required to make some application state change (see Section 13.3.1 on page 233). Each command knows if the operation can be safely executed given the current model state and can undo and redo that operation. It is good practice to implement commands as small operations and compose more complex commands by chaining together many simple commands. Finally, it is important to note that although GEF commands and Eclipse commands are related concepts, they are implemented as completely separate class hierarchies.
GEF provides a rich framework for displaying models as collections of Draw2D figures. Users interact with the figures using tools and actions, which translate user input into requests. EditParts
translate these requests into commands that can be executed, undone, and redone.
Chapter source (see Section 2.6 on page 20).
Clayberg, Eric, and Dan Rubel, Eclipse Plug-ins, Third Edition. Addison-Wesley, Boston, 2009.
GEF and Draw2D Plug-in Developer Guide, Eclipse Documentation (see http://help.eclipse.org/).
Moore, Bill, David Dean, Anna Gerber, Gunnar Wagenknecht, and Philippe Vanderheyden, Eclipse Development Using the Graphical Editing Framework and the Eclipse Modeling Framework. IBM Redbooks, February 2004.
Majewski, Bo, A Shape Diagram Editor, Eclipse Corner Articles, 2004 (see www.eclipse.org/articles/).
Steinberg, Dave, Frank Budinsky, Marcelo Paternostro, and Ed Merks, EMF: Eclipse Modeling Framework. Addison-Wesley, Boston, 2009.
18.117.186.46