Using annotations

Using annotations on a document is not difficult. Everything you have to do is to define visual appearance of your annotation and extend one class which will represent this annotation. For example, if you are writing a module which interacts with an open document containing some sort of program code, and the user has made a syntax error in the code which you were able to detect and want to point out, you may want to mark the line or part of the line as "erroneous". To achieve this you must do:

1.) Describe appearance of your annotation. This is so called annotation type which consist of attributes like colorings etc. Once you have defined the annotation type you can create document annotations which will reference this annotation type. Definition of annotation type involves creation of XML file with the format specified by <A HREF="http://www.netbeans.org/dtds/annotation-type-1_0.dtd">annotation-type-1_0.dtd</A>. This XML file must be register in your module installation layer in directory "Editors/AnnotationTypes". The annotation type may look like following:

<type 
    name='YourModule-AnnotationTypeName'
    description_key='ID_OF_LOCALIZED_NAME_OF_ANNOTATION_TYPE'
    localizing_bundle='org.foo.Bundle'
    visible='true' 
    glyph='URL_of_glyph_icon'
    highlight='RGB_value_of_highlight_color'
    type='line' />
As you can see the definition of the annotation type consist of highlight color, the glyph icon which is shown in the left corner of the editing area - so called glyph gutter, the localized name, etc. For more details about each field in annotation-type-1_0.dtd see end of this chapter.

2.) Extend Annotation abstract class and define your own annotation. The abstract methods which must be override are:

public abstract String getAnnotationType();
this method must return the name attribute of your XML annotation type (type.name). Through this method the annotation is joined with the annotation type.
public abstract String getShortDescription();
this method may return tooltip text for the annotation. It is possible to return annotation tooltip text asynchronously. Just return for the first call null value and start evaluation of the tooltip text. After the tooltip text has been evaluated, fire property change:
firePropertyChange(Annotation.PROP_SHORT_DESCRIPTION, null, null);
It is guaranteed that Editor listens on this property and refreshes the tooltip text if property has changed.

3.) Last step is to attach created annotation to some Annotatable object. If you check JavaDoc you will discover that Annotatable abstract class is implemented by Line and Line.Part classes. The Line is used for whole line annotations, the Line.Part for annotation of the part of the line. For example:

Line.Set lineSet = DataObject.find (fs.findResource("foo.java")).getCookie(LineCookie.class).getLineSet ();
Line line = lineSet.getCurrent (123);
Annotation yourAnno = new YourAnnotation();
yourAnno.attach(line);
Back to our example with erroneous line - we have just annotated it. If the user corrects the problem (you could use a document change listener to detect this), it is just as easy to remove the annotation:
yourAnno.detach();
It is possible that there might be more than one annotation on the same line. In this case it depends on the capabilities of editor how the annotations will be displayed. The easiest solution is that only one annotation is visible at time and user can cycle through them. If this happen it may come in handy to force editor to move your annotation in front of others:
yourAnno.moveToFront();
The IDE presents a control panel to the user in which it is possible to customize the colors associated with the annotation types. The definition of appearance of the annotation type consist of foreground color, highlight color and glyph icon. But it is not guaranteed that every editor will have capabilities to use all these markings: it is possible that an editor for which arbitrary style support is difficult, may choose to provide special display of only some of these attributes.

Detailed description of annotation type

Attributes of the type element are: Except the already mentioned element type, the annotation type can contain also the combinations element - definition of the combinations. If two annotations from one module are on the same line it might make sense to combine them into one annotation (means visually). For example if debugger module attached breakpoint to some line and the current program counter annotation reached the same line, it's better to show combination of these two annotations rather than two separate annotations. And this is what the combinations are good for. This combination is normal annotation type as you know it (it has glyph icon and colors), plus it contains the definition of annotation types which are combined by this type, for example the combination of program counter with breakpoint would would be defined as:
<combinations tiptext_key='PC_BREAKPOINT_COMBINATION_TOOLTIP_TEXT'>
  <combine annotationtype='NameOfTheBreakpointAnnotationType'/>
  <combine annotationtype='NameOfTheCurrentPCAnnotationType'/>
</combinations>
It is responsibility of editors to display combinations when the criteria for combinations as defined in annotation types are met.

Attributes of the combinations element are:

The combinations element can contain only combine elements (for each annotation type one) and they can have these attributes:

Handling annotations

Your editor must do two things to support annotations:

NbDocument.Annotatable

This interface has two method. One which adds annotation to the document:
public void addAnnotation(Position startPos, int length, Annotation annotation);
As you can see the annotation is defined by Position in document, length of the annotation - if the annotation is whole line annotation, the length will have value of -1, and the annotation instance. Now it is responsibility of editor to collect all annotations for the document and to display them properly. Usually you take advantage of StyledDocument for changing the style of the line (or part of the line). As for the glyph icon it is fully on the editor how it will represent it. For the motivation you can check the Netbeans Editor implementation.

Second method is:

public void removeAnnotation(Annotation annotation);
and it is used for removal of annotation. This method is called when the document is going to be closed.

Annotation type XML files

As for the visual attributes of the annotations, the editor must parse the XML files at "Editors/AnnotationTypes" directory. For the example how to do this it is again recommended to check the implementation in Netbeans Editor. For future is planned some support where the parsing will not be necessary.