1818import java .awt .Dimension ;
1919import java .util .*;
2020import javax .swing .*;
21+ import javax .swing .event .ChangeEvent ;
22+ import javax .swing .event .ChangeListener ;
23+
2124import java .awt .event .*;
2225
23- public class AlgVisualizer implements ActionListener {
26+ public class AlgVisualizer implements ActionListener , ChangeListener {
2427
28+ private final int CONTENT_WIDTH = 900 ;
29+ private final int CONTENT_HEIGHT = 960 ;
30+ private final int ARR_DISPLAY_HEIGHT = 900 ;
31+ private final int FPS_MIN = 1 ;
32+ private final int FPS_INIT = 10 ;
33+ private final int FPS_MAX = 100 ;
34+ private final String [] SIZE_OPTIONS = { "10" , "50" , "100" , "300" , "450" , "900" }; // array size options
2535 private int n ;
26- private final int CONTENT_WIDTH = 800 ;
27- private final int CONTENT_HEIGHT = 860 ;
28- private final int ARR_DISPLAY_HEIGHT = 800 ;
29- private final String [] SIZE_OPTIONS = { "10" , "50" , "100" , "200" , "400" , "800" }; // array size options
36+ private int numSwaps ;
37+ private int delay ;
38+ private long totalDelay ;
3039 private Integer indexComparisons ;
3140 private long startTime ; // start time of a sort
3241 private long endTime ; // end time of a sort
42+ private long visualizationTime ;
43+ private long sortingTime ;
3344 private boolean doBubbleSort ;
3445 private boolean doInsertionSort ;
3546 private boolean doSelectionSort ;
@@ -47,8 +58,9 @@ public class AlgVisualizer implements ActionListener {
4758 private JButton selectionButton ;
4859 private JButton mergeButton ;
4960 private JButton quickButton ;
50- private JButton performanceButton ;
5161 private JComboBox <String > sizeChanger ;
62+ private JSlider FPSslider ;
63+ private JLabel performanceLabel ;
5264 private SwingWorker <Void , Integer []> arrSort ;
5365
5466 /*
@@ -83,6 +95,11 @@ public void initializeVars() {
8395 arr = shuffleArr (arr );
8496
8597 indexComparisons = 0 ;
98+ startTime = 0 ;
99+ endTime = 0 ;
100+ visualizationTime = 0 ;
101+ sortingTime = 0 ;
102+ setDelay (1000 / FPS_INIT );
86103
87104 // Initialize objects that will display and sort the array
88105
@@ -131,10 +148,13 @@ public void initializeVars() {
131148 sizeChanger .addActionListener (this );
132149 sizeChanger .setBackground (Color .WHITE );
133150
134- performanceButton = new JButton ("Performance" );
135- performanceButton .addActionListener (this );
136- performanceButton .setBackground (Color .WHITE );
137- performanceButton .setEnabled (false ); // This button is not available until a sort is complete
151+ FPSslider = new JSlider (JSlider .HORIZONTAL , FPS_MIN , FPS_MAX , FPS_INIT );
152+ FPSslider .addChangeListener (this );
153+ FPSslider .setBackground (Color .DARK_GRAY );
154+ // Initialize the performance label and center it
155+
156+ performanceLabel = new JLabel ();
157+ performanceLabel .setHorizontalAlignment (SwingConstants .CENTER );
138158 }
139159
140160 /*
@@ -152,14 +172,15 @@ public void setFrame() {
152172 buttonPanel .add (mergeButton );
153173 buttonPanel .add (quickButton );
154174 buttonPanel .add (sizeChanger );
155- buttonPanel .add (performanceButton );
175+ buttonPanel .add (FPSslider );
156176
157177 // Initialize and make the frame visible
158178 frame = new JFrame ("Algorithm Visualizer" );
159179 frame .setDefaultCloseOperation (JFrame .EXIT_ON_CLOSE );
160180 frame .setResizable (false ); // Cannot be resizable, causes visual issues
161181 frame .add (buttonPanel , BorderLayout .PAGE_START ); // Button panel added to the top of the frame
162182 frame .add (arrPanel , BorderLayout .PAGE_END ); // Array display is added to the bottom of the frame
183+ frame .add (performanceLabel );
163184 frame .pack ();
164185 frame .setLocationRelativeTo (null ); // center of the screen
165186 frame .setVisible (true );
@@ -215,14 +236,16 @@ public void actionPerformed(ActionEvent event) {
215236 // reset and paint the new array
216237 reset ();
217238 arrSort .execute ();
218- } else if (event .getSource () == performanceButton ) {
219- int numSwaps = arrDisplay .getSwappedIndexes ().size ();
220- long visualizationTime = endTime - startTime ; // net time
221- long sortingTime = visualizationTime - (60 * numSwaps + 1 ); // - NEED TO FIX
222- String statsMessage = String .format (
223- "Index Comparisons : %d Index Swaps : %d Visualization Time : %dms Sorting Time : %dms" ,
224- indexComparisons , numSwaps , visualizationTime , sortingTime );
225- JOptionPane .showMessageDialog (frame , statsMessage , "Performance" , JOptionPane .PLAIN_MESSAGE );
239+ }
240+ }
241+
242+ @ Override
243+ public void stateChanged (ChangeEvent e ) {
244+ JSlider source = (JSlider ) e .getSource ();
245+ if (!source .getValueIsAdjusting ()) {
246+ int fps = (int ) source .getValue ();
247+ delay = 1000 / fps ; // ms
248+ setDelay (delay );
226249 }
227250 }
228251
@@ -239,7 +262,6 @@ public void reset() {
239262 setStopSort (true );
240263 arr = shuffleArr (arr );
241264 arrDisplay .clearSwappedIndexes ();
242- arrDisplay .setNumChunk (0 );
243265 arrDisplay .setComplete (false );
244266 arrDisplay .setArr (arr );
245267 indexComparisons = 0 ;
@@ -257,6 +279,9 @@ public void resetSwingWorker(AlgVisualizer alg, Integer[] arr, ArrDisplay displa
257279 public void resetTime () {
258280 startTime = 0 ;
259281 endTime = 0 ;
282+ visualizationTime = 0 ;
283+ sortingTime = 0 ;
284+ totalDelay = 0 ;
260285 }
261286
262287 public Integer [] shuffleArr (Integer [] arr ) {
@@ -274,6 +299,40 @@ public Integer[] fillArr(Integer[] arr) {
274299 return arr ;
275300 }
276301
302+ /*
303+ * updatePerformance will be called every time the array is repainted. This
304+ * makes it slower / not real time when there is a high delay.
305+ *
306+ * We get the values for each performance statistic we want to track (number of
307+ * swaps, number of comparisons, visualization time, sorting time), format them
308+ * into a string that will then be assigned to the JLabel's text.
309+ *
310+ * frame.pack() makes sure that our new text will fit in the frame, and will
311+ * adjust if it does not.
312+ */
313+ public void updatePerformance () {
314+ numSwaps = arrDisplay .getSwappedIndexes ().size ();
315+ System .out .println ("total delay " + totalDelay );
316+ if (!getSort ().equals ("Not Sorting" ) && arrDisplay .getNumChunks () == 1 ) {
317+ visualizationTime = System .currentTimeMillis () - startTime ;
318+ sortingTime = visualizationTime - totalDelay ;
319+ } else if (arrDisplay .getNumChunks () > 1 ) {
320+ visualizationTime = System .currentTimeMillis () - startTime ;
321+ sortingTime = visualizationTime - totalDelay ;
322+ }
323+ if (stopSort ) {
324+ resetTime ();
325+ }
326+
327+ String performance = String .format (
328+ "Index Comparisons : %d Index Swaps : %d Visualization Time : %dms Sorting Time : %dms" ,
329+ indexComparisons , numSwaps , visualizationTime , sortingTime );
330+
331+ performanceLabel .setText (performance );
332+
333+ frame .pack ();
334+ }
335+
277336 public Integer [] getArr () {
278337 return arr ;
279338 }
@@ -366,10 +425,6 @@ public void setN(int n) {
366425 this .n = n ;
367426 }
368427
369- public JButton getPerformanceButton () {
370- return performanceButton ;
371- }
372-
373428 public Integer getIndexComparisons () {
374429 return indexComparisons ;
375430 }
@@ -393,4 +448,44 @@ public long getEndTime() {
393448 public void setEndTime (long endTime ) {
394449 this .endTime = endTime ;
395450 }
451+
452+ public JLabel getPerformanceLabel () {
453+ return performanceLabel ;
454+ }
455+
456+ public void setPerformanceLabel (JLabel performanceLabel ) {
457+ this .performanceLabel = performanceLabel ;
458+ }
459+
460+ public int getNumSwaps () {
461+ return numSwaps ;
462+ }
463+
464+ public void setNumSwaps (int numSwaps ) {
465+ this .numSwaps = numSwaps ;
466+ }
467+
468+ public int getDelay () {
469+ return delay ;
470+ }
471+
472+ public void setDelay (int delay ) {
473+ this .delay = delay ;
474+ }
475+
476+ public JSlider getFPSslider () {
477+ return FPSslider ;
478+ }
479+
480+ public void setFPSslider (JSlider fPSslider ) {
481+ FPSslider = fPSslider ;
482+ }
483+
484+ public long getTotalDelay () {
485+ return totalDelay ;
486+ }
487+
488+ public void setTotalDelay (long totalDelay ) {
489+ this .totalDelay = totalDelay ;
490+ }
396491}
0 commit comments