Tutorial Examples of MAEPlugins

MAExplorer | MAEPlugin home | Design | Open Java API | MJA classes | MJA javadocs | Open Java API javadocs |
Plugin Tutorial Examples | List of Plugins | Developing a Plugin | Installing Plugins |
MAExplorer home | MAExplorer revisions notes | Help desk

This document gives a simple tutorial example of MAEPlugins source code. After you have read this you might look at some of the source code from actual plugins. Note that there are several base class plugins (PopupPlugin, FilterPlugin, NormalizationPlugin, etc.) that require different overide methods or have abstract methods you must implement. Look at the examples to clarify this.

1. Example of a simple PopupPlugin and how it uses the Open Java API

The following code illustrated how to create a simple popup plugin ExamplePlugin.java using the Open Java API by extending the PopupPlugin. It passes the MaeJavaAPI mja instance to the actual workhorse, Example.java, that then retrieves and saves any MAExplorer data it requires. We show very simple examples of this code to give the flavor of the procedures required and how it interfaces with the API.

1.1 Example of plugin class that is loaded into MAExplorer

For convenience, we will name the class that is loaded into MAExplorer XxxxxPlugin.java and the subsequent primary body of the plugin class Xxxxx.java where Xxxxx is some particular class. In our following example, Xxxxx is "Example", but it might be "MyNewClusterMethod" etc. We first show ExamplePlugin.java that serves as the interface between MAExplorer and the primary body class Example.java.

1.1.1. You must import the two class definitions:

  import MAEPlugin.popup.PopupPlugin;
  import MAEPlugin.*;
If you are writting other types of plugins, you need to import those instead (eg. MAEPlugin.analysis.NormalizationPlugin, MAEPlugin.analysis.FilterPlugin, etc).

1.1.2 The XxxxxPlugin.java class must have the following methods as a minimum:

  1. XxxxxPlugin() - is the constructor for the class (here it is ExamplePlugin).
  2. pluginMain() - the method end-users must implement to use the API.
  3. updateCurGene() - update any data since current gene has changed.
  4. updateFilter() - update any dependent data since Filter has changed.
  5. updateSlider() - update any dependent data since a threshold slider may have changed.
  6. updateLabels() - update any dependent data since global labels may have changed.
  7. close() - close the plugin

The XxxxxPlugin() method is called at the time the plugin is loaded. Any particular actions that may be required can be performed at that time. In this example, we merely set the name of the plugin as it is to appear in the Plugins pull-down menu.

The pluginMain() method is called at the time the plugin is invoked by selecting the menu entry.

The four special event handling methods updateCurGene(), updateFilter(), updateSlider(), and updateLabels() are invoked by the MAExplorer PopupRegistry when any of these events occurs. If you are doing nothing with the events, they may be no-ops. However, if you want to take action on these events, you would normally implement the actual event handling code in your Xxxxx.java class.

/** File: ExamplePlugin.java */

import MAEPlugin.popup.PopupPlugin;
import MAEPlugin.*;

/**
 * This class invokes the ExamplePlugin plugin.
 */

public class ExamplePlugin extends PopupPlugin implements MAEUpdateListener
  {     
     /** The current instance of a plugin called "Example". 
      * The instance may be non-null if run previously and is needed to kill
      * a previous instance when new instances are created.
      */
     private Example
       eObj= null;
     
     /** 
      * ExamplePlugin() - this is the constructor end-users must implement 
      * to use the API. It is called at the time the plugin is loaded.
      */
     public ExamplePlugin() throws PluginException
       { /* ExamplePlugin */
         /* Note: "Example plugin" is a string that appears in the 
          * Plugin menu. 
          */
         setMenuLabel("Example plugin"); 
         
         MJApopupRegistry
           pr= MAExplorer.mja.mjaPopupRegistry;           
         int
           propBits= (pr.PRPROP_CUR_GENE | pr.PRPROP_FILTER | pr.PRPROP_LABEL |
                      pr.PRPROP_SLIDER | pr.PRPROP_UNIQUE);           
         pr.addUniquePopupWindowToReg(this, "ShowListActiveFilters", propBits);
       } /* ExamplePlugin */

     
     /** pluginMain() - the method end-users must implement to use the API.
      * It is invoked when the user selects the plugin in a menu.
      */
     public void pluginMain()
       { /* pluginMain */          
         MaeJavaAPI
           mja= MAExplorer.mja;     /* Open Java API library access */ 
     
         if(eObj==null)
            eObj= new Example(mja);
         else
           { /* re-rerun Example on new data */
             eObj.dispose();
             eObj= null;
             System.gc();
             mja.mjaUtil.maeRepaint();
             eObj= new Example(mja);  
           } 
       } /* pluginMain */ 
           
   /** updateCurGene() - update any data since current gene has changed.
    * This is invoked by the MAExplorer PopupRegistry.
    * @param mid is the MID (Master Gene ID) that is the new current gene.
    */
   public void updateCurGene(int mid) 
     { 
       if(eObj!=null)
         eObj.updateCurGene(mid;
    }  
 
   /** updateFilter() - update any dependent data since the data Filter 
    * has changed. This is invoked by the MAExplorer PopupRegistry.
    */
   public void updateFilter()  
     { 
       if(eObj!=null)
         eObj.updateFilter();
     }
 
   /** updateSlider() - update any dependent data since a threshold slider 
    * has changed. This is invoked by the MAExplorer PopupRegistry.
    */
   public void updateSlider() 
     { 
       if(eObj!=null)
         eObj.updateSlider();
     }
 
   /** updateLabels() - update any dependent data since global labels 
    * have changed. This is invoked by the MAExplorer PopupRegistry.
    */
   public void updateLabels() 
     { 
       if(eObj!=null)
         eObj.updateLabels();
     }   

   /**
    * close() - close the plugin. This will be called if you
    * had specified the plugin as PRPROP_UNIQUE since previous
    * instances will be closed before the new instance is started.
    * @param preserveDataStructuresFlag to save data structures
    */
   public void close(boolean preserveDataStructuresFlag)
     { 
       if(eObj!=null)
         eObj.close();
     }

  } /* end of class ExamplePlugin*/

1.2 Example of the main body of plugin code

The main body of code the plugin writer generates is illustrated here showing how one might access data and methods from the Open Java API. We illustrate this with a very simple example, Example.java, showing the entry point a retrieving a few data structures from the Open Java API. In this example, we will popup a new Frame and add Action and Window listeners (code not shown to support the Frame since that is not the point of this example). However, any Java code could be used.

/** File: Example.java */

public class ListActiveFilters extends Frame 
       implements ActionListener, WindowListener, etc.
{
     
  /** Example() - Constructor 
   */
  public Example(MaeJavaAPI mja)  
    { /* Example */
      /* [1] Access Open Java API required through MaeJavaAPI instances
       * of these MJA classes.
       */
      MJAfilter
        mjaFilter= mja.mjaFilter;          /* Open Java API library */ 
      MJAgeneList
        mjaGeneList= mja.mjaGeneList;      /* Open Java API library */ 
      MJAproperty
        mjaProperty= mja.mjaProperty;      /* Open Java API library */ 
      MJAsampleList
        mjaSampleList= mja.mjaSampleList;  /* Open Java API library */ 
        
      /* [2] Get the data  */                           
      String
        sR= "Example of some data accessed from MAExplorer\n",
        maePrjPath= mjaProperty.getMaeCurProjectPath(), 
        maeBrowserTitle= mjaProperty.getMaeBrowserTitle(),
        maeDatabase= mjaProperty.getMaeDatabaseTitle(),
        maeDbSubset= mjaProperty.getMaeDbSubsetTitle();
      String
        sActive[]= mjaFilter.getListFilterNames();
       int
         nActive= sActive.length;
       sR += "  LIST OF ACTIVE FILTERS\n";
       for(int i=0;i<nActive;i++)
         if(sActive[i]!=null)
           sR += "   " + sActive[i] + "\n";
 
      int
        nSamples= mjaSampleList.getNbrHPsamples();
      String
        sampleNames[]= mjaSampleList.getHP_Elist_SampleNames(); 
      sR += "  LIST OF SAMPLES\n";
      for(int i=0;i<nSamples;i++)
        sR += sampleName[i] +"\n";
 
      int
        filteredMIDlist[]= mjaGeneList.getMIDindicesForFilterGeneList(),
        nFilteredGenes= filteredMIDlist.length;
      String
        filteredGeneNames[]=
             mjaGeneList.getGeneFieldDataFromGeneList("workingCL", "GeneName");
      sR += " LIST OF FILTERED GENES\n";
      for(int i=0;i<nSamples;i++)
        sR += "Gene ["+filteredMIDlist[i]+"] = "+filteredGeneNames[i]+"\n";
     
      System.out.println(sR);         /* print to java console */
    } /* Example */    
            
  /* In this example, no actions are taken on popup registry events.
   * However, the methods must exist in the code.
   */
  public void updateCurGene(int mid) { }
  public void updateFilter() { }
  public void updateSlider() { }
  public void updateLabels() { }
  public void close() {this.destroy(); }

} /* end of class Example.java */