From d83aa08d1cb2b52ab208f0a6f260264550e82fbe Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 20 Aug 2020 15:52:27 -0500 Subject: [PATCH 1/4] Added Performance label Added a JLabel between the buttonPanel and arrPanel that shows performance statistics and is updated every time that the frame is repainted. --- .../algorithmvisualizer/AlgVisualizer.java | 86 ++++++++++++++----- .../algorithmvisualizer/ArrDisplay.java | 20 ++--- .../algorithmvisualizer/ArrSorting.java | 9 +- 3 files changed, 79 insertions(+), 36 deletions(-) diff --git a/src/com/example/algorithmvisualizer/AlgVisualizer.java b/src/com/example/algorithmvisualizer/AlgVisualizer.java index 5916c2f..62b7549 100644 --- a/src/com/example/algorithmvisualizer/AlgVisualizer.java +++ b/src/com/example/algorithmvisualizer/AlgVisualizer.java @@ -22,11 +22,13 @@ public class AlgVisualizer implements ActionListener { - 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 n; + private int numSwaps; + private int delay; private Integer indexComparisons; private long startTime; // start time of a sort private long endTime; // end time of a sort @@ -47,8 +49,8 @@ public class AlgVisualizer implements ActionListener { private JButton selectionButton; private JButton mergeButton; private JButton quickButton; - private JButton performanceButton; private JComboBox sizeChanger; + private JLabel performanceLabel; private SwingWorker arrSort; /* @@ -83,6 +85,9 @@ public void initializeVars() { arr = shuffleArr(arr); indexComparisons = 0; + startTime = 0; + endTime = 0; + setDelay(2); // Initialize objects that will display and sort the array @@ -131,10 +136,10 @@ 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 + // Initialize the performance label and center it + + performanceLabel = new JLabel(); + performanceLabel.setHorizontalAlignment(SwingConstants.CENTER); } /* @@ -152,7 +157,6 @@ public void setFrame() { buttonPanel.add(mergeButton); buttonPanel.add(quickButton); buttonPanel.add(sizeChanger); - buttonPanel.add(performanceButton); // Initialize and make the frame visible frame = new JFrame("Algorithm Visualizer"); @@ -160,6 +164,7 @@ public void setFrame() { 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); @@ -215,14 +220,6 @@ 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); } } @@ -239,7 +236,6 @@ public void reset() { setStopSort(true); arr = shuffleArr(arr); arrDisplay.clearSwappedIndexes(); - arrDisplay.setNumChunk(0); arrDisplay.setComplete(false); arrDisplay.setArr(arr); indexComparisons = 0; @@ -274,6 +270,36 @@ 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(); + + long visualizationTime = 0; + long sortingTime = 0; + if (!getSort().equals("Not Sorting")) { + visualizationTime = System.currentTimeMillis() - startTime; + sortingTime = visualizationTime - (delay * (arrDisplay.getNumChunks() - 1)); + } + + 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; } @@ -366,10 +392,6 @@ public void setN(int n) { this.n = n; } - public JButton getPerformanceButton() { - return performanceButton; - } - public Integer getIndexComparisons() { return indexComparisons; } @@ -393,4 +415,28 @@ 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; + } } diff --git a/src/com/example/algorithmvisualizer/ArrDisplay.java b/src/com/example/algorithmvisualizer/ArrDisplay.java index a47d5af..f7ec896 100644 --- a/src/com/example/algorithmvisualizer/ArrDisplay.java +++ b/src/com/example/algorithmvisualizer/ArrDisplay.java @@ -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 swappedIndexes; private Integer[] arr; @@ -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 @@ -89,6 +90,7 @@ public void paintComponent(Graphics g) { // Draw the current indexes bar graphics2d.fillRect(x, y, width, height); } + algVisualizer.updatePerformance(); } public ArrayList getSwappedIndexes() { @@ -104,12 +106,12 @@ public void clearSwappedIndexes() { swappedIndexes = new ArrayList(); } - 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() { @@ -117,10 +119,6 @@ public boolean 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; } diff --git a/src/com/example/algorithmvisualizer/ArrSorting.java b/src/com/example/algorithmvisualizer/ArrSorting.java index 36f74f1..3e53f19 100644 --- a/src/com/example/algorithmvisualizer/ArrSorting.java +++ b/src/com/example/algorithmvisualizer/ArrSorting.java @@ -18,12 +18,11 @@ public class ArrSorting extends SwingWorker { - 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; @@ -87,8 +86,8 @@ protected Void doInBackground() throws Exception { protected void process(List 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); @@ -101,7 +100,7 @@ protected void process(List chunks) { */ private void sleep() { try { - Thread.sleep(delay); + Thread.sleep(algVisualizer.getDelay()); } catch (InterruptedException e) { e.printStackTrace(); } From bbd0780c1a673e83ec2e6fad726c809a873a9410 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 20 Aug 2020 16:02:31 -0500 Subject: [PATCH 2/4] Changed Window size, added JSlider --- .../algorithmvisualizer/AlgVisualizer.java | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/com/example/algorithmvisualizer/AlgVisualizer.java b/src/com/example/algorithmvisualizer/AlgVisualizer.java index 62b7549..6e32001 100644 --- a/src/com/example/algorithmvisualizer/AlgVisualizer.java +++ b/src/com/example/algorithmvisualizer/AlgVisualizer.java @@ -22,10 +22,10 @@ public class AlgVisualizer implements ActionListener { - 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 final int CONTENT_WIDTH = 900; + private final int CONTENT_HEIGHT = 960; + private final int ARR_DISPLAY_HEIGHT = 900; + private final String[] SIZE_OPTIONS = { "10", "50", "100", "300", "450", "900" }; // array size options private int n; private int numSwaps; private int delay; @@ -50,6 +50,7 @@ public class AlgVisualizer implements ActionListener { private JButton mergeButton; private JButton quickButton; private JComboBox sizeChanger; + private JSlider FPSslider; private JLabel performanceLabel; private SwingWorker arrSort; @@ -135,6 +136,8 @@ public void initializeVars() { sizeChanger = new JComboBox(SIZE_OPTIONS); // Pass the String containing all of the size options sizeChanger.addActionListener(this); sizeChanger.setBackground(Color.WHITE); + + FPSslider = new JSlider(JSlider.HORIZONTAL, 0, 30, 15); // Initialize the performance label and center it @@ -157,6 +160,7 @@ public void setFrame() { buttonPanel.add(mergeButton); buttonPanel.add(quickButton); buttonPanel.add(sizeChanger); + buttonPanel.add(FPSslider); // Initialize and make the frame visible frame = new JFrame("Algorithm Visualizer"); @@ -439,4 +443,12 @@ public int getDelay() { public void setDelay(int delay) { this.delay = delay; } + + public JSlider getFPSslider() { + return FPSslider; + } + + public void setFPSslider(JSlider fPSslider) { + FPSslider = fPSslider; + } } From 1d33d44f7919366512ea5a979b8fc33ea96e96de Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 20 Aug 2020 17:21:04 -0500 Subject: [PATCH 3/4] Added Working FPS bar (Close #14) --- .../algorithmvisualizer/AlgVisualizer.java | 38 +++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/src/com/example/algorithmvisualizer/AlgVisualizer.java b/src/com/example/algorithmvisualizer/AlgVisualizer.java index 6e32001..86160e8 100644 --- a/src/com/example/algorithmvisualizer/AlgVisualizer.java +++ b/src/com/example/algorithmvisualizer/AlgVisualizer.java @@ -18,13 +18,19 @@ 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 int numSwaps; @@ -32,6 +38,8 @@ public class AlgVisualizer implements ActionListener { 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; @@ -88,7 +96,9 @@ public void initializeVars() { indexComparisons = 0; startTime = 0; endTime = 0; - setDelay(2); + visualizationTime = 0; + sortingTime = 0; + setDelay(1000 / FPS_INIT); // Initialize objects that will display and sort the array @@ -136,9 +146,10 @@ public void initializeVars() { sizeChanger = new JComboBox(SIZE_OPTIONS); // Pass the String containing all of the size options sizeChanger.addActionListener(this); sizeChanger.setBackground(Color.WHITE); - - FPSslider = new JSlider(JSlider.HORIZONTAL, 0, 30, 15); + 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(); @@ -227,6 +238,16 @@ public void actionPerformed(ActionEvent event) { } } + @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); + } + } + /* * Reset method is called whenever the user presses the reset button, or when a * new size of array is chosen from the size changer. This method stops sorting, @@ -257,6 +278,8 @@ public void resetSwingWorker(AlgVisualizer alg, Integer[] arr, ArrDisplay displa public void resetTime() { startTime = 0; endTime = 0; + visualizationTime = 0; + sortingTime = 0; } public Integer[] shuffleArr(Integer[] arr) { @@ -288,11 +311,12 @@ public Integer[] fillArr(Integer[] arr) { public void updatePerformance() { numSwaps = arrDisplay.getSwappedIndexes().size(); - long visualizationTime = 0; - long sortingTime = 0; - if (!getSort().equals("Not Sorting")) { + if (!getSort().equals("Not Sorting") && arrDisplay.getNumChunks() == 1) { visualizationTime = System.currentTimeMillis() - startTime; sortingTime = visualizationTime - (delay * (arrDisplay.getNumChunks() - 1)); + } else if (arrDisplay.getNumChunks() > 1) { + visualizationTime = System.currentTimeMillis() - startTime; + sortingTime = sortingTime + (System.currentTimeMillis() - sortingTime); } String performance = String.format( From abf029f955f5d5021f74f25ba74b952e83a2a1a5 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 20 Aug 2020 18:49:13 -0500 Subject: [PATCH 4/4] performance label working again --- .../algorithmvisualizer/AlgVisualizer.java | 19 ++++++++++++++++--- .../algorithmvisualizer/ArrSorting.java | 2 ++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/com/example/algorithmvisualizer/AlgVisualizer.java b/src/com/example/algorithmvisualizer/AlgVisualizer.java index 86160e8..97ee297 100644 --- a/src/com/example/algorithmvisualizer/AlgVisualizer.java +++ b/src/com/example/algorithmvisualizer/AlgVisualizer.java @@ -35,6 +35,7 @@ public class AlgVisualizer implements ActionListener, ChangeListener { private int n; 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 @@ -280,6 +281,7 @@ public void resetTime() { endTime = 0; visualizationTime = 0; sortingTime = 0; + totalDelay = 0; } public Integer[] shuffleArr(Integer[] arr) { @@ -310,13 +312,16 @@ public Integer[] fillArr(Integer[] arr) { */ 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 - (delay * (arrDisplay.getNumChunks() - 1)); + sortingTime = visualizationTime - totalDelay; } else if (arrDisplay.getNumChunks() > 1) { visualizationTime = System.currentTimeMillis() - startTime; - sortingTime = sortingTime + (System.currentTimeMillis() - sortingTime); + sortingTime = visualizationTime - totalDelay; + } + if(stopSort) { + resetTime(); } String performance = String.format( @@ -475,4 +480,12 @@ public JSlider getFPSslider() { public void setFPSslider(JSlider fPSslider) { FPSslider = fPSslider; } + + public long getTotalDelay() { + return totalDelay; + } + + public void setTotalDelay(long totalDelay) { + this.totalDelay = totalDelay; + } } diff --git a/src/com/example/algorithmvisualizer/ArrSorting.java b/src/com/example/algorithmvisualizer/ArrSorting.java index 3e53f19..cecdb6e 100644 --- a/src/com/example/algorithmvisualizer/ArrSorting.java +++ b/src/com/example/algorithmvisualizer/ArrSorting.java @@ -101,6 +101,8 @@ protected void process(List chunks) { private void sleep() { try { Thread.sleep(algVisualizer.getDelay()); + if (!algVisualizer.stopSort()) + algVisualizer.setTotalDelay(algVisualizer.getTotalDelay() + algVisualizer.getDelay()); } catch (InterruptedException e) { e.printStackTrace(); }