import jdsl.core.algo.traversals.*; import java.awt.*; import java.awt.geom.*; import jdsl.core.api.*; /** * @author Lucy Perry (lep) * @version JDSL 2 */ public class TreeDrawer extends EulerTour { // Traversal of a tree that is specialized to draw a // tree within an applet. protected int Yoffset = 40; // Y offset from (0,0) protected int Xoffset = 20; // X offset from (0,0) protected Graphics g; // where to draw the tree protected Color background; // fill color protected int totalShift; // a running total to shift bounding boxes. The shift // distance is the sum of the shifts stored at // ancestors. public TreeDrawer(Graphics gg) { g=gg; background = g.getColor(); } /** * When visiting a node for the first time we shift x by totalShift */ protected void visitFirstTime(Position pos){ int x = ((Integer)pos.get("x")).intValue(); int shift = ((Integer)pos.get("shift")).intValue(); pos.set("x", new Integer(x+totalShift)); totalShift += shift; } /** * When visiting a node for the last time we draw the node. */ protected void visitLastTime(Position pos){ int shift = ((Integer)pos.get("shift")).intValue(); if(!tree_.isRoot(pos)) { //Draw the edge to the parent g.setColor(Color.black); g.drawLine(xPos(pos), yPos(pos), xPos(tree_.parent(pos)), yPos(tree_.parent(pos))); } Color strColor; if (tree_.isExternal(pos)) { strColor=Color.black; } else { strColor=Color.red; } drawString(pos, strColor); totalShift -= shift; cleanup(pos); } /** * External nodes are drawn in the same manner as internal nodes */ protected void visitExternal( Position pos ) { visitFirstTime(pos); visitLastTime(pos); } /** * Draw the string at its proper location. */ private void drawString(Position pos, Color strColor) { String str=pos.element().toString(); int ascent = ((Integer)pos.get("ascent")).intValue(); int descent = ((Integer)pos.get("descent")).intValue(); Rectangle2D bounds = ((Rectangle2D)pos.get("bounds")); int height = (int)bounds.getHeight(); int width = (int)bounds.getWidth(); int x = xPos(pos)-width/2; int y = yPos(pos)-ascent/2; g.setColor(background); g.fillRect(x,y,width,ascent+descent); y += ascent; g.setColor(strColor); g.drawString(str,x,y); } private int xPos(Position p) { int x = ((Integer)p.get("x")).intValue(); int width = ((Integer)p.get("width")).intValue(); return x + width/2 + Xoffset; } private int yPos(Position p) { return ((Integer)p.get("y")).intValue()+Yoffset; } private void cleanup(Position p) { p.destroy("x"); p.destroy("y"); p.destroy("shift"); p.destroy("ascent"); p.destroy("descent"); p.destroy("bounds"); } }