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: using windows

(updated August 2005)

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;
    /* Here the module keeps a reference to its window */
    BTreeWindow bTreeWindow;
    
    /*--------------------------------------*/
    /*The basic substitute for a constructor for modules  (overrides method of MesquiteModule)*/
    public boolean startJob(CommandRecord commandRec) {
        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);
        /* The module is here making its window */
        bTreeWindow= new BTreeWindow( this, treeDrawCoordTask, numberTask);
        /* Only one MesquiteWindow can be the designated window of a module.  Generally
        if multiple windows are needed, it is better to use multiple modules
        or instantiations of a module to control them.  The need for a single
        window only arises from the ties between the hierarchical employment arrangment
        of modules and the corresponding heirarchical rules for where menus and menu
        items should be placed.  The method setModuleWindow designates a window as
        being the window for a module. */
        setModuleWindow(bTreeWindow);
        /* Generally the window should not be made visible in startJob if the module
        was started up in the execution of a script.  The reason is that scripts
        typically set the size and location of windows, but they can only do that
        after startJob has completed.  If scripted, it is therefore better to
        avoid showing the window here, and instead allowing the window to size and locate
        itself, and expect that the script will later send a showWindow command to the module */
        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)*/
        /* This method is called when the module's window go-away box is touched.  
        The module can respond appropriately (in this case it shuts itself down by
        calling iQuit(); */
     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;
        /* A module, in returning its snapshot, should embed the snapshot for its window.
        MesquiteWindows construct their own snapshots to record size, position, font, and so on.
        Here the snapshot is recovered, and then embedded using the incorporate method.
        The command "getWindow" is understood by all Mesquite modules, and is used so that the
        module returns a reference to its window, which then is scripted by the tell It command */
        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);
        /* Because the commands of this snapshot will be executed as a script, the window
        was not made visible when it was created in startJob.  Hence, and explicit call
        to showWindow needs to be made. This command is understood by all MesquiteModules,
        and provokes them to make visible their designated window. */
        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, 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();
                return numberTask;
            }
        }
        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*/
/* Here is the window to show the tree, as a subclass of MesquiteWindow */
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){
        /* The constructor for the MesquiteWindow needs to know what module is in charge
        of the window.  The boolean passed indicates whether the window is with (true) or without
        (false) the information bar by default. */
        super(ownerModule, true); 
        this.treeDrawCoordTask = treeDrawCoordTask;
        this.numberTask = numberTask;
        /* Because of Mesquite's (some-would-say-foolish) avoidance of LayoutManagers, 
        the window size should not be set using setSize or setBounds.  Rather,
        setWindowSize should be used */
        setWindowSize(500,400);
        setBackground(Color.white);
        p = new TextField();
        p.setBackground(Color.yellow);
        /* Because MesquiteWindows have the information bar and several alternative 
        views (graphics, text, parameters, explanations, and so on), Components should not
        be added straight to the window using add().  A call to addToWindow adds the component
        to the graphics view of the window. */
        addToWindow(p);
        /* See description of this method below */
        resetTitle();
    }
    /*--------------------------------------*/
    /* Used to get the title for window (overrides abstract method of MesquiteWindow)*/
    /* Mesquite needs to review the titles of windows occasionally in case they are
    out of date (for instance, if the name of the data file has changed).
    MesquiteWindows therefore should provide a resetTitle() method to set their titles.*/
    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)*/
    /* setWindowSize is the method that should be used to size MesquiteWindows */
    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)*/
    /* This method is called when the window is resized by the user or operating system.
    Subclasses of MesquiteWindow can override it to adjust the sizes of their components
    as necessary */
    public void windowResized(){
        sizeDisplays();
    }
    /*--------------------------------------*/
    /*Disposes of the window*/
    /* Called when the window is being closed for good */
    public void dispose(){
        if (treeDisplay!=null){
            if (treeDisplay.getTree()!=null)
                treeDisplay.getTree().dispose();
            treeDisplay.dispose();
        }
        super.dispose();
    }
}


© W. Maddison & D. Maddison 2000-2001