Sindbad~EG File Manager

Current Path : /usr/home/beeson/public_html/dynamicgeometry/org/dynamicgeometry/diagrammer/
Upload File :
Current File : /usr/home/beeson/public_html/dynamicgeometry/org/dynamicgeometry/diagrammer/Diagrammer.java

                                                                     /**
 * Diagrammer.java
 *
 * Created on October 23, 2006, 9:58 PM
 *
 *    Copyright (C) 2006  Christopher Mathenia
 *
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 2 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 */

 /* 10.23.06  Beeson changed calls to value() to setLabelFromString */
 /* 10.23.06  Beeson changed the way startData is called since now it's in scripts.  */

package org.dynamicgeometry.diagrammer;

import java.util.*;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import org.dynamicgeometry.scripts.*;

public class Diagrammer extends JApplet implements ActionListener, MenuListener
{
        private static final int READY = 0; // state of applet is ready for user action
        private static final int UNSELECT_OR_DRAG = 1; // mouse pressed on selected point, so either unselect or drag
        private static final int SELECT_OR_DRAG = 2; // mouse pressed on unselected point, so either select or drag
        private static final int UNSELECT = 3; // mouse pressed on selected non-draggable point (zero isInput)
        private static final int SELECT = 4; // mouse pressed on non-selected, non-draggable point (zero isInput)
        private static final int DRAG = 5; // mouse dragged, so set state to drag
        private static final int DRAW_POINT_OR_SEGMENT = 6; // mouse pressed on canvas, so either draw point or segment
        private static final int DRAW_SEGMENT = 7; // mouse dragged, so draw segment

        //  menu name and primitive menu items
        private static final String MENU_TITLE = "Construct";
        private String[] primitiveMenuItems =
        {
                "Line","Ray","Segment","Triangle","Quadrilateral","Circle","Arc","Extend","Intersect Two Lines",
                "Intersect Line and Circle 1","Intersect Line and Circle 2","Intersect Two Circles (R)","Intersect Two Circles (L)"
        };

        // point and non-point labels
        private static final String[] pointLabel = { "A","B","C","D","E","F","G","H","I","J","K","L","M" };
        private static final String[] objectLabel = { "n","o","p","q","r","s","t","u","v","w","x","y","z" };

        // keep track of which labels to use
        private int pointCounter;
        private int objectCounter;
        private int pointRound = 0;
        private int objectRound = 0;

        // to set an object isInput
        private static final int IS_INPUT = 0;
        private static final int NOT_INPUT = 1;

        // parameters passed in from webpage
        private boolean testMode;
        private String testerResult; // to display test result
        private String whichConstruction;
        private String[] startConstructions; // spec number 12. list of constructions can be passed in for menu

        private int state; // holds the various states of applet
        private boolean shiftDown; // holds state of shift key
        private boolean disable; // if true, user cannot draw anything, only drag

        private ArrayList<GeometricObject> theFigure; // holds all objects in order of creation
        private ArrayList<GeometricObject> selected; // holds all selected objects in order of selection
        private Stack<ArrayList<GeometricObject>> historyFigure; // holds theFigure at each state for undo menu
        private Stack<Integer[]> historyLabel; // holds labels at each state for undo menu
        private Stack<String> historyUndoText; // keep track of undo items for display in menu

        private java.awt.Point curPoint; // to calc distance traveled while dragging
        private GeometricObject targetObject; // keeps track of object if mouse pressed on it

        private JMenu menu;
        private JMenuItem undoMenuItem;
        private JMenuItem testModeMenuItem;

        /**
         * Initializes drawing canvas, menu, and variables when applet is first loaded.
         */
        public void init()
        {
                setContentPane(new DynamicCanvas());
                targetObject = null;
                curPoint = null;
                shiftDown = false;
                testMode = false;
                testerResult = null;
                whichConstruction = null;
                startConstructions = null;
                disable = false;
                theFigure = new ArrayList<GeometricObject>();
                selected = new ArrayList<GeometricObject>();
                historyLabel = new Stack<Integer[]>();
                historyFigure = new Stack<ArrayList<GeometricObject>>();
                historyUndoText = new Stack<String>();
                initMenu();
        }

        /**
         * Initializes necessary variables after init() or after user browses
         * back to webpage. Also, retrieves parameter information from webpage,
         * sets the menu and requests focus in browser window.
         */
        public void start()
        {
                state = READY;

                // initialize label variables
                pointCounter = 0;
                objectCounter = 0;
                pointRound = 0;
                objectRound = 0;

                historyUndoText.push("undo"); // initialize undo history

                getParameters();
                if (whichConstruction != null)
                {
                        try
                        {
                           Scripts s = Scripts.getScriptObject(whichConstruction);
                           ArrayList<GeometricObject> figure =  s.startData(getWidth(),getHeight());
                           setFigure(figure);
                        }
                        catch (Exception ex)
                        {
                             ex.printStackTrace();
                        }
                }
                menu.setVisible(true);
                this.setVisible(true);
                repaint();
                getContentPane().requestFocusInWindow();
        }

        /**
         * Clears resources when user browses away from webpage.
         */
        public void stop()
        {
                targetObject = null;
                curPoint = null;
                historyUndoText.clear();
                historyLabel.clear();
                historyFigure.clear();
                theFigure.clear();
                selected.clear();
                System.gc();
        }

        /**
         * Releases resources when user closes browser.
         */
        public void destroy()
        {
                historyUndoText = null;
                historyLabel = null;
                historyFigure = null;
                theFigure = null;
                selected = null;
                System.gc();
        }

        /**
         * Iterates through figure reseting the location of all GeometricObjects
         * that have isInput field != 0. Location is set according to the location of
         * the object's arguments used to create it. If location is undefined, then
         * sets object visible to false.
         *
         * @param figure        ArrayList<GeometricObject> containing constructed GeometricObjects
         */
        public void updateConstructions(ArrayList<GeometricObject> figure)
        {
                SymbolTable symTbl = new SymbolTable(figure.toArray(new GeometricObject[figure.size()]));
                GeometricObject newObj = null;
                GeometricObject[] results;
                boolean visible = false;
                for (GeometricObject obj : figure)
                {
                        // find constructed point objects
                        if (obj.getIsInput() != IS_INPUT && obj instanceof Point && obj.getConstruction() != null)
                        {
                                try
                                {
                                        results = symTbl.Execute1("", obj.getConstruction(), obj.getArgs().toArray(new GeometricObject[obj.getArgs().size()]));
                                        newObj = results[0];
                                }
                                catch(Exception e) // objects moved in such a way that it no longer exists
                                {
                                        newObj = null;
                                        e.printStackTrace();  // added by Beeson 12.22.06
                                }
                                if (newObj != null) // continue testing for null here in case sym table stops throwing null and returns null
                                {
                                        ((Point)obj).setX(((Point)newObj).getX());
                                        ((Point)obj).setY(((Point)newObj).getY());
                                        if (!obj.isVisible())
                                        {
                                                visible = true;
                                                for (GeometricObject arg : obj.getArgs())
                                                {
                                                        if (!arg.isVisible())
                                                        {
                                                                visible = false;
                                                                break;
                                                        }
                                                }
                                                if (visible)
                                                {
                                                        obj.setVisible(true);
                                                }
                                        }
                                }
                                else // newObj null so make invisible if not already
                                {
                                        if (obj.isVisible())
                                            obj.setVisible(false);
                                }
                        }

                        if (obj.isVisible()) // check for arguments changed to visible false
                        {
                                for(GeometricObject arg : obj.getArgs())
                                {
                                        if (!arg.isVisible())
                                        {
                                            obj.setVisible(false);
                                            break;
                                        }
                                }
                        }
                        else // check for all arguments visible true
                        {
                                visible = true;
                                for (GeometricObject arg : obj.getArgs())
                                {
                                        if (!arg.isVisible())
                                        {
                                            visible = false;
                                            break;
                                        }
                                }
                                if (visible && obj.getIsInput() == IS_INPUT)
                                { // args of non input object could be visible while obj is not
                                        obj.setVisible(true);
                                }
                        }
                }
        }

        /**
         * Resets Diagrammer. If disable is true, then state set to DISABLED,
         * otherwise state READY. If DISABLED, user can only drag and select
         * objects. User cannot create objects and all menu items are disabled.
         *
         * @param disable       boolean indicating whether Diagrammer should
         *                      enter DISABLED state
         */
        public void disableDiagrammer(boolean disable)
        {
                //stop();
                this.disable = disable;
                //start();
                repaint();
        }

        /**
         *  setSelected calls setSelection which sets the corresponding
         *  object selection to true and adds object to selected array.
         *
         *  @param i    int index of object in theFigure to get selection set
         *  @param b    boolean: true indicates selection true. false indicates selection false.
         */
        public void setSelected(int i, boolean b)
        {
                if (i < theFigure.size())
                {
                        setSelection(theFigure.get(i), b);
                }
        }

        /**
         *  setColor applies the given Color to the object in theFigure
         *  that corresponds to the given index.
         *
         *  @param i    int index of object in theFigure to get color set
         *  @param c    Color c to set object
         */
        public void setColor(int i, Color c)
        {
                if (i < theFigure.size())
                {
                        theFigure.get(i).setColor(c);
                }
        }

        /**
         *  setLevel applies the given int level to the object in theFigure
         *  that corresponds to the given index.
         *
         *  @param i    int index of object in theFigure to get level set
         *  @param l    int level to set object
         */
        public void setLevel(int i, int l)
        {
                if (i < theFigure.size())
                {
                        theFigure.get(i).setLevel(l);
                }
        }

        /**
         *  setFigure sets the passed in ArrayList<GeometricObject> as theFigure.
         *  Resets selected according to new ArrayList. Add label to object if needed.
         *
         *  @param newFigure        ArrayList containing constructed GeometricObjects
         *
         */
        public void setFigure(ArrayList<GeometricObject> newFigure)
        {
                theFigure = newFigure;
                selected.clear();
                for (GeometricObject obj : theFigure)
                {
                        if (obj.isSelected())
                        {
                                selected.add(obj);
                        }
                        if (obj.getLabel() == null)
                        {
                                if (obj instanceof Point)
                                {
                                        obj.setLabelFromString(getPointLabel());
                                }
                                else
                                {
                                        obj.setLabelFromString(getObjectLabel());
                                }
                        }
                }
                updateConstructions(theFigure);
                repaint();
        }

        /**
         *  getFigure returns reference to theFigure
         *
         *  @return     ArrayList<GeometrictObject> theFigure
         */
        public ArrayList<GeometricObject> getFigure()
        {
                return theFigure;
        }

        /**
         *  getSelected returns reference to selected
         *
         *  @return     ArrayList<GeometrictObject> selected
         */
        public ArrayList<GeometricObject> getSelected()
        {
                return selected;
        }

        /**
         *  addObject adds object to theFigure
         *
         *  @param obj  GeometricObject to get added to theFigure
         */
        public void addObject(GeometricObject obj)
        {
                theFigure.add(obj);
                if (obj.isSelected())
                {
                        selected.add(obj);
                }
                if (obj.getLabel() == null)
                {
                        if (obj instanceof Point)
                        {
                                obj.setLabelFromString(getPointLabel());
                        }
                        else
                        {
                                obj.setLabelFromString(getObjectLabel());
                        }
                }
        }

        /**
         *  removeObject removes object corresponding to given int index from theFigure
         *
         *  @param i    int index of object to get removed from theFigure
         */
        public void removeObject(int i)
        {
                GeometricObject obj = theFigure.remove(i);
                if (obj != null && obj.isSelected())
                {
                        selected.remove(obj);
                }
        }

        /**
         *  actionPerformed is called when the user selects a menu item. actionPerformed creates a new SymbolTable by
         *  passing an array of selected objects created from the selected ArrayList<GeometricObject>. Then SymbolTable
         *  calls Execute from this SymbolTable object. That is, actionPerformed identifies the action
         *  called and calls execute passing in the corresponding command and selected objects. Appends the object
         *  returned by SymbolTable.execute to theFigure.
         *
         *  @param e    ActionEvent representing an action
         */
        public void actionPerformed(ActionEvent e)
        {

                GeometricObject[] args = null;
                GeometricObject newObj = null;
                GeometricObject[] results;
                String action = e.getActionCommand();
                int index = 0;
                if (action.equals(historyUndoText.peek())) // Undo
                {
                        undo();
                }
                else if (action.equals(testModeMenuItem.getText())) // Tester
                {
                        try
                        {
                                Tester tester = new Tester(this);
				                String result = tester.check(whichConstruction);
                                if (result.equals("yes"))
                                {
                                        //testerResult = "Pass";
                                        tester.updateDatabase(whichConstruction);
					javax.swing.JOptionPane.showMessageDialog(this, "The answer is correct.", "You did it!", javax.swing.JOptionPane.INFORMATION_MESSAGE);
                                } else {
                                        //testerResult = "Fail";
					javax.swing.JOptionPane.showMessageDialog(this, result, "Oops...", javax.swing.JOptionPane.ERROR_MESSAGE);
				}
                        }
                        catch (Exception ex)
                        {
                                System.out.println("Tester check.");
                                ex.printStackTrace();
                        }
                }
                else
                {
                        setHistory("Create " + action);
                        if (action.equals(primitiveMenuItems[index++])) // Line
                        {
                                args = new GeometricObject[2];
                                args[0] = selected.get(0);
                                args[1] = selected.get(1);
                                newObj = getConstructedObject("line", args, IS_INPUT);
                        }
                        else if (action.equals(primitiveMenuItems[index++])) // Ray
                        {
                                args = new GeometricObject[2];
                                args[0] = selected.get(0);
                                args[1] = selected.get(1);
                                newObj = getConstructedObject("ray", args, IS_INPUT);

                        }
                        else if (action.equals(primitiveMenuItems[index++])) // Segment
                        {
                                args = new GeometricObject[2];
                                args[0] = selected.get(0);
                                args[1] = selected.get(1);
                                newObj = getConstructedObject("segment", args, IS_INPUT);
                        }
                        else if (action.equals(primitiveMenuItems[index++])) // Triangle
                        {
                                newObj = new Triangle();
                                for (GeometricObject arg : selected)
                                {
                                        newObj.addArg(arg);
                                }
                                newObj.setIsInput(IS_INPUT);
                                newObj.setLabelFromString(getObjectLabel());
                                newObj.setVisible(true);
                        }
                        else if (action.equals(primitiveMenuItems[index++])) // Quadrilateral
                        {
                                newObj = new Quadrilateral();
                                for (GeometricObject arg : selected)
                                {
                                        newObj.addArg(arg);
                                }
                                newObj.setIsInput(IS_INPUT);
                                newObj.setLabelFromString(getObjectLabel());
                                newObj.setVisible(true);
                        }
                        else if (action.equals(primitiveMenuItems[index++])) // Circle
                        {
                                args = new GeometricObject[2];
                                args[0] = selected.get(0);
                                args[1] = selected.get(1);
                                newObj = getConstructedObject("circle", args, IS_INPUT);
                        }
                        else if (action.equals(primitiveMenuItems[index++])) // Arc
                        {
                                // arc( Point Point, Point A, Point B ) - arc from A to B clockwise on Circle C
                                args = new GeometricObject[4];
                                int i = 0;
                                for (GeometricObject selectedObj : selected)
                                {
                                        if (selectedObj.getClass().getName().equals("org.dynamicgeometry.diagrammer.Circle"))
                                        {
                                                args[i++] = selectedObj.getArgs().get(0);
                                                args[i++] = selectedObj.getArgs().get(1);
                                                setSelection(selectedObj, false);
                                                theFigure.remove(selectedObj);
                                                break; // found circle, so break
                                        }
                                }
                                for (GeometricObject selectedObj : selected)
                                {
                                        // covers segment, ray
                                        if (selectedObj instanceof Line)
                                        {
                                                args[i++] = selectedObj.getArgs().get(0); // start
                                                args[i] = selectedObj.getArgs().get(1); // end
                                                break; // found line, so break
                                        }
                                }
                                newObj = getConstructedObject("arc", args, IS_INPUT);
                        }
                        else if (action.equals(primitiveMenuItems[index++])) // Extend
                        {
                                // extend(A,B,C,D) - constructs point E on ray AB (so B is between A and E) such that BE = CD
                                args = new GeometricObject[4];
                                int i = 0;
                                for (GeometricObject selectedObj : selected)
                                {
                                        if (selectedObj.getClass().getName().equals("org.dynamicgeometry.diagrammer.Ray"))
                                        {
                                                args[i++] = selectedObj.getArgs().get(0); // start
                                                args[i++] = selectedObj.getArgs().get(1); // end
                                        }
                                }
                                if (i == 2) // not 2 Rays
                                {
                                        for (GeometricObject selectedObj : selected)
                                        {
                                                if (selectedObj instanceof Line && !(selectedObj instanceof Ray))
                                                {
                                                        args[i++] = selectedObj.getArgs().get(0); // start
                                                        args[i] = selectedObj.getArgs().get(1); // end
                                                        break; // found line, so break
                                                }
                                        }
                                }
                                newObj = getConstructedObject("extend", args, NOT_INPUT);
                        }
                        else if (action.equals(primitiveMenuItems[index++])) // Intersect Lines
                        {
                                newObj = getConstructedObject("intersectLines", parseIntersectLines(), NOT_INPUT);
                        }
                        else if (action.equals(primitiveMenuItems[index++])) // Intersect Line Circle1
                        {
                                newObj = getConstructedObject("intersectLineCircle1", parseIntersectLineCircle(), NOT_INPUT);
                        }
                        else if (action.equals(primitiveMenuItems[index++])) // Intersect Line Circle2
                        {
                                newObj = getConstructedObject("intersectLineCircle2", parseIntersectLineCircle(), NOT_INPUT);
                        }
                        else if (action.equals(primitiveMenuItems[index++])) // Intersect Circle1
                        {
                                newObj = getConstructedObject("intersectCircles1", parseIntersectCircles(), NOT_INPUT);
                        }
                        else if (action.equals(primitiveMenuItems[index++])) // Intersect Circle2
                        {
                                newObj = getConstructedObject("intersectCircles2", parseIntersectCircles(), NOT_INPUT);
                        }
                        else // non primitive construction
                        {
                                for (String script : Scripts.Euclid)
                                {
                                        if (action.equals(script))
                                        {
                                                GeometricObject[] arg = new GeometricObject[selected.size()];
                                                for (int i = 0; i < selected.size(); i++)
                                                {
                                                        arg[i] = selected.get(i);
                                                }
                                                try
                                                {
                                                        SymbolTable symTbl = new SymbolTable(theFigure.toArray(new GeometricObject[theFigure.size()]));
                                                        results = symTbl.Execute1(/*getPointLabel()*/"", action, arg); //selected.toArray(new GeometricObject[selected.size()]));
                                                        newObj = results[0];
                                                        if (!(newObj instanceof Point))
                                                        {
                                                                newObj.setLabelFromString(getObjectLabel());
                                                                checkFigure(newObj);

                                                        }
                                                        else
                                                        {
                                                                newObj.setLabelFromString(getPointLabel());
                                                        }
                                                        newObj.setIsInput(NOT_INPUT);
                                                        newObj.setVisible(true);


                                                        break; // found call, so break
                                                }
                                                catch(Exception ex)
                                                {
                                                        System.out.println("this should never happen, b/c menu item wouldn't be enabled");
                                                        ex.printStackTrace();
                                                }
                                                break; // found so break
                                        }
                                }
                        }
                        if (newObj != null)
                        {
                                theFigure.add(newObj);
//                                updateConstructions(theFigure);
                        }
                } // end undo else
                repaint();
        }


        /**
         *  Calls updateMenu() to set menu items appropriately when user selects menu
         *  @param e    MenuEvent representing menu selection action
         */
        public void menuSelected(MenuEvent e)
        {
                updateMenu();
        }

        /**
         *  Unused method from implemented abstract listener
         *  @param e    MenuEvent representing canceled menu action
         */
        public void menuCanceled(MenuEvent e)
        {
        }

        /**
         *  Unused method from implemented abstract listener
         *  @param e    MenuEvent representing Deselected menu action
         */
        public void menuDeselected(MenuEvent e)
        {
        }

        /*********** End Public Methods ***************/

        /**
         *  getConstructedObject is a helper class for ActionPerformed.
         *  Instantiate SymbolTable based on selected objects and pass command and arguments
         *  to get a constructed object. If null is returned and object was suppose to be
         *  zero isInput object, then create object and give appropriate settings along with
         *  visible value of false (since its arguments are in a position that doesn't allow it
         *  to be created). If is not a zero isinput object and/or is returned, then set visible
         *  to true and continue on to give appropriate settings. Return the object.
         */
        private GeometricObject getConstructedObject(String cmd, GeometricObject[] args, int input)
        {
                SymbolTable symTbl = new SymbolTable(theFigure.toArray(new GeometricObject[theFigure.size()]));
                GeometricObject newObj = null;
                GeometricObject[] results;
                try
                {
                        results = symTbl.Execute1("", cmd, args);
                        newObj = results[0];
                }
                catch(Exception ex)
                {
                        System.out.println("this should never happen, b/c menu item would not be enabled");
                        ex.printStackTrace();
                }
                if (newObj != null) // continue testing for null in case symtable returns null instead of throwing
                {
                        newObj.setVisible(true);
                        newObj.setIsInput(input);
                        if (newObj instanceof Point)
                        {
                                newObj.setLabelFromString(getPointLabel());
                        }
                        else
                        {
                                newObj.setLabelFromString(getObjectLabel());
                        }
                }
                return newObj;
        }

        /**
         *  Recursively checks if an object's arguments are in theFigure.
         *  If not, then sets appropriate settings and adds to theFigure.
         */
        private void checkFigure(GeometricObject obj)
        {
                for (GeometricObject o : obj.getArgs())
                {
                        if(!(o instanceof Point))
                        {
                                checkFigure(o);
                        }

                        if (!theFigure.contains(o))
                        {
                                o.setIsInput(NOT_INPUT);
                                o.setVisible(true);
                                if (o instanceof Point)
                                {
                                        o.setLabelFromString(getPointLabel());
                                }
                                else
                                {
                                        o.setLabelFromString(getObjectLabel());
                                }
                                theFigure.add(o);
                        }
                }

        }

        /**
         *  setSelection sets a given object to the passed boolean value and updates
         *  selected array accordingly.
         *
         *  If select is true
         *      1.  Object already selected: move object to top of selected list
         *      2.  Object not selected, then select object and add to selected list
         *
         *  If select is false
         *      1.  Unselect object
         *      2.  Remove object from selected list
         */
        private void setSelection(GeometricObject obj, boolean select)
        {
                if (select)
                {
                        if (obj.isSelected()) // already selected, but move object to top of selected list
                        {
                                selected.remove(obj);
                        }
                        else // not already selected
                        {
                                obj.setSelected(select);
                        }
                        selected.add(obj);
                }
                else // unselect
                {
                        obj.setSelected(select);
                        selected.remove(obj);
                }
        }

        /**
         *  clearSelection sets each object's selection in selected array to false
         *  and removes all objects from selected array.
         */
        private void clearSelection()
        {
                for (GeometricObject obj : selected)
                {
                        obj.setSelected(false);
                }
                selected.clear();
        }

        /**
         *  setHistory adds the given ArrayList<GeometricObject> and undo text to
         *  the history stack and updates the history counters.
         */
        private void setHistory(String text)
        {
                historyUndoText.push("undo " + text);

                ArrayList<GeometricObject> ary = getCopyArray(theFigure);
                historyFigure.push(ary);

                Integer[] curState = new Integer[4];
                curState[0] = new Integer(pointCounter);
                curState[1] = new Integer(objectCounter);
                curState[2] = new Integer(pointRound);
                curState[3] = new Integer(objectRound);
                historyLabel.push(curState);

                for (GeometricObject obj : ary) // selection for undo is all false
                {
                        obj.setSelected(false);
                }
        }

        /**
         *  undo resets theFigure to the array at top of history stack, resets history pointers
         *  and removes undo text from top of history text stack. Lastly, clears all selected objects.
         */
        private void undo()
        {
                historyUndoText.pop();
                theFigure = historyFigure.pop();
                Integer[] curState = historyLabel.pop();
                pointCounter  = curState[0].intValue();
                objectCounter = curState[1].intValue();
                pointRound    = curState[2].intValue();
                objectRound   = curState[3].intValue();

                clearSelection();
        }


        /**
         *  getCopyArray returns a duplicate ArrayList<GeometricObject> of given array.
         *  Creates a new ArrayList and calls helper methods to:
         *
         *  For each object in array:
         *      1.  create new object in target at same index location.
         *      2.  copy settings of each of those objects
         *
         *  Effectively, a deep clone is returned.
         *
         *  This method set to public before demo to assist Tester work around
         *  a bug. Tester needs a true copy of theFigure with structure intact.
         */
        public ArrayList<GeometricObject> getCopyArray(ArrayList<GeometricObject> source)
        {
                ArrayList<GeometricObject> target = new ArrayList<GeometricObject>();
                copyArray(source, target);
                copySettings(source, target);
                return target;
        }

        /**
         *  copyArray creates a new object in target of same type for every object
         *  in source.
         *
         *  The target array is returned.
         */
        private ArrayList<GeometricObject> copyArray(ArrayList<GeometricObject> source, ArrayList<GeometricObject> target)
        {
                for (GeometricObject sourceObj : source)
                {
                        if (sourceObj.getClass().getName().equals("org.dynamicgeometry.diagrammer.Point"))
                        {
                                target.add(new Point());
                        }
                        else if (sourceObj.getClass().getName().equals("org.dynamicgeometry.diagrammer.Segment"))
                        {
                                target.add(new Segment());
                        }
                        else if (sourceObj.getClass().getName().equals("org.dynamicgeometry.diagrammer.Ray"))
                        {
                                target.add(new Ray());
                        }
                        else if (sourceObj.getClass().getName().equals("org.dynamicgeometry.diagrammer.Line"))
                        {
                                target.add(new Line());
                        }
                        else if (sourceObj.getClass().getName().equals("org.dynamicgeometry.diagrammer.Triangle"))
                        {
                                target.add(new Triangle());
                        }
                        else if (sourceObj.getClass().getName().equals("org.dynamicgeometry.diagrammer.Quadrilateral"))
                        {
                                target.add(new Quadrilateral());
                        }
                        else if (sourceObj.getClass().getName().equals("org.dynamicgeometry.diagrammer.Arc"))
                        {
                                target.add(new Arc());
                        }
                        else if (sourceObj.getClass().getName().equals("org.dynamicgeometry.diagrammer.Circle"))
                        {
                                target.add(new Circle());
                        }
                        else
                        {
                                System.out.println("Illegal Object in theFigure");
                        }
                }
                return target;
        }

        /**
         *  copySettings applies the settings from each object in source array to
         *  target array.
         *
         *  For each object in source:
         *      1.  set isVisible and isInput settings.
         *      2.  if object is Point, then apply coordinates; otherwise,
         *          set corresponding links to object arguments.
         *
         *  The target array is returned.
         */
        private ArrayList<GeometricObject> copySettings(ArrayList<GeometricObject> source, ArrayList<GeometricObject> target)
        {
                GeometricObject sourceObj = null;
                GeometricObject targetObj = null;

                for (int i = 0; i < source.size(); i++)
                {
                        sourceObj = source.get(i);
                        targetObj = target.get(i);

                        // set variables - no selected b/c all objects in new are not selected
                        targetObj.setColor(sourceObj.getColor());
                        targetObj.setVisible(sourceObj.isVisible());
                        targetObj.setLineThickness(sourceObj.getLineThickness());
                        targetObj.setIsInput(sourceObj.getIsInput());
                        targetObj.setLevel(sourceObj.getLevel());
                        targetObj.setConstruction(sourceObj.getConstruction());
                        targetObj.setSelected(sourceObj.isSelected());

                        // set label
                        Label lbl = new Label();
                        lbl.setLabel(sourceObj.getLabel().toString());
                        lbl.setVisible(sourceObj.getLabel().getVisible());
                        targetObj.setLabel(lbl);

                        for (GeometricObject arg : sourceObj.getArgs()) // map links to arguments
                        {
                                try
                                {
                                        targetObj.addArg(target.get(source.indexOf(arg)));
                                }
                                catch(Exception np)
                                {
                                 //       System.out.println("*** Copy Crasher *** " + arg);
                                 //       np.printStackTrace();
                                }
                        }

                        // if point, set location
                        if (sourceObj.getClass().getName().equals("org.dynamicgeometry.diagrammer.Point"))
                        {
                                ((Point)targetObj).setX(((Point)sourceObj).getX());
                                ((Point)targetObj).setY(((Point)sourceObj).getY());
                        }
                }
                return target;
        }

        /**
         *  getPointLabel returns next point label available.
         */
        private String getPointLabel()
        {
                if (pointRound == 0 && pointCounter < pointLabel.length)
                {
                        return pointLabel[pointCounter++];
                }
                else
                {
                        if (pointCounter == pointLabel.length)
                        {
                                pointCounter = 0;
                                pointRound++;
                        }
                        return pointLabel[pointCounter++] + pointRound;
                }
        }

        /**
         *  getObjectLabel returns next object label available.
         */
        private String getObjectLabel()
        {
                if (objectRound == 0 && objectCounter < objectLabel.length)
                {
                        return objectLabel[objectCounter++];
                }
                else
                {
                        if (objectCounter == objectLabel.length)
                        {
                                objectCounter = 0;
                                objectRound++;
                        }
                        return objectLabel[objectCounter++] + objectRound;
                }
        }

        /**
         *  getParameters retrieves parameters from webpage
         */
        private void getParameters()
        {
                String param = getParameter("disable");
                if (param != null)
                {
                        this.disable = Boolean.parseBoolean(param);
                        param = null; // to be safe.
                }

                param = getParameter("testMode");
                if (param != null)
                {
                        this.testMode = Boolean.parseBoolean(param);
                        param = null; // to be safe.
                }

                param = getParameter("startConstruction");
                if (param != null)
                {
                        startConstructions = param.split(",");
                }
                this.whichConstruction = getParameter("whichConstruction");
//testing
//        this.whichConstruction = "EquilateralTriangle";
//        this.testMode = true;
        }

        /**
         *  returns array with appropriate arguments from selected for intersect lines
         */
        private GeometricObject[] parseIntersectLines()
        {
                GeometricObject[] args = new GeometricObject[4];
                int index = 0;
                for (GeometricObject selectedObj : selected)
                {
                        if (selectedObj instanceof Line) // covers segment, ray
                        {
                                args[index++] = selectedObj.getArgs().get(0); // start
                                args[index++] = selectedObj.getArgs().get(1); // end
                        }
                }
                return args;
        }

        /**
         *  returns array with appropriate arguments from selected for intersect line circle
         */
        private GeometricObject[] parseIntersectLineCircle()
        {
                // intersectLineCircle1( Point A, Point B, Point C, Point D) -
                // point of intersection of line AB with circle(C,D) that is nearer to the A end of line AB. if they meet
                GeometricObject[] args = new GeometricObject[4];
                int index = 0;
                for (GeometricObject selectedObj : selected)
                {
                        if (selectedObj instanceof Line) // covers segment, ray
                        {
                                args[index++] = selectedObj.getArgs().get(0); // start
                                args[index++] = selectedObj.getArgs().get(1); // end
                                break; // found line, so break
                        }
                }
                for (GeometricObject selectedObj : selected)
                {
                        if (selectedObj.getClass().getName().equals("org.dynamicgeometry.diagrammer.Circle"))
                        {
                                args[index++] = selectedObj.getArgs().get(0); // center
                                args[index++] = selectedObj.getArgs().get(1); // circumference
                                break; // found circle, so break
                        }
                }
                return args;
        }

        /**
         *  returns array with appropriate arguments from selected for intersect circle
         */
        private GeometricObject[] parseIntersectCircles()
        {
                GeometricObject[] args = new GeometricObject[2];
                int index = 0;
                for (GeometricObject selectedObj : selected)
                {
                        if (selectedObj.getClass().getName().equals("org.dynamicgeometry.diagrammer.Circle"))
                        {
                                args[index++] = selectedObj;
                        }
                }
                return args;
        }

        /**
         *  initMenu instantiates a menu and adds menu items from primitiveMenuItems to menu.
         *  Also, initMenu adds undo menu item and adds menu to the menu bar of Diagrammer.
         */
        private void initMenu()
        {
                menu = new JMenu(MENU_TITLE);
                menu.addMenuListener(this);

                JMenuItem menuItem = null;
                undoMenuItem = new JMenuItem();
                undoMenuItem.addActionListener(this);
                menu.add(undoMenuItem); // undo

                for (String item : primitiveMenuItems)
                {
                        menuItem = new JMenuItem(item);
                        menuItem.addActionListener(this);
                        menu.add(menuItem);
                }
                testModeMenuItem = new JMenuItem("Check My Work"); // no null in action
                testModeMenuItem.addActionListener(this);

                JMenuBar menuBar = new JMenuBar();
                menuBar.add(menu);
                this.setJMenuBar(menuBar);
        }

        /**
         *  updateMenu sets menu items enabled according to what objects are currently selected in
         *  Diagrammer content pane.
         */
        private void updateMenu()
        {
                for (int i = 0; i < menu.getItemCount(); i++)
                {
                        menu.getItem(i).setEnabled(false);
                }

                if (!disable)
                {
                        undoMenuItem.setText(historyUndoText.peek()); // set undo text top of stack
                        if (historyUndoText.size() > 1) // undo
                        {
                                undoMenuItem.setEnabled(true);
                        }
                        // count each type in selected to test what menuitems to enable
                        int points = 0;
                        int segments = 0;
                        int rays = 0;
                        int lines = 0;
                        int triangles = 0;
                        int arcs = 0;
                        int circles = 0;
                        for (GeometricObject obj : selected)
                        {
                                if (obj instanceof Point) points++;
                                else if (obj instanceof Segment) segments++;
                                else if (obj instanceof Ray) rays++;
                                else if (obj instanceof Line) lines++;
                                else if (obj instanceof Triangle) triangles++;
                                else if (obj instanceof Arc) arcs++;
                                else if (obj instanceof Circle) circles++;
                        }

                        try
                        {
                                // set menu items enabled according to what is currently selected
                                // SymbolTable symTbl = new SymbolTable(theFigure.toArray(new GeometricObject[theFigure.size()]));
                                SymbolTable symTbl = new SymbolTable(selected.toArray(new GeometricObject[selected.size()]));

                                if (selected.size() == 2 && points == 2)
                                {
                                        menu.getItem(1).setEnabled(true);   //  Line
                                        menu.getItem(2).setEnabled(true);   //  Ray
                                        menu.getItem(3).setEnabled(true);   //  Segment
                                        menu.getItem(6).setEnabled(true);   //  Circle
                                }
                                else if (selected.size() == 3 && points == 3)
                                {
                                        menu.getItem(4).setEnabled(true); // Triangle
                                }
                                else if (selected.size() == 4 && points == 4)
                                {
                                        menu.getItem(5).setEnabled(true); // Quadrilateral
                                }
                                else if (selected.size() <= 6 && (lines + rays + segments == 2) && (points == 4  || points == 3))
                                {
                                        if (rays >= 1)
                                        {
                                                menu.getItem(8).setEnabled(true); // Extend (must have at least 1 Ray)
                                        }
                                        if (symTbl.Execute1("", "intersectLines", parseIntersectLines()) != null)
                                        {
                                                menu.getItem(9).setEnabled(true); // Insersect lines
                                        }
                                }
                                else if (selected.size() <= 6 && (lines + rays + segments == 1) && circles == 1 && points <= 4 && points >= 2)
                                {
                                        menu.getItem(7).setEnabled(true);   //  Arc
                                        if (symTbl.Execute1("", "intersectLineCircle1", parseIntersectLineCircle()) != null)
                                        {
                                                menu.getItem(10).setEnabled(true); // intersectLineCircle1
                                        }
                                        if (symTbl.Execute1("", "intersectLineCircle2", parseIntersectLineCircle()) != null)
                                        {
                                                menu.getItem(11).setEnabled(true); // intersectLineCircle2
                                        }
                                }
                                else if (selected.size() <= 6 && circles == 2 && points <= 4 && points >= 2)
                                {
                                        if (symTbl.Execute1("", "intersectCircles1", parseIntersectCircles()) != null)
                                        {
                                                menu.getItem(12).setEnabled(true); // instersectCircle1
                                        }
                                        if (symTbl.Execute1("", "intersectCircles2", parseIntersectCircles()) != null)
                                        {
                                                menu.getItem(13).setEnabled(true); // intersectCircle2
                                        }
                                }

                                // clear items in case testMode or whichConstruction updated
                                int max = primitiveMenuItems.length + 1; // undo
                                menu.remove(testModeMenuItem);
                                while (menu.getItemCount() > primitiveMenuItems.length + 1) // 2 = undo + testModeMenuItem
                                {
                                        menu.remove(menu.getItemCount() - 1);
                                }
                                if (testMode)
                                {
                                        testModeMenuItem.setEnabled(true);
                                        menu.add(testModeMenuItem);
                                }
                                if (whichConstruction != null)
                                {
                                        if (Scripts.earlier(whichConstruction, "NotInEuclid"))
                                        {
                                                GeometricObject[] arg = new GeometricObject[selected.size()];
                                                for (int j = 0; j < selected.size(); j++)
                                                {
                                                        arg[j] = selected.get(j);
                                                }

                                                JMenuItem menuItem = null;
                                                for (String script : Scripts.Euclid)
                                                {
                                                        if (Scripts.earlier(script,whichConstruction))
                                                        {
                                                                menuItem = new JMenuItem(script);
                                                                if (symTbl.Execute1("", script, arg) != null)
                                                                {
                                                                        menuItem.setEnabled(true);
                                                                }
                                                                else
                                                                {
                                                                        menuItem.setEnabled(false);
                                                                }

                                                                menuItem.addActionListener(this);
                                                                menu.add(menuItem);
                                                        }
                                                }
                                                if (Scripts.earlier(whichConstruction, "NotInEuclid"))
                                                {
                                                        menuItem = new JMenuItem(whichConstruction);
                                                        if (symTbl.Execute1("", whichConstruction, arg) != null)
                                                        {
                                                                menuItem.setEnabled(true);
                                                        }
                                                        else
                                                        {
                                                                menuItem.setEnabled(false);
                                                        }
                                                        menuItem.addActionListener(this);
                                                        menu.add(menuItem);
                                                }
                                        }
                                }
                                else if (startConstructions != null)
                                {
                                        GeometricObject[] arg = new GeometricObject[selected.size()];
                                        for (int j = 0; j < selected.size(); j++)
                                        {
                                                arg[j] = selected.get(j);
                                        }

                                        JMenuItem menuItem = null;
                                        for (String script : startConstructions)
                                        {
                                                menuItem = new JMenuItem(script);
                                                if (symTbl.Execute1("", script, arg) != null)
                                                {
                                                        menuItem.setEnabled(true);
                                                }
                                                else
                                                {
                                                        menuItem.setEnabled(false);
                                                }

                                                menuItem.addActionListener(this);
                                                menu.add(menuItem);
                                        }

                                }
                        }
                        catch(Exception np)
                        { // do nothing.. just testing for menu items enabled
                        }
                } // end not disable
        }

        /**
         *  class DynamicCanvas provides the area (canvas) where objects are drawn.
         */
        private class DynamicCanvas extends JPanel implements MouseListener, MouseMotionListener, KeyListener
        {
                /**
                 *  Constructor for DynamicCanvas
                 */
                public DynamicCanvas()
                {
                        addKeyListener(this);
                        addMouseListener(this);
                        addMouseMotionListener(this);
                        setBackground(Color.white);
                }

                /**
                 *  If user presses mouse button while cursor is over canvas, then evaluates
                 *  whether cursor was over an object or empty portion of canvas and applies
                 *  selection and state of application accordingly.
                 */
                public void mousePressed(MouseEvent e)
                {
                        java.awt.Point p = e.getPoint();
                        curPoint = p;

                        GeometricObject obj = null;
                        GeometricObject point = null;
                        GeometricObject geoObject = null;

                        // search last added point, if no point, then last added object.
                        for (ListIterator<GeometricObject> iter = theFigure.listIterator(theFigure.size()); iter.hasPrevious(); )
                        {
                                obj = iter.previous();
                                if (obj.isVisible() && obj.clickedOn(p.getX(), p.getY()))
                                {
                                        if (obj instanceof Point)
                                        {
                                                if (obj.getIsInput() == IS_INPUT)
                                                {
                                                        point = obj;
                                                        break; // found non-zero isinput Point, so break
                                                }
                                                else if (point == null)
                                                {
                                                        point = obj; // found zero isinput Point, so keep looking
                                                }
                                        }
                                        else if (geoObject == null)
                                        {
                                                geoObject = obj; // set to top segment and continue looking for point
                                        }
                                }
                        }
                        if (point != null) // mouse down on point
                        {
                                targetObject = point;
                                if (point.isSelected())
                                {
                                        if (point.getIsInput() != IS_INPUT)
                                        {
                                                state = UNSELECT;
                                        }
                                        else
                                        {
                                                state = UNSELECT_OR_DRAG;
                                        }
                                }
                                else // point not selected
                                {
                                        if (point.getIsInput() != IS_INPUT)
                                        {
                                                state = SELECT;
                                        }
                                        else
                                        {
                                                state = SELECT_OR_DRAG;
                                        }

                                        if (!shiftDown)
                                        {
                                                clearSelection();
                                        }
                                        setSelection(point, true);
                                }
                        }
                        else if (geoObject != null) // no point, but mouse down on top of object
                        {
                                targetObject = geoObject;

                                if (geoObject.isSelected())
                                {
                                        state = UNSELECT_OR_DRAG;
                                }
                                else // segment not selected
                                {
                                        state = SELECT_OR_DRAG;

                                        if (!shiftDown)
                                        {
                                                clearSelection();
                                        }

                                        setSelection(geoObject, true);

                                        // select geoObject parts
                                        ArrayList<GeometricObject> args = geoObject.getArgs();
                                        for (GeometricObject arg : args)
                                        {
                                                setSelection(arg, true);
                                        }
                                }
                        }
                        else if (!disable) // draw point - mouse down on empty portion of canvas
                        {
                                state = DRAW_POINT_OR_SEGMENT;
                                setHistory("Create Point");

                                point = new Point(p.getX(), p.getY());
                                point.setVisible(true);
                                point.setIsInput(IS_INPUT);
                                point.setLabelFromString(getPointLabel());

                                targetObject = point;
                                theFigure.add(point);

                                if (!shiftDown) // set selection of new point
                                {
                                        clearSelection();
                                }
                                else // shift down
                                {
                                        setSelection(point, true);
                                }
                        }
                        this.repaint();
                }


                /**
                 *  mouseDragged is called after mouse pressed and user drags mouse. Depending on
                 *  state of application, either draws a segment or moves selected objects
                 *  in accordance with mouse drag.
                 */
                public void mouseDragged(MouseEvent e)
                {
                        java.awt.Point p = e.getPoint();

                        if (state == UNSELECT_OR_DRAG || state == SELECT_OR_DRAG)
                        {// state UNSELECT_OR_DRAG or SELECT_OR_DRAG first mouseDragged event only
                                // if (!disable)   Beeson commented this out 12.22.06.  Why was it here?
                                {
                                        setHistory("Move");
                                }
                                state = DRAG;
                        }

                        if (state == DRAG) // state is DRAG, so drag!
                        {
                                // move all selected points relative to distance cursor traveled
                                double distanceX = p.getX() - curPoint.getX();
                                double distanceY = p.getY() - curPoint.getY();

                                for (GeometricObject selectedObj : selected)
                                {
                                        if (selectedObj.getIsInput() == IS_INPUT && selectedObj.getClass().getName().equals("org.dynamicgeometry.diagrammer.Point"))
                                        {
                                                ((Point)selectedObj).setX(((Point)selectedObj).getX() + distanceX);
                                                ((Point)selectedObj).setY(((Point)selectedObj).getY() + distanceY);
                                        }
                                }
                                updateConstructions(theFigure); // updates constructed objects in theFigure
                                curPoint = p;
                        }
                        else if (state == DRAW_POINT_OR_SEGMENT) // start drawing segment
                        {
                                state = DRAW_SEGMENT;

                                Point endpoint = new Point(p.x, p.y); // end point for segment
                                endpoint.setVisible(true);
                                endpoint.setIsInput(IS_INPUT);
                                endpoint.setLabelFromString(getPointLabel());

                                theFigure.add(endpoint);

                                Segment segment = new Segment((Point)targetObject, endpoint);
                                segment.setVisible(true);
                                segment.setIsInput(IS_INPUT);
                                segment.setLabelFromString(getObjectLabel());

                                historyUndoText.pop(); // update undo menu text
                                historyUndoText.push("undo Create Segment and end Points");

                                theFigure.add(segment);

                                if (shiftDown)
                                {
                                        setSelection(targetObject, true);
                                        setSelection(endpoint, true);
                                        setSelection(segment, true);
                                }
                        }
                        else if (state == DRAW_SEGMENT) // still drawing segment
                        {
                                GeometricObject obj = theFigure.get(theFigure.size() - 2); // get endpoint of segment
                                ((Point)obj).setX(p.getX());
                                ((Point)obj).setY(p.getY());
                                curPoint = p;
                        }
                        this.repaint();
                }

                /**
                 *  mouseReleased is called after mouse pressed and user releases the button.
                 *  A call is made to this method regardless of whether mouseDragged is called.
                 *  Depending on the state of the application, either unselects an object,
                 *  selects an object, unselects all objects except the object mouse pressed on.
                 */
                public void mouseReleased(MouseEvent e)
                {
                        java.awt.Point p = e.getPoint();

                        if (state == UNSELECT_OR_DRAG || state == UNSELECT) // No drag, so UNSELECT
                        {
                                if (shiftDown) // UNSELECT and shift pressed, so unselect the clicked on object only
                                {
                                        setSelection(targetObject, false);

                                        if (targetObject.getIsInput() == IS_INPUT && targetObject.getClass().getName().equals("org.dynamicgeometry.diagrammer.Point"))
                                        {
                                                // if non-zero point, then also unselect any objects it is a part of
                                                // don't want to check args of non-zero isinput
                                                ArrayList<GeometricObject> unselectObjs = new ArrayList<GeometricObject>();

                                                for (GeometricObject selectedObj : selected)
                                                {
                                                        if (selectedObj.getIsInput() == IS_INPUT) // if selectedObj non-zero isinput, then don't want to unselect arguments
                                                        {
                                                                for (GeometricObject arg : selectedObj.getArgs()) // see if any arg constructing object is targetObject
                                                                {
                                                                        if (arg == targetObject) // if an arg is targetObject, then add object to list to be unselected
                                                                        {
                                                                                unselectObjs.add(selectedObj);
                                                                        }
                                                                }
                                                        }
                                                }
                                                for (GeometricObject obj : unselectObjs) // set selection for any unselectObj
                                                {
                                                        setSelection(obj, false);
                                                }
                                        }
                                }
                                else // UNSELECT and shift not pressed, so unselect all except for clicked on object.
                                {
                                        if (selected.size() == 1) // if single point, then unselect.
                                        {
                                                setSelection(targetObject, false);
                                        }
                                        else
                                        {
                                                clearSelection(); // seems easier to clear all, then reselect object
                                                setSelection(targetObject, true);

                                                if (targetObject.getIsInput() == IS_INPUT) // non-zero isinput objects get their arguments selected
                                                {
                                                        for (GeometricObject arg : targetObject.getArgs()) // if re-selected target is not a point, then have to re-select its points
                                                        {
                                                                setSelection(arg, true);
                                                        }
                                                }
                                        }
                                }
                        }
                        // else if SELECT.. do nothing.. SELECT aready selected on mouse pressed
                        // else if DRAG do nothing.. no longer checking whether dragged on top of another
                        // else if SELECT_OR_DRAG do nothing.. no drag, so SELECT and already selected on mouse pressed
                        // else if DRAW_POINT_OR_SEGMENT do nothing.. no drag, so DRAW_POINT and point already drawn on mouse pressed
                        // else if DRAW_SEGMENT do nothing.. no longer checking whether dragged on top of another
                        state = READY;
                        targetObject = null;
                        curPoint = null;
                        this.repaint();
                }

                /**
                 *  paintComponent is called after a call to repaint() via paint().
                 *  Calls appropriate method to update the menu and calls draw method
                 *  of each object in theFigure.
                 */
                public void paintComponent(Graphics g)
                {
                        super.paintComponent(g);
                        Graphics2D g2D = (Graphics2D)g;
                        for (GeometricObject obj : theFigure)
                        {
                                obj.draw(g2D);
                        }
                        if (testerResult != null)
                        {
                                g.drawString("Result: " + testerResult, 5, 15);
                                testerResult = null;
                        }
                        this.requestFocusInWindow();
                }

                /**
                 *  If shift key is pressed, then sets shiftsDown to true.
                 */
                public void keyPressed(KeyEvent e)
                {
                        if (e.getKeyCode() == KeyEvent.VK_SHIFT)
                        {
                                shiftDown = true;
                        }
                }

                /**
                 *  If shift key is released, then sets shiftsDown to false.
                 */
                public void keyReleased(KeyEvent e)
                {
                        if (e.getKeyCode() == KeyEvent.VK_SHIFT)
                        {
                                shiftDown = false;
                        }
                }

                /**
                 *  Unused method from implemented abstract listener
                 */
                public void mouseClicked(MouseEvent e)
                {
                }

                /**
                 *  Unused method from implemented abstract listener
                 */
                public void mouseEntered(MouseEvent e)
                {
                }

                /**
                 *  Unused method from implemented abstract listener
                 */
                public void mouseExited(MouseEvent e)
                {
                }

                /**
                 *  Unused method from implemented abstract listener
                 */
                public void mouseMoved(MouseEvent e)
                {
                }

                /**
                 *  Unused method from implemented abstract listener
                 */
                public void keyTyped(KeyEvent e)
                {
                }

        } // end dynamicCanvas
}

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists