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.
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).
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 */