General Modularity Example Module Projects & Files Commands & Scripting
Windows Menus Charts Tables Buttons & tools
Trees and Taxa Characters & Models Documentation General Utilities
Introduction The module's source code Employing other modules Menus
Commands & snapshots Automatic documentation generation Windows

An example module: automatic documentation

(updated February 2001)

For more details on Mesquite's documentation generation, see the page on automatic documentation.

This source code may not be the latest version. Check the newest source code in mesquite.developer.BabyTreeWindow


package mesquite.examples.BabyTreeWindow;

import java.applet.*;
import java.awt.*;
import mesquite.lib.*;
import mesquite.lib.duties.*;

/*========================================*/
/*A simple example module that displays a tree window that depends on a tree in a standard tree window*/
public class BabyTreeWindow extends TreeWindowAssistantN {
    DrawTreeCoordinator treeDrawCoordTask;
    NumberForTree numberTask;
    BTreeWindow bTreeWindow;
    
    /*--------------------------------------*/
    /*The basic substitute for a constructor for modules  (overrides method of MesquiteModule)*/
    public boolean startJob(String arguments, Object condition, boolean scripting, boolean hiredByName) {
        treeDrawCoordTask= (DrawTreeCoordinator)hireEmployee(scripting, DrawTreeCoordinator.class, null);
        if (treeDrawCoordTask == null)
            return false;
        numberTask= (NumberForTree)hireEmployee(scripting, NumberForTree.class, "Number to calculate");
        makeMenu("Baby");
        /*Menus could be defined directly in the code of other methods, but menu definitions placed
         in the defineMenus() method are accessible to Mesquite's automatic documentation generation*/
        defineMenus();
        addMenuItem( "-", null);
        bTreeWindow= new BTreeWindow( this, treeDrawCoordTask, numberTask);
        setModuleWindow(bTreeWindow);
        if (!scripting)
             bTreeWindow.setVisible(true);
        resetAllMenuBars();
        return true;
    }
    /*--------------------------------------*/
    /*Menus defined in this method are visible to Mesquite's automatic documentation system  (overrides method of MesquiteModule)*/
    /* This method is called early in Mesquite's startup process, not to actually create the menu item, 
     but for Mesquite's automatic documentation system to find names of menu items and the commands they
     trigger.  It also serves to define the menu items when the module is instantiated (note call in 
     startJob above)*/
    public void defineMenus(){
        addSubmenu(null, "Number to calculate", makeCommand("setNumberTask",  (Commandable)this), NumberForTree.class);
    }
    /*--------------------------------------*/
    /*A method necessary with modules of subclass TreeWindowAssistantN; allows standard tree window
    on which this module depends to indicate tree has changed  (overrides method of TreeWindowAssistantN)*/
    public void setTree(Tree tree, boolean scripting) {
        bTreeWindow.setTree(tree, scripting);
    }
    /*--------------------------------------*/
    /*Makes the module shut down when the go-away box of the window is touched  (overrides method of MesquiteModule)*/
     public void windowGoAway(MesquiteWindow whichWindow) {
        whichWindow.hide();
        whichWindow.dispose();
        iQuit();
    }
    /*--------------------------------------*/
    /*Returns the snapshot necessary to get this module back to the current state.  Note that it incorporates
      a snapshot from its window  (overrides method of MesquiteModule)*/
    public Snapshot getSnapshot(MesquiteFile file) {
        if (bTreeWindow ==null)
           return null;
        Snapshot fromWindow = bTreeWindow.getSnapshot(file);
        if (fromWindow == null || fromWindow.getNumLines() ==0)
            return null;
        Snapshot sn = new Snapshot();
        sn.addLine("getWindow");
        sn.addLine("tell It");
        sn.incorporate(fromWindow, true);
        sn.addLine("endTell");
        sn.addLine("getTreeDrawCoordinator", treeDrawCoordTask);
        sn.addLine("setNumberTask", numberTask);
        sn.addLine("showWindow");
        return sn;
    }
    /*--------------------------------------*/
    /*The standard method for Commandable interface; receives commands either for snapshotting purposes
      or from menu actions  (overrides method of MesquiteModule)*/
    public Object doCommand(String commandName, String arguments, boolean scripting, CommandChecker checker) {
        /*The CommandChecker object is a special object that can exist in one of two forms: the simple checker
        (CommandChecker.defaultChecker) merely checks that two Strings contain the same value, to determine
        if the command given matches one being sought.  This defaultChecker is used when doCommand is serving
        to command the module.  Thus, if the commandName String contains "getTreeDrawCoordinator", then in the
        following line the checker returns true, and the subsequent line is executed; otherwise it returns
        false and the next "else" statement is entered.  However, when Mesquite is generating documentation,
        a different form of CommandChecker is passed here.  This different form always returns false, and so
        these if/else if statements are entered in sequence until they are exhausted.  In the process,
        this special CommandChecker records the parameters passed to it: the command being sought, as well
        as the other Strings, and uses them to compose documentation.  The first String passed to checker.compare
        is explanation of what the command does, and the second is a statement of what parameters (if any)
        the command takes.  */

        if (checker.compare(this.getClass(), "Returns the module serving as the window's draw tree coordinator", null, commandName, "getTreeDrawCoordinator"))
            return treeDrawCoordTask;
        else if (checker.compare(this.getClass(), "Sets which module class should calculate a number for the tree", "[name of module]", commandName, "setNumberTask")) {
            NumberForTree temp= (NumberForTree)replaceEmployee(scripting, NumberForTree.class, arguments, null, numberTask);
            if (temp!=null) {
                numberTask = temp;
                bTreeWindow.setNumberTask(numberTask, scripting);
                resetContainingMenuBar();
                return numberTask;
            }
        }
        else {
            try {return super.doCommand(commandName, arguments, scripting, checker);}
            catch (NoSuchMethodError e){}
        }
        return null;
    }
    /*--------------------------------------*/
    /*Receives message from employees that their parameters have changed an recalculation may be needed  (overrides method of MesquiteModule)*/
    public void employeeParametersChanged(MesquiteModule employee, MesquiteModule source, boolean scripting) {
        if (employee== numberTask)
            bTreeWindow.recalculate(scripting);
    }
    /*--------------------------------------*/
    /*Indicates to the name of this module for purposes of menu listings and documentation.  (overrides method of MesquiteModule)*/
    /*This method returns the name of the module as used in most places in documentation and informing 
    the user what modules are operating*/
    public String getName() {
        return "Baby Tree Window";
    }
    /*--------------------------------------*/
    /*Returns the version of this module.  (overrides method of MesquiteModule)*/
    /*This method is important in documentation to indicate the version.*/
    public String getVersion() {
        return "0.9";
    }
    /*--------------------------------------*/
    /*Returns an explanation of what the module does.  (overrides method of MesquiteModule)*/
    /*This method explains what the module does.  It can be a long explanation if needed, to serve as an
    introductory paragraph */
    public String getExplanation() {
        return "Displays a single tree (the same as in a tree window)." ;
    }
    /*--------------------------------------*/
    /*Returns the authors of the module.  (overrides method of MesquiteModule)*/
    /*This method indicates the authors of the module*/
    public String getAuthors() {
        return "Wayne Maddison";
    }
}
    
/*========================================*/
/*The window (Frame) itself shown on the screen, containing a tree that is the same as the one in the standard tree window*/
public class BTreeWindow extends MesquiteWindow  {
    TreeDisplay treeDisplay;
    DrawTreeCoordinator treeDrawCoordTask;
    TextField p;
    MesquiteNumber num = new MesquiteNumber();
    NumberForTree numberTask;
    Tree tree;
    
    public BTreeWindow (BabyTreeWindow ownerModule, DrawTreeCoordinator treeDrawCoordTask, NumberForTree numberTask){
        super(ownerModule, true); 
        this.treeDrawCoordTask = treeDrawCoordTask;
        this.numberTask = numberTask;
        setWindowSize(500,400);
        setBackground(Color.white);
        p = new TextField();
        p.setBackground(Color.yellow);
        addToWindow(p);
        resetTitle();
    }
    /*--------------------------------------*/
    /* Used to get the title for window (overrides abstract method of MesquiteWindow)*/
    public void resetTitle(){
        setTitle("Baby Tree Window"); 
    }
    /*--------------------------------------*/
    /* Resize the tree display and other components.*/
    public void sizeDisplays(){
        if (treeDisplay==null) return;
        int totalWidth = getWidth();
        int totalHeight = getHeight() - 30;
        treeDisplay.setSize(totalWidth,totalHeight);
        treeDisplay.setFieldSize(totalWidth,totalHeight);
        if (p!=null)
            p.setBounds(0,totalHeight, totalWidth, 30);
    }
    /*--------------------------------------*/
    /*Sets the tree to be shown in the window.*/
    public void setTree(Tree newTree, boolean scripting){
        if (treeDisplay == null) {
            Taxa taxa = newTree.getTaxa();
            treeDisplay =treeDrawCoordTask.createOneTreeDisplay(taxa, this); 
            addToWindow(treeDisplay);
            treeDisplay.setLocation(0,0);
            sizeDisplays();
        }
        
        if (treeDisplay.getTree()!=null)
            treeDisplay.getTree().dispose();
        if (newTree!=null) {
            tree = newTree.cloneTree();
            treeDrawCoordTask.setTreeOfOneDisplay(tree);
            recalculate(scripting);
            treeDisplay.suppressDrawing(false);
            treeDisplay.setVisible(true);
            treeDisplay.repaint();
        }
    }
    /*--------------------------------------*/
    /*Sets what module is to be used for calculating the number for the tree*/
    public void setNumberTask(NumberForTree numTask, boolean scripting){
        numberTask = numTask;
        recalculate(scripting);
    }
    /*--------------------------------------*/
    /*Recalculates the number for the tree*/
    public void recalculate(boolean scripting){
        if (numberTask!=null && tree !=null){
            numberTask.calculateNumber(tree, num, scripting);
            p.setText(numberTask.getName() + " " + num);
        }
        else
            p.setText("");
    }
    /*--------------------------------------*/
    /*Sets the size of the window (setSize and setBounds should not be used!!!>  (overrides method of MesquiteWindow)*/
    public void setWindowSize(int w, int h){
        super.setWindowSize(w,h);
        sizeDisplays();
    }
    /*--------------------------------------*/
    /* Called when the window has been resized, e.g. by user. (overrides method of MesquiteWindow)*/
    public void windowResized(){
        sizeDisplays();
    }
    /*--------------------------------------*/
    /*Disposes of the window*/
    public void dispose(){
        if (treeDisplay!=null){
            if (treeDisplay.getTree()!=null)
                treeDisplay.getTree().dispose();
            treeDisplay.dispose();
        }
        super.dispose();
    }
}


© W. Maddison & D. Maddison 2000-2001