1/* 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * - Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * - Neither the name of Oracle nor the names of its 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32/* 33 * This source code is provided to illustrate the usage of a given feature 34 * or technique and has been deliberately simplified. Additional steps 35 * required for a production-quality application, such as security checks, 36 * input validation and proper error handling, might not be present in 37 * this sample code. 38 */ 39 40 41 42import java.awt.Color; 43import java.awt.Dimension; 44import java.awt.Graphics; 45import java.awt.event.MouseEvent; 46import java.awt.event.MouseListener; 47 48 49/** 50 * A simple applet class to demonstrate a sort algorithm. 51 * You can specify a sorting algorithm using the "alg" 52 * attribute. When you click on the applet, a thread is 53 * forked which animates the sorting algorithm. 54 * 55 * @author James Gosling 56 */ 57@SuppressWarnings("serial") 58public class SortItem extends java.applet.Applet implements Runnable, 59 MouseListener { 60 61 /** 62 * The thread that is sorting (or null). 63 */ 64 private Thread kicker; 65 /** 66 * The array that is being sorted. 67 */ 68 int arr[]; 69 /** 70 * The high water mark. 71 */ 72 int h1 = -1; 73 /** 74 * The low water mark. 75 */ 76 int h2 = -1; 77 /** 78 * The name of the algorithm. 79 */ 80 String algName; 81 /** 82 * The sorting algorithm (or null). 83 */ 84 SortAlgorithm algorithm; 85 Dimension initialSize = null; 86 87 /** 88 * Fill the array with random numbers from 0..n-1. 89 */ 90 void scramble() { 91 initialSize = getSize(); 92 int a[] = new int[initialSize.height / 2]; 93 double f = initialSize.width / (double) a.length; 94 95 for (int i = a.length; --i >= 0;) { 96 a[i] = (int) (i * f); 97 } 98 for (int i = a.length; --i >= 0;) { 99 int j = (int) (i * Math.random()); 100 int t = a[i]; 101 a[i] = a[j]; 102 a[j] = t; 103 } 104 arr = a; 105 } 106 107 /** 108 * Pause a while. 109 * @see SortAlgorithm 110 */ 111 void pause() { 112 pause(-1, -1); 113 } 114 115 /** 116 * Pause a while, and draw the high water mark. 117 * @see SortAlgorithm 118 */ 119 void pause(int H1) { 120 pause(H1, -1); 121 } 122 123 /** 124 * Pause a while, and draw the low&high water marks. 125 * @see SortAlgorithm 126 */ 127 void pause(int H1, int H2) { 128 h1 = H1; 129 h2 = H2; 130 if (kicker != null) { 131 repaint(); 132 } 133 try { 134 Thread.sleep(20); 135 } catch (InterruptedException e) { 136 } 137 } 138 139 /** 140 * Initialize the applet. 141 */ 142 @Override 143 public void init() { 144 String at = getParameter("alg"); 145 if (at == null) { 146 at = "BubbleSort"; 147 } 148 149 algName = at + "Algorithm"; 150 scramble(); 151 152 resize(100, 100); 153 addMouseListener(this); 154 } 155 156 @Override 157 public void start() { 158 h1 = h2 = -1; 159 scramble(); 160 repaint(); 161 showStatus(getParameter("alg")); 162 } 163 164 /** 165 * Deallocate resources of applet. 166 */ 167 @Override 168 public void destroy() { 169 removeMouseListener(this); 170 } 171 172 /** 173 * Paint the array of numbers as a list 174 * of horizontal lines of varying lengths. 175 */ 176 @Override 177 public void paint(Graphics g) { 178 int a[] = arr; 179 int y = 0; 180 int deltaY = 0, deltaX = 0, evenY = 0; 181 182 Dimension currentSize = getSize(); 183 int currentHeight = currentSize.height; 184 int currentWidth = currentSize.width; 185 186 // Check to see if the applet has been resized since it 187 // started running. If so, need the deltas to make sure 188 // the applet is centered in its containing panel. 189 // The evenX and evenY are because the high and low 190 // watermarks are calculated from the top, but the rest 191 // of the lines are calculated from the bottom, which 192 // can lead to a discrepancy if the window is not an 193 // even size. 194 if (!currentSize.equals(initialSize)) { 195 evenY = (currentHeight - initialSize.height) % 2; 196 deltaY = (currentHeight - initialSize.height) / 2; 197 deltaX = (currentWidth - initialSize.width) / 2; 198 199 if (deltaY < 0) { 200 deltaY = 0; 201 evenY = 0; 202 } 203 if (deltaX < 0) { 204 deltaX = 0; 205 } 206 } 207 208 // Erase old lines 209 g.setColor(getBackground()); 210 y = currentHeight - deltaY - 1; 211 for (int i = a.length; --i >= 0; y -= 2) { 212 g.drawLine(deltaX + arr[i], y, currentWidth, y); 213 } 214 215 // Draw new lines 216 g.setColor(Color.black); 217 y = currentHeight - deltaY - 1; 218 for (int i = a.length; --i >= 0; y -= 2) { 219 g.drawLine(deltaX, y, deltaX + arr[i], y); 220 } 221 222 if (h1 >= 0) { 223 g.setColor(Color.red); 224 y = deltaY + evenY + h1 * 2 + 1; 225 g.drawLine(deltaX, y, deltaX + initialSize.width, y); 226 } 227 if (h2 >= 0) { 228 g.setColor(Color.blue); 229 y = deltaY + evenY + h2 * 2 + 1; 230 g.drawLine(deltaX, y, deltaX + initialSize.width, y); 231 } 232 } 233 234 /** 235 * Update without erasing the background. 236 */ 237 @Override 238 public void update(Graphics g) { 239 paint(g); 240 } 241 242 /** 243 * Run the sorting algorithm. This method is 244 * called by class Thread once the sorting algorithm 245 * is started. 246 * @see java.lang.Thread#run 247 * @see SortItem#mouseUp 248 */ 249 @Override 250 public void run() { 251 try { 252 if (algorithm == null) { 253 algorithm = (SortAlgorithm) Class.forName(algName).newInstance(); 254 algorithm.setParent(this); 255 } 256 algorithm.init(); 257 algorithm.sort(arr); 258 } catch (Exception e) { 259 } 260 } 261 262 /** 263 * Stop the applet. Kill any sorting algorithm that 264 * is still sorting. 265 */ 266 @Override 267 public synchronized void stop() { 268 if (algorithm != null) { 269 try { 270 algorithm.stop(); 271 } catch (IllegalThreadStateException e) { 272 // ignore this exception 273 } 274 kicker = null; 275 } 276 } 277 278 /** 279 * For a Thread to actually do the sorting. This routine makes 280 * sure we do not simultaneously start several sorts if the user 281 * repeatedly clicks on the sort item. It needs to be 282 * synchronized with the stop() method because they both 283 * manipulate the common kicker variable. 284 */ 285 private synchronized void startSort() { 286 if (kicker == null || !kicker.isAlive()) { 287 kicker = new Thread(this); 288 kicker.start(); 289 } 290 } 291 292 @Override 293 public void mouseClicked(MouseEvent e) { 294 showStatus(getParameter("alg")); 295 } 296 297 @Override 298 public void mousePressed(MouseEvent e) { 299 } 300 301 /** 302 * The user clicked in the applet. Start the clock! 303 */ 304 @Override 305 public void mouseReleased(MouseEvent e) { 306 startSort(); 307 e.consume(); 308 } 309 310 @Override 311 public void mouseEntered(MouseEvent e) { 312 } 313 314 @Override 315 public void mouseExited(MouseEvent e) { 316 } 317 318 @Override 319 public String getAppletInfo() { 320 return "Title: SortDemo \nAuthor: James Gosling 1.17f, 10 Apr 1995 \nA simple applet class to demonstrate a sort algorithm. \nYou can specify a sorting algorithm using the 'alg' attribute. \nWhen you click on the applet, a thread is forked which animates \nthe sorting algorithm."; 321 } 322 323 @Override 324 public String[][] getParameterInfo() { 325 String[][] info = { 326 { "alg", "string", 327 "The name of the algorithm to run. You can choose from the provided algorithms or suppply your own, as long as the classes are runnable as threads and their names end in 'Algorithm.' BubbleSort is the default. Example: Use 'QSort' to run the QSortAlgorithm class." } 328 }; 329 return info; 330 } 331} 332