Listato commentato di SortItem


Tutte le implementazioni sono sottoclassi della classe SortAlgorithm che usa la classe SortItem che andremo a commentare. Entrambe queste classi sono state disegnate e implementate da James Gosling, che ha anche implementato Bubble Sort e Quick Sort.

La classe SortItem è essa stessa un applet che si prende cura dell'interfaccia e dell'inizializzazione. Esso crea un oggetto SortAlgorithm, che è anche un thread, si occupa del disegno e fa le pause dopo lo swap. Durante le pause l'applet è ridisegnato.

Usando l'attributo "alg" puoi specificare un algoritmo di sorting. Quando tu clicchi sullo start comincia un thread che anima l'algoritmo di sorting.

import java.awt.*;
public class SortItem extends java.applet.Applet
Tutte le applet estendono le funzionalità di java.applet.Applet 
implements Runnable {
implements runnable serve per gestire i threads e dare un metodo run () di default
private Thread kicker
Il thread che sta per ordinare (o null)
int arr[]
   int oldarr[];
Array che sta per essere ordinato
int h1= -1;
   int oldh1 = h1;
The high water mark
int h2= -1;
   int oldh2 = h2;
The low water mark.
String algName;
Nome dell'algoritmo
SortAlgorithm algorithm;
L'algoritmo di sorting (o null)
    int array_size = 64;
    int rectheight = 3;
    int rectspace  = 3;
    int applet_width = 300;
    int applet_height = 475;
    protected int pause_milli_secs = 100;
    int min_millis = 20;
    int max_millis = 1000;
    int graphics_y_start;
    Button title_button;
    Button faster;
    Button much_faster;
    Button slower;
    Button much_slower;
    TextField speed;
    Panel speed_panel;

   void scramble() {
Riempie l'array con numeri random da 0 a n-1
int a[] = new int[array_size];
        double f = 2.0;
        int i;
l'array a[] tratterà oggetti interi e sarà grande array-size=64

        for (i = a.length; --i >= 0;) {
           a[i] = (int)(i * f);
         }
per i che va da 63 a 0 con decremento di 1
 a[63]=63*2=126, a[62]=62*2=124 etc
        for (i = a.length; --i >= 0;) {
              int j = (int)(i * Math.random());
              int t = a[i];
              a[i] = a[j];
              a[j] = t;
       }

       arr = a;

       oldarr = new int [array_size];
       for (i = 0; i < array_size; i++) {
            oldarr[i] = -1;
      }
   }

   void pause() {
       pause(-1, -1);
    }
Pause a while. @see SortAlgorithm
void pause(int H1) {
          pause(H1, -1);
    }
Pause a while, and draw the high water mark. @see SortAlgorithm
void pause(int H1, int H2) {
         h1 = H1;
         h2 = H2;
         if (kicker != null) {
            repaint();
        }
        try {Thread.sleep(pause_milli_secs);} catch (InterruptedException e){}
     }
Pause a while, and draw the low&high water marks. @see SortAlgorithm

   public void init() {
             String at = getParameter("alg");
             if (at == null) {
                at = "NoSort";
             }
Inizializzazione dell'applet
        new Button ("Start " + at);
creazione oggetto
            title_button. addActionListener (
registrazione del componente (oggetto creato con la classe che è
interessata a processare l'evento legato ad un'azione)
                 new ActionListener() {
ActionListener è un'interfaccia astratta che intercetta gli
eventi legati alle azioni
                       public void actionPerformed (ActionEvent ae) {
                               startSort();
                       }
                }
             );
            this.add (title_button);
Quando accade l'evento, il metodo actionPerformed dell'oggetto è invocato

         speed_panel = new Panel();
         faster = new Button ("F");
         faster.addActionListener(
              new ActionListener() {
                    public void actionPerformed(ActionEvent ae) {
                          if (pause_milli_secs >= min_millis + 20) {
                                 set_pause (pause_milli_secs - 20);
                          }
                    }
              }
        );

         much_faster = new Button ("FF");
         much_faster.addActionListener(
              new ActionListener() {
                    public void actionPerformed(ActionEvent ae) {
                          if (pause_milli_secs >= min_millis + 100) {
                                 set_pause (pause_milli_secs - 100);
                          }
                    }
              }
        );

         slower = new Button ("S");
         slower.addActionListener(
              new ActionListener() {
                    public void actionPerformed(ActionEvent ae) {
                          if (pause_milli_secs <= max_millis - 20) {
                                 set_pause (pause_milli_secs + 20);
                          }
                    }
              }
         );

         much_slower = new Button ("SS");
         much_slower.addActionListener(
              new ActionListener() {
                    public void actionPerformed(ActionEvent ae) {
                          if (pause_milli_secs <= max_millis - 100) {
                             set_pause (pause_milli_secs + 100);
                          }
                    }
              }
        );

      speed = new TextField("Speed", 7);
      speed.setEditable(false);

      speed_panel.setLayout(new FlowLayout (FlowLayout.CENTER, 15, 5));
     speed_panel.add (much_slower);
     speed_panel.add (slower);
     speed_panel.add (speed);
     speed_panel.add (faster);
     speed_panel.add (much_faster);

     add (speed_panel);

     graphics_y_start = 100;

     algName = at + "Algorithm";
     scramble();

     resize(applet_width, applet_height);
 

  }
termina l'init 

 
 

  protected void set_pause (int millis) {
         if ((millis <= max_millis) && (millis >= min_millis)) {
             pause_milli_secs = millis;
             speed.setText ("ms " + pause_milli_secs);
         }

         if (pause_milli_secs < min_millis + 100) {
             much_faster.setEnabled(false);
         } else {
             much_faster.setEnabled(true);
            }

         if (pause_milli_secs < min_millis + 20) {
               faster.setEnabled(false);
         } else {
               faster.setEnabled(true);
            }

         if (pause_milli_secs > max_millis - 100) {
              much_slower.setEnabled(false);
         } else {
               much_slower.setEnabled(true);
            }

         if (pause_milli_secs > max_millis - 20) {
              slower.setEnabled(true);
         } else {
                 slower.setEnabled(false);
             }

 }

     public void paint(Graphics g) {
     int a[] = arr;
     int y;
Paint the array of numbers as a list of horizontal lines of varying lenghts.
   g.setColor(getBackground());
Si cerca di essere veloci cancellando solo le linee che sono
state cambiate dall'ultimo ridisegnamento. Cancella
anche le linee rosse e blu dei watermarks.

     y = graphics_y_start;
     for (int i = 0; i < arr.length;i++, y+= rectheight + rectspace) {y=graphics_y_start=100 vedi sopra,  y=y+6 y=9 volte da 100 a 478 cioè 9 volte 63 aggiunte di 6
             if (oldarr[i] != arr[i]) {
                 g.fillRect (0, y, getSize().width, rectheight);
             }

             if (i == oldh1) {
                 g.fillRect (0, y, getSize().width, rectheight);
             }

             if (i == oldh2) {
                g.fillRect (0, y, getSize().width, rectheight);
             }

     }

    g.setColor(Color.black);
settiamo il colore nero per disegnare le nuove linee

     y = graphics_y_start;        //graphics_y_start=100 vedi sopra
     for (int i = 0; i < arr.length; i++, y += rectheight + rectspace) {
         g.fillRect (0, y, arr[i] * 2, rectheight);
     }
     y = graphics_y_start;
     if (h1 >= 0) {
         g.setColor(Color.red);
         y += (h1) * (rectheight + rectspace) + (rectheight / 2);
         g.drawLine(0, y, getSize().width, y);
     }
     y = graphics_y_start;
     if (h2 >= 0) {
         g.setColor(Color.blue);
         y += (h2) * (rectheight + rectspace) + (rectheight / 2);
         g.drawLine(0, y, getSize().width, y);
     }
     oldh1 = h1;
     oldh2 = h2;

  }
 

   public void update(Graphics g) {
    paint(g);
        for (int i = 0; i < arr.length; i++) {
            oldarr[i] = arr[i];
        }
    }
Update without erasing the background.
public void run() {
         try {
             if (algorithm == null) {
                  algorithm = (SortAlgorithm)Class.forName(algName).newInstance();
                  algorithm.setParent(this);
             }
         algorithm.init();
         algorithm.sort(arr);
         } catch(Exception e) {
         }
     }

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 synchronized void stop() {
          if (algorithm != null){
                try {
                      algorithm.stop();
                } catch (IllegalThreadStateException e) {
                // ignore this exception
                   }
                kicker = null;
         }
    }
Stop the applet. Kill any sorting algorithm that is still sorting.
   private synchronized void startSort() {
             if (kicker == null || !kicker.isAlive()) {
                 scramble();
                 repaint();
                 kicker = new Thread( this);

                 kicker.start();
             }
    }
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.
}