Skip to content

Commit a9caa4c

Browse files
authored
Merge pull request #25 from dlarocque/NewFeature
Added Slider to change speed & Performance Label
2 parents c59ee74 + abf029f commit a9caa4c

File tree

3 files changed

+134
-40
lines changed

3 files changed

+134
-40
lines changed

src/com/example/algorithmvisualizer/AlgVisualizer.java

Lines changed: 119 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,29 @@
1818
import java.awt.Dimension;
1919
import java.util.*;
2020
import javax.swing.*;
21+
import javax.swing.event.ChangeEvent;
22+
import javax.swing.event.ChangeListener;
23+
2124
import 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
}

src/com/example/algorithmvisualizer/ArrDisplay.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public class ArrDisplay extends JComponent {
2222
private static final long serialVersionUID = 1L;
2323
private int swappedIndex1;
2424
private int swappedIndex2;
25-
private int numChunk; // amount of frames painted since the array was shuffled
25+
private int numChunks; // amount of frames painted since the array was shuffled
2626
private boolean isComplete; // if the array is sorted
2727
private ArrayList<Integer[]> swappedIndexes;
2828
private Integer[] arr;
@@ -61,8 +61,9 @@ public void paintComponent(Graphics g) {
6161
swappedIndex1 = -1;
6262
swappedIndex2 = -1;
6363
} else if (!algVisualizer.stopSort()) {
64-
swappedIndex1 = swappedIndexes.get(numChunk - 1)[0];
65-
swappedIndex2 = swappedIndexes.get(numChunk - 1)[1];
64+
// exclude the first chunk as its used to draw the first array, not related to the sorting
65+
swappedIndex1 = swappedIndexes.get(numChunks - 1)[0]; // index out of bounds exception?
66+
swappedIndex2 = swappedIndexes.get(numChunks - 1)[1];
6667
}
6768

6869
// Iterate through the array and drawn every index
@@ -89,6 +90,7 @@ public void paintComponent(Graphics g) {
8990
// Draw the current indexes bar
9091
graphics2d.fillRect(x, y, width, height);
9192
}
93+
algVisualizer.updatePerformance();
9294
}
9395

9496
public ArrayList<Integer[]> getSwappedIndexes() {
@@ -104,23 +106,19 @@ public void clearSwappedIndexes() {
104106
swappedIndexes = new ArrayList<Integer[]>();
105107
}
106108

107-
public void setNumChunk(int numChunk) {
108-
this.numChunk = numChunk;
109+
public void setNumChunk(int numChunks) {
110+
this.numChunks = numChunks;
109111
}
110112

111-
public int getNumChunk() {
112-
return numChunk;
113+
public int getNumChunks() {
114+
return numChunks;
113115
}
114116

115117
public boolean isComplete() {
116118
return isComplete;
117119
}
118120

119121
public void setComplete(boolean complete) {
120-
// Performance Button's availability is based on whether or not the array is
121-
// sorted.
122-
algVisualizer.getPerformanceButton().setEnabled(complete);
123-
124122
this.isComplete = complete;
125123
}
126124

src/com/example/algorithmvisualizer/ArrSorting.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,11 @@
1818

1919
public class ArrSorting extends SwingWorker<Void, Integer[]> {
2020

21-
private Integer delay = 10;
2221
private int n;
2322
private Integer[] arr;
2423
private AlgVisualizer algVisualizer;
2524
private ArrDisplay arrDisplay;
26-
private int numChunk;
25+
private int numChunks;
2726

2827
public ArrSorting(AlgVisualizer algVisualizer, Integer[] arr, ArrDisplay arrDisplay) {
2928
this.algVisualizer = algVisualizer;
@@ -87,8 +86,8 @@ protected Void doInBackground() throws Exception {
8786
protected void process(List<Integer[]> chunks) {
8887
while (chunks.size() > 0) {
8988
// Paint each cloned array and update number of chunks
90-
numChunk++;
91-
arrDisplay.setNumChunk(this.numChunk);
89+
numChunks++;
90+
arrDisplay.setNumChunk(this.numChunks);
9291
arrDisplay.setArr(chunks.get(0));
9392
arrDisplay.repaint();
9493
chunks.remove(0);
@@ -101,7 +100,9 @@ protected void process(List<Integer[]> chunks) {
101100
*/
102101
private void sleep() {
103102
try {
104-
Thread.sleep(delay);
103+
Thread.sleep(algVisualizer.getDelay());
104+
if (!algVisualizer.stopSort())
105+
algVisualizer.setTotalDelay(algVisualizer.getTotalDelay() + algVisualizer.getDelay());
105106
} catch (InterruptedException e) {
106107
e.printStackTrace();
107108
}

0 commit comments

Comments
 (0)