import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.Color; import java.awt.Graphics; import javax.swing.*; //import javax.swing.Timer; /** * @author Dung X. Nguyen * @author Stephen B. Wong */ public class SortControl { public final static int ArraySize = 20; public final static int TimeSlice = 100; // in ms. private SortGUI _frame = new SortGUI (); private JTextArea _txtArea = _frame.getOutputTA(); // cached since called many times. private GraphCanvas _graphCanvas = _frame.getGraphCanvas(); // cached since called many times. private IOrdered[] _gcDataArray = makeArray(); private ACompareSorter _aCSorter; /** * Updates the view every 100 ms. Redraws array graph and redisplays array text. */ private Timer _timer = new Timer(TimeSlice, new ActionListener() { public void actionPerformed(ActionEvent e) { updateViews (); } }); private ILambda _appendCmd = new ILambda () { public Object apply (Object x) { _txtArea.append (""+ ((OCInteger)x).getValue()+"\n"); return x; // returns "whatever"! Not an issue here. } }; /** * Draw horizontal bars. */ class GraphBarsCommand implements ILambda { private int _minVal = 1; private int _maxVal = ArraySize; private Graphics _g; private int _xIdx; private double _m, _b; // y = _mx + _b. private int _minY; private int _maxY = ArraySize / 2; private ILambda _drawing = new ILambda() { /** * Draws horizontal bars. * @param x an OCInteger. */ public Object apply (Object x) { int dotSize = 10; _g.setColor (((OCInteger) x).getColor()); _g.fillRect (0, 4 + (dotSize + 7) * _xIdx++ , 10 + _minY - (int)(_m * ((OCInteger)x).getValue() + _b), dotSize - 2); return x; // or whatever... } }; public Object apply(Object g) { _g = (Graphics)g; _xIdx = 0; _minY = _graphCanvas.getHeight() - _maxY; _m = ((double)(_maxY - _minY)) / (_maxVal - _minVal); _b = ((double)(_minY * _maxVal - _maxY * _minVal)) / (_maxVal - _minVal); return ArrayMapCar.Singleton.apply (_gcDataArray, _drawing); // can be done using ILambda anonymous class. } }; /** * Draws circular dots. */ class GraphDotsCommand implements ILambda { private int _minVal = 1; private int _maxVal = ArraySize; private Graphics _g; private int _xIdx; private double _m, _b; // y = _mx + _b. private int _minY; private int _maxY = ArraySize / 2; private ILambda _drawing = new ILambda() { /** * Draws circular dots. * @param x an OCInteger. */ public Object apply (Object x) { int dotSize = 10; _g.setColor (((OCInteger)x).getColor()); _g.fillOval (dotSize * _xIdx++, (int)(_m * ((OCInteger)x).getValue() + _b), dotSize, dotSize); return x; // or whatever... } }; public Object apply(Object g) { _g = (Graphics)g; _xIdx = 0; _minY = _graphCanvas.getHeight() - _maxY; _m = ((double)(_maxY - _minY)) / (_maxVal - _minVal); _b = ((double)(_minY * _maxVal - _maxY * _minVal)) / (_maxVal - _minVal); return ArrayMapCar.Singleton.apply (_gcDataArray, _drawing); // can be done using ILambda anonymous class. } }; public SortControl() { _graphCanvas.setDrawable (new GraphBarsCommand ()); //_graphCanvas.setDrawable (new GraphDotsCommand ()); _aCSorter = CInsertionSorter.Singleton; _frame.getInsertionRBtn().setSelected(true); _frame.getInsertionRBtn().addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { _aCSorter = CInsertionSorter.Singleton; } }); _frame.getQuickRBtn().addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { _aCSorter = CQuickSorter.Singleton; } }); _frame.getMergeRBtn().addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { _aCSorter = new CMergeSorter (ArraySize); } }); _frame.getSelectionRBtn().addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { _aCSorter = CSelectionSorter.Singleton; } }); _frame.getRandomizeBtn().addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { randomizeBtn_actionPerformed(e); } }); _frame.getSortBtn().addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { gSortBtn_actionPerformed(e); } }); _frame.validate(); _frame.setVisible(true); updateViews (); } /** * Redraws array graph and redisplays array text. */ private void updateViews () { _txtArea.setText(""); ArrayMapCar.Singleton.apply (_gcDataArray, _appendCmd); // can be done using ILambda anynonymous class. _graphCanvas.repaint(); } /** * Runs the selected sorting algorithm in a separate thread. */ private final 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 (); updateViews (); } }; _timer.start (); sortThread.start(); } /** * Randomizes the data array. */ private void randomizeBtn_actionPerformed(ActionEvent e) { for(int i = 0; i < _gcDataArray.length; i++) { int x = (int) (_gcDataArray.length * Math.random()); IOrdered tmp = _gcDataArray[i]; _gcDataArray[i] = _gcDataArray[x]; _gcDataArray[x] = tmp; } updateViews (); } /** * Creates a sorted data array ranging from 0 to ArraySize - 1 with a "middle-of-the-spectrum" * RGB color. */ private IOrdered[] makeArray() { int loColorValue = -16*1024*1024; int hiColorValue = -1; Color normalColor = new SorterColor((loColorValue+hiColorValue)/2, loColorValue, hiColorValue); IOrdered[] temp = new OCInteger[ArraySize]; for (int i=0; i < temp.length; i++) { temp [i] = new OCInteger (i + 1, normalColor); } return temp; } /** * Enables/Disables all GUI's buttons. * @param yes true means enable. */ private void setEnabledBtns(boolean yes) { _frame.getInsertionRBtn ().setEnabled (yes); _frame.getMergeRBtn ().setEnabled (yes); _frame.getQuickRBtn ().setEnabled (yes); _frame.getQuickRBtn ().setEnabled (yes); _frame.getRandomizeBtn ().setEnabled (yes); _frame.getSelectionRBtn ().setEnabled (yes); _frame.getSortBtn ().setEnabled (yes); } public static void main(String[] args) { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch(Exception e) { } new SortControl(); } }