Event Architecture from Model to Diagram Elements
There is little documented about how changes to the UML model are reflected on the diagram in a consistent way. Diagrams and diagram elements (Figs) have been designed by various developers without a common standard. Over time implementation of notations and change of UML model repository have introduced changes which have unexpected side effects and for which there are short term work around.
This page is an attempt to formalize a common way of working for all diagram elements. It is to clearly separate GUI from notation and UML model and prevent excessive reconstruction of the GUI composite parts and excessive adding and removal of listeners from the GUI to notation and UML model.
The existing diagrams do not fit what is described here. This description is documenting the approach taken in development of the Activity diagram for UML2. Once development of that diagram is stable the lessons learned here will be used in other diagram types as they split out into their own modules.
Simple Diagram Elements
A Fig (org.tigris.gef.presentation.Fig) is the most basic diagram element in the GEF library. It has an optional "owner" which is typically a UML element.
All Figs must implement a getMinimumSize() method to prevent them from being sized smaller than they can display their own contents.
A FigText is a specialist Fig for displaying (and possibly editing) text.
This is a primitive Fig that can be placed on a diagram with no relation to a UML model element.
A FigNotation is a specialist FigText for displaying (and possibly editing) text for some UML element. Its minimum size is the width and height that will fit that text for its current font. A FigNotation will always have an owner.
Composite Diagram Elements
All composite Figs must implement a setBoundsImpl(x, y, w, h) method which will both set their own bounds and also layout any child Figs contained within themselves to fit those bounds. The logic of how the child Figs are layed out belongs to the setBoundsImpl of the composite that contains those children but that logic must respect the minimum size of each child as part of the layout.
The getMinimumSize() method of a composite Fig must calculate its minimum size based on the minimum size of the child Figs and its own logic of how these are to be layed out.
A FigComposite is a composite Fig made up of several child Figs. A FigComposite knows its own bounds but does not directly draw its own shape. The FigComposite controls the positioning and sizing of the child Figs within itself and the child Figs contain the logic to draw themselves composite child Figs.
The calcBounds() method is responsible for reshaping the composite parts of a Fig when one of its child parts has changed. Only the top level Fig that is not a composite part itself will perform this functionality so any call to calcBounds will result in a call to the calcBounds method of the parent Fig until the top level has been reached.
The top level parent will then set its own bounds so that all child parts will fit within itself (and as a result reshape all its children to fit those new bounds).
A FigCompartment is a specialist FigComposite where all child Figs are displayed vertically. The minimum height if the sum of the minimum height of all child figs. The minimum width is the same as the child Fig with the largest minimum width. When resizing all child Figs resize to the width of the compartment.
A FigNameCompartment is a specialist FigCompartment that would only be expected to hold two children. One of those is a FigCompartment itself which is to hold a list FigNotations for stereotypes.
The other is a FigNotation for display (and possibly editing) the model element notation.
Node Presentation Diagram Elements
The following are all FigComposite specializations that are used to control the entire layout of a node on the diagram. Which presentation is used depends on the state of the node. The states that effect which presentation to use are the type of the owner (e.g. Class, Interface, Use Case, Actor etc) and the profile.
A FigNamedRect is a specialist FigComposite containing a FigNameCompartment and a FigRect. On resize the children are laid out so that the text displays within the rectangle. The minimum size is that allowed by the notation with a border surrounding it.
This is typically used as presentation for objects
A FigNamedRRect is a specialist FigComposite containing a FigNameCompartment and a FigRRect. On resize the children are laid out so that the text displays within the rectangle. The minimum size is that allowed by the notation with a border surrounding it.
This is typically used as presentation for states
A FigNamedOval is a specialist FigComposite containing a FigNameCompartment and a FigCircle. On resize the children are laid out so that the text displays within the oval. The minimum size is that allowed by the notation with an oval border surrounding it.
This is typically used as presentation for use cases
A FigCompartmentBox is a specialist FigComposite containing several FigCompartments. Each compartment is separated by a horizontal line and the whole figure has a line border.
This is typically used as presentation for classifiers such as Class, Interface, ?DataType etc
Node Diagram Elements
A FigBaseNode is a Fig to which edges can be attached. This Fig always has a UML element owner. A FigBaseNode contains only one child Fig that defines its presentation.
The separation of presentation from the node into some other class allows the presentation of the node to change without having to destroy and re-create an instance of the node itself.
Many of the methods of a FigBaseNode such as setBoundsImpl and getMaximumSize delegate the call to presentation Fig without adding any extra value.
Manual Resizing of Diagram Nodes
As a FigBaseNode is resized by the user its setBounds method is called in order to resize its contents.
It will prevent resizing so that the node is smaller than its minimum size
Resizing Due to Receipt of Notation Event
A FigNotation does not listen for model events. Instead it listens for notation events which tell it exactly what text to display and whether to present it bold,underlined and/or italic.
If in acting on a notation event the Figs actual size becomes less than its minimum size then a message is sent the the top-most parent FigComposite to reset its bounds.
Resizing Due to Receipt of a Add/Remove UML Element Event
A FigCompartment is the only Fig that listens add and remove UML element events.
On receipt of a remove event it looks for a child Fig inside itself with an owner the same as the removed model element. If found the Fig is removed and calcBounds() is called so that the compartments are closed up.
On receipt of an add event a new FigNotation is created for the new model element and added to the compartment. The calcBounds() method is called so that room is made for the increased size of the compartment.
Deletion of model elements
The only Figs listening for deletions are FigBaseNode and FigBaseEdge. The node or edge is removed from the diagram.