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.
<folder name="YourAnnotationTypeActions">
<file name="org-foo-BarAction.instance" />
</folder>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:
<combinations tiptext_key='COMBINATION_TOOLTIP_TEXT' min_optionals='1'>
<combine annotationtype='debugger-disabledbreakpoint' optional='true'/>
<combine annotationtype='debugger-conditionalbreakpoint' optional='true'/>
<combine annotationtype='debugger-currentpc'/>
</combinations>This way we specify that both breakpoint are conditional, but that at least one must be found (min_optionals='1') to match condition for combining. The combinations element can contain only combine elements (for each annotation type one) and they can have these attributes:
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.