网页
综合
更新时间 2026-11-13 17:51:09
Building a Database Schema Diagram Editor with GEF
自动蜘蛛
www.eclipse.org
正文约 6000 字
Phil Zoio, Realsolve Solutions Ltd. September 27, 2004
Having graphical editing capabilities can be a real asset, if not an essential feature, for many tools and applications. Examples are not hard to think of: UML tools, GUI builders, in fact, any application which comprises a dynamic model which can be visualized. With GEF, Eclipse developers have at their disposal a framework which can really simplify development of graphical editors. This article uses a simple but non-trivial example to show how a GEF application works - and what you need to do to get it to perform its little miracles.
The screenshot below shows what our example editor looks like. The edit area uses a "flyout" palette which contains some very basic entries and can be minimized to increase the editable screen area. On the right side is a scrollable graphical viewer containing the tables and their relationships.
Download and unzip the example plug-in schemaeditor.zip into your eclipse/ directory, then create a new diagram by launching the wizard from the File menu: File -> New -> Example ... -> GEF (Graphical Editing Framework) -> Schema Diagram Editor.
At the heart of GEF is the Model-View-Controller pattern, discussed in Randy Hudson's introductory tutorial How to Get Started with the GEF, and also providing a focus for much of this article.
The starting point for any GEF application is the model. This is what needs to be displayed, edited and persisted. Our somewhat oversimplified model contains the following classes:
Of course, we need to decide what we want our editor to be able to do with the model. Here, we want to be able to:
The display component in both GEF and draw2d is built around the draw2d IFigure interface. Figures in draw2d are lightweight objects which can be nested to create a complex graphical representation. The view is created by rendering and laying out the set of figures which reflect the model. In a typical GEF application, you would normally create a set of customized IFigure implementations, each subclassing Figure.
If you're unfamiliar with draw2d and Figures, take a look at Daniel Lee's article on Display a UML Diagram using Draw2D,
In our application we have the following figures:
We haven't provided any custom figures to represent connections - we simply use the draw2d PolylineConnection class, which is a just a line with zero or more kinks or bend points.
Because the table names as well as the number of columns and their names are likely to change during the lifetime of a TableFigure instance, we want our ColumnsFigure and TableFigure to be resizable. A key role in allowing this to happen is played by layout managers, another important part of the draw2d framework.
GEF provides a layout management framework which is distinct from the Swing and Eclipse SWT layout managers: its job is specifically to handle layout of the child figures of draw2d IFigure instances. Your job as an application developer is to decide which layout manager to use for each figure containing child figures.
Broadly speaking, there are three types of layout managers:
The GEF developer needs to understand which layout managers can be best applied in which situation. Structured layout managers are suitable when there is a well defined parent-child relationship between the containing figure and its children and the children are not related to each other in arbitrary ways. In our example application, TableFigure uses a ToolbarLayout to place its children (simply stacking them vertically). The ColumnsFigure does the same with its child Label objects, but uses the FlowLayout for this purpose.
This kind of arrangement of course does not work with SchemaFigure - any of its child TableFigures may be related to any other via a primary key/foreign key relationship, so we cannot simply stack the table figures next to each other or side by side. For SchemaFigure we need to choose between either a constraint-based layout manager or a graph layout manager. In our example application we use both. Users can switch between manual layout, which involves dragging table figures to their desired locations, and automatic placement of figures using geometry computation algorithms. How this is done is beyond the scope of this article, although interested readers can examine the DelegatingLayoutManager class in the example application source code.
Open a schema diagram editor and make some changes, switching between manual and automatic layout using the icon.
We only really move into GEF territory proper when we start talking about the controller in the MVC trilogy. GEF provides an abstraction that prevents the model from having to know about the figures, and vice versa. At the centre of this architecture is the EditPart interface.
The first thing to know is that typically every separately editable part of the model will need to be associated with an EditPart instance. This means that there will usually be a close to one-for-one mapping between classes in the model hierarchy and classes in the EditPart hierarchy. In most cases, an EditPart is also a GraphicalEditPart, which means that as well as managing a model component, it also has an associated view component. Because the model and view are completely decoupled, all coordination between the model and the view must be managed by the EditPart. This coordination can be divided into two separate areas of activity:
When an instance of any of these classes is created, it is automatically associated with a part of the model. This is a build-in feature of the framework. As part of our editor, we have to provide an EditPartFactory implementation. Ours looks like this:
SchemaDiagramPart, TablePart and ColumnPart all extend AbstractGraphicalEditPart and implement GraphicalEditPart. In addition, TablePart can be a node in a primary/foreign key relationship, so it has to implement NodeEditPart. Finally, RelationshipPart represents the connection part of the relationship, so it extends AbstractConnecti
本页为82搜索生成的网页快照,内容来自站内索引;演示数据的原文链接仅作示例。