import java.awt.*; import java.io.InputStream; import java.util.Hashtable; import java.net.*; /** * A simple applet class to demonstrate a sort algorithm. * You can specify a sorting algorithm using the "alg" * attribyte. When you click on the applet, a thread is * forked which animates the sorting algorithm. */ public class SortItem extends java.applet.Applet implements Runnable { /** * The thread that is sorting (or null). */ private Thread kicker; /** * The array that is being sorted. */ int arr[]; /** * The high water mark. */ int h1 = -1; /** * The low water mark. */ int h2 = -1; /* The numbers being switched. */ int s1=-1, s2=-1, status = 0, continuous=0; /** * The name of the algorithm. */ String algName; /** * The sorting algorithm (or null). */ SortAlgorithm algorithm; /** * Fill the array with numbers from 0..n-1. */ void inorder() { int a[] = new int[30]; for (int i=0; i<30; i++) a[i] = (int) i; arr = a; } /** * Fill the array with numbers from n-1..0. */ void reverseorder() { int a[] = new int[30]; for (int i=0; i<30; i++) a[i] = (int) (29-i); arr = a; } /** * Fill the array with random numbers from 0..n-1. */ void scramble() { int a[] = new int[30]; for (int i=0; i<30; i++) a[i] = (int) i; for (int i = 0; i<30; i++) { int j = (int)(i * Math.random()); int t = a[i]; a[i] = a[j]; a[j] = t; } arr = a; } /** * Pause a while. * @see SortAlgorithm */ void pause() { pause(-1, -1); } /** * Pause a while, and draw the high water mark. * @see SortAlgorithm */ void pause(int H1) { pause(H1, -1, -1, -1); } /** * Pause a while, and draw the low&high water marks. * @see SortAlgorithm */ void pause(int H1, int H2) { pause(H1, H2, -1, -1); } void pause(int H1, int H2, int S1, int S2) { h1 = H1; h2 = H2; s1 = S1; s2 = S2; if (kicker != null) repaint(); status = -1; while (status != 1) { try {Thread.sleep(50);} catch (InterruptedException e){} if (continuous == 1) status = 1; } } /** * Initialize the applet. */ public void init() { String at = getParameter("alg"); String order = getParameter("order"); if (at == null) { algName = "QS"; } else algName = at; if (order.equals("sorted")) inorder(); else if (order.equals("reverse")) reverseorder(); else scramble(); resize(1000, 50); } /** * Paint the array of numbers as a list * of horizontal lines of varying lenghts. */ public void paint(Graphics g) { int a[] = arr; int x; String num = ""; int cx = 30, xoffset = 6; Font f = new Font("Helvetica", Font.BOLD, 18); g.setFont(f); // Erase old lines g.setColor(Color.white); g.fillRect(0, 0, size().width, size().height); // Draw new lines g.setColor(Color.black); x = 5; for (int i = 0; i<30; x += cx, i++) { num = "" + arr[i]; if ((i == s1) || (i == s2) || (arr[i] == s1-100) || (arr[i] == s2-100)) { g.setColor(Color.blue); g.drawString(num, x, size().height - 30); g.setColor(Color.black); } else g.drawString(num, x, size().height - 1); } if (h1 >= 0) { g.setColor(Color.red); x = h1 * cx + xoffset; g.drawLine(x, 0, x, size().height); } if (h2 >= 0) { g.setColor(Color.green); x = h2 * cx + xoffset; g.drawLine(x, 0, x, size().height); } } /** * Update without erasing the background. */ public void update(Graphics g) { paint(g); } /** * Run the sorting algorithm. This method is * called by class Thread once the sorting algorithm * is started. * @see java.lang.Thread#run * @see SortItem#mouseUp */ public void run() { try { if (algorithm == null) { algorithm = (SortAlgorithm)Class.forName(algName).newInstance(); algorithm.setParent(this); } algorithm.init(); algorithm.sort(arr); } catch(Exception e) { } } /** * Stop the applet. Kill any sorting algorithm that * is still sorting. */ 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 } } } /** * For a Thread to actually do the sorting. This routine makes * sure we do not simultaneously start several sorts if the user * repeatedly clicks on the sort item. It needs to be * synchronoized with the stop() method because they both * manipulate the common kicker variable. */ private synchronized void startSort() { if (kicker == null || !kicker.isAlive()) { repaint(); kicker = new Thread(this); kicker.start(); } } /** * The user clicked in the applet. Start the clock! */ public boolean mouseUp(java.awt.Event evt, int x, int y) { if (status == 0) { status = 1; startSort(); } return true; } public boolean mouseDown(java.awt.Event evt, int x, int y) { if (status == -1) status = 1; if (evt.clickCount >= 2) continuous = 1; return true; } }