1 import java.awt.Color;
2 import java.awt.Graphics2D;
3 import java.awt.geom.Line2D;
4 import java.util.concurrent.locks.Lock;
5 import java.util.concurrent.locks.ReentrantLock;
6 import javax.swing.JComponent;
7
8 /**
9 This class sorts an array, using the selection sort algorithm.
10 */
11 public class SelectionSorter
12 {
13 private static final int DELAY = 100;
14
15 private int[] a;
16 private Lock sortStateLock;
17
18 // The component is repainted when the animation is paused
19 private JComponent component;
20
21 // These instance variables are needed for drawing
22 private int markedPosition = -1;
23 private int alreadySorted = -1;
24
25 /**
26 Constructs a selection sorter.
27 @param anArray the array to sort
28 @param aComponent the component to be repainted when the animation
29 pauses
30 */
31 public SelectionSorter(int[] anArray, JComponent aComponent)
32 {
33 a = anArray;
34 sortStateLock = new ReentrantLock();
35 component = aComponent;
36 }
37
38 /**
39 Sorts the array managed by this selection sorter.
40 */
41 public void sort()
42 throws InterruptedException
43 {
44 for (int i = 0; i < a.length - 1; i++)
45 {
46 int minPos = minimumPosition(i);
47 sortStateLock.lock();
48 try
49 {
50 swap(minPos, i);
51 // For animation
52 alreadySorted = i;
53 }
54 finally
55 {
56 sortStateLock.unlock();
57 }
58 pause(2);
59 }
60 }
61
62 /**
63 Finds the smallest element in a tail range of the array
64 @param from the first position in a to compare
65 @return the position of the smallest element in the
66 range a[from]...a[a.length - 1]
67 */
68 private int minimumPosition(int from)
69 throws InterruptedException
70 {
71 int minPos = from;
72 for (int i = from + 1; i < a.length; i++)
73 {
74 sortStateLock.lock();
75 try
76 {
77 if (a[i] < a[minPos]) minPos = i;
78 // For animation
79 markedPosition = i;
80 }
81 finally
82 {
83 sortStateLock.unlock();
84 }
85 pause(2);
86 }
87 return minPos;
88 }
89
90 /**
91 Swaps two entries of the array.
92 @param i the first position to swap
93 @param j the second position to swap
94 */
95 private void swap(int i, int j)
96 {
97 int temp = a[i];
98 a[i] = a[j];
99 a[j] = temp;
100 }
101
102 /**
103 Draws the current state of the sorting algorithm.
104 @param g2 the graphics context
105 */
106 public void draw(Graphics2D g2)
107 {
108 sortStateLock.lock();
109 try
110 {
111 int deltaX = component.getWidth() / a.length;
112 for (int i = 0; i < a.length; i++)
113 {
114 if (i == markedPosition)
115 g2.setColor(Color.RED);
116 else if (i <= alreadySorted)
117 g2.setColor(Color.BLUE);
118 else
119 g2.setColor(Color.BLACK);
120 g2.draw(new Line2D.Double(i * deltaX, 0,
121 i * deltaX, a[i]));
122 }
123 }
124 finally
125 {
126 sortStateLock.unlock();
127 }
128 }
129
130 /**
131 Pauses the animation.
132 @param steps the number of steps to pause
133 */
134 public void pause(int steps)
135 throws InterruptedException
136 {
137 component.repaint();
138 Thread.sleep(steps * DELAY);
139 }
140
141 }