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.
Example problem of current implementation
?FigAttribute gets the model element via notation so that it changes it text.
?FigClass also gets a notification because its possible that the attribute text change means that the whole bounds of the class needs to change to fit that text. The ?FigClass then rearranges all the child Figs it contains.
The problem may be deeper than this. The child Figs may well be deleted and recreated in this process. It may also be that listeners to the model are dropped and then added again. As a result some events from the model might be missed.
Progress an an improved implementation
As part of the implementation of the UML2 activity diagram work is progressing to improve this.
The implementation so far is -
When the name of a text Fig changes due to a notation event its own setBounds() method is called to change the size of itself. setBounds fires a "bounds" ?PropertyEvent
The parent Fig that contains that text Fig is listening to its child for that event. When received it determines if the child still fits inside itself. If not it resizes all of its children (but no recreation of Figs or listeners).
That resize will be by calling its own setBounds. The next step was going to be to make the next level up Fig listen for that "bounds" change until the events have bounced all the way up. At this point work has paused.
Potential problems with improved implemention
The solution developed so far has some drawbacks.
Typically a Fig is responsible for laying out all the child Figs inside itself. It can check the max and min size of each and then place them where required. It's setBoundsImpl() where this layout takes place.
Those child figs then layout out their own children etc.
There is a danger that if things aren't coded carefully an event will bounce up a level asking for a re-layout. That may result in change in size of the child fig that requested it and that again in turn request the parent to lay out again. We get a constant loop.
Even if things were done perfectly there can still be too many repeated calls to layout the Figs.
An attribute grows so its compartment grows and lays out all its attributes.
Because the compartment grows the class grows and lays out all its compartments (which in turns lays out all the attributes in the attribute compartment)
A Proposed Solution
Do not use events - this is overkill as there is a composite relationship between parent and child already.
When a notation changes a text Fig, the follow should happen -
The text Fig calculates its minimum size. If its minimum size is greater than its actual size it calls the childLayoutRequest method of its parent Fig.
The parent Fig will do the same with no layout taking place of its own Figs - checking only its own minimum size against its current size.
The calls continue up from parent to child until either there is no parent or the minimum size fits the parent.
At this point the parent level reach repositions its own child Fig and those children reposition their own children rattling downwards just once.
The composite structure of diagram elements
Resizing of diagram nodes
Reacting to model elements changes represented as text
Reacting to model elements changes represented as composite parts