[Texas PLT logo]

COMP 202: Principles of Object-Oriented Programming II

  Sorting Animation  

Today's Menu


I. Sample Program

This link contains the Java source code of a GUI application that animates the various sorting algorithms discussed in the above. This link contains the corresponding class files as an executable jar file.

Play around with this program to see how it behaves.  The program is designed according to the MVC pattern as shown in the UML diagram below.

MVC.png (33895 bytes)

In the above diagram, the model is an array of OCInteger objects that is to be sorted according to a concrete ACompareSorter selected at runtime.   

SortGUI is the view.

SortCtrl is the controller and has a concrete ILambda called _appendCmd to print the data array on the JTextArea of SortGUI.  

The Command Pattern:

As mentioned earlier, ILambda  represents the abstraction of a function that is capable of performing a task given an input and returning an output object.  The SortCntrl$GraphBarsCmnd object and _appendCmd define what to display on the view SortGUI.  But they only appear to GraphCanvas and SortCtrl, respectively as ILambda objects.   GraphCanvas and SortCtrl ask their respective ILambda objects to carry out their tasks (by calling apply) without knowing what the tasks are.   These are simple examples of what is called the Command Pattern.

SortCtrl maintains a Timer object that runs in a separate Thread and updates the views at regular time slices.  The Timer object dictates when to repaint.  This is a basic technique in Java animation.

II. Basic Java Animation and Threads

When the sort button is clicked,  the selected sorting algorithm is executed in a separate Thread.  The key method for the Thread object is run().   To carry out a task on a Thread, all we have to do is to instantiate a Thread object, override the Thread.run() method to perform the desired task, and start the Thread's execution by calling its start() method.  SortControl.gSortBtn_actionPerformed illustrates how sorting is done in a separate Thread.

private void gSortBtn_actionPerformed(ActionEvent e) {
    setEnabledBtns (false); // all GUI's buttons are disabled.
    Thread sortThread = new Thread() {
        public void run() {
            _aCSorter.init ();

            new GraphicSorter (_aCSorter).sort (_gcDataArray,0,_gcDataArray.length-1);
            setEnabledBtns (true); // all GUI's buttons are enabled.
           
_timer.stop ();
        }
    };
    _timer.start ();
    sortThread.start();
}

The Timer object has its own ActionListeners that run in separate threads.  At regular time slices, the Timer object fires an ActionEvent to its listeners, which respond by executing their own actionPerformed method.   Here's the code for the Timer object in SortCtrl.

private Timer _timer = new Timer (TimeSlice, new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            updateViews ();
        }
    }
);

At each time slice, the views of the data array are updated.  Since the data array is being sorted in a different thread, its views will have changed, giving the illusion of animation.  How do we display the data array?

III. Decorator Pattern

The abstract sorting algorithm, ACompareSorter, and its concrete variants have no notion of displaying the data array.  To add new displaying capability without modifying any existing code, we apply what is called the decorator pattern to ACompareSorter.  Below is a UML diagram illustrating the design.

Sorter.png (20408 bytes)

In the above diagram, GraphicSorter is called a decorator for ACompareSorter.  It wraps a concrete ACompareSorter, the "decoree", intercepts all requests to the decoree, performs additional works (decoration) before and/or after delegating the requests to the decoree.  This provides additional functionalities to the decoree without changing any of its code.  Here is the code for GraphicSorter.split.

public int split(IOrdered[] A, int lo, int hi) {
    int s = _aCSorter.split (A,lo, hi); // delegates to decoree

    SorterColor color = (SorterColor) ((IColored)A[s]).getColor ();
    Color splitColor = color.getLoSplit ();
    for(int i = lo; i < s; i++) {
        ((IColored) A[i]).setColor (splitColor);
    }

    splitColor = color.getHiSplit ();
    for(int i=s;i<=hi;i++) {
        ((IColored) A[i]).setColor (splitColor);
    }
    try {
        System.out.println ("Split at " + s);
        Thread.sleep(NapDuration);
    }
    catch(Exception e){}
    return s;
}

In the above,  when a GraphicSorter splits, it first calls on its decoree to split the data array as usual, then it changes the colors of the splitted arrays.  It also slows down the sorting  to allow time for the view update by going to sleep a little.  SorterColor is a subclass of Color that implements a very application specific coloring scheme.  The data array contains objects that are both IOrdered and IColoredIOrdered  (similar to Comparable) is needed for comparison in sorting.  IColored is needed for graphically drawing the data objects in different colors.

Exercises:

1. Experiment with different time slices for the Timer and GraphicSorter.

2. After the discussion of  heap sort in the next lecture (#39), add heap sort and a radio button for heap sort to the above system.

  Sorting Animation  

URL: http://www.clear.rice.edu/comp202/08-fall/lectures/sortAnim/index.shtml
Copyright © 2008-2010 Mathias Ricken and Stephen Wong