package edu.princeton.cs.algs4.growingtree.framework; /* * @(#)TreeJPanel.java * * Last Modified: 9/01/02 */ import java.io.File; import javax.swing.*; import javax.swing.event.*; import java.awt.*; import java.awt.image.*; import java.awt.event.*; import java.awt.geom.*; import java.util.*; import java.beans.*; /** * This class provides the panel for a Tree. It keeps the graphics for drawing * the tree and the image for redrawing. It also keeps a timer for the animation and all changes * to the tree proceed through the panel. This is a class that is extended for each specific tree. * * @author Corey Sanders * @version 3.5 9/15/01 */ public class TreeJPanel

extends DrawingJPanel implements OptionListener, ActionListener, TreeMessageListener { /** * TreeHead kept for the current Panel. */ private AnimatingTreeHead

tree; /** * Timer for the animation. */ javax.swing.Timer animationTimer; /** * The delay rate for the animation, set to DEFAULT_DELAY. */ private int delayRate; /** * Represents the current type of inserting value. */ private String keyType; /** * Flag whether the tree is animating or not. */ private boolean animating = true; /** * Flag whether the tree is stepping or not. */ private boolean step = false; /** * Listeners for the tree messages passed. */ private LinkedList treeListeners = new LinkedList(); /** * command passed for type errors. */ public static final String TYPEERR = "type"; /** * command passed for no key errors. */ public static final String NOKEY= "key"; /** * String representing integer types. */ public static final String INTEGER = "Integer"; /** * String representing character types. */ public static final String CHARACTER = "Character"; /** * String representing double types. */ public static final String DOUBLE = "Double"; /** * String representing DRAWING color scheme. */ public static final String DRAWING = "Drawing Schemes"; /** * String representing DRAWING color scheme. */ public static final String BACKGROUND = "Background Color"; /** * String representing INSERT color scheme. */ public static final String INSERT = "Insert Schemes"; /** * String representing SEARCH color scheme. */ public static final String SEARCH = "Search Schemes"; /** * String representing SELECT color scheme. */ public static final String SELECT = "Select Schemes"; /** * String representing ROTATE color scheme. */ public static final String ROTATE = "Rotate Schemes"; /** * String representing DELETE color scheme. */ public static final String DELETE = "Delete Schemes"; /** * String representing TRAVERSE color scheme. */ public static final String TRAVERSE = "Traversal Schemes"; /** * String representing Node color scheme. */ public static final String NODE = "Node"; /** * String representing Key color scheme. */ public static final String KEY = "Key"; /** * String representing Paint color scheme. */ public static final String PAINT = "Paint"; /** * String representing node left color scheme. */ public static final String NODE_LEFT_SETTINGS = "Node Left"; /** * String representing node right color scheme. */ public static final String NODE_RIGHT_SETTINGS = "Node Right"; /** * String representing node animator color scheme. */ public static final String NODE_ANIMATOR_SETTINGS = "Node Animator"; /** * String representing key animator color scheme. */ public static final String KEY_ANIMATOR_SETTINGS = "Key Animator"; /** * String representing key original color scheme. */ public static final String KEY_ORIGINAL_SETTINGS = "Key Original"; /** * String representing node root color scheme. */ public static final String NODE_ROOT_SETTINGS = "Node Root"; /** * String representing node child color scheme. */ public static final String NODE_CHILD_SETTINGS = "Node Child"; /** * String representing node descendant color scheme. */ public static final String NODE_DESCENDANT_SETTINGS = "Node Descendant"; /** * String representing node original color scheme. */ public static final String NODE_ORIGINAL_SETTINGS = "Node Original"; /** * String representing the left paint. */ public static final String LEFT_PAINT = "Paint Left"; /** * String representing the right paint. */ public static final String RIGHT_PAINT = "Paint Right"; /** * The default delay for animation (90). */ public static final int DEFAULT_DELAY = 1; /** * Sole constructor which sets all of the default values for the Panel. Calls the super * constructor of JPanel. Also, it adds itself to listen to component events. */ public TreeJPanel() { super(); // Set delay rate setDelayRate(DEFAULT_DELAY); // Initiates timer setAnimationTimer(new javax.swing.Timer(delayRate, this)); // Sets the default insert type setKeyType(INTEGER); } /****************/ /* Mutators */ /****************/ /** * Sets the head of the tree currently drawn in the Panel. * * @param tree AnimatingTreeHead head. */ public void setTree(AnimatingTreeHead

tree) { if (getTree() != null) { getTree().removeTreeMessageListener(this); } this.tree = tree; getTree().addTreeMessageListener(this); } /** * Sets the delay rate for the timer for the animation. * * param t int delay rate. */ public void setDelayRate(int t) { //delayRate = (int)((t*-10) + 1000); delayRate = t; if (getAnimationTimer() != null) { getAnimationTimer().setDelay(delayRate); } } /** * Sets whether the tree is animating or not. * * @param animating boolean flag as to whether the tree is animating. */ public void setAnimating(boolean animating) { this.animating = animating; setDrawTree(true); repaint(); } /** * Sets whether the tree is stepping or not. * * @param step boolean flag as to whether the tree is stepping. */ public void setStep(boolean step) { this.step = step; getTree().setStepPause(step); } /** * Sets the animation timer for the animation of the panel. * * @param animationTimer javax.swing.Timer defining the steps of animation. */ protected void setAnimationTimer(javax.swing.Timer animationTimer) { this.animationTimer = animationTimer; } /** * Sets the key type for the tree. * * @param keyType String defining the type of key in the tree. */ protected void setKeyType(String keyType) { this.keyType = keyType; } /** * Given a String, converts the string into the specific type set currently for the tree. * A NumberFormatException is caught and an error message String is returned instead * of an object. * * @param text String to be converted into an object. * * @return the object after converting to the type of the tree, or a String error message. */ protected KeyType stringToType(String text) { String errors; KeyType returnObject = null; // Allow flexibility for the first item if (this.getTree().getChild() == null) { try { returnObject = new KeyType(Integer.parseInt(text)); setKeyType(INTEGER); } catch (NumberFormatException e) { try { returnObject = new KeyType(Double.parseDouble(text)); setKeyType(DOUBLE); } catch (NumberFormatException e2) { returnObject = new KeyType(text.charAt(0)); setKeyType(CHARACTER); } } } // Make sure the key type is correct else { try { if (getKeyType().equals(INTEGER)) { returnObject = new KeyType(Integer.parseInt(text)); } if (getKeyType().equals(CHARACTER)) { returnObject = new KeyType(text.charAt(0)); } if (getKeyType().equals(DOUBLE)) { returnObject = new KeyType(Double.parseDouble(text)); } } catch (NumberFormatException e) { errors = new String(" "+text+" "); returnObject = new KeyType(errors); } } return returnObject; } /****************/ /* Accesors */ /****************/ /** * Gets the title for the tree. * * @return String defining the title of the tree. */ public String getTitle() { return "None"; } /** * Get the tree message. The method calls TreeStatusMessage of the tree within the panel. */ public String getTreeStatusMessage() { return getTree().getTreeStatusMessage(); } /** * Gets the head of the tree currently drawn in the Panel. * * @return TreeHead the tree head. */ public AnimatingTreeHead

getTree() { return tree; } /** * Gets whether the tree is animating or not. * * @param true if the tree is animating. */ public boolean isAnimating() { return animating; } /** * Gets whether the tree is stepping or not. * * @param true if the tree is stepping. */ public boolean isStep() { return step; } /** * Gets the key type for the tree. * * @return String defining the type of key in the tree. */ public String getKeyType() { return keyType; } /** * Gets the animation timer for the animation of the panel. * * @return javax.swing.Timer defining the steps of animation. */ protected javax.swing.Timer getAnimationTimer() { return animationTimer; } /** * Gets the input options for the current tree. * * @return String array of the options for the current tree. */ public void getInputOptions() { String[] options = {INTEGER, CHARACTER, DOUBLE}; TreeMessageEvent messageEvent = new TreeMessageEvent(this, TreeMessageEvent.PANEL, TreeMessageEvent.SET_INPUT_OPTIONS, options); ListIterator list = treeListeners.listIterator(0); while (list.hasNext()) { ((TreeMessageListener)list.next()).treeMessageEventPerformed(messageEvent); } } /** * Gets a List of objects made from the String text. The method first gets a List of * Strings using getStringList. Then the method uses stringToType * repeatedly, constructing a LinkedList of objects. Any incorrect strings, the error message * is automatically made and sent in the form of a Dialog. * * @param text String to be made into an Object list. * * @return LinkedList List of objects. */ protected LinkedList getObjectList(String text) { StringBuffer errors = null; LinkedList objectList = new LinkedList(); LinkedList stringList = getStringList(text); int stringListSize = stringList.size(); for (int i=0; i getStringList(String text) { int previousLocation = -1; LinkedList stringList = new LinkedList(); // Remove leading and following whitespace. String workingText = text.trim(); // Length of string int stringLength = workingText.length(); // Go through entire string and put words followed by spaces into linked list. for (int i=0; igetObjectList to produce objects. Then, those objects are inserted with * a newly made DrawingKey. * * @param text String to be inserted into the tree. */ protected void insertKeys(String text) { // Set initial status. setAnimationStatus(); // Object list constructed LinkedList insertObjects = getObjectList(text); StringBuffer errors = null; int objectListSize = insertObjects.size(); // Proceed through list for (int i=0; i< objectListSize; i++) { KeyType key = insertObjects.get(i); // bug fix for when the text includes multiples of the same key if (insertObjects.indexOf(key) != i) { if (errors == null) errors = new StringBuffer(); errors.append(" " + key + " "); continue; } if (getTree().isTreeEmpty()) { getTree().insert(key, new DrawingKey(insertObjects.get(i))); drawTree(); } else { // Insert the object and a new drawing key boolean success = getTree().insert(key, new DrawingKey(insertObjects.get(i))); if (!success) { if (errors == null) errors = new StringBuffer(); errors.append(" " + key + " "); } } } setDrawTree(true); repaint(); getTree().MakeTree(getDrawTreeGraphics()); drawTree(); if (errors != null) { makeDuplicateErrorMessage(errors.toString()); } } /** * Searches the given text for keys in the tree. The method uses the protected method * getObjectList to produce objects. Then, those objects are searched for. * * @param text String to be searched into the tree. */ protected void searchKeys(String text) { // Set initial status. setAnimationStatus(); // Object list constructed LinkedList insertObjects = getObjectList(text); int objectListSize = insertObjects.size(); // Proceed through list for (int i=0; i< objectListSize; i++) { KeyType key = insertObjects.get(i); // Search getTree().search(key); } setDrawTree(true); repaint(); } /** * Selects the given text for keys in the tree. The method uses the protected method * getObjectList to produce objects. Then, those objects are selected. * * @param text String to be selected into the tree. */ protected void selectKeys(String text) { // Set initial status. setAnimationStatus(); // Object list constructed LinkedList stringList = getStringList(text); int stringListSize = stringList.size(); // Proceed through list for (int i=0; i< stringListSize; i++) { try { int key = (Integer.decode((String)stringList.get(i))).intValue(); Tree

returnTree = getTree().select(getTree().getChild(), key); if (returnTree == null) { messageAction(TreeMessageEvent.ERROR_MESSAGE, "You must enter an integer less\nthan the size of that node's subtree!"); } } catch (NumberFormatException e) { makeTypeIntegerErrorMessage(" selection."); break; } } setDrawTree(true); repaint(); } /** * Deletes the given text from the tree. The method uses the protected method * getObjectList to produce objects. Then, those objects are deleted. * * @param text String to be deleted into the tree. */ protected void deleteKeys(String text) { // Set initial status. setAnimationStatus(); StringBuffer errors = null; // Object list constructed LinkedList insertObjects = getObjectList(text); int objectListSize = insertObjects.size(); // Proceed through list for (int i=0; i< objectListSize; i++) { KeyType key = insertObjects.get(i); // Delete if(!getTree().remove(key)) { if (errors == null) { errors = new StringBuffer(); } errors.append(" "+key+" "); } } if (errors != null) { makeMissingErrorMessage(errors.toString()); } setDrawTree(true); repaint(); getTree().MakeTree(getDrawTreeGraphics()); drawTree(); } /*******************/ /* Click Commands */ /*******************/ /** * Deletes the given node from the tree. * * @param node the Tree node to be deleted from the tree. */ protected void deleteNode(Tree

node) { // Set initial status. setAnimationStatus(); getTree().remove(node); setDrawTree(true); repaint(); } /** * Partitions the given node. A JOptionPane appears requesting the entering of the kth element * with which to partition. * * @param node the node to partition. */ protected void partitionNode(Tree

node) { // Set initial status. setAnimationStatus(); if (node == null) return; // Get the kth element. String response = JOptionPane.showInputDialog(this, "Please enter the kth\nelement to partition:", "Partition Element", JOptionPane.QUESTION_MESSAGE); try { int key = (Integer.decode(response)).intValue(); Tree

returnTree = getTree().partition(node, key); if (returnTree == null) { JOptionPane.showMessageDialog(this, "You must enter an integer less than the size of that node's subtree!", "Type Error", JOptionPane.ERROR_MESSAGE); } } catch (NumberFormatException e) { JOptionPane.showMessageDialog(this, "You must enter an integer count for a partition!", "Type Error", JOptionPane.ERROR_MESSAGE); } setDrawTree(true); repaint(); } /** * Selects the given node. A JOptionPane appears requesting the entering of the kth element * with which to select. * * @param node the node to select from. */ protected void selectNode(Tree

node) { // Set initial status. setAnimationStatus(); if (node == null) return; // Get the kth element. String response = JOptionPane.showInputDialog(this, "Please enter the kth\nelement to select:", "Select Element", JOptionPane.QUESTION_MESSAGE); try { int key = (Integer.decode(response)).intValue(); Tree

returnTree = getTree().select(node, key); if (returnTree == null) { JOptionPane.showMessageDialog(this, "You must enter an integer less than the size of that node's subtree!", "Type Error", JOptionPane.ERROR_MESSAGE); } } catch (NumberFormatException e) { JOptionPane.showMessageDialog(this, "You must enter an integer count for a partition!", "Type Error", JOptionPane.ERROR_MESSAGE); } setDrawTree(true); repaint(); } /** * Changes the input according to the text string. The tree is cleared if it is not empty. * Also a key type change message is sent to all listeners. * * @param text the String representing the input change. */ protected void inputChange(String text) { // Already set if (getKeyType().equals(text)) return; // Clear tree clear(); setKeyType(text); } /** * Clears the tree. Initiates a JOptionPane to confirm clearing. */ protected int clearTree() { // Set initial status. setAnimationStatus(); // Confirm int response = JOptionPane.showConfirmDialog(this, "Are you sure you wish to clear the tree?", "Clear Tree", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (response == JOptionPane.YES_OPTION) { // Clears tree clear(); // Cleared tree return 1; } // Didn't clear return 0; } /** * Clears the tree. Does not initiate a JOptionPane to confirm clearing. Just clears. */ protected void clear() { // Clears tree getTree().clear(); setDrawTree(true); repaint(); } /************************************************/ /* Commands that are called after OptionEvents. */ /************************************************/ public void setSubtreeCountsCommand(boolean visible) { setDrawTree(true); repaint(); } /** * Insert command. Simply calls insertKeys with the text. Overide if necessary. * * @param text String to insert. */ public void insertCommand(String text) { insertKeys(text); } /** * Search command. Simply calls searchKeys with the text. Overide if necessary. * * @param text String to search. */ public void searchCommand(String text) { searchKeys(text); } /** * Delete command. Simply calls deleteKeys with the text. Overide if necessary. * * @param text String to delete. */ public void deleteCommand(String text) { deleteKeys(text); } /** * Insert command. Simply calls insertKeys with the text. Overide if necessary. * * @param node Tree to delete. */ public void deleteCommand(Tree

node) { deleteNode(node); } /** * Select command. Simply calls selectKeys with the text. Overide if necessary. * * @param text String to select. */ public void selectCommand(String text) { selectKeys(text); } /** * Select command. Simply calls selectKeys with the text. Overide if necessary. * * @param text String to select. */ public void selectCommand(Tree

node) { selectNode(node); } /** * Clear command. Simply calls clearTree. Overide if necessary. */ public void clearCommand() { clearTree(); } /** * Clear all command. Simply calls clear. Overide if necessary. */ public void clearAllCommand() { clear(); } /** * Partition command. Simply calls partitionNode. Overide if necessary. * * @param node Tree to partition. */ public void partitionCommand(Tree

node) { partitionNode(node); } /** * RotateUp command. Does Nothing (not all trees have rotations). Overide if necessary. * * @param node Tree to rotateUp. */ public void rotateUpCommand(Tree

node) { } /** * RotateToTop command. Does Nothing (not all trees have rotations). Overide if necessary. * * @param node Tree to rotateToTop. */ public void rotateToTopCommand(Tree

node) { } /** * RotateUpDouble command. Does Nothing (not all trees have rotations). Overide if necessary. * * @param node Tree to rotateUpDouble. */ public void rotateUpDoubleCommand(Tree

node) { } /** * Splay command. Does Nothing (not all trees have rotations). Overide if necessary. * * @param node Tree to splay. */ public void splayCommand(Tree

node) { } /** * Balance command. Does Nothing. Overide if necessary. * * @param node Tree to balance. */ public void balanceCommand(Tree

node) { } /** * Traverse command. Does Nothing. Overide if necessary. * * @param traverseType int that defines the traverseType. */ public void traverseCommand(int traverseType) { } /** * Play command. */ public void playCommand() { getTree().setJumpStep(false); getTree().setStepPause(false); getTree().play(); } /** * Play command. */ public void playStepCommand() { getTree().setJumpStep(false); getTree().setStepPause(true); getTree().play(); } /** * Play command. */ public void playFastCommand() { getTree().setJumpStep(true); getTree().setStepPause(true); getTree().play(); } /** * Play command. */ public void rewindCommand() { getTree().setJumpStep(false); getTree().setStepPause(false); getTree().rewind(); } /** * Play command. */ public void rewindStepCommand() { getTree().setJumpStep(false); getTree().setStepPause(true); getTree().rewind(); } /** * Play command. */ public void rewindFastCommand() { getTree().setJumpStep(true); getTree().setStepPause(true); getTree().rewind(); } /** * Pause command. */ public void pauseCommand() { getTree().pause(); } /** * Stop command. */ public void stopCommand() { getTree().stop(); } /** * Animation command. * * @param step boolean turning animation on or off. */ public void animatingCommand(boolean animatingCommand) { setAnimating(animatingCommand); } /** * Animation quality command. * * @param quality int setting the quality of the animation. */ public void animationQualityCommand(int quality) { setDelayRate(quality); } /** * Animation speed command. * * @param speed int setting the speed of the animation. */ public void animationSpeedCommand(int speed) { getTree().setTreeAnimationsStepSize(speed); } /** * Input Change Command. * * @param input string setting the new input type. */ public void inputChangeCommand(String input) { inputChange(input); } public void saveTreeCommand(TreeJPanel

panel) { if (panel != this) { panel.setSettings(this); } } /** * Constructs a popupmenu, using the actionlistener passed. The popupMenu * contains all of the options available through the current tree. For this * class, no items are added, making it necessary to overide the method. * * @param actionListener the listener add to the actions of all the items made in the menu. * * @return JPopupMenu which is the menu constructed within the panel. */ public JPopupMenu makeJPopupMenu(ActionListener actionListener) { JPopupMenu popupMenu = new JPopupMenu(); return popupMenu; } /** * Passes a message to make the color scheme options for the current Panel. Generally called * if this panel becomes selected. A tree message is sent with TreeMessageEvent.COLOR_PANEL with * this as the object. */ public void makeColorSchemeOptions() { messageAction(TreeMessageEvent.COLOR_PANEL, this); } /** * Passes a message to make the color settings options for the current Panel. Generally called * if this panel becomes selected. A tree message is sent with TreeMessageEvent.SET_PRESET_COLOR_OPTIONS with * this as the object. */ public void makeColorSettings() { messageAction(TreeMessageEvent.SET_PRESET_COLOR_OPTIONS, this); } /** * Constructs the color settings for this tree, using the given parameter. * * @param allTreeToolsPanel Panel to construct the color settings. */ public void constructColorOptions(ColorOptionsJPanel allTreeToolsPanel) { } /** * Constructs the color settings combo box and sets the box for the given colorOptionsPanel. * * @param colorOptionsPanel the colorOptionsPanel for which the JComboBox is set. */ public void constructPresetColorOptions(ColorOptionsJPanel colorOptionsPanel) { } /************************/ /* Tree Message Methods */ /************************/ /** * Adds an TreeMessageListener from the TREE, according to * the TreeMessageListener interface and the TreeMessageEvent. * * @param l the listener added recieves the TreeMessageEvents occuring. */ public void addTreeMessageListener(TreeMessageListener l) { treeListeners.add(l); } /** * Removes an TreeMessageListener from the TREE, according to * the TreeMessageListener interface and the TreeMessageEvent. * * @param l the listener removed from recieving the TreeMessageEvents occuring. */ public void removeTreeMessageListener(TreeMessageListener l) { treeListeners.remove(l); } /** * Calls all of the treeListeners of the Tree and passes the tree message information information regarding the * status of the Tree. * * @param msg String message for the action of the message. * @param msgObj the accompanying object for the message. */ protected void messageAction(String msg, Object msgObj) { // Returns if the panel is not shown, and the message is not an error or tree status (msgObj = tree). if (!isComponentShown() && !(msg.equals(TreeMessageEvent.ERROR_MESSAGE)) && !(msg.equals(TreeMessageEvent.COLOR_PANEL)) && !(msgObj == getTree()) && !(msg.equals(TreeMessageEvent.SET_PRESET_COLOR_OPTIONS))) { return; } if (msgObj == getTree()) { TreeMessageEvent messageEvent = new TreeMessageEvent(this, TreeMessageEvent.PANEL, TreeMessageEvent.STATUS_MESSAGE); ListIterator list = treeListeners.listIterator(0); while (list.hasNext()) { ((TreeMessageListener)list.next()).treeMessageEventPerformed(messageEvent); } } TreeMessageEvent messageEvent = new TreeMessageEvent(this, TreeMessageEvent.PANEL, msg, msgObj); ListIterator list = treeListeners.listIterator(0); while (list.hasNext()) { ((TreeMessageListener)list.next()).treeMessageEventPerformed(messageEvent); } } /******************************/ /* Implements OptionListener. */ /******************************/ /** * Sets the settings for the panel param. * * @param panel the panel for the settings to be set. */ public void setSettings(TreeJPanel

panel) { } /** * Recieved an event from an OptionJPanel with one of the given commands. The Panel * responds accordingly. The Methods it calls (for example: insertCommand, rotateCommand...) * should be overiden in extending classes to functionable. * * @param e OptionEvent recieved from the event performed. */ public void optionEventPerformed(OptionEvent e) { if (e.getActionCommand().equals(OptionEvent.INTEGER_FIELDS_ON)) { setSubtreeCountsCommand(true); } if (e.getActionCommand().equals(OptionEvent.INTEGER_FIELDS_OFF)) { setSubtreeCountsCommand(false); } if (e.getActionCommand().equals(OptionEvent.INSERT)) { insertCommand((String)e.getObjectValue()); } if (e.getActionCommand().equals(OptionEvent.CLEAR)) { clearCommand(); } if (e.getActionCommand().equals(OptionEvent.CLEAR_ALL)) { clearAllCommand(); } if (e.getActionCommand().equals(OptionEvent.ROTATE_CLICK)) { rotateUpCommand((Tree

)e.getObjectValue()); } if (e.getActionCommand().equals(OptionEvent.ROTATE_TOP_CLICK)) { rotateToTopCommand((Tree

)e.getObjectValue()); } if (e.getActionCommand().equals(OptionEvent.ROTATE_DOUBLE_CLICK)) { rotateUpDoubleCommand((Tree

)e.getObjectValue()); } if (e.getActionCommand().equals(OptionEvent.SPLAY_CLICK)) { splayCommand((Tree

)e.getObjectValue()); } if (e.getActionCommand().equals(OptionEvent.PARTITION_CLICK)) { partitionCommand((Tree

)e.getObjectValue()); } if (e.getActionCommand().equals(OptionEvent.DELETE)) { deleteCommand((String)e.getObjectValue()); } if (e.getActionCommand().equals(OptionEvent.DELETE_CLICK)) { deleteCommand((Tree

)e.getObjectValue()); } if (e.getActionCommand().equals(OptionEvent.INPUT_CHANGE_ALL)) { inputChangeCommand((String)e.getObjectValue()); } if (e.getActionCommand().equals(OptionEvent.SEARCH)) { searchCommand((String)e.getObjectValue()); } if (e.getActionCommand().equals(OptionEvent.SELECT)) { selectCommand((String)e.getObjectValue()); } if (e.getActionCommand().equals(OptionEvent.SELECT_CLICK)) { selectCommand((Tree

)e.getObjectValue()); } if (e.getActionCommand().equals(OptionEvent.BALANCE)) { balanceCommand(null); } if (e.getActionCommand().equals(OptionEvent.BALANCE_CLICK)) { balanceCommand((AnimatingTree

)e.getObjectValue()); } if (e.getActionCommand().equals(OptionEvent.PREORDER_TRAVERSAL)) { traverseCommand(TreeHead.PREORDER_TRAVERSAL); } if (e.getActionCommand().equals(OptionEvent.POSTORDER_TRAVERSAL)) { traverseCommand(TreeHead.POSTORDER_TRAVERSAL); } if (e.getActionCommand().equals(OptionEvent.INORDER_TRAVERSAL)) { traverseCommand(TreeHead.INORDER_TRAVERSAL); } if (e.getActionCommand().equals(OptionEvent.LEVELORDER_TRAVERSAL)) { traverseCommand(TreeHead.LEVELORDER_TRAVERSAL); } if (e.getActionCommand().equals(OptionEvent.ANIMATION_PAUSE)) { pauseCommand(); } if (e.getActionCommand().equals(OptionEvent.ANIMATION_STOP)) { stopCommand(); } if (e.getActionCommand().equals(OptionEvent.ANIMATION_PLAY)) { playCommand(); } if (e.getActionCommand().equals(OptionEvent.ANIMATION_REWIND)) { rewindCommand(); } if (e.getActionCommand().equals(OptionEvent.ANIMATION_STEP_REWIND)) { rewindStepCommand(); } if (e.getActionCommand().equals(OptionEvent.ANIMATION_STEP_FORWARD)) { playStepCommand(); } if (e.getActionCommand().equals(OptionEvent.ANIMATION_FAST_REWIND)) { rewindFastCommand(); } if (e.getActionCommand().equals(OptionEvent.ANIMATION_FAST_FORWARD)) { playFastCommand(); } if (e.getActionCommand().equals(OptionEvent.ANIMATION_ON)) { animatingCommand(true); } if (e.getActionCommand().equals(OptionEvent.ANIMATION_OFF)) { animatingCommand(false); } if (e.getActionCommand().equals(OptionEvent.ANIMATION_QUALITY)) { animationQualityCommand(((Integer)e.getObjectValue()).intValue()); } if (e.getActionCommand().equals(OptionEvent.ANIMATION_SPEED)) { animationSpeedCommand(((Integer)e.getObjectValue()).intValue()); } if (e.getActionCommand().equals(OptionEvent.GET_INPUT_OPTIONS)) { getInputOptions(); } if (e.getActionCommand().equals(OptionEvent.SAVE_ALL)) { saveTreeCommand((TreeJPanel

)e.getObjectValue()); } } /************************************************/ /* Implements TreeMessage Listener */ /************************************************/ /** * Listens to tree message events. * * @param e TreeMessageEvent that contains information about the tree. */ public void treeMessageEventPerformed(TreeMessageEvent e) { // FINISH message or REDRAW message if ((e.getMessage().equals(Animation.FINISH)) || (e.getMessage().equals(Animation.REDRAW))) { setDrawTree(true); repaint(); } // Else send the message out further to those listenning to this object if (!(e.getMessage().equals(Animation.REDRAW))) { messageAction(e.getMessage(), e.getMessageObject()); } } /************************************************/ /* Implements Action Listener */ /************************************************/ /** * Listens to action events. * * @param e ActionEvent that contains information about the tree. */ public void actionPerformed(ActionEvent e) { repaint(); } }