blob: f63a2034b7a4a8545c8a7e200b5e587b02279b43 [file] [log] [blame]
<?php
/*******************************************************************************
* Copyright (c) 2015 Eclipse Foundation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://eclipse.org/legal/epl-v10.html
*
* Contributors:
* Eric Poirier (Eclipse Foundation) - Initial implementation
*******************************************************************************/
?>
<h1 class="article-title"><?php echo $pageTitle; ?></h1>
<p>
<a target="_blank" href="http://www.eclipse.org/Xtext/">Xtext</a>
provides you with a powerful IDE and a rich featured text editor for
your domain-specific language with little effort. But sometimes, a
picture says more than a thousand words: You want to have some
additional graphical representation of your models, a set of
diagrams.
</p>
<p>Diagrams are superior to code when it comes to high-level views.
But while programmers can easily cope with files that contain
several hundred lines of code, the same amount of information
usually blows a diagram and destroys all its suggestiveness.
Diagrams with just a few nodes and edges showing on a certain aspect
of the models only are best fit for human readers. Such aspects are
often spread across various model files. So in order to add the best
value for the language users on top of an Xtext infrastructure, we
need to allow them to create multiple diagrams, each highlighting
just a subset of model information, picked from multiple model
files. In other words, diagrams that have a completely different
structure than their associated textual models.</p>
<p>Traditional graphical editing frameworks focus on editing the
underling model through the diagram. But synchronizing the model
changes from textual and diagram editors is very hard if their
content's structures differ. In most cases, the integration will
lead to major usability quirks like unexpected editor behavior,
forced save operations, blocked editors or even data loss.</p>
<p>
So rather than working around the hard challenges of integrating
graphical and textual <i>model</i> editing, we can leave model
modification to Xtext. For the graphical stuff we can concentrate on
<i>diagram</i> editing and leave the underlying model read-only.
This way we can spend our energy on the things that really matter to
the user, like easy and useful ways to populate diagrams or best
visual appearance.
</p>
<p>
In Eclipse, one could build such graphical views using <a
href="http://www.eclipse.org/gef/zest/">Zest</a> or <a
href="http://www.eclipse.org/gef">GEF</a>. If model and diagram do
not differ too much in structure, a small code generator targeting <a
target="_blank" href="http://www.graphviz.org/">GraphViz</a> is a
very simple solution with high quality output.
</p>
<p>
The following screencast shows another solution for an Xtext-based
domain model language. The graphical editor is using FXDiagram, a
diagram framework based on <a target="_blank"
href="http://docs.oracle.com/javafx/">JavaFX</a>. FXDiagram offers
a very smooth user experience, excellent rendering, support for
touch-pad gestures, animated undo/redo, diagram persistence, export
to scalable vector graphics and much more. If you are interested in
learning more, feel free to contact me.
</p>
<br />
<iframe allowfullscreen="" height="562" src="//player.vimeo.com/video/104115680" class="img-responsive"></iframe>
<br />
<br />
<p>No matter with what graphics technology you choose to implement a
diagram for your Xtext-based language, there are a few things you
should know in order to connect the diagram view/editor to the rest
of the infrastructure.</p>
<p>
Let us first have a look how to implement a context menu action for
the Xtext editor to show the element at the current cursor position
in the diagram. In Eclipse, you have to implement a <i>handler</i>
for such an action. Xtext offers a bunch of classes making your life
easier. <i>EditorUtils</i> detects the Xtext editor for the
handler’s action and <i>EObjectAtOffsetHelper</i> finds the semantic
model element at a given text offset.
</p>
<p>
As the document – and thereby the model parsed from it – is subject
to editing, you have to make sure nobody is changing it while you
traverse it to derive your diagram. You can execute code in a read
transaction on the <i>XtextDocument</i> by wrapping it in an <i>IUnitOfWork</i>
that you pass to the <i>XtextDocument#readOnly</i> method.
</p>
<p>
The following snipped shows an example handler written in <a
target="_blank" href="http://www.xtend-lang.org/">Xtend</a>.
</p>
<br />
<script
src="https://gist.github.com/JanKoehnlein/c260544ef13e89096e10.js"></script>
<p>
Note that the <i>@Inject</i> annotation in the example requires you
to use your language's executable extension factory when you
register the handler class it in the <i>plugin.xml</i> of your
language's UI plug-in. See the <a
href="http://www.eclipse.org/Xtext/documentation.html#equinoxSetup">Xtext
documentation</a> for details.
</p>
<p>
To navigate from a diagram element back to it&#8217;s element
definition in the text, you need to store some back reference. The
model element itself is not suitable, as its lifecycle is bound to
the one of the editor, and the parser is even free to expunge model
elements whenever the document is re-parsed. As Xtext is based on <a
href="http://www.eclipse.org/modeling/emf/">EMF</a>, each model
element has a unique URI. You should always use these URIs to store
references to model elements beyond the boundaries of a read/write
transaction. An element&#8217;s URI is provided by EMF's <i>EcoreUtil#getURI</i>
method.
</p>
<p>
Having the URI, the navigation to the respective model
element&#8217;s definition is easiest to implement using
Xtext&#8217;s <i>IURIEditorOpener</i>. If your diagram view supports
selection listeners, the respective Xtend code could look like this:
</p>
<br />
<script
src="https://gist.github.com/JanKoehnlein/7b35aecde807eb317fcc.js"></script>
<div class="bottomitem">
<h3>About the Authors</h3>
<div class="row">
<div class="col-sm-12">
<div class="row">
<div class="col-sm-8">
<img class="author-picture"
src="/community/eclipse_newsletter/2014/august/images/jan.jpg"
alt="jan koehnlein" height="90" />
<p class="author-name">
</div>
<div class="col-sm-16">
<p class="author-name">
Jan Koehnlein<br />
<a target="_blank" href="http://itemis.com/">itemis</a>
</p>
<ul class="author-link">
<li><a target="_blank" href="http://koehnlein.blogspot.de/">Blog</a>
</li>
<li><a target="_blank" href="https://twitter.com/jankoehnlein">Twitter</a></li>
<li><a target="_blank"
href="https://plus.google.com/116635061773096754601/posts">Google
+</a></li> <?php echo $og; ?>
</ul>
</div>
</div>
</div>
</div>
</div>