IDE concepts

For the following part we will refer to a concrete example grammar in order to explain certain aspect of the UI more clearly. The used example grammar is as follows:

grammar org.eclipse.text.documentation.Sample 
    with org.eclipse.xtext.common.Terminals

generate gen 'http://www.eclipse.org/xtext/documentation/Sample' as gen

Model :
  "model" intAttribute=INT (stringDescription=STRING)? "{" 
     (rules += AbstractRule)* 
  "}" 
;

AbstractRule:
  RuleA | RuleB
;

RuleA :
   "RuleA" "(" name = ID ")" ;

RuleB return gen::CustomType:
   "RuleB" "(" ruleA = [RuleA] ")" ;

Label Provider

A nice part of the Eclipse tooling that comes with Xtext is the outline view. It shows the structure of your model as a tree and allows quick navigation to model elements. Thus it helps to get an overview on the current state in the editor at a glance. To make the appearance of the outline more appealing it is very easy possible to provide customization for the label and the image that is used for an element. Actually this customization will be used at various places in your IDE, for example in the window that displays completion proposals when content assist was invoked. (Customizing the structure of the outline is described in a separate chapter).

The LabelProvider is the service which is used to compute the image for model elements and – as its name suggests – the label that represents an element. What you basically have to do is to provide an implementation for two methods which read Image getImage(Object) and String getText(Object) respectively. As this tends to be cumbersome due to instanceof and cast orgies, Xtext ships with a reasonable and convenient default implementation.

DefaultLabelProvider

The default implementation of the LabelProvider interface utilizes the polymorphic dispatcher idiom to implement an external visitor as the requirements of the LabelProvider are kind of a best match for this pattern. It comes down to the fact that the only thing you need to do is to implement a method that matches a specific signature. It either provides a image filename or the text to be used to represent your model element. Have a look at following example to get a more detailed idea about the DefaultLabelProvider.

public class SampleLabelProvider extends DefaultLabelProvider {

  String text(RuleA rule) {
return "Rule: " + rule.getName();
}

String image(RuleA rule) {
return "ruleA.gif";
}

String image(RuleB rule) {
return "ruleB.gif";
}

}

The declarative implementation of the label itself is pretty straightforward. The image in turn is expected to be found in a file named icons/<result of image-method> in your plugin. This path is actually configurable by google guice. Have a look at the PluginImageHelper to learn about the customizing possibilities.

What is especially nice about the default implementation is the actual reason for its class name: It provides very reasonable defaults. To compute the label for a certain model element, it will at first have a look for an EAttribute that is called name and try to use this one. If it cannot find a feature like this, it will try to use the first feature, that can be used best as a label. At worst it will return the class name of the model element, which is kind of unlikely to happen.

More advanced usage patterns of the DefaultLabelProvider include a dispatching to an error handler called String error_text(Object, Exception) and String error_image(Object, Exception) respectively.