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  }