How to extend Notes 8: coupling custom LiveText recognisers to a Java action

I get so many question on how to extend Notes 8 that I finally decided to create a series of blog posts on how to do it. All the posts in the series may be found under the extending_notes8 tag. In all of the examples I assume a working knowledge of Eclipse and Java programming and how to work with extension points.

For this post I’ll build on the “How to extend Notes 8: coupling LiveText to a Java action“-post and show how to act on your own custom recognizer.

Most of the work is actually the same than for using the built-in recognizers but now you need to utilize your custom recognizer. So you need a recognizer – there are of cause ways to do this programmatically but that’s the focus for another post. For now lets focus on using existing recognizers. Do that by adding your recognizer to Notes – either using MyWidgets or simply importing a recognizer using an extension.xml file such as this one. Remember you need both the recognizer AND the content type it produces (the file has both).

For this example I’ll use the extension.xml I link to above – to install simply drag the link to your MyWidgets sidebar panel. That file gives you a new recognizer with an id of “DCR.Toddlerdemo.885487295” and a content type with an id of “DCCT.demonotes85inspirationproductno.1361861595”. As in previous posts you link your Java action to the content type so make a note of the id.

Now create your Java action class – again implemening org.eclipse.ui.IObjectActionDelegate – and add the org.eclipse.ui.popupMenus extension point to your plugin.xml file using the content type id as below.

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
   <extension  point="org.eclipse.ui.popupMenus">
      <objectContribution id="com.lekkimworld.livetxt.objectContr1"
               <objectState name="content.type"
               <objectState name="contents" value="" />
         <action class="com.lekkimworld.livetext.MyAction"
            label="Do stuff!" />

Again when it comes to grabbing the contents of the recognized LiveText it comes down to you selectionChanged-method of your Java action. If your custom recognizer doesn’t use capture groups your contents will be in the “contents” property as previously. If you DO use capture groups you need to use the names you specified for the capture groups when you mapped it to the widget – we’ll look at that another time. The example code below simply assumes a single group.

public void selectionChanged(IAction action, ISelection selection) {
   IDocumentContent doc = null;

   // cast/adapt selection
   if (selection instanceof StructuredSelection) {
      Object sel = ((StructuredSelection)selection).getFirstElement();
      if (sel instanceof IDocumentContent) {
         doc = (IDocumentContent)sel;
   } else if (selection instanceof IDocumentContent) {
      doc = (IDocumentContent)selection;
   } else {
      // try and adapt
      IAdapterManager amgr = Platform.getAdapterManager();
      doc = (IDocumentContent)amgr.getAdapter(selection,
   if (null == doc) {
      this.selection = null;

   // get number from document property
   this.selection = doc.getProperties().getProperty("contents");

That’s all. Again the main post is knowing how but again 95% of the plugin.xml file and the Java action is the same. In a future post in this series I’ll show how to act upon custom recognizers using capture groups. Stay tuned…