General Modularity Example Module Projects & Files Commands & Scripting
Windows Menus Charts Tables Buttons & tools
Trees and Taxa Characters & Models Documentation General Utilities
Modular architecture Modules: subclasses of MesquiteModule Modules employing other modules
Duty Classes Writing modules Documentation for particular modules Packages of Modules
Also: User's introduction to modularity class MesquiteModule Example Module

Writing Mesquite modules

(updated August 2005)

If you want to write your own module, probably most important is to examine some example module code. Find a module that does an analogous task, and base your module on that. It is true that you can create a module by subclassing MesquiteModule and overriding a few methods, but likely it won't do much useful. It will be particularly helpful to examine existing modules for examples of how to structure the doCommand and getSnapshot methods, but also for more specialized methods for particular duty classes.

These might be the steps in making a module.

  1. First, decide on what the module is to do. Subclass the correct duty class. For instance, if you want to make a module that returns a number for a tree, subclass the duty class NumberForTree.
  2. Second, find code for a module of the same duty class to serve as an example. You might even want to copy the code and strip out the details to obtain a skeletal module on which to build yours (assuming you are planning to LGPL your source as well).
  3. Third, check to see what methods are required of a module of that duty class. Add them to your module.
  4. Fourth, compile the module. Its class files should be placed in a directory of the same name as the class of the module, within the mesquite directory in the Mesquite_Folder. Module directories are not expected to be placed directly in the mesquite directory, but rather in subdirectories thereof (e.g. in Mesquite_Folder/mesquite/decorator/). A module AddTinsel.class of the decorator package would therefore be Mesquite_Folder/mesquite/decorator/AddTinsel/AddTinsel.class.
  5. Fifth, if necessary, write the manual. It should be named manual.html and it should be placed in the module's directory.

Below is code for a small example module, one that returns the number of taxa in the tree. A more complex module showing a window is described here.


 /** Note: the getNumber and getResultString methods will probably be soon eliminated from NumberForTree modules */

package mesquite.basic.NumberOfTaxa;
import mesquite.lib.*;  //Where most Mesquite library classes are defined
import mesquite.lib.duties.*; //Where NumberForTree is defined

/**A little module that can counts the number of terminal taxa in a tree.
Usually not to useful, but serves to demonstrate NumberForTree modules*/
public class NumberOfTaxa extends NumberForTree {
  MesquiteNumber nt;

  /**The standard substitute for a constructor (NOTE: do not use constructors for
   Mesquite modules). This method is called when a module is hired and is to be
   started up.  Basic initialization should happen here, just as in a constructor.*/
    /* Overrides method of MesquiteModule */
  public boolean startJob(String arguments, Object condition, CommandRecord commandRec, boolean hiredByName) {
      nt= new MesquiteNumber();
      return true;
  }

  /**Required by NumberForTree; called in case module needs to initialize anything 
  (e.g. querying user for details) before calculations start in earnest.*/
    /* Overrides method of MesquiteModule */
  public void initialize(Tree tree, CommandRecord commandRec)() {
  }

  /**The main calculating method for NumberForTree modules.  The tree for which a
   number is to be calculated is passed as a parameter, as is a number wrapper class 
   to receive the result.  The boolean "scripting" indicates whether the request
   comes in the context of a script being executed.*/
  public void calculateNumber(Tree tree, MesquiteNumber result, MesquiteNumber resultString, CommandRecord commandRec) {
     if (result==null)
        return;
     nt.setValue(tree.numberOfTerminalsInClade(tree.getRoot()));
     result.setValue(nt);
     if (resultString != null)
        resultString.setValue("Number of terminal taxa in tree: " + nt);
  }
  
  /**Returns an explanation of what the module does.*/
    /* Overrides method of MesquiteModule */
  public String getParameters() {
     return "Number of taxa in tree";
  }

  /**Returns the name of the module.*/
    /* Overrides method of MesquiteModule */
  public String getName() {
     return "Number of Taxa";
  }


  /**Returns the version of the module.*/
    /* Overrides method of MesquiteModule */
  public String getVersion() {
     return "1.0";
  }

  /**Returns an explanation of what the module does.*/
    /* Overrides method of MesquiteModule */
  public String getExplanation() {
   return "Counts the number of taxa in a tree." ;
  }
     
} 


© W. Maddison & D. Maddison 1999-2005