/** * A simple applet class to demonstrate a pattern matching algorithm. * You can specify a pattern matching algorithm from the menu, and * also specify a pattern and a text. * When you click on the applet, a thread is forked which animates * the pattern matching algorithm. * * @author Masayuki Takeda * @version 0.01a, xx July 1996 */ import java.applet.Applet; import java.awt.*; public class PatternMatchingItem extends java.applet.Applet implements Runnable { /** * The thread that is sorting (or null). */ private Thread kicker; public int Sleep_Value = 50; public TextField p_input, t_input; public int Offset = 180; public boolean Pause_Flag; /** * pattern, text, and information about one matching stage */ char P[], T[]; int M, N; int Position, Current; int Comparisons = 0; boolean Match[], Trivial[], Mismatch, Found; /** * The name of the algorithm. */ String algName; /** * The pattern matching algorithm (or null). */ PatternMatchingAlgorithm algorithm; /** * Pause a while, and draw the pattern and the text. * @see PatternMatchingAlgorithm */ void pause(int position, boolean trivial[], int current, boolean mismatch, boolean found, int comparisons) { Position = position; for (int i = 0; i < M; i++) Trivial[i] = trivial[i]; Current = current; Mismatch = mismatch; Found = found; Comparisons = comparisons; if (kicker != null) { repaint(); } if (Sleep_Value == 0) { /* Step by Step */ Pause_Flag = true; while (Pause_Flag && !algorithm.stopRequested) { try {Thread.sleep(10);} catch (InterruptedException e){} } } else { try {Thread.sleep(Sleep_Value);} catch (InterruptedException e){} } } public void set_pattern_and_text(String pattern, String text) { N = text.length(); M = pattern.length(); T = new char [N]; P = new char [M]; text. getChars(0, N, T, 0); pattern.getChars(0, M, P, 0); Match = new boolean [M]; Trivial = new boolean [M]; Position = -1; Current = -1; } /** * Initialize the applet. */ public void init() { Button b; Panel buttons = new Panel(); // buttons.setLayout(new GridLayout(1,3)); // buttons.setLayout(new GridLayout(3,1)); buttons.add(b = new Button("start")); buttons.add(b = new Button("stop") ); buttons.add(b = new Button("next step")); Panel tools = new Panel(); Choice ch = new Choice(); ch.addItem("Naive"); ch.addItem("Morris_Pratt"); ch.addItem("Knuth_Morris_Pratt"); ch.addItem("Boyer_Moore"); ch.addItem("Boyer_Moore_Galil"); tools.add(ch); ch = new Choice(); ch.addItem("very fast"); ch.addItem("fast"); ch.addItem("medium"); ch.addItem("slow"); ch.addItem("very slow"); ch.addItem("step by step"); tools.add(ch); Panel input = new Panel(); input.setLayout(new GridLayout(2,2)); input.add(new Label("pattern")); input.add(p_input = new TextField("abaabab")); input.add(new Label("text")); input.add(t_input = new TextField("abbabbabaababaaa")); add(buttons); add(tools); add(input); algName = "Naive"; set_pattern_and_text(p_input.getText(), t_input.getText()); } void print_char(Graphics g, int off_x, int off_y, char t[], int idx) { int x_coord = off_x + 15*idx; int y_coord = off_y; g.fillRect(x_coord, y_coord - 12, 15, 12); g.setColor(Color.black); g.drawChars(t, idx, 1, x_coord+3, y_coord-2); } void new_alignment(Graphics g) { /* print pattern */ for (int i = 0; i < N; i++) { g.setColor(Color.white); print_char(g, 10, Offset, T, i); } g.setColor(Color.darkGray); g.drawLine(10, Offset, 10+15*N, Offset); g.drawLine(10+15*N, Offset-12, 10+15*N, Offset); /* print pattern */ for (int j = 0; j < M; j++) { g.setColor(Color.white); if (Trivial[j] == true) { g.setColor(Color.green); } print_char(g, 10+15*Position, Offset+20, P, j); } g.setColor(Color.darkGray); g.drawLine(10+15*Position, Offset+20, 10+15*(Position+M), Offset+20); g.drawLine(10+15*(Position+M), Offset+20-12, 10+15*(Position+M), Offset+20); } void current_status(Graphics g) { /* print text */ g.setColor(Color.white); if (Position+Current <= N) { if (Mismatch) { g.setColor(Color.red); } else { g.setColor(Color.yellow); } print_char(g, 10, Offset, T, Position+Current); } /* print pattern */ if (Current < M && !Mismatch) { g.setColor(Color.yellow); print_char(g, 10+15*Position, Offset+20, P, Current); } } /** * Paint the pattern and the text with matching information */ public void paint(Graphics g) { /* print text */ if (Position < 0) { g.setColor(Color.red); g.drawString("Choose an algorithm, and click the start button.", 30, Offset); g.drawString("You can alter the pattern and the text.", 30, Offset+20); return ; } g.setColor(Color.blue); g.drawString(algName + " algorithm", 10, Offset-20); if (Current < 0) { new_alignment(g); } else { current_status(g); if (Found) g.drawString("Found!!!", 200, Offset-20); } g.setColor(getBackground()); g.fillRect(77, Offset + 50, 30, 10); g.setColor(Color.black); g.drawString("Comparisons = "+Comparisons, 10, Offset+60); } public void update(Graphics g) { if (Current == -1) { g.setColor(getBackground()); g.fillRect(0,0,500,250); g.setColor(Color.white); } paint(g); } /** * Run the pattern matching algorithm. This method is * called by class Thread once the pattern matching algorithm * is started. * @see java.lang.Thread#run * @see PatternMatchingItem#mouseUp */ public void run() { try { algorithm = (PatternMatchingAlgorithm)Class.forName(algName).newInstance(); algorithm.setParent(this); algorithm.init(); // p_input.disable(); // t_input.disable(); algorithm.find(T,N,P,M); // p_input.enable(); // t_input.enable(); } catch(Exception e) { } } /** * Stop the applet. Kill any pattern matching algorithm that * is still processing. */ public synchronized void stop() { if (kicker != null) { try { kicker.stop(); } catch (IllegalThreadStateException e) { // ignore this exception } kicker = null; } if (algorithm != null){ try { algorithm.stop(); } catch (IllegalThreadStateException e) { // ignore this exception } } // Input.dispose(); } private synchronized void startPatternMatching() { if (kicker == null || !kicker.isAlive()) { set_pattern_and_text(p_input.getText(), t_input.getText()); repaint(); kicker = new Thread(this); kicker.start(); } } public boolean action(Event e, Object arg) { if (e.target instanceof Choice) { if (arg.equals("very slow")) { Sleep_Value = 2000; } else if (arg.equals("slow")) { Sleep_Value = 1000; } else if (arg.equals("medium")) { Sleep_Value = 500; } else if (arg.equals("fast")) { Sleep_Value = 200; } else if (arg.equals("very fast")) { Sleep_Value = 50; } else if (arg.equals("step by step")) { Sleep_Value = 0; } else { algName = (String)arg; } } else if (e.target instanceof Button) { if (arg.equals("start")) { startPatternMatching(); } else if (arg.equals("stop")) { if (algorithm != null) algorithm.stop(); } else if (arg.equals("next step")) { Pause_Flag = false; } } return true; } }