Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 119 additions & 24 deletions src/com/example/algorithmvisualizer/AlgVisualizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,29 @@
import java.awt.Dimension;
import java.util.*;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import java.awt.event.*;

public class AlgVisualizer implements ActionListener {
public class AlgVisualizer implements ActionListener, ChangeListener {

private final int CONTENT_WIDTH = 900;
private final int CONTENT_HEIGHT = 960;
private final int ARR_DISPLAY_HEIGHT = 900;
private final int FPS_MIN = 1;
private final int FPS_INIT = 10;
private final int FPS_MAX = 100;
private final String[] SIZE_OPTIONS = { "10", "50", "100", "300", "450", "900" }; // array size options
private int n;
private final int CONTENT_WIDTH = 800;
private final int CONTENT_HEIGHT = 860;
private final int ARR_DISPLAY_HEIGHT = 800;
private final String[] SIZE_OPTIONS = { "10", "50", "100", "200", "400", "800" }; // array size options
private int numSwaps;
private int delay;
private long totalDelay;
private Integer indexComparisons;
private long startTime; // start time of a sort
private long endTime; // end time of a sort
private long visualizationTime;
private long sortingTime;
private boolean doBubbleSort;
private boolean doInsertionSort;
private boolean doSelectionSort;
Expand All @@ -47,8 +58,9 @@ public class AlgVisualizer implements ActionListener {
private JButton selectionButton;
private JButton mergeButton;
private JButton quickButton;
private JButton performanceButton;
private JComboBox<String> sizeChanger;
private JSlider FPSslider;
private JLabel performanceLabel;
private SwingWorker<Void, Integer[]> arrSort;

/*
Expand Down Expand Up @@ -83,6 +95,11 @@ public void initializeVars() {
arr = shuffleArr(arr);

indexComparisons = 0;
startTime = 0;
endTime = 0;
visualizationTime = 0;
sortingTime = 0;
setDelay(1000 / FPS_INIT);

// Initialize objects that will display and sort the array

Expand Down Expand Up @@ -131,10 +148,13 @@ public void initializeVars() {
sizeChanger.addActionListener(this);
sizeChanger.setBackground(Color.WHITE);

performanceButton = new JButton("Performance");
performanceButton.addActionListener(this);
performanceButton.setBackground(Color.WHITE);
performanceButton.setEnabled(false); // This button is not available until a sort is complete
FPSslider = new JSlider(JSlider.HORIZONTAL, FPS_MIN, FPS_MAX, FPS_INIT);
FPSslider.addChangeListener(this);
FPSslider.setBackground(Color.DARK_GRAY);
// Initialize the performance label and center it

performanceLabel = new JLabel();
performanceLabel.setHorizontalAlignment(SwingConstants.CENTER);
}

/*
Expand All @@ -152,14 +172,15 @@ public void setFrame() {
buttonPanel.add(mergeButton);
buttonPanel.add(quickButton);
buttonPanel.add(sizeChanger);
buttonPanel.add(performanceButton);
buttonPanel.add(FPSslider);

// Initialize and make the frame visible
frame = new JFrame("Algorithm Visualizer");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false); // Cannot be resizable, causes visual issues
frame.add(buttonPanel, BorderLayout.PAGE_START); // Button panel added to the top of the frame
frame.add(arrPanel, BorderLayout.PAGE_END); // Array display is added to the bottom of the frame
frame.add(performanceLabel);
frame.pack();
frame.setLocationRelativeTo(null); // center of the screen
frame.setVisible(true);
Expand Down Expand Up @@ -215,14 +236,16 @@ public void actionPerformed(ActionEvent event) {
// reset and paint the new array
reset();
arrSort.execute();
} else if (event.getSource() == performanceButton) {
int numSwaps = arrDisplay.getSwappedIndexes().size();
long visualizationTime = endTime - startTime; // net time
long sortingTime = visualizationTime - (60 * numSwaps + 1); // - NEED TO FIX
String statsMessage = String.format(
"Index Comparisons : %d Index Swaps : %d Visualization Time : %dms Sorting Time : %dms",
indexComparisons, numSwaps, visualizationTime, sortingTime);
JOptionPane.showMessageDialog(frame, statsMessage, "Performance", JOptionPane.PLAIN_MESSAGE);
}
}

@Override
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider) e.getSource();
if (!source.getValueIsAdjusting()) {
int fps = (int) source.getValue();
delay = 1000 / fps; // ms
setDelay(delay);
}
}

Expand All @@ -239,7 +262,6 @@ public void reset() {
setStopSort(true);
arr = shuffleArr(arr);
arrDisplay.clearSwappedIndexes();
arrDisplay.setNumChunk(0);
arrDisplay.setComplete(false);
arrDisplay.setArr(arr);
indexComparisons = 0;
Expand All @@ -257,6 +279,9 @@ public void resetSwingWorker(AlgVisualizer alg, Integer[] arr, ArrDisplay displa
public void resetTime() {
startTime = 0;
endTime = 0;
visualizationTime = 0;
sortingTime = 0;
totalDelay = 0;
}

public Integer[] shuffleArr(Integer[] arr) {
Expand All @@ -274,6 +299,40 @@ public Integer[] fillArr(Integer[] arr) {
return arr;
}

/*
* updatePerformance will be called every time the array is repainted. This
* makes it slower / not real time when there is a high delay.
*
* We get the values for each performance statistic we want to track (number of
* swaps, number of comparisons, visualization time, sorting time), format them
* into a string that will then be assigned to the JLabel's text.
*
* frame.pack() makes sure that our new text will fit in the frame, and will
* adjust if it does not.
*/
public void updatePerformance() {
numSwaps = arrDisplay.getSwappedIndexes().size();
System.out.println("total delay " + totalDelay);
if (!getSort().equals("Not Sorting") && arrDisplay.getNumChunks() == 1) {
visualizationTime = System.currentTimeMillis() - startTime;
sortingTime = visualizationTime - totalDelay;
} else if (arrDisplay.getNumChunks() > 1) {
visualizationTime = System.currentTimeMillis() - startTime;
sortingTime = visualizationTime - totalDelay;
}
if(stopSort) {
resetTime();
}

String performance = String.format(
"Index Comparisons : %d Index Swaps : %d Visualization Time : %dms Sorting Time : %dms",
indexComparisons, numSwaps, visualizationTime, sortingTime);

performanceLabel.setText(performance);

frame.pack();
}

public Integer[] getArr() {
return arr;
}
Expand Down Expand Up @@ -366,10 +425,6 @@ public void setN(int n) {
this.n = n;
}

public JButton getPerformanceButton() {
return performanceButton;
}

public Integer getIndexComparisons() {
return indexComparisons;
}
Expand All @@ -393,4 +448,44 @@ public long getEndTime() {
public void setEndTime(long endTime) {
this.endTime = endTime;
}

public JLabel getPerformanceLabel() {
return performanceLabel;
}

public void setPerformanceLabel(JLabel performanceLabel) {
this.performanceLabel = performanceLabel;
}

public int getNumSwaps() {
return numSwaps;
}

public void setNumSwaps(int numSwaps) {
this.numSwaps = numSwaps;
}

public int getDelay() {
return delay;
}

public void setDelay(int delay) {
this.delay = delay;
}

public JSlider getFPSslider() {
return FPSslider;
}

public void setFPSslider(JSlider fPSslider) {
FPSslider = fPSslider;
}

public long getTotalDelay() {
return totalDelay;
}

public void setTotalDelay(long totalDelay) {
this.totalDelay = totalDelay;
}
}
20 changes: 9 additions & 11 deletions src/com/example/algorithmvisualizer/ArrDisplay.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class ArrDisplay extends JComponent {
private static final long serialVersionUID = 1L;
private int swappedIndex1;
private int swappedIndex2;
private int numChunk; // amount of frames painted since the array was shuffled
private int numChunks; // amount of frames painted since the array was shuffled
private boolean isComplete; // if the array is sorted
private ArrayList<Integer[]> swappedIndexes;
private Integer[] arr;
Expand Down Expand Up @@ -61,8 +61,9 @@ public void paintComponent(Graphics g) {
swappedIndex1 = -1;
swappedIndex2 = -1;
} else if (!algVisualizer.stopSort()) {
swappedIndex1 = swappedIndexes.get(numChunk - 1)[0];
swappedIndex2 = swappedIndexes.get(numChunk - 1)[1];
// exclude the first chunk as its used to draw the first array, not related to the sorting
swappedIndex1 = swappedIndexes.get(numChunks - 1)[0]; // index out of bounds exception?
swappedIndex2 = swappedIndexes.get(numChunks - 1)[1];
}

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

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

public void setNumChunk(int numChunk) {
this.numChunk = numChunk;
public void setNumChunk(int numChunks) {
this.numChunks = numChunks;
}

public int getNumChunk() {
return numChunk;
public int getNumChunks() {
return numChunks;
}

public boolean isComplete() {
return isComplete;
}

public void setComplete(boolean complete) {
// Performance Button's availability is based on whether or not the array is
// sorted.
algVisualizer.getPerformanceButton().setEnabled(complete);

this.isComplete = complete;
}

Expand Down
11 changes: 6 additions & 5 deletions src/com/example/algorithmvisualizer/ArrSorting.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@

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

private Integer delay = 10;
private int n;
private Integer[] arr;
private AlgVisualizer algVisualizer;
private ArrDisplay arrDisplay;
private int numChunk;
private int numChunks;

public ArrSorting(AlgVisualizer algVisualizer, Integer[] arr, ArrDisplay arrDisplay) {
this.algVisualizer = algVisualizer;
Expand Down Expand Up @@ -87,8 +86,8 @@ protected Void doInBackground() throws Exception {
protected void process(List<Integer[]> chunks) {
while (chunks.size() > 0) {
// Paint each cloned array and update number of chunks
numChunk++;
arrDisplay.setNumChunk(this.numChunk);
numChunks++;
arrDisplay.setNumChunk(this.numChunks);
arrDisplay.setArr(chunks.get(0));
arrDisplay.repaint();
chunks.remove(0);
Expand All @@ -101,7 +100,9 @@ protected void process(List<Integer[]> chunks) {
*/
private void sleep() {
try {
Thread.sleep(delay);
Thread.sleep(algVisualizer.getDelay());
if (!algVisualizer.stopSort())
algVisualizer.setTotalDelay(algVisualizer.getTotalDelay() + algVisualizer.getDelay());
} catch (InterruptedException e) {
e.printStackTrace();
}
Expand Down