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: use of Commands and Snapshots

(updated August 2005)

See commands snapshots

This source code may not be the latest version. Check the newest source code in mesquite.examples.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, CommandRecord commandRec, boolean hiredByName) {
        treeDrawCoordTask= (DrawTreeCoordinator)hireEmployee(commandRec, DrawTreeCoordinator.class, null);
        if (treeDrawCoordTask == null)
            return false;
        numberTask= (NumberForTree)hireEmployee(commandRec, NumberForTree.class, "Number to calculate");
        makeMenu("Baby");
        addSubmenu(null, "Number to calculate", makeCommand("setNumberTask",  this), NumberForTree.class);
        addMenuItem( "-", null);
        bTreeWindow= new BTreeWindow( this, treeDrawCoordTask, numberTask);
        setModuleWindow(bTreeWindow);
        /* Note that if this module is started up in the context of scripting, it does not
        immediately request the window to be shown.  This allows the script for the window
        to set the window's size and position before it's shown, so that the window will
        appear in its correct size and position.  Otherwise, the window would appear here
        in some default location and size, then after the module has started up
        the script for the window would be executed, and the user would see the window
        move itself to a new location and size. */
        if (!commandRec.scripting())
             bTreeWindow.setVisible(true);
        resetAllMenuBars();
        return true;
    }
    /*--------------------------------------*/
    /*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, CommandRecord commandRec) {
        bTreeWindow.setTree(tree, commandRec);
    }
    /*--------------------------------------*/
    /*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)*/
    /* Snapshots store scripts that can return a Commandable object to its current state.
    They are used in saving files and in cloning windows.  Because this module concerns
    itself mostly with one window, the snapshot revolves around that window.*/

    public Snapshot getSnapshot(MesquiteFile file) {
        /* If there is no window, return no snapshot */
        if (bTreeWindow ==null)
           return null;
        /* Get the snapshot from the window, so that the window can be returned to its
        current state (size, position, font, etc.) */
        Snapshot fromWindow = bTreeWindow.getSnapshot(file);
        if (fromWindow == null || fromWindow.getNumLines() ==0)
            return null;
        /* Create a new snapshot to be returned */
        Snapshot sn = new Snapshot();
        /* The getWindow command will cause the module to return a reference to its window*/
        sn.addLine("getWindow");
        /* The tell It command will indicate subsequent commands are to be directed to the window*/
        sn.addLine("tell It");
        /* Here the snapshot commands for the window is incorporated.*/
        sn.incorporate(fromWindow, true);
        /* The endTell command indicates commandRec of the window is finished, and
        subsequent commands are to be directed to the module.*/
        sn.addLine("endTell");
        /* The getTreeDrawCoordinator command requests the module to return a reference to its
        employee module that coordinates tree drawing.  Because the current tree drawing
        employee module is passed as a parameter to addLine, the snapshot building system
        automatically inserts at this point a the snapshot commands of the tree drawing
        module (surrounded by tell It... endTell).  This gives the programmer control
        over when the employee scripts are executed.  (Otherwise, Mesquite detects
        which employees have not yet had their snapshots incorporated, and automatically
        includes them after the commands defined in this snapshot.)
        sn.addLine("getTreeDrawCoordinator", treeDrawCoordTask);
        /* The setNumberTask command sets what module is to be used to calculate a number
        for the tree.  Because the current module is passed as a parameter, it will
        (as explained above) have its snapshot inserted at this point, surrounded by
        tell It...endTell.  This can work because the setNumberTask command causes
        doCommand to respond by returning the module hired, and thus the "It" of the tell command
        will refer to the module returned. */
        sn.addLine("setNumberTask", numberTask);
        /* This causes the window to be shown (The command is not seen below, but is
        a standard command handled by the doCommand method of MesquiteModule).  Note that
        the call to showWindow is made after the window's script is executed, so that
        the window can position and size itself before it is shown.*/
        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)*/
    /* The doCommand method is characteristic of the Commandable interface.  Via it, 
     a Commandable is sent commands for execution.  The first parameter is the name of the
     command, the second the arguments.  The second, a CommandRecord, helps the Commandable
     know if it should bother the user with queries or not (typically if the command is
     being executed as part of a script, it should be assumed the user shouldn't be
     bothered.  There may be other behavioral differences between a command executed under
     commandRec versus not.  The last parameter is a CommandChecker. For the purpose of
     executing commands, the CommandChecker merely asks whether commandName.equalsIgnoreCase(target)
     where target is the command sought (e.g., "getTreeDrawCoordinator").  (The reason for
     the use of a CommandChecker is explained with respect to automatic documentation.)*/

    public Object doCommand(String commandName, String arguments, CommandRecord commandRec, CommandChecker checker) {
        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(commandRec, NumberForTree.class, arguments, null, numberTask);
            if (temp!=null) {
                numberTask = temp;
                bTreeWindow.setNumberTask(numberTask, commandRec);
                resetContainingMenuBar();
                /* The doCommand method should return the module newly hired.  This
                means that in a script, "It" will take on the value of this module, and
                a tell It statement immediately following will know it refers to the
                hired module. Commands that hire a module should always return
              the module as the returned Object. */
                return numberTask;
            }
        }
     /* The doCommand method should call the doCommand method of the superclass to pass 
     any unhandled commands on to the superclass*/
        else 
				return super.doCommand(commandName, arguments, commandRec, checker);
        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, CommandRecord commandRec) {
        if (employee== numberTask)
            bTreeWindow.recalculate(commandRec);
    }
    /*--------------------------------------*/
    /*Indicates to the name of this module for purposes of menu listings and documentation.  (overrides method of MesquiteModule)*/
    public String getName() {
        return "Baby Tree Window";
    }
    /*--------------------------------------*/
    /*Returns the version of this module.  (overrides method of MesquiteModule)*/
    public String getVersion() {
        return "0.9";
    }
    /*--------------------------------------*/
    /*Returns an explanation of what the module does.  (overrides method of MesquiteModule)*/
    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)*/
    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*/
/* This window, even though it doesn't show a doCommand method, is a Commandable
by virtue of its superclass, MesquiteWindow.  The MesquiteWindow class has a doCommand
method that accepts a number of standard commands, including some to size the window
and locate it.  It has a corresponding getSnapshot method that returns the window to
its current state.  This allows the windows to return to their sizes and positions when
files are saved and reopened, via the script saved in the Mesquite block of NEXUS files.*/
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, CommandRecord commandRec){
        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(commandRec);
            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, CommandRecord commandRec){
        numberTask = numTask;
        recalculate(commandRec);
    }
    /*--------------------------------------*/
    /*Recalculates the number for the tree*/
    public void recalculate(CommandRecord commandRec){
        if (numberTask!=null && tree !=null){
            numberTask.calculateNumber(tree, num, commandRec);
            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-2005