diff --git a/AlgorithmVisualizer.java b/AlgorithmVisualizer.java new file mode 100644 index 0000000..4ba00a6 --- /dev/null +++ b/AlgorithmVisualizer.java @@ -0,0 +1,6 @@ +/** AlgorithmVisualizer.java is responsibe for running the project */ +public class AlgorithmVisualizer { + public static void main(String[] args){ + new Main(); // referencing to the Main Class + } +} diff --git a/Main.java b/Main.java new file mode 100644 index 0000000..62b99d2 --- /dev/null +++ b/Main.java @@ -0,0 +1,81 @@ +/** + * Main.java includes: + * - Menus and menu items + * - Main frame + */ + +import java.awt.event.*; +import javax.swing.*; + +public class Main extends JFrame { + // Menubar + static JMenuBar menuBar; + + // JMenu + static JMenu mainMenu, helpDesk; + + // Menu items + static JMenuItem menuItem1, menuItem2, menuItem3, menuItem4; + + Main() { + // Create a menubar + menuBar = new JMenuBar(); + + // Create a menu + mainMenu = new JMenu("Menu"); + helpDesk = new JMenu("Help"); + + // Create a menu items + menuItem1 = new JMenuItem("Path Finding"); // Its for future vision + menuItem2 = new JMenuItem("Sorting Techniques"); // Done + menuItem3 = new JMenuItem("Puzzle Sorting"); // Its for future vision + menuItem4 = new JMenuItem("How it Works"); // About + + ListenerClass listener = new ListenerClass(); + + // Register listeners + menuItem1.addActionListener(listener); + menuItem2.addActionListener(listener); + menuItem3.addActionListener(listener); + + // Add menu items to menu + mainMenu.add(menuItem1); + mainMenu.add(menuItem2); + mainMenu.add(menuItem3); + helpDesk.add(menuItem4); + + // Add menu to menu bar + menuBar.add(mainMenu); + menuBar.add(helpDesk); + + // Add menubar to frame + setJMenuBar(menuBar); + + setTitle("Eightsoft"); + setSize(800, 800); + setLocation(300, 5); + setVisible(true); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + } + + class ListenerClass implements ActionListener { + String value; + + // Project Main Logic (Moving Panels) + public void actionPerformed(ActionEvent e) { + if (e.getSource() == menuItem1) { + System.out.println(" Path Finding Algorith (We will add it in future for portfolio)"); + } + else if (e.getSource() == menuItem2) { + // Creating Object + new Sorting(); + System.out.println("Menu Item 2 choosed"); + } + else if (e.getSource() == menuItem2) { + System.out.println(" Picture pazzling algorith (We will add it in future for portfolio)"); + } + setVisible(false); // will close the previous window + } + } + +} // Menu diff --git a/README.md b/README.md index cd71867..48e6b07 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,40 @@ # Algorithm Visualizer in Java - -By @Alimov-8 👨🏻‍💻 and @Rustam-Z 👨🏼‍💻 -🕐 Coming soon ... +Developed by [@Rustam-Z](https://github.com/Rustam-Z) and [@Alimov-8](https://github.com/Alimov-8) + +Demo video: https://youtu.be/huR1NSwUnAY + +Finish date: December 13, 2020 + +## Project Features +- Sorting Algorithms Visualizer `DONE` +- [Picture Puzzle Sorter](https://www.youtube.com/watch?v=Bc0sVtB_-ak) `TODO` +- [Pathfinding algorithm](https://clementmihailescu.github.io/Pathfinding-Visualizer/) `TODO` + +## First Prototype + + +## How to run? +``` +javac AlgorithmVisualizer.java +java AlgorithmVisualizer +``` + +## Skills Gained +- Multi-Threading using Swing Worker +- Customizing Swing Components +- Working with Graphics 2D +- Different sorting algorithms + +## References: +- https://clementmihailescu.github.io/Sorting-Visualizer/ +- https://www.geeksforgeeks.org/java-swing-jmenubar/ +- https://stackoverflow.com/questions/31094904/jmenu-not-appearing-until-window-is-resized +- https://stackoverflow.com/questions/4716372/java-how-do-i-close-a-jframe-while-opening-another-one +- First prototype video: https://www.youtube.com/watch?v=RxjXC1SM1A4 +- https://stackoverflow.com/questions/4246351/creating-random-colour-in-java +- https://stackoverflow.com/questions/782265/how-do-i-use-swingworker-in-java +- https://docs.oracle.com/javase/tutorial/essential/concurrency/sleep.html +- https://stackoverflow.com/questions/1097366/java-swing-revalidate-vs-repaint +- Merge sort: https://www.baeldung.com/java-merge-sort +- http://www.java2s.com/Tutorials/Java/Swing/JSlider/Add_change_event_listener_to_a_JSlider_in_Java.htm diff --git a/Sorting.java b/Sorting.java new file mode 100644 index 0000000..7315385 --- /dev/null +++ b/Sorting.java @@ -0,0 +1,118 @@ +// Main GUI part of Sorting. + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; + +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +public class Sorting extends Main { + // Object of the SortingAlgorithm, which includes the sorting algorithms + SortingAlgorithm sortAlgo = new SortingAlgorithm(); + + // Panels: pPanel1 - option bar, pPanel2 - visualization bar + JPanel pPanel1, pPanel2; + + // Option buttons for choosing sorting techniques, speed, and size of array + // Will be added to pPanel1 + JButton jbtRandomize, jbtMerge, jbtBubble, jbtInsertion, jbtSelection, jbtStart; + + // Progress Bar + JProgressBar jb1; + + JSlider slider = new JSlider(0, 100, 2); + + public Sorting(){ + // Panel for options (bubble sort, insertion sort...) + pPanel1 = new JPanel(); + pPanel1.setLayout(new GridLayout(1, 7)); + pPanel1.setBackground(Color.CYAN); + + // Panel for visualization part + pPanel2 = new JPanel(); + pPanel2.setLayout(new BorderLayout()); + + // Buttons + jbtRandomize = new JButton("Randomize"); + jbtMerge = new JButton("Merge Sort"); + jbtBubble = new JButton("Bubble Sort"); + jbtInsertion = new JButton("Insertion Sort"); + jbtSelection = new JButton("Selection Sort"); + jbtStart = new JButton("Start"); + jbtStart.setBackground(Color.GRAY); + + // Slider + // slider.setPreferredSize(new Dimension(150, 30)); + // slider.setMajorTickSpacing(50); + // slider.setPaintTicks(false); + + // Adding elements to pPanel1 + pPanel1.add(jbtRandomize); + pPanel1.add(jbtMerge); pPanel1.add(jbtSelection); pPanel1.add(jbtBubble); pPanel1.add(jbtInsertion); + // pPanel1.add(jbtStart); + pPanel1.add(slider, BorderLayout.WEST); + + // Adding elements to pPanel2 + pPanel2.add(sortAlgo, BorderLayout.CENTER); + + // Register listener, event handling + ListenerClass listener = new ListenerClass(); + jbtRandomize.addActionListener(listener); + jbtMerge.addActionListener(listener); + jbtBubble.addActionListener(listener); + jbtInsertion.addActionListener(listener); + jbtSelection.addActionListener(listener); + jbtStart.addActionListener(listener); + + // Add Panels to the Main JFrame + add(pPanel1, BorderLayout.NORTH); + add(pPanel2, BorderLayout.CENTER); + + // Slider settings + slider.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent event) { + int value = slider.getValue(); + sortAlgo.setSIZE(value); + // Graphics g = new Graphics(); + // sortAlgo.initBarHeight(); + sortAlgo.BAR_WIDTH = (float)800 / sortAlgo.getSIZE(); // bar width + sortAlgo.repaint(); + System.out.println(value); + + } + }); + } + + class ListenerClass implements ActionListener { + // Handles the Button operations + + public void actionPerformed(ActionEvent e) { + + if (e.getSource() == jbtRandomize) { + sortAlgo.initShuffler(); + } + else if (e.getSource() == jbtMerge) { + sortAlgo.mergeSort(); // Merge sort algorithm + sortAlgo.initShuffler(); // shuffling + } + else if (e.getSource() == jbtBubble) { + sortAlgo.bubbleSort(); // Bubble sort algorithm + sortAlgo.initShuffler(); // shuffling + } + else if (e.getSource() == jbtInsertion) { + sortAlgo.insertionSort(); // Insertion algorithm + sortAlgo.initShuffler(); // shuffling + } + else if (e.getSource() == jbtSelection) { + sortAlgo.selectionSort(); // Insertion algorithm + sortAlgo.initShuffler(); // shuffling + } + else if (e.getSource() == jbtStart) { + System.out.println("jbtStart button clicked"); + } + } + } // ListenerClass + +} // Sorting diff --git a/SortingAlgorithm.java b/SortingAlgorithm.java new file mode 100644 index 0000000..0b106d2 --- /dev/null +++ b/SortingAlgorithm.java @@ -0,0 +1,221 @@ +// Implementation of Sorting algorithms + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.geom.Rectangle2D; +import java.util.Random; + +import javax.swing.JPanel; +import javax.swing.SwingWorker; + +public class SortingAlgorithm extends JPanel { + private final int WIDTH = 800, HEIGHT = WIDTH * 9 / 16; + public int SIZE = 100; // the number if sorting elements + public float BAR_WIDTH = (float)WIDTH / SIZE; // bar width + private float[] bar_height = new float[SIZE]; // height of bars + private SwingWorker shuffler, sorter; + private int current_index, traversing_index; // needed for following colloring the items + + SortingAlgorithm() { + setBackground(Color.BLACK); + setPreferredSize(new Dimension(WIDTH, HEIGHT)); + initBarHeight(); // initialize the height of each bar + // initShuffler(); // shuffle each bar + } + + // setter for SIZE + public void setSIZE(int SIZE) { + this.SIZE = SIZE; + } + + // getter for SIZE + int getSIZE() { + return SIZE; + } + + // repaint() will automaticly call this function + // needed for coloring + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + + // Create randomizer + Random random = new Random(); + + // Drawing the rectangles + Graphics2D g2d = (Graphics2D)g; + g2d.setColor(Color.CYAN); + Rectangle2D.Float bar; + + for(int i = 0; i < getSIZE(); i++ ) { + // random colors + // final float hue = random.nextFloat(); + // final float saturation = 0.9f; //1.0 for brilliant, 0.0 for dull + // final float luminance = 1.0f; //1.0 for brighter, 0.0 for black + + // g2d.setColor(Color.getHSBColor(hue, saturation, luminance)); + bar = new Rectangle2D.Float(i * BAR_WIDTH, 0, BAR_WIDTH-1, bar_height[i]); + g2d.fill(bar); // g2d.draw(bar); + } + + // Color setter for the current object + g2d.setColor(Color.RED); + bar = new Rectangle2D.Float(current_index * BAR_WIDTH, 0, BAR_WIDTH, bar_height[current_index]); + g2d.fill(bar); + + // Color setter for the traversing object + g2d.setColor(Color.YELLOW); + bar = new Rectangle2D.Float(traversing_index * BAR_WIDTH, 0, BAR_WIDTH, bar_height[traversing_index]); + g2d.fill(bar); + } + + public void insertionSort() { + /*Insertion sort algorithm*/ + // Multithreading used for hadling the sorting + sorter = new SwingWorker<>() { + @Override + public Void doInBackground() throws InterruptedException { // function for calling multithreading + // Insertion sort algorithm starts + for(current_index = 1; current_index < getSIZE(); current_index++) { + traversing_index = current_index; + while(traversing_index > 0 && bar_height[traversing_index] < bar_height[traversing_index - 1]) { + swap(traversing_index, traversing_index - 1); + traversing_index--; + + Thread.sleep(10); // controls the speed + repaint(); // we need it because we ofter replace the contents of a JPanel + } + } + current_index = 0; + traversing_index = 0; + + return null; + } + }; + } + + public void bubbleSort() { + /*Bubble sorting algorithm*/ + sorter = new SwingWorker<>() { + @Override + public Void doInBackground() throws InterruptedException { + for(current_index = 0; current_index < getSIZE(); current_index++) { + for(traversing_index = 1; traversing_index < (getSIZE() - current_index); traversing_index++) { + if(bar_height[traversing_index - 1] > bar_height[traversing_index]) { + swap(traversing_index, traversing_index - 1); + traversing_index--; // just for annimation + + Thread.sleep(10); // controls the speed + repaint(); // we need it because we ofter replace the contents of a JPanel + } + } + } + current_index = 0; + traversing_index = 0; + + return null; + } + }; + } + + public void mergeSort() { + /*Merge sorting algorithm*/ + // Change code from bubbleSort to mergeSort + // TODO + + sorter = new SwingWorker<>() { + @Override + public Void doInBackground() throws InterruptedException { + for(current_index = 0; current_index < getSIZE(); current_index++) { + for(traversing_index = 1; traversing_index < (getSIZE() - current_index); traversing_index++) { + if(bar_height[traversing_index - 1] > bar_height[traversing_index]) { + swap(traversing_index, traversing_index - 1); + traversing_index--; // just for annimation + + Thread.sleep(10); // controls the speed + repaint(); // we need it because we ofter replace the contents of a JPanel + } + } + } + current_index = 0; + traversing_index = 0; + + return null; + } + }; + } + + + public void selectionSort() { + /*Merge sorting algorithm*/ + // Change code from bubbleSort to mergeSort + // TODO + + sorter = new SwingWorker<>() { + @Override + public Void doInBackground() throws InterruptedException { + for(current_index = 0; current_index < getSIZE() - 1; current_index++) { + int min_index = current_index; + for(int traversing_index = current_index + 1; traversing_index < getSIZE(); traversing_index++) { + if (bar_height[traversing_index] < bar_height[min_index]) { + min_index = traversing_index; + } + } + swap(current_index, min_index); + Thread.sleep(10); // controls the speed + repaint(); // we need it because we ofter replace the contents of a JPanel + } + + current_index = 0; + traversing_index = 0; + + return null; + } + }; + } + + public void initShuffler() { + /*Shuffles each bar*/ + shuffler = new SwingWorker<>() { + @Override + public Void doInBackground() throws InterruptedException { + int middle = getSIZE() / 2; + for (int i = 0, j = middle; i < middle; i++, j++) { + int randow_index = new Random().nextInt(getSIZE()); + swap(i, randow_index); + + randow_index = new Random().nextInt(getSIZE()); + swap(j, randow_index); + + Thread.sleep(10); // controls the speed + repaint(); // we need it because we ofter replace the contents of a JPanel + } + return null; + } + // after finishing the process + @Override + public void done() { + super.done(); + sorter.execute(); + } + }; + shuffler.execute(); + } + + public void initBarHeight() { + /*Initialize the height of each bar*/ + float interval = (float)HEIGHT / getSIZE(); + for(int i = 0; i < getSIZE(); i++) { + bar_height[i] = i * interval; + } + } + + public void swap(int indexA, int indexB) { + /*Swaps the elements*/ + float temp = bar_height[indexA]; + bar_height[indexA] = bar_height[indexB]; + bar_height[indexB] = temp; + } +} \ No newline at end of file diff --git a/algo_vis.java b/algo_vis.java deleted file mode 100644 index d7407a1..0000000 --- a/algo_vis.java +++ /dev/null @@ -1 +0,0 @@ -Hello World ! diff --git a/assets/mvp1.gif b/assets/mvp1.gif new file mode 100644 index 0000000..902b36e Binary files /dev/null and b/assets/mvp1.gif differ diff --git a/examples/Algorithm.java b/examples/Algorithm.java new file mode 100644 index 0000000..e8d3864 --- /dev/null +++ b/examples/Algorithm.java @@ -0,0 +1,89 @@ +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.util.*; + + +public class Algorithm extends JFrame{ + // Menu Bar + JMenuBar menuBar =new JMenuBar(); + JMenu mainMenu = new JMenu("Menu"); + JMenu helpDesk = new JMenu("Help"); + JMenuItem menu1 = new JMenuItem("Path Finding"); + JMenuItem menu2 = new JMenuItem("Sorting Techniques"); + JMenuItem menu3 = new JMenuItem("Pic Puzzle Sorting"); + JMenuItem menu4 = new JMenuItem("How it Works"); + + Algorithm(){ + // Adding MenuBar to the frame + mainMenu.add(menu1); mainMenu.add(menu2); mainMenu.add(menu3); helpDesk.add(menu4); + menuBar.add(mainMenu); menuBar.add(helpDesk); + setJMenuBar(menuBar); + + // Register listeners + ListenerClass listener = new ListenerClass(); + menu1.addActionListener(listener); + menu2.addActionListener(listener); + menu3.addActionListener(listener); + } + + public static void main(String[] args){ + JFrame frame = new Algorithm(); + frame.setTitle("Project 2020 by EightSoft Academy"); + frame.setSize(700,500); + frame.setLocation(200, 100); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setVisible(true); + } + + class ListenerClass implements ActionListener { + String value; + + // Project Main Logic (Moving Panels) + public void actionPerformed(ActionEvent e) { + if (e.getSource() == menu1) { + Sorting sort = new Sorting(); + } + } + } + +} + + +class Sorting { + JFrame frameSorting = new JFrame("Sorting"); + // Values + ArrayList list=new ArrayList();//Creating arraylist + + // Sorting Buttons + JButton jbtRandomize, jbtReset, jbtBubble, jbtInsertion, jbtSelection, jbtStart; // Sorting Buttons + JPanel p1Sorting, p2Sorting; + Random rand = new Random(); + + Sorting(){ + // Buttons for sorting + jbtRandomize = new JButton("Randomize");//create button + jbtReset = new JButton("Reset");//create button + jbtBubble = new JButton("Bubble sort");//create button + jbtInsertion = new JButton("Insertion sort");//create button + jbtSelection = new JButton("Selection sort");//create button + jbtStart = new JButton("Start");//create button + + // Panel for buttons + p1Sorting = new JPanel(); + p1Sorting.setLayout(new GridLayout(7,1)); + + // Adding Buttons to the panel + p1Sorting.add(jbtRandomize); p1Sorting.add(jbtReset); p1Sorting.add(jbtSelection); + p1Sorting.add(jbtBubble); p1Sorting.add(jbtInsertion); p1Sorting.add(jbtStart); + + // Adding frame + frameSorting.add(p1Sorting, BorderLayout.WEST); + frameSorting.setTitle("Sorting"); + frameSorting.setSize(700,500); + frameSorting.setLocation(200, 100); + frameSorting.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frameSorting.setVisible(true); + } + +} diff --git a/examples/ExampleMenu1.java b/examples/ExampleMenu1.java new file mode 100644 index 0000000..b843710 --- /dev/null +++ b/examples/ExampleMenu1.java @@ -0,0 +1,87 @@ +// Java program Program to add a menubar +// and add menuitems, submenu items and also add +// ActionListener to menu items +import java.awt.*; +import javax.swing.*; +import java.awt.event.*; + +public class ExampleMenu1 extends JFrame implements ActionListener { + // menubar + static JMenuBar mb; + + // JMenu + static JMenu x, x1; + + // Menu items + static JMenuItem m1, m2, m3, s1, s2; + + // create a frame + static JFrame f; + + // a label + static JLabel l; + + // main class + public static void main(String[] args) { + + // create an object of the class + ExampleMenu1 m = new ExampleMenu1(); + + // create a frame + f = new JFrame("Menu demo"); + + // create a label + l = new JLabel("no task "); + + // create a menubar + mb = new JMenuBar(); + + // create a menu + x = new JMenu("Menu"); + x1 = new JMenu("submenu"); + + // create menuitems + m1 = new JMenuItem("MenuItem1"); + m2 = new JMenuItem("MenuItem2"); + m3 = new JMenuItem("MenuItem3"); + s1 = new JMenuItem("SubMenuItem1"); + s2 = new JMenuItem("SubMenuItem2"); + + // add ActionListener to menuItems + m1.addActionListener(m); + m2.addActionListener(m); + m3.addActionListener(m); + s1.addActionListener(m); + s2.addActionListener(m); + + // add menu items to menu + x.add(m1); + x.add(m2); + x.add(m3); + x1.add(s1); + x1.add(s2); + + // add submenu + x.add(x1); + + // add menu to menu bar + mb.add(x); + + // add menubar to frame + f.setJMenuBar(mb); + + // add label + f.add(l); + + // set the size of the frame + f.setSize(500, 500); + f.setVisible(true); + } + public void actionPerformed(ActionEvent e) + { + String s = e.getActionCommand(); + + // set the label to the menuItem that is selected + l.setText(s + " selected"); + } +} diff --git a/examples/InsertionSort.txt b/examples/InsertionSort.txt new file mode 100644 index 0000000..758a476 --- /dev/null +++ b/examples/InsertionSort.txt @@ -0,0 +1,128 @@ +package examples; + +// Insertion sort visualizer + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.geom.Rectangle2D; +import java.util.Random; + +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.SwingWorker; + +public class InsertionSort extends JPanel { + private final int WIDTH = 800, HEIGHT = WIDTH * 9 /16; + private final int SIZE = 200; // the number if sorting elements + private final float BAR_WIDTH = (float)WIDTH / SIZE; // bar width + private float[] bar_height = new float[SIZE]; // height of bars + private SwingWorker shuffler, sorter; + private int current_index, traversing_index; + + InsertionSort() { + setBackground(Color.BLACK); + setPreferredSize(new Dimension(WIDTH, HEIGHT)); + initBarHeight(); // initialize the height of each bar + initSorter(); + initShuffler(); + } + + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + + Graphics2D g2d = (Graphics2D)g; + g2d.setColor(Color.CYAN); + Rectangle2D.Float bar; + for(int i = 0; i < SIZE; i++ ) { + bar = new Rectangle2D.Float(i * BAR_WIDTH, 0, BAR_WIDTH, bar_height[i]); + g2d.fill(bar); // g2d.draw(bar); + } + + g2d.setColor(Color.RED); + bar = new Rectangle2D.Float(current_index * BAR_WIDTH, 0, BAR_WIDTH, bar_height[current_index]); + g2d.fill(bar); + + g2d.setColor(Color.GREEN); + bar = new Rectangle2D.Float(traversing_index * BAR_WIDTH, 0, BAR_WIDTH, bar_height[traversing_index]); + g2d.fill(bar); + } + + public void initBarHeight() { + float interval = (float)HEIGHT / SIZE; + for(int i = 0; i < SIZE; i++) { + bar_height[i] = i * interval; + } + } + + public void initSorter() { + sorter = new SwingWorker<>() { + @Override + public Void doInBackground() throws InterruptedException { + for(current_index = 1; current_index < SIZE; current_index++) { + traversing_index = current_index; + while(traversing_index > 0 && bar_height[traversing_index] < bar_height[traversing_index - 1]) { + swap(traversing_index, traversing_index - 1); + traversing_index--; + + Thread.sleep(1); + repaint(); + } + } + current_index = 0; + traversing_index = 0; + + return null; + } + }; + } + + public void initShuffler() { + shuffler = new SwingWorker<>() { + @Override + public Void doInBackground() throws InterruptedException { + int middle = SIZE / 2; + for (int i = 0, j = middle; i < middle; i++, j++) { + int randow_index = new Random().nextInt(SIZE); + swap(i, randow_index); + + randow_index = new Random().nextInt(SIZE); + swap(j, randow_index); + + Thread.sleep(10); + repaint(); + } + return null; + } + + @Override + public void done() { + super.done(); + sorter.execute(); + } + }; + shuffler.execute(); + } + + public void swap(int indexA, int indexB) { + float temp = bar_height[indexA]; + bar_height[indexA] = bar_height[indexB]; + bar_height[indexB] = temp; + } + + public static void main(String args[]) { + SwingUtilities.invokeLater(() -> { + JFrame frame = new JFrame("Insertion Sort"); + //frame.setResizable(false); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setContentPane(new InsertionSort()); + frame.validate(); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + } +}