Feb 26

In the text editor, the markers are displayed on the vertical ruler. In Java source editor (CompilationUnitEditor class), you can click a problem marker, then a suggestion list will pop up. It’s pretty user friendly, isn’t it?

Then, how to implement our own clickable annotation marker? Generally the following steps address the issue:

  1. Add the extension org.eclipse.ui.editorActions.
  2. Add an editorContribution sub node. Config the contribution.
  3. Implement an AbstractRulerActionDelegate for the contribution. In its createAction method, return your customized action.
  4. Implement your customized action by extending SelectMarkerRulerAction. In the action, you may be interested to traverse through annotation model, to invoke the appropriate commands.

Examples are best tutorials.  Therefore, let’s take a look at Java source editor in org.eclipse.jdt.ui, step bey step:

1. The editorActions contribution in JDT UI plug-in:

  1.  
  2. <extension point="org.eclipse.ui.editorActions">
  3.         <editorContribution
  4.             targetID="org.eclipse.jdt.ui.CompilationUnitEditor"
  5.             id="org.eclipse.jdt.internal.ui.CompilationUnitEditor.ruler.actions">
  6.                 <action
  7.                label="%JavaSelectRulerAction.label"
  8.                class="org.eclipse.jdt.internal.ui.javaeditor.JavaSelectRulerAction"
  9.                actionID="RulerClick"
  10.                id="org.eclipse.jdt.internal.ui.javaeditor.JavaSelectRulerAction">
  11.          </action>
  12.         </editorContribution>
  13. </extension>
  14.  

Pay attention to actionID and targetID.

2. The AbstractRulerActionDelegate. It uses template pattern to let you create your own action:

  1.  
  2. public class JavaSelectRulerAction extends AbstractRulerActionDelegate {
  3.         protected IAction createAction(ITextEditor editor, IVerticalRulerInfo rulerInfo) {
  4.                 return new JavaSelectAnnotationRulerAction(JavaEditorMessages.getBundleForConstructedKeys(), "JavaSelectAnnotationRulerAction.", editor, rulerInfo); //$NON-NLS-1$
  5.         }
  6. }
  7.  

3. The SelectMarkerRulerAction. It is needed to access the annotation model. If you don’t need to access annotation model, of course you can use other actions. The Java editor version is JavaSelectAnnotationRulerAction. It contains complicated relations. Therefore, to make it simple, here I paste my simple version:

  1.  
  2. public class DataRequestSelectAnnotationRulerAction extends SelectMarkerRulerAction {
  3.  
  4.         private ITextEditor fTextEditor;
  5.         private boolean fHasCorrection;
  6.         private Position fPosition;
  7.         private Annotation fAnnotation;
  8.  
  9.         public DataRequestSelectAnnotationRulerAction(ResourceBundle bundle, String prefix,
  10.                         ITextEditor editor, IVerticalRulerInfo ruler) {
  11.                 super(bundle, prefix, editor, ruler);
  12.                 fTextEditor = editor;
  13.         }
  14.  
  15.         @Override
  16.         public void run() {
  17.                 runWithEvent(null);
  18.         }
  19.  
  20.         @Override
  21.         public void runWithEvent(Event event) {
  22.                 if(fHasCorrection){
  23.                         ITextOperationTarget operation= (ITextOperationTarget) fTextEditor.getAdapter(ITextOperationTarget.class);
  24.                         final int opCode= ISourceViewer.QUICK_ASSIST;
  25.                         if (operation != null && operation.canDoOperation(opCode)) {
  26.                                 fTextEditor.selectAndReveal(fPosition.getOffset(), fPosition.getLength());
  27.                                 operation.doOperation(opCode);
  28.                         }
  29.                 }
  30.         }
  31.  
  32.         @Override
  33.         public void update() {
  34.                 findDataRequestAnnotation();
  35.                 setEnabled(true);
  36.  
  37.                 super.update();
  38.         }
  39.  
  40.         private void findDataRequestAnnotation(){
  41.                 fPosition = null;
  42.                 fAnnotation = null;
  43.                 fHasCorrection = false;
  44.  
  45.                 AbstractMarkerAnnotationModel model = this.getAnnotationModel();
  46.                 IAnnotationAccessExtension annotationAccess = this.getAnnotationAccessExtension();
  47.  
  48.                 IDocument document = getDocument();
  49.                 if(model == null)
  50.                         return;
  51.  
  52.                 boolean hasAssistLightbulb = true;
  53.  
  54.                 Iterator iter = model.getAnnotationIterator();
  55.                 int layer = Integer.MIN_VALUE;
  56.  
  57.                 while(iter.hasNext()){
  58.                         Annotation annotation = (Annotation)iter.next();
  59.  
  60.                         if(annotation.isMarkedDeleted())
  61.                                 continue;
  62.  
  63.                         int annotationLayer = layer;
  64.                         if(annotationAccess != null){
  65.                                 annotationLayer = annotationAccess.getLayer(annotation);
  66.                                 if(annotationLayer < layer)
  67.                                         continue;
  68.                         }
  69.  
  70.                         Position position = model.getPosition(annotation);
  71.                         if(!includesRulerLine(position, document))
  72.                                 continue;
  73.  
  74.                         boolean isReadOnly = fTextEditor instanceof ITextEditorExtension && ((ITextEditorExtension)fTextEditor).isEditorInputReadOnly();
  75.  
  76.                         if(!isReadOnly && (
  77.                                         ((hasAssistLightbulb && annotation instanceof TemporaryAnnotation)))
  78.                         ){
  79.                                 fPosition = position;
  80.                                 fAnnotation = annotation;
  81.                                 fHasCorrection = true;
  82.                                 layer = annotationLayer;
  83.                                 return;
  84.                         }
  85.  
  86.                 }
  87.         }
  88.  
  89. }
  90.  

Hope the example above helps.

  • Share/Bookmark