<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | |
<html> | |
<head> | |
<meta content="text/html; charset=utf-8" http-equiv="Content-Type"> | |
<title>Providing add functionality</title> | |
<link href="../book.css" rel="Stylesheet" type="text/css"> | |
<link href="../code.css" rel="Stylesheet" type="text/css"> | |
</head> | |
<body> | |
<h1>Providing Add Functionality</h1> | |
<p>A detailed description of the architecture and basic concepts of Graphiti can | |
be found <a href="graphiti-introduction.htm#Architecture_and_Basic_Concepts">here</a>. | |
</p> | |
<h2>Architecture: Pictogram Model Linked With Domain Model</h2> | |
<p>In the terms of Graphiti “add” means to add a graphical representation | |
of an existing domain model object (= business object) to the diagram. What kinds | |
of business objects can be added to a diagram of a specific type is decided by the | |
add features delivered by the feature provider.</p> | |
<p>For our example the graphical representation of a EClass is illustrated in the | |
Figure. We want to see a rounded rectangle containing a separator like horizontal | |
line and above that line the name of the corresponding EClass.</p> | |
<p> </p> | |
<p> | |
<img alt="Graphical representation of a | |
EClass" height="117" src="visio/package-shape.gif" width="155"> </p> | |
<p><strong>Figure: Graphical representation of a EClass</strong> </p> | |
<p> </p> | |
<p>Graphiti supports a kind of linkage between elements of the domain model and | |
elements of the model defining the graphical representation – the so called <em> | |
Pictograms Model.</em> These links are called <em>pictogram links</em>. Each diagram | |
contains one container for all pictogram links – called <em>diagram link</em>. | |
</p> | |
<p>You can see the linkage structure of the example in the Figure: Column one shows | |
the entity model of the graphical representation of exactly one EClass. A container | |
shape aggregates two child shapes (a container shape itself can be aggregated in | |
another container shape or in a diagram). All three shapes themselves aggregate | |
specific graphics algorithms, providing the complete information to allow the rendering | |
on a screen. Examples for this information are background color, foreground color, | |
size, position, visibility and line width. In our example we have a rounded rectangle | |
providing an additional corner radius, a polyline having defined end- and bendpoints | |
and a text label containing a text value.</p> | |
<p> </p> | |
<p><img alt="" height="350" src="visio/pictogram-model.png" width="557"> </p> | |
<p><strong>Figure: Linkage structure example</strong> </p> | |
<p> </p> | |
<p>The container shape and likewise the shape containing the text label are related | |
to a corresponding EClass. This relationship is realized through special link objects | |
(pictogram link) holding references to both sides: to the pictograms side and to | |
the business side.</p> | |
<h2>Creating an add feature</h2> | |
<p>In this example we want to enable the editor’s users to add EClasses to the diagram. | |
As a result it should be possible to drag an EClass from the tree and drop it on | |
the diagram. Therefore we have to create an add feature and make it available in | |
the feature provider.</p> | |
<p>An add feature has to implement the interface | |
<a href="../../../javadoc/org/eclipse/graphiti/features/IAddFeature.html">IAddFeature</a>. | |
Instead of implementing it directly it should extend one of the available base classes. | |
In this example we extend the base class | |
<a href="../../../javadoc/org/eclipse/graphiti/features/impl/AbstractAddShapeFeature.html"> | |
AbstractAddShapeFeature</a>. </p> | |
<p>In this case we have to implement/overwrite two methods:</p> | |
<ul> | |
<li>The method | |
<a href="../../../javadoc/org/eclipse/graphiti/func/IAdd.html#canAdd(org.eclipse.graphiti.features.context.IAddContext)"> | |
canAdd</a> has to check the given context and therefore it decides if a business | |
object can be added.</li> | |
<li>The method | |
<a href="../../../javadoc/org/eclipse/graphiti/func/IAdd.html#add(org.eclipse.graphiti.features.context.IAddContext)"> | |
add</a> finally has to create the pictogram structure described above and has | |
to establish the linkage to the business object.</li> | |
</ul> | |
<p>Additionally we have to create graphics algorithms and place them at the appropriate | |
location (get location from given context). Additionally, the name of the EClass | |
has to be set as the text label’s value.</p> | |
<p>You can see the complete implementation of the add feature here:</p> | |
<!-- Begin code ------------------------------------------------------------------------------- --> | |
<p> </p> | |
<div class="literallayout"> | |
<div class="incode"> | |
<p class="code"><span class="keyword">package </span>org.eclipse.graphiti.examples.tutorial.features;<br> <br> | |
<span class="keyword">public class</span> TutorialAddEClassFeature | |
<span class="keyword">extends </span>AbstractAddShapeFeature {<br> <br> | |
<span class="keyword">private static final</span> IColorConstant | |
<span class="string"><em>E_CLASS_TEXT_FOREGROUND</em> </span>=<br> | |
IColorConstant.<span class="string">BLACK</span>;<br> <br> | |
<span class="keyword">private static final</span> IColorConstant | |
<span class="string"><em>E_CLASS_FOREGROUND</em> </span>=<br> | |
<span class="keyword">new </span>ColorConstant(98, 131, 167);<br><br> <span class="keyword"> | |
private static final</span> IColorConstant <span class="string"><em> | |
E_CLASS_BACKGROUND</em> </span>=<br><span class="keyword"> | |
new</span> ColorConstant(187, 218, 247);<br> <br> | |
<span class="keyword">public </span>TutorialAddEClassFeature(IFeatureProvider | |
fp) {<br> | |
<span class="keyword">super</span>(fp);<br> }<br> <br> | |
<span class="keyword">public </span>boolean canAdd(IAddContext context) | |
{<br> <span class="comment">// | |
check if user wants to add a EClass</span><br> | |
<span class="keyword">if </span>(context.getNewObject() | |
<span class="keyword">instanceof </span>EClass) {<br> | |
<span class="comment">// check if user wants to add to a diagram</span><br> | |
<span class="keyword">if (</span>context.getTargetContainer() | |
<span class="keyword">instanceof </span>Diagram) {<br> | |
<span class="keyword"> return true</span>;<br> | |
}<br> }<br> | |
<span class="keyword"> return false</span>;<br> }<br> <br> | |
<span class="keyword">public </span>PictogramElement add(IAddContext context) | |
{<br> EClass addedClass = (EClass) | |
context.getNewObject();<br> Diagram | |
targetDiagram = (Diagram) context.getTargetContainer();<br> <br> | |
<span class="comment">// CONTAINER SHAPE WITH ROUNDED RECTANGLE</span><br> | |
IPeCreateService peCreateService = Graphiti.getPeCreateService();<br> | |
ContainerShape containerShape =<br> | |
peCreateService.createContainerShape(targetDiagram, | |
<span class="keyword">true</span>);<br> <br> | |
<span class="comment">// define a default size for the shape</span><br> | |
<span class="keyword">int </span>width = 100;<br> | |
<span class="keyword">int </span>height = 50; <br> | |
IGaService gaService = Graphiti.getGaService();<br> <br> | |
{<br> | |
<span class="comment">// create and set graphics algorithm</span><br> | |
RoundedRectangle roundedRectangle =<br> | |
gaService.createRoundedRectangle(containerShape, 5, 5);<br> | |
roundedRectangle.setForeground(manageColor(<em class="string">E_CLASS_FOREGROUND</em>));<br> | |
roundedRectangle.setBackground(manageColor(<span class="string"><em>E_CLASS_BACKGROUND</em></span>));<br> | |
roundedRectangle.setLineWidth(2);<br> | |
gaService.setLocationAndSize(roundedRectangle,<br> | |
context.getX(), context.getY(), width, height);<br> <br> | |
<span class="comment">// if added Class has no resource we add it to the | |
resource <br> | |
// of the diagram<br> | |
// in a real scenario the business model would have its own resource</span><br> | |
<span class="keyword"> if</span> (addedClass.eResource() == | |
<span class="keyword">null</span>) {<br> | |
getDiagram().eResource().getContents().add(addedClass);<br> | |
}<br> | |
<span class="comment">// create link and wire it</span><br> | |
link(containerShape, addedClass);<br> | |
}<br> <br> | |
<span class="comment">// SHAPE WITH LINE</span><br> | |
{<br> | |
<span class="comment">// create shape for line</span><br> | |
Shape shape = peCreateService.createShape(containerShape, | |
<span class="keyword">false</span>);<br> <br> | |
<span class="comment">// create and set graphics algorithm</span><br> | |
Polyline polyline =<br> | |
gaService.createPolyline(shape, <span class="keyword">new int</span>[] { | |
0, 20, width, 20 });<br> | |
polyline.setForeground(manageColor(<span class="string"><em>E_CLASS_FOREGROUND</em></span>));<br> | |
polyline.setLineWidth(2);<br> | |
}<br> <br> | |
<span class="comment">// SHAPE WITH TEXT</span><br> | |
{<br> | |
<span class="comment">// create shape for text</span><br> | |
Shape shape = peCreateService.createShape(containerShape, | |
<span class="keyword">false</span>);<br> <br> | |
<span class="comment">// create and set text graphics algorithm</span><br> | |
Text text = gaService.createText(shape, addedClass.getName());<br> | |
text.setForeground(manageColor(<span class="string"><em>E_CLASS_TEXT_FOREGROUND</em></span>));<br> | |
text.setHorizontalAlignment(Orientation.<span class="string"><em>ALIGNMENT_CENTER</em> | |
</span>); <br> | |
<span class="comment">// vertical alignment has as default value "center"</span><br> | |
text.setFont(gaService.manageDefaultFont(getDiagram(), | |
<span class="keyword">false</span>, <span class="keyword">true</span>));<br> | |
gaService.setLocationAndSize(text, 0, 0, width, 20);<br> <br> | |
<span class="comment">// create link and wire it</span><br> | |
link(shape, addedClass);<br> }<br> <br> | |
<span class="keyword">return </span>containerShape;<br> | |
}<br>}<br> </p> | |
</div> | |
</div> | |
<p> </p> | |
<!-- End code ------------------------------------------------------------------------------- --> | |
<p class="Note"><strong>Note on graphics algorithms and values:</strong> Graphics | |
algorithms, which are created with "create"-methods, have suitable default values | |
as comfort. Default values are defined in the meta model and the framework. The rounded rectangle | |
has the following default values: {lineWidth: 1, lineStyle: SOLID, filled: <unset>, | |
lineVisible: <unset>, transparency: 0.0, width: 0, height: 0, x: 0, y: 0}. When | |
using the "create plain"-methods instead, all values have to be set explicitly. | |
You can find more details about setting values and styles in chapter | |
<a href="http://www.spiegel.de/">"Using Styles"</a>, | |
<a href="default_values.html">"Default Attribute Values of Graphics Algorithms"</a> and in the JavaDoc of | |
<a href="../../../javadoc/org/eclipse/graphiti/services/IGaCreateService.html">IGaCreateService</a>.</p> | |
<p class="Note"><b>Note on colors and fonts:</b> In contrast to other graphical | |
objects like e.g. rectangles or lines, colors and fonts are managed objects. This | |
means that the Graphiti framework keeps track of these objects and enables reuse | |
within one diagram: one specific color (the combination of its RGB values) or a | |
specific font (the name along with its size and the flags for italic and bold) is | |
stored only once within the diagram and is referenced by all objects using this | |
specific color or font. This is why they are not simply created as the other objects | |
but retrieved via the IGaService.manage* methods. </p> | |
<p class="Note">The default font handled by the convenience methods manageDefaultFont | |
is simply the standard font Graphiti uses if nothing else is defined; it is defined | |
as Arial in size 8 in straight representation (no italics, no bold). There might | |
be special font instances of the default font for italic and/or bold representation.</p> | |
<p class="Note">Colors and fonts are basically immutable objects; once they are | |
created there attributes should not be changed again. Instead a new color or font | |
should be requested by calling the manage* methods and set for the relevant objects. | |
Fonts and colors that are no longer needed can of course be deleted but this is | |
not handled by the Graphiti framework and is a task that needs to be implemented | |
by the tool builder if desired.</p> | |
<p class="Note"><b>Note on text fields and the fonts they use:</b> Text fields can | |
be created as above; in this case they do not automatically receive a font, but | |
the tool builder is able to define and set any desired font. On the other hand text | |
fields may also be created using the default font; to do this simply use the createDefaultText | |
methods instead of createText (analogue creation methods for MultiText objects exist). | |
Changing the font lateron will result in having an additional unused font inside | |
your diagram unless the tool builder cares about deleting no longer used fonts. | |
</p> | |
<h2>Test: Add a EClass</h2> | |
<p class="Note">Note: if the project wizard for a "<a href="example-projects.htm">New | |
Graphiti Sample Project</a>" does not work correctly and you can not test the add | |
feature as described below, please continue with the next chapter and | |
<a href="create-feature.htm">provide create functionality</a>. That will allow to | |
test the add feature directly in the diagram. </p> | |
<p>Now we can start the editor again. It should be possible to drop an EClass from | |
the tree of the "Graphiti Sample" project into the diagram "Add Feature".</p> | |
<p> </p> | |
<p><img alt="" height="624" src="visio/predefined-eclass.png" width="640"> </p> | |
<p> </p> | |
<p><strong>Figure: Add PredefinedEClass to the editor</strong></p> | |
<p> </p> | |
<p>Without any further implementations it should be possible to move the EClass | |
shapes around, resize them, remove them (context menu) and even delete them.</p> | |
<p> </p> | |
</body> | |
</html> |