Skip to content

Commit d14ad1d

Browse files
committed
Fixed #23 See comments for desc
1 parent 0f52c7b commit d14ad1d

File tree

3 files changed

+70
-50
lines changed

3 files changed

+70
-50
lines changed

src/com/example/algorithmvisualizer/AlgVisualizer.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ public void initializeVars() {
8686

8787
// Initialize objects that will display and sort the array
8888

89-
arrDisplay = new ArrDisplay(this, arr);
89+
arrDisplay = new ArrDisplay(this);
90+
arrDisplay.setArr(arr);
9091
arrDisplay.setPreferredSize(new Dimension(CONTENT_WIDTH, ARR_DISPLAY_HEIGHT));
9192

9293
arrSort = new ArrSorting(this, this.arr, this.arrDisplay);
@@ -217,7 +218,7 @@ public void actionPerformed(ActionEvent event) {
217218
} else if (event.getSource() == performanceButton) {
218219
int numSwaps = arrDisplay.getSwappedIndexes().size();
219220
long visualizationTime = endTime - startTime; // net time
220-
long sortingTime = visualizationTime - (60 * numSwaps + 1); // - 60 seconds of sleep time between each swap
221+
long sortingTime = visualizationTime - (60 * numSwaps + 1); // - NEED TO FIX
221222
String statsMessage = String.format(
222223
"Index Comparisons : %d Index Swaps : %d Visualization Time : %dms Sorting Time : %dms",
223224
indexComparisons, numSwaps, visualizationTime, sortingTime);
@@ -238,7 +239,7 @@ public void reset() {
238239
setStopSort(true);
239240
arr = shuffleArr(arr);
240241
arrDisplay.clearSwappedIndexes();
241-
arrDisplay.setFramesPainted(0);
242+
arrDisplay.setNumChunk(0);
242243
arrDisplay.setComplete(false);
243244
arrDisplay.setArr(arr);
244245
indexComparisons = 0;

src/com/example/algorithmvisualizer/ArrDisplay.java

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,14 @@ public class ArrDisplay extends JComponent {
2222
private static final long serialVersionUID = 1L;
2323
private int swappedIndex1;
2424
private int swappedIndex2;
25-
private int framesPainted; // amount of frames painted since the array was shuffled
25+
private int numChunk; // 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;
2929
private AlgVisualizer algVisualizer;
3030

31-
public ArrDisplay(AlgVisualizer algVisualizer, Integer[] arr) {
31+
public ArrDisplay(AlgVisualizer algVisualizer) {
3232
this.algVisualizer = algVisualizer;
33-
this.arr = arr;
3433
swappedIndexes = new ArrayList<Integer[]>();
3534
}
3635

@@ -39,12 +38,15 @@ public ArrDisplay(AlgVisualizer algVisualizer, Integer[] arr) {
3938
* visualization of the array in bar graph form. This method is called through
4039
* the use of the repaint() method that is called in the SwingWorkers publish()
4140
* method. We use loops to iterate through the array and draw every index,
42-
* filling the arrPanel. A list of arrays contains pairs of swapped indexes that
43-
* are drawn in red & blue. We iterate through this list every frame by keeping
44-
* track of the amount of frames drawn. ISSUE : If the number of framesPainted
45-
* is out of sync with the List of pairs of swappedIndexes, the coloured bars
46-
* will be out of sync with the actual indexes that are being swapped, giving
47-
* the effect of a very noticeable delay.
41+
* filling the arrPanel.
42+
*
43+
* Since this method can take some time to execute, it may only be able to draw
44+
* a fraction of the total frames at lower delay times.
45+
*
46+
* There is a list of swappedIndexes that contains each pair of indexes that
47+
* were swapped during sorting. Since we always draw the most recent chunk,
48+
* numChunks will always represent the number of the array clone we're drawing,
49+
* so using that to get the correct index in swappedIndexes will work.
4850
*/
4951
@Override
5052
public void paintComponent(Graphics g) {
@@ -59,8 +61,8 @@ public void paintComponent(Graphics g) {
5961
swappedIndex1 = -1;
6062
swappedIndex2 = -1;
6163
} else if (!algVisualizer.stopSort()) {
62-
swappedIndex1 = swappedIndexes.get(framesPainted)[0];
63-
swappedIndex2 = swappedIndexes.get(framesPainted++)[1];
64+
swappedIndex1 = swappedIndexes.get(numChunk - 1)[0];
65+
swappedIndex2 = swappedIndexes.get(numChunk - 1)[1];
6466
}
6567

6668
// Iterate through the array and drawn every index
@@ -102,12 +104,12 @@ public void clearSwappedIndexes() {
102104
swappedIndexes = new ArrayList<Integer[]>();
103105
}
104106

105-
public void setFramesPainted(int framesPainted) {
106-
this.framesPainted = framesPainted;
107+
public void setNumChunk(int numChunk) {
108+
this.numChunk = numChunk;
107109
}
108110

109-
public int getFramesPainted() {
110-
return framesPainted;
111+
public int getNumChunk() {
112+
return numChunk;
111113
}
112114

113115
public boolean isComplete() {

src/com/example/algorithmvisualizer/ArrSorting.java

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

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

21-
private final int SLEEP_TIME = 60; // sleep time between frames drawn (ms)
21+
private Integer delay = 10;
2222
private int n;
2323
private Integer[] arr;
2424
private AlgVisualizer algVisualizer;
2525
private ArrDisplay arrDisplay;
26+
private int numChunk;
2627

2728
public ArrSorting(AlgVisualizer algVisualizer, Integer[] arr, ArrDisplay arrDisplay) {
2829
this.algVisualizer = algVisualizer;
@@ -37,7 +38,7 @@ public ArrSorting(AlgVisualizer algVisualizer, Integer[] arr, ArrDisplay arrDisp
3738
* determine what buttons was clicked, helping determine what action to do next.
3839
* If a reset was done, redraw the new shuffled array, and reset this object so
3940
* that it is able to sort the next time execute() is called. If a sorting
40-
* algorithm was clicked, simply perform that sorting algortihm. Make sure to
41+
* algorithm was clicked, simply perform that sorting algorithm. Make sure to
4142
* set the start and end times for the performance window at the end of sorting.
4243
*/
4344
@Override
@@ -65,29 +66,42 @@ protected Void doInBackground() throws Exception {
6566
}
6667

6768
/*
68-
* This method is called by the publish(arr.clone()) method in the sorting
69-
* algorithms. It takes in a chunk of the array that was sent as a parameter,
70-
* and repaints it using the overridden paintComponent(). ISSUE : If an array
71-
* clone is sent to this method as a chunk before the repaint() method is
72-
* complete, the visualization can come out of sync. See issue #23 at
73-
* https://github.com/dlarocque/AlgorithmVisualizer/issues/23
69+
* This method accepts a clone of the array that was sent to it as a parameter
70+
* from the sorting algorithms. If this method isn't finished executing by the
71+
* time that another publish(Arr.clone()) is made, it will send in the array
72+
* clone at the end of the list of chunks.
73+
*
74+
* Since the repaint() method can not keep up with the amount of chunks sent in
75+
* from the sorting algorithms when there is very low delay time (Repaint time
76+
* depends on the system), it will only draw a fraction of the array clones sent
77+
* to it.
78+
*
79+
* To make sure that the colored bars representing the swapped indexes are in
80+
* sync with the array being painted, we track the amount of chunks sent, and
81+
* send it to arrDisplay, so that whenever repaint() has the opportunity to
82+
* execute, the chunk number of the array clone that is being drawn will be
83+
* represented by numChunk, which will be used to get the swappedIndexes from
84+
* the list. ( numChunk are swappedIndexes.size() are always equal. )
7485
*/
7586
@Override
7687
protected void process(List<Integer[]> chunks) {
77-
if (chunks.size() > 1) {
78-
// If chunks > 1, Red bars will be out of sync
79-
System.out.println("OVERLOAD" + chunks.size());
88+
while (chunks.size() > 0) {
89+
// Paint each cloned array and update number of chunks
90+
numChunk++;
91+
arrDisplay.setNumChunk(this.numChunk);
92+
arrDisplay.setArr(chunks.get(0));
93+
arrDisplay.repaint();
94+
chunks.remove(0);
8095
}
81-
arrDisplay.repaint();
8296
}
8397

8498
/*
85-
* Amount of time this thread will sleep for, waiting for the repaint() method
86-
* to draw the previous clone of the array.
99+
* The amount of time this thread waits after sending a chunk to be drawn in the
100+
* Event Dispatch Thread
87101
*/
88102
private void sleep() {
89103
try {
90-
Thread.sleep(SLEEP_TIME);
104+
Thread.sleep(delay);
91105
} catch (InterruptedException e) {
92106
e.printStackTrace();
93107
}
@@ -116,17 +130,18 @@ private void bubbleSort() {
116130
// Add the pair of indexes that were swapped to the list.
117131
arrDisplay.addSwappedIndexes(j, j + 1);
118132
// Repaint the new array.
119-
publish();
133+
publish(arr.clone());
120134
sleep();
121135
}
122136
}
123137
}
124138
}
125-
// If sorting hasn't been stopped, set end time, complete and draw one more time.
139+
// If sorting hasn't been stopped, set end time, complete and draw one more
140+
// time.
126141
if (!algVisualizer.stopSort()) {
127142
algVisualizer.setEndTime(System.currentTimeMillis());
128143
arrDisplay.setComplete(true);
129-
publish();
144+
publish(arr.clone());
130145
sleep();
131146
}
132147
}
@@ -154,13 +169,13 @@ private void selectionSort() {
154169
// Add a pair of swapped indexes
155170
arrDisplay.addSwappedIndexes(min_idx, i);
156171
// Repaint the new array.
157-
publish();
172+
publish(arr.clone());
158173
sleep();
159174
}
160175
// If sorting hasn't been stopped, set complete and draw one more time.
161176
if (!algVisualizer.stopSort()) {
162177
arrDisplay.setComplete(true);
163-
publish();
178+
publish(arr.clone());
164179
sleep();
165180
}
166181
}
@@ -178,7 +193,7 @@ private void insertionSort() {
178193

179194
while (j >= 0 && arr[j] > key) { // compare arr[j] and arr[i]
180195
if (algVisualizer.stopSort()) {
181-
publish();
196+
publish(arr.clone());
182197
sleep();
183198
break;
184199
}
@@ -190,7 +205,7 @@ private void insertionSort() {
190205
// Add a pair of swapped indexes
191206
arrDisplay.addSwappedIndexes(j, j + 1);
192207
// Repaint the array
193-
publish();
208+
publish(arr.clone());
194209
sleep();
195210
}
196211
// Add a pair of swapped indexes
@@ -201,7 +216,7 @@ private void insertionSort() {
201216
// If sorting hasn't been stopped, set complete and draw one more time.
202217
if (!algVisualizer.stopSort()) {
203218
arrDisplay.setComplete(true);
204-
publish();
219+
publish(arr.clone());
205220
sleep();
206221
}
207222
}
@@ -222,7 +237,7 @@ private void mergeSort(int l, int r) {
222237
// If sorting is done and a reset has not been done, repaint one more time
223238
if (isSorted() && !algVisualizer.stopSort()) {
224239
arrDisplay.setComplete(true);
225-
publish();
240+
publish(arr.clone());
226241
sleep();
227242

228243
}
@@ -268,15 +283,15 @@ private void merge(int l, int m, int r) {
268283
// Add a pair of swapped indexes
269284
arrDisplay.addSwappedIndexes(k, k + i);
270285
// Repaint the array
271-
publish();
286+
publish(arr.clone());
272287
sleep();
273288
} else {
274289
arr[k] = R[j];
275290
j++;
276291
// Add a pair of swapped indexes
277292
arrDisplay.addSwappedIndexes(k, k + j);
278293
// Repaint the arrays
279-
publish();
294+
publish(arr.clone());
280295
sleep();
281296
}
282297
k++;
@@ -292,7 +307,7 @@ private void merge(int l, int m, int r) {
292307
// Add a pair of swapped indexes
293308
arrDisplay.addSwappedIndexes(k, k + i);
294309
// Repaint the array
295-
publish();
310+
publish(arr.clone());
296311
sleep();
297312
i++;
298313
k++;
@@ -307,7 +322,7 @@ private void merge(int l, int m, int r) {
307322
arr[k] = R[j];
308323
// Add a pair of swapped indexes
309324
arrDisplay.addSwappedIndexes(k, k + j);
310-
publish();
325+
publish(arr.clone());
311326
sleep();
312327
j++;
313328
k++;
@@ -316,7 +331,7 @@ private void merge(int l, int m, int r) {
316331
}
317332

318333
private void quickSort(int low, int high) {
319-
if (algVisualizer.getSort().equals("Quick Sort") && !algVisualizer.stopSort()) { // Needed because of recursion
334+
if (algVisualizer.getSort().equals("Quick Sort") && !algVisualizer.stopSort()) { // Needed because of recursion
320335
if (low < high) {
321336
// pi is partitioning index, arr[pi] is now at right place
322337
int pi = partition(low, high);
@@ -330,7 +345,7 @@ private void quickSort(int low, int high) {
330345
// the array is sorted besides this
331346
if (isSorted() && !algVisualizer.stopSort()) {
332347
arrDisplay.setComplete(true);
333-
publish();
348+
publish(arr.clone());
334349
sleep();
335350
}
336351
}
@@ -342,7 +357,8 @@ private int partition(int low, int high) {
342357
int i = (low - 1); // index of smaller element
343358

344359
for (int j = low; j < high; j++) {
345-
if (algVisualizer.getSort().equals("Quick Sort") && !algVisualizer.stopSort()) { // Needed because of recursion
360+
if (algVisualizer.getSort().equals("Quick Sort") && !algVisualizer.stopSort()) { // Needed because of
361+
// recursion
346362
// Add a comparison
347363
algVisualizer.setIndexComparisons(algVisualizer.getIndexComparisons() + 1);
348364

@@ -363,7 +379,8 @@ private int partition(int low, int high) {
363379
}
364380
}
365381
}
366-
if (algVisualizer.getSort().equals("Quick Sort") && !algVisualizer.stopSort()) { // Needed because of recursion
382+
if (algVisualizer.getSort().equals("Quick Sort") && !algVisualizer.stopSort()) { // Needed because of
383+
// recursion
367384
// swap arr[i+1] and arr[high] (or pivot)
368385
int temp = arr[i + 1];
369386
arr[i + 1] = arr[high];

0 commit comments

Comments
 (0)