/* RBTreeAlgThread.java */ import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; import java.util.*; import ciips.animation.*; public class RBTreeAlgThread extends AlgThread implements ItemListener, ActionListener, InputCompleteListener { RBTree tree; IntList int_list; static String[] RBTreeDataSets = { "Data Set 0", "Data Set 1", "Data Set 2"}; private static String base_data_file_name = "rb"; static String[] options = { "Display as RBT Trees", "Display as 2,3,4 Trees" }; static final int RBT_DISPLAY = 0; static final int T234_DISPLAY = 1; static final int ADD_NODE = 1; static final int DELETE_NODE = 2; static final int PRINT_PANEL = 3; private boolean rbt_display = true; private boolean t234_display = true; private AlgAnimFrame f; static final int x_offset = 10; static final int y_offset = 50; /** Set the number of comment panel lines needed **/ static { AlgAnimFrame.COMPANEL_LINES = 5; } static { ciips.animation.UIFrame.allowUI( true ); } static Font font = new Font("Courier", Font.PLAIN, 12); static private final int N_HISTORY_PANELS = 4; private static final int WAITING = 0; private static final int ADD_ITEM = 1; private static final int DELETE_ITEM = 2; private static final int STOP = 3; private class NextAction { int next_action = WAITING; public NextAction() { }; public void setNextAction( int x ) { next_action = x; } } private NextAction next_action = new NextAction(); private int next_value = -1; static private int seq = 0; // Sequence number for this thread private int this_seq; static private final boolean DEBUG = true; static private final boolean DEBUG1 = false; public RBTreeAlgThread( AlgAnimFrame frame ) { super(); // setParms( frame, RBTreeDataSets, N_HISTORY_PANELS ); setParms( frame, base_data_file_name, N_HISTORY_PANELS ); f = frame; this_seq = seq++; System.out.println("RBTreeAlgThread " + this_seq + " constructed OK"); } public boolean loadData( int choice ) { String fn; DataInputStream inStream; String line = null; System.out.println("loadData: choice " + choice ); if ( choice == AlgAnimFrame.UI_SELECTED ) { System.out.println("RBTReeAlgThread:loadData - user input selected"); UIFrame uif = frame.getUIFrame(); int_list = uif.getIntList(); if( DEBUG ) System.out.println("RBTAlgThread:loadData " + int_list ); } else { fn = base_data_file_name + choice; System.out.println("loadData: filename ["+fn+"]"); try { URL dataURL = new URL(frame.getApplet().getCodeBase(), fn); int_list = new NamedIntList( dataURL ); } catch (IOException e) { System.out.println("Data file or source file not found"); } catch (NullPointerException e) {} } return int_list != null; } static private int titlex = 5, titley = 5; ComBox adding; static ComBox final_tree = new ComBox( titlex, titley, "Final Red-Black Tree", font ); public void run() { System.out.println("RBTreeAlgThread:run - enter"); // Create the lock object in this thread next_action = new NextAction(); int k = getDataPanelCount(); // Capture reference to the current panel DrawingPanel dpAfter = frame.getCurrentPanel(); // Ensure that an off-screen graphics buffer is built Graphics g = dpAfter.getOffScreenGraphics(); if ( dpAfter == null ) { System.out.println( "run: null drawingPanel"); return; } f.clearPanels(); tree = new RBTree(); boolean opt[] = f.getOptions(); tree.setRBTDisplay( !opt[RBT_DISPLAY] ); generateData(); try { if ( int_list != null ) { if( DEBUG ) System.out.println( "RBTAlgThread:run int list " + int_list ); for(k=0;k0)?data:(-data); dpAfter.removeAllCom(); if ( data > 0 ) { AlgAnimFrame.showText( 1, "Adding new node " + value ); adding = new ComBox( titlex, titley, "Adding " + value, font ); dpAfter.addCom( adding ); // Insert into the tree tree.InsertNode( data ); } else { // Delete it RBNode z = tree.FindNode( value ); if ( z != null ) { String del_caption = "Deleting " + value; AlgAnimFrame.showText(1, del_caption); adding = new ComBox( titlex, titley, del_caption, font ); dpAfter.addCom( adding ); tree.DeleteNode( z, frame ); } else { Exception e = new Exception("Deleting - Value " + value + " not in tree"); System.out.println("RBTreeAlgThread:run " + e.getMessage() ); AlgAnimFrame.showText(2, e.getMessage() ); throw e; } } adding.appendText(" - complete"); /*-*/ tree.drawRBTree(); AlgAnimFrame.showText(4, "Fixup complete"); AlgAnimFrame.pauseStep(); dpAfter.repaint(); AlgAnimFrame.pauseStep(); dpAfter.shuffleDown(); System.out.println("RBTreeAlgThread:run - tree drawn"); dpAfter.removeCom( adding ); } AlgAnimFrame.showText( 1, "Final Red-Black Tree" ); dpAfter.addCom( final_tree ); // finish creating tree dpAfter.repaint(); if( DEBUG ) System.out.println( "RBTAlgThread:run waiting .." ); try { do { // Wait until stop is hit Thread.sleep( 1000L ); if( DEBUG1 ) System.out.println( "RBTAlgThread(" + this_seq + "):run - next_action " + next_action.next_action ); switch( next_action.next_action ) { case ADD_ITEM: System.out.println("RBTreeAlgThread:run - adding extra item " + next_value ); // Disable more additions for a while? dpAfter.removeAllCom(); adding = new ComBox( titlex, titley, "Adding " + next_value, font ); dpAfter.addCom( adding ); // Insert into the tree tree.InsertNode( next_value ); System.out.println("RBTreeAlgThread:run - tree drawn"); dpAfter.removeCom( adding ); dpAfter.addCom( final_tree ); dpAfter.repaint(); next_action.next_action = WAITING; break; case DELETE_ITEM: // Can we find this item? System.out.println("RBTreeAlgThread:run - deleting " + next_value ); dpAfter.removeAllCom(); adding = new ComBox( titlex, titley, "Deleting " + next_value, font ); RBNode z = tree.FindNode( next_value ); if ( z != null ) { String del_caption = "Deleting " + next_value; AlgAnimFrame.showText(1, del_caption); adding = new ComBox( titlex, titley, del_caption, font ); dpAfter.addCom( adding ); tree.DeleteNode( z, frame ); tree.drawRBTree(); dpAfter.removeAllCom(); dpAfter.addCom( final_tree ); dpAfter.repaint(); } else { AlgAnimFrame.showText(1, "Node " + next_value + " isn't in the tree!"); } next_action.next_action = WAITING; break; } } while( next_action.next_action != STOP ); } catch( InterruptedException e ) { System.out.println("RBTreeAlgThread:run - int exception " + e.getMessage() ); } f.finishAlg(); } else { System.out.println("Data file not found\n"); } } catch( Exception e ) { System.out.println("RBTreeAlgThread:run - exception " + e.getClass().getName() + "(" + e.getMessage() + ")" ); } } public void optionChanged( int index, boolean new_state ) { if( DEBUG ) System.out.println("RBTAlgThread: option " + index + " becomes " + new_state ); optionAction( index, new_state ); } private void optionAction( int index, boolean on ) { if( DEBUG ) System.out.println( "RBTAlgThread:optionAction - " + index + (on?" on":" off") ); if ( index < 0 ) { } else { switch( index ) { case RBT_DISPLAY: rbt_display = on; if ( tree != null ) tree.setRBTDisplay( on ); break; case T234_DISPLAY: t234_display = on; break; } } } public void itemStateChanged( ItemEvent e ) { String cmd = e.paramString(); boolean state = false; if( DEBUG ) System.out.println( "RBTAlgThread:itemStateChanged - item " + cmd ); ItemSelectable item = e.getItemSelectable(); int option_index = -1; for( int k=0;k= 0 ) { switch( index ) { case ADD_ACTION: if( DEBUG ) System.out.println("ADD action"); // Don't create a new one! if ( AddDialog == null ) AddDialog = new InputDialog( frame, "Enter value of item to add" ); AddDialog.show(); if( DEBUG ) System.out.println("RBTAlgThread:actPerf - wait for input" ); break; case DEL_ACTION: if( DEBUG ) System.out.println("DEL action"); // Don't create a new one! if ( DeleteDialog == null ) DeleteDialog = new InputDialog( frame, "Enter value of item to delete" ); DeleteDialog.show(); break; case PRINT_ACTION: System.out.println("PRINT action"); break; } } else { System.out.println("RBTreeAlgThread:actionPerformed - unknown action"); } } public void inputComplete( InputDialogEvent e ) { InputDialog src = (InputDialog)(e.getSource() ); String t = e.getText(); next_value = Integer.parseInt( t.trim() ); if( DEBUG ) System.out.println( "RBTAlgThread(" + this_seq + "):inputComplete " + src + " H " + src.hashCode() + " val " + next_value ); //if( DEBUG ) System.out.println( "RBTAlgThread:inputComplete aD " + AddDialog + // " H " + AddDialog.hashCode() ); if ( src == AddDialog ) { if( DEBUG ) System.out.println( "RBTAlgThread:inputComplete - it's an ADD" ); next_action.setNextAction( ADD_ITEM ); // next_action.notify(); } else if ( src == DeleteDialog ) { next_action.setNextAction( DELETE_ITEM ); if( DEBUG ) System.out.println( "RBTAlgThread:inputComplete - it's an DELETE" ); // next_action.notify(); } else { System.out.println("RBTAlgThread:inputComplete - src " + src + " unknown"); } } }