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
216 changes: 60 additions & 156 deletions src/com/example/algorithmvisualizer/AlgVisualizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@

package com.example.algorithmvisualizer;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.util.*;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
Expand All @@ -25,12 +22,10 @@

public class AlgVisualizer implements ActionListener, ChangeListener {

private final int CONTENT_WIDTH = 900;
private final int ARR_DISPLAY_HEIGHT = 900;
private final int FPS_MIN = 2;
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 String[] sizeOptions = { "10", "50", "100", "300", "450", "900" }; // array size options
private int n;
private int numSwaps;
private int delay;
Expand All @@ -46,125 +41,19 @@ public class AlgVisualizer implements ActionListener, ChangeListener {
private boolean doQuickSort;
private boolean stopSort; // True if sorting is stopped
private Integer[] arr; // array that is going to be sorted
private JFrame frame;
private JPanel arrPanel;
private ArrDisplay arrDisplay;
private JPanel buttonPanel;
private JButton resetButton;
private JButton bubbleButton;
private JButton insertionButton;
private JButton selectionButton;
private JButton mergeButton;
private JButton quickButton;
private JComboBox<String> sizeChanger;
private JSlider FPSslider;
private JLabel performanceLabel;
private ContentWindow frame;
private SwingWorker<Void, Integer[]> arrSort;

/*
* In main(), we initialize an AlgVisualizer object, all instance variables, set
* up the frame / window that the application will run inside, and make it
* visible. By the end, a window containing what is meant to be shown on
* application start up will open on the users screen, waiting for input.
*/
public static void main(String[] args) {
AlgVisualizer algVisualizer = new AlgVisualizer();
algVisualizer.initializeVars();
algVisualizer.setFrame();
}

/*
* This method initializes all of this classes instance variables. The array is
* initialized, filled, and shuffled. The arrDisplay object that paints the
* array in bar graph form is initialized and passed the array. All buttons are
* initialized and include an action listener.
*
*/
public void initializeVars() {

n = Integer.parseInt(SIZE_OPTIONS[0]);
arr = initArr();

indexComparisons = 0;
setDelay(1000 / FPS_INIT);

// Initialize objects that will display and sort the array
arrDisplay = new ArrDisplay(this);
arrDisplay.setArr(arr);
arrDisplay.setPreferredSize(new Dimension(CONTENT_WIDTH, ARR_DISPLAY_HEIGHT));

arrSort = new ArrSorting(this, this.arr, this.arrDisplay);

// Panels in the frame that will hold all components.
// JPanels use the flowLayout to manage their components automatically.
buttonPanel = new JPanel();
buttonPanel.setBackground(Color.DARK_GRAY);

arrPanel = new JPanel();
arrPanel.add(arrDisplay);

// Initialize all components and add action listeners
resetButton = new JButton("Reset");
resetButton.addActionListener(this);
resetButton.setBackground(Color.WHITE);

bubbleButton = new JButton("Bubble Sort");
bubbleButton.addActionListener(this);
bubbleButton.setBackground(Color.WHITE);

selectionButton = new JButton("Selection Sort");
selectionButton.addActionListener(this);
selectionButton.setBackground(Color.WHITE);

insertionButton = new JButton("Insertion Sort");
insertionButton.addActionListener(this);
insertionButton.setBackground(Color.WHITE);

mergeButton = new JButton("Merge Sort");
mergeButton.addActionListener(this);
mergeButton.setBackground(Color.WHITE);

quickButton = new JButton("Quick Sort");
quickButton.addActionListener(this);
quickButton.setBackground(Color.WHITE);

sizeChanger = new JComboBox<String>(SIZE_OPTIONS); // Pass the String containing all of the size options
sizeChanger.addActionListener(this);
sizeChanger.setBackground(Color.WHITE);

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);
}

/*
* setFrame() will add all the components that were initialized in the
* initializeVars() method to JPanels, which will then also be added to the main
* JFrame. The frame is initialized and made visible.
*/
public void setFrame() {
// Add JButtons / components to button panel
buttonPanel.add(resetButton);
buttonPanel.add(bubbleButton);
buttonPanel.add(selectionButton);
buttonPanel.add(insertionButton);
buttonPanel.add(mergeButton);
buttonPanel.add(quickButton);
buttonPanel.add(sizeChanger);
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);
algVisualizer.setN(Integer.parseInt(algVisualizer.getSizeOptions()[0]));
algVisualizer.setArr(algVisualizer.initArr());
algVisualizer.setFrame(new ContentWindow(algVisualizer));
// Seems very messy
algVisualizer.setIndexComparisons(0);
algVisualizer.setDelay(1000 / algVisualizer.getInitFPS());
algVisualizer.setSwingWorker(
new ArrSorting(algVisualizer, algVisualizer.arr, algVisualizer.getFrame().getArrDisplay()));
}

/*
Expand All @@ -185,27 +74,27 @@ public void actionPerformed(ActionEvent event) {
doMergeSort = false;
doQuickSort = false;
// Find the source of the action
if (event.getSource() == bubbleButton) {
if (event.getSource() == frame.getBubbleButton()) {
doBubbleSort = true;
arrSort.execute();
} else if (event.getSource() == selectionButton) {
} else if (event.getSource() == frame.getSelectionButton()) {
doSelectionSort = true;
arrSort.execute();
} else if (event.getSource() == insertionButton) {
} else if (event.getSource() == frame.getInsertionButton()) {
doInsertionSort = true;
arrSort.execute();
} else if (event.getSource() == mergeButton) {
} else if (event.getSource() == frame.getMergeButton()) {
doMergeSort = true;
arrSort.execute();
} else if (event.getSource() == quickButton) {
} else if (event.getSource() == frame.getQuickButton()) {
doQuickSort = true;
arrSort.execute();
} else if (event.getSource() == resetButton) {
} else if (event.getSource() == frame.getResetButton()) {
reset();
arrSort.execute();
} else if (event.getSource() == sizeChanger) {
} else if (event.getSource() == frame.getSizeChanger()) {
// Find what size was selected, and set n to that value
String selectedSize = (String) sizeChanger.getSelectedItem();
String selectedSize = (String) frame.getSizeChanger().getSelectedItem();
n = Integer.valueOf(selectedSize);
// reset and paint the new array
reset();
Expand All @@ -232,20 +121,14 @@ public void stateChanged(ChangeEvent e) {
* SwingWorker, we simply re-instantiate it so that we are able to call it
* again.
*/

public void reset() {
setStopSort(true);
arr = initArr();
arrDisplay.clearSwappedIndexes();
arrDisplay.setComplete(false);
frame.getArrDisplay().clearSwappedIndexes();
frame.getArrDisplay().setComplete(false);
indexComparisons = 0;
resetTime();
resetSwingWorker(this, arr, arrDisplay);
}

// Re-instantiates the SwingWorker so that execute() can be called again.
public void resetSwingWorker(AlgVisualizer alg, Integer[] arr, ArrDisplay displayArr) {
arrSort = new ArrSorting(this, arr, displayArr);
setSwingWorker(new ArrSorting(this, arr, frame.getArrDisplay()));
}

// Reset the timer on the previous sort that was done, used in the reset()
Expand All @@ -256,7 +139,7 @@ public void resetTime() {
sortingTime = 0;
totalDelay = 0;
}

public Integer[] initArr() {
Integer[] arr = new Integer[n];
arr = fillArr(arr);
Expand Down Expand Up @@ -291,48 +174,53 @@ public Integer[] fillArr(Integer[] arr) {
* adjust if it does not.
*/
public void updatePerformance() {
numSwaps = arrDisplay.getSwappedIndexes().size();
if (!getSort().equals("Not Sorting") && arrDisplay.getNumChunks() == 0) {
numSwaps = frame.getArrDisplay().getSwappedIndexes().size();
if (!getSort().equals("Not Sorting") && frame.getArrDisplay().getNumChunks() == 0) {
visualizationTime = System.currentTimeMillis() - startTime;
sortingTime = visualizationTime - totalDelay;
} else if (arrDisplay.getNumChunks() > 1 && !arrDisplay.isComplete()) {
} else if (frame.getArrDisplay().getNumChunks() > 1 && !frame.getArrDisplay().isComplete()) {
visualizationTime = System.currentTimeMillis() - startTime;
sortingTime = visualizationTime - totalDelay;
}
if(stopSort) {
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.getPerformanceLabel().setText(performance);
frame.pack();
}

public Integer[] getArr() {
return arr;
}

public int getArrDispHeight() {
return ARR_DISPLAY_HEIGHT;
public void setArr(Integer[] arr) {
this.arr = arr;
}

public int getWidth() {
return CONTENT_WIDTH;
public void setN(int n) {
this.n = n;
}

public JFrame getJFrame() {
public ContentWindow getFrame() {
return frame;
}

public ArrDisplay getDisplayArr() {
return arrDisplay;
public void setFrame(ContentWindow frame) {
this.frame = frame;
}

public SwingWorker<Void, Integer[]> getArrSorting() {
return arrSort;
}

// Re-instantiates the SwingWorker so that execute() can be called again.
public void setSwingWorker(SwingWorker<Void, Integer[]> arrSort) {
this.arrSort = arrSort;
}

public void setSort(String sort) {
if (sort.equals("Bubble Sort")) {
doBubbleSort = true;
Expand Down Expand Up @@ -381,11 +269,7 @@ public boolean stopSort() {
* disable them.
*/
public void setStopSort(boolean toSet) {
bubbleButton.setEnabled(toSet);
selectionButton.setEnabled(toSet);
insertionButton.setEnabled(toSet);
mergeButton.setEnabled(toSet);
quickButton.setEnabled(toSet);
frame.setSortButtons(toSet);
stopSort = toSet;
}

Expand Down Expand Up @@ -424,4 +308,24 @@ public long getTotalDelay() {
public void setTotalDelay(long totalDelay) {
this.totalDelay = totalDelay;
}

public String[] getSizeOptions() {
return sizeOptions;
}

public void setSizeOptions(String[] sizeOptions) {
this.sizeOptions = sizeOptions;
}

public int getMaxFPS() {
return FPS_MAX;
}

public int getInitFPS() {
return FPS_INIT;
}

public int getMinFPS() {
return FPS_MIN;
}
}
12 changes: 7 additions & 5 deletions src/com/example/algorithmvisualizer/ArrDisplay.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ public class ArrDisplay extends JComponent {
private ArrayList<Integer[]> swappedIndexes;
private Integer[] arr;
private AlgVisualizer algVisualizer;
private ContentWindow frame;

public ArrDisplay(AlgVisualizer algVisualizer) {
public ArrDisplay(AlgVisualizer algVisualizer, ContentWindow frame) {
this.algVisualizer = algVisualizer;
this.frame = frame;
swappedIndexes = new ArrayList<Integer[]>();
}

Expand All @@ -52,7 +54,7 @@ public ArrDisplay(AlgVisualizer algVisualizer) {
public void paintComponent(Graphics g) {
Graphics2D graphics2d = (Graphics2D) g;
graphics2d.setColor(Color.DARK_GRAY);
graphics2d.fillRect(0, 0, algVisualizer.getWidth(), algVisualizer.getArrDispHeight());
graphics2d.fillRect(0, 0, frame.getArrDisplayWidth(), frame.getArrDisplayHeight());
if (algVisualizer.getSort().equals("Not Sorting") || isComplete) {
swappedIndex1 = -1;
swappedIndex2 = -1;
Expand All @@ -63,10 +65,10 @@ public void paintComponent(Graphics g) {
}
// Iterate through the array and drawn every index
for (int i = 0; i < arr.length; i++) {
int width = (int) (algVisualizer.getWidth() / (double) arr.length);
int height = arr[i] * (algVisualizer.getArrDispHeight() / arr.length);
int width = (int) (frame.getArrDisplayWidth() / (double) arr.length);
int height = arr[i] * (frame.getArrDisplayHeight() / arr.length);
int x = i * width;
int y = algVisualizer.getArrDispHeight() - height;
int y = frame.getArrDisplayHeight() - height;
if (i == swappedIndex1 && !algVisualizer.stopSort()) {
graphics2d.setColor(Color.RED);
} else if (i == swappedIndex2 && !algVisualizer.stopSort()) {
Expand Down
2 changes: 1 addition & 1 deletion src/com/example/algorithmvisualizer/ArrSorting.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ protected Void doInBackground() throws Exception {
if (algVisualizer.stopSort()) {
publish(arr.clone());
sleep();
algVisualizer.resetSwingWorker(algVisualizer, arr, arrDisplay);
algVisualizer.setSwingWorker(new ArrSorting(algVisualizer, arr, arrDisplay));
} else {
algVisualizer.setStartTime(System.currentTimeMillis());
if (algVisualizer.getSort().equals("Bubble Sort")) {
Expand Down
Loading