package edu.princeton.cs.algs4.growingtree.framework;
/*
* @(#)BalanceBSTAnimation.java
*
* Last Modified: 9/15/01
*/
import java.util.*;
import java.awt.*;
/** *
* The Animation object that defines the Balancing of a node in a BSTTree. Two constructors exist,
* one setting the starting string command and step time (preferred use). The other uses defaults.
* The animation builds PartitionBSTAnimation
s from the head node as it goes, keeping
* only one currently animating and allowing rewinding only to the previous
* rotation. The color schemes are set by the head call. The call is
* makePartitionAnimation
.
* * @author Corey Sanders * @version 1.4 9/15/01 */ public class BalanceBSTAnimation
extends AbstractAnimation implements AnimationListener { /** * Refers to the current PartitionBSTAnimation being drawn. */ PartitionBSTAnimation
currentPartition; /** * Holds the node that is replacing. */ private GrowingTreeNode
node; /** * Holds the node that is replacing. */ private GrowingTreeNode
replacingNode; /** * Private doubles used to hold the current location steps. */ private double currentLocation = 0.0; /** * The constructor which initiates the status. The node * which is being balanced must be passed. * * @param node the BSTTree from which the balancing takes place. * @param startingCmd the Animation command that this should start. * @param stepTime the time for each step of the Animation. Sets the initial value. */ public BalanceBSTAnimation(GrowingTreeNode
node, String startingCmd, int stepTime) { super(); setNode(node); setStartingCommand(startingCmd); setStepTime(stepTime); } /** * The constructor which initiates the status and sets the starting command and step time * * @param node the BSTTree which is balanced. */ public BalanceBSTAnimation(GrowingTreeNode
node) { this(node, Animation.PLAY, DEFAULT_STEP); } /************************/ /* Accessor methods */ /************************/ /** * Gets the node from which the balancing takes place. * * @return BSTTree of the node currently being balanced. */ public GrowingTreeNode
getNode() { return node; } /** * Gets the node currently being replaced by the node being balanced (not set until after partition occurs). * * @return BSTTree of the node currently being replaced and animated. */ public GrowingTreeNode
getReplacingNode() { return replacingNode; } /************************/ /* Mutator methods */ /************************/ /** * Sets the node from which the balancing takes place. * * @param node BSTTree of the node currently being balanced. */ public void setNode(GrowingTreeNode
node) { this.node = node; } /** * Sets the node that will replace the balanced node. * * @param GrowingTreeNode of the node replacing the balancing node. */ public void setReplacingNode(GrowingTreeNode
node) { replacingNode = node; } /*********************/ /* Animation methods */ /*********************/ /** * Draws the animation of the next step, using the status of the animation (Animation.PLAY, Animation.PAUSE and so forth). * After completing the drawing, the Animation sends an AnimationEvent to all its listeners, indicating * any information that the listerners may wish to use.
* BSTTreeHead calls: *
selectTreeType
- to locate the replacing node without moving itbalance
- to make recursive calls once the animation has completed)((GrowingTreeHead
)getNode().getHead()).selectTreeType(getNode(), getNode().size() / 2)); } if (getReplacingNode() == null) { return; } // Do actual balancing in tree (Setting the correct final location). getNode().getHead().balanceTreeType(getReplacingNode()); } // BEGIN status if (getStatus().equals(Animation.BEGIN)) { animationAction(); // Beginning message messageAction(Animation.BEGIN + " Balance of "+getNode().getKey().toString()); // set starting status setStatus(getStartingCommand()); // Set partition currentPartition =(PartitionBSTAnimation
)((GrowingTreeHead
)getNode().getHead()).makePartitionAnimation(getNode(), getNode().size() / 2); // Set replacing node (Using selectTree) setReplacingNode((GrowingTreeNode
)((GrowingTreeHead
)getNode().getHead()).selectTreeType(getNode(), getNode().size() / 2));
currentPartition.addAnimationListener(this);
currentPartition.drawAnimation(g2, getStatus());
return;
}
// Currently on a step and no changes have occured. Return to startingStatus
if (getStatus().equals(Animation.STEP)) {
setStatus(getStartingCommand());
}
// PLAY status
if (getStatus().equals(Animation.PLAY)) {
// Set values for animation
currentPartition.setStepTime(getStepTime());
currentPartition.setStep(getStep());
// Set play status
currentPartition.setStatus(Animation.PLAY);
// Draw rotation animation
currentPartition.drawAnimation(g2, Animation.PLAY);
messageAction(Animation.PLAY);
// Finished with current partition
if (currentPartition.getStatus().equals(Animation.FINISH)) {
setStatus(Animation.FINISH);
}
}
// REWIND status
if (getStatus().equals(Animation.REWIND)) {
// Set values for animation
currentPartition.setStepTime(getStepTime());
currentPartition.setStep(getStep());
// Set play status
currentPartition.setStatus(Animation.REWIND);
// Draw rotation animation
currentPartition.drawAnimation(g2, Animation.REWIND);
messageAction(Animation.REWIND);
}
// PAUSE status
if (getStatus().equals(Animation.PAUSE)) {
// Set play status
currentPartition.setStatus(Animation.PAUSE);
// Draw rotation animation
currentPartition.drawAnimation(g2, Animation.PAUSE);
messageAction(Animation.PAUSE);
}
// STOP status
if (getStatus().equals(Animation.STOP)) {
messageAction(Animation.STOP);
return;
}
// FINISH status
if (getStatus().equals(Animation.FINISH)) {
messageAction(Animation.FINISH);
messageAction("*--------Balance of "+getNode().getKey().toString()+"--------*\nReplaced by "+getReplacingNode().getKey().toString());
animationAction();
messageAction(Animation.REDRAW);
return;
}
// Call listeners
animationAction();
}
/**
* Calls all of the listeners of the current Animation and passed information regarding the
* progress and status of the current Animation. Additionally, the id of the type of animation is
* passed. Within, the animationEventPerformed
method is called.
*
* @param cmd String Animation command passed instead of the current Status.
* @param description String description for messages.
*/
protected void animationAction(String cmd, String description) {
super.animationAction(AnimationEvent.BALANCE_BST_ANIMATION, cmd, description, currentLocation);
}
/**
* Implements AnimationListener
which requires the following method.
* The only status of animation it listens for is Animation.ANIMATION_MESSAGE
, to pass
* the message on.
*
* @param e AnimationEvent that represents the information of the Animation.
*/
public void animationEventPerformed(AnimationEvent e) {
// set location each progress call.
currentLocation = e.getProgress();
if (e.getStatus().equals(Animation.ANIMATION_MESSAGE)) {
messageAction(e.getAnimationDescription());
}
if (e.getStatus().equals(Animation.STEP)) {
animationAction(Animation.STEP, null);
}
}
}