package ciips.animation.tree; import java.awt.*; import ciips.animation.*; public class MultiNode extends BasicNode { protected MultiNode child[]; private int child_cnt; // Actual number of children protected int max_children = 10; // Maximum number of children protected Color active = Color.black; protected Color inactive = Color.white; protected Color labelColor = Color.blue; protected Dimension diameter= new Dimension (8,8); //default for the nodes private static final boolean DEBUG = false; /** * Create a new leaf node with multiple children. */ public MultiNode( ) { child = new MultiNode[ max_children ]; child_cnt = 0; } /** * Create a new leaf node with multiple children * with the weight and number of children as specified by the parameter */ public MultiNode( Object weight, int max_children ) { this.weight = weight; this.max_children = max_children; if( max_children > 0 ) { // Sentinel has no children child = new MultiNode [max_children]; } child_cnt = 0; } /** Adds a new node **/ public void append ( MultiNode b ) throws OverflowException { if (child_cnt < child.length ) { child[child_cnt++] = b; } else throw new OverflowException("MultiNode: append overflow"); } public int getChildCount(){ return child_cnt; } public void setChildCount(){ child_cnt++; } /** Start at a node and set the positions for the sub-tree elements * dx is the distance between two child nodes in x direction * dy is the distance between the parent and the child node in y direction **/ public void setPosition(int x, int y, int width, int height) { int start_x, start_y, dx, dx2, inc_child = 0, padd = 5; super.setXY( x, y ); if( DEBUG ) System.out.println("MultiNode:SetPosition - Node weight is (" + super.getData() + ") at position (" + x + "," + y + ")"); if ( child_cnt > 0) { start_x = x - Math.abs( width / 2 ); start_y = y + height; dx = Math.abs( width / child_cnt); dx2 = Math.abs( dx / 2); /* if ( child_cnt <=1 ) width = dx * 2; else */ width = dx; for (int i=0 ; i<=max_children ; i++) { if ( child[i] != null ) { inc_child++; child[i].setPosition( start_x + (( dx*inc_child )- dx2), start_y, width, height); } } } } /** Draw the edge from node to children **/ public void drawEdge( Graphics g, MultiNode child) { g.setColor( Color.black ); g.drawLine( x + (diameter.width/2), y + diameter.height, child.x + (diameter.height/2), child.y); } /** Draws the corresponding node and the edge to the child nodes **/ public void draw( Graphics g, MultiNode sentinel ) { // Draws a node and descending edges .. except those to the sentinel g.setColor( nodeColor ); g.fillRect(x, y, diameter.width, diameter.height); g.setColor(Color.black); g.drawRect(x, y, diameter.width, diameter.height); g.setColor( Color.white ); g.drawString(""+getData(), x + diff_x, y+diff_y); // Now draw descending edges, unless it's a sentinel for (int i=0; i child_cnt) || (index >= max_children) ) { throw new OverflowException("MultiNode: setNode illegal value"); } child[index] = node; } /** * Get a specific node .. returns null if index is illegal or the node does not exist **/ public MultiNode getTreeNode(int index) { if( (index < 0) || (index >= child_cnt) ) { return null; } return child[index]; } /** * Check if this node is a leaf node. * @return true if the node is a leaf node; false otherwise. */ public boolean isLeaf() { return weight == null; } } /** * public boolean isSentinel() { * return weight == null; * } * * public MultiNode makeSentinel() { * MultiNode s = new MultiNode( null, 0 ); * return s; * } * * public void addChild() { * MultiNode new_node = new MultiNode( null, 0 ); * for ( int i=0; i