Skip to content

Commit

Permalink
Selection sort implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
hugh5 committed Nov 1, 2022
1 parent 4656737 commit 26a243c
Show file tree
Hide file tree
Showing 9 changed files with 302 additions and 4 deletions.
14 changes: 14 additions & 0 deletions src/Launcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Windows".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
if ("Mac OS X".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
// Style not available
}
MainWindow main = new MainWindow();
main.show();
}
Expand Down
64 changes: 60 additions & 4 deletions src/MainWindow.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,73 @@
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class MainWindow implements ActionListener, ChangeListener {
private final JFrame window;
private MenuPanel menuPanel;
private SortingPanel sortingPanel;
public static final int MAX = 48;
public static final int MIN = 2;

public class MainWindow {
private JFrame window;

public MainWindow() {
window = new JFrame();
window.setTitle("Tetris");
window.setLayout(new BorderLayout(10, 5));
window.setTitle("Sorting Visualiser");
window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
window.setSize(800, 500);
window.setSize(1200, 800);
window.setLocationRelativeTo(null);

createMenuButtons();
createVisualiserPanel();
}

private void createMenuButtons() {
menuPanel = new MenuPanel();
menuPanel.addActionListeners(this);
menuPanel.addChangeListeners(this);
window.add(menuPanel.getNorthPanel(), BorderLayout.NORTH);
window.add(menuPanel.getSouthPanel(), BorderLayout.SOUTH);
}

private void createVisualiserPanel() {
sortingPanel = new SortingPanel();
window.add(sortingPanel, BorderLayout.CENTER);
}

public JFrame getWindow() {
return window;
}

public void show() {
window.setVisible(true);
}

@Override
public void actionPerformed(ActionEvent e) {
System.out.println(e);
if (e.getSource() instanceof JButton) {
if (e.getActionCommand().equals("generate")) {
sortingPanel.generateArray();
} else if (e.getActionCommand().equals("start")) {
sortingPanel.start(menuPanel.getSortingMethod());
}
}
}

@Override
public void stateChanged(ChangeEvent e) {
if (e.getSource() instanceof JSlider) {
if (((JSlider)e.getSource()).getName().equals("length")) {
sortingPanel.generateArray(((JSlider) e.getSource()).getValue());
System.out.println(((JSlider) e.getSource()).getValue() + ":" + e);
} else if (((JSlider)e.getSource()).getName().equals("speed")) {
sortingPanel.setSpeed(((JSlider) e.getSource()).getValue());
System.out.println(((JSlider) e.getSource()).getValue() + ":" + e);
}
}
}
}
128 changes: 128 additions & 0 deletions src/MenuPanel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import javax.swing.*;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionListener;
import java.net.URL;

public class MenuPanel {
private JPanel northPanel;
private JPanel southPanel;
private JButton generate;
private JSlider length;
private JLabel lengthLabel;
private JComboBox<String> sortingMethod;
private JButton start;
private JButton forward;
private JButton backward;
private JSlider speed;
private JLabel speedLabel;

private static final String[] sorts = new String[]{"Selection Sort"};

public MenuPanel() {
createNorthPanel();
createSouthPanel();
}

private void createNorthPanel() {
northPanel = new JPanel();
northPanel.setLayout(new FlowLayout(FlowLayout.LEFT));

URL generateURL = getClass().getResource("assets/random.png");
if (generateURL != null) {
ImageIcon generateIcon = new ImageIcon(generateURL);
generateIcon = new ImageIcon(generateIcon.getImage().getScaledInstance(20, 20, Image.SCALE_DEFAULT));
generate = new JButton("New Array", generateIcon);
} else {
generate = new JButton("New Array");
}
northPanel.add(generate);

length = new JSlider(MainWindow.MIN, MainWindow.MAX);
northPanel.add(length);
length.setValue(MainWindow.MAX / 2);

lengthLabel = new JLabel();
northPanel.add(lengthLabel);
lengthLabel.setText("Length:" + length.getValue());

sortingMethod = new JComboBox<>(sorts);
northPanel.add(sortingMethod);
}

private void createSouthPanel() {
southPanel = new JPanel();
southPanel.setLayout(new FlowLayout(FlowLayout.CENTER));

URL backURL = getClass().getResource("assets/backward.png");
if (backURL != null) {
ImageIcon backIcon = new ImageIcon(backURL);
backIcon = new ImageIcon(backIcon.getImage().getScaledInstance(20, 20, Image.SCALE_DEFAULT));
backward = new JButton(backIcon);
} else {
backward = new JButton("Step Backward");
}
southPanel.add(backward);

URL startURL = getClass().getResource("assets/start.png");
if (startURL != null) {
ImageIcon startIcon = new ImageIcon(startURL);
startIcon = new ImageIcon(startIcon.getImage().getScaledInstance(20, 20, Image.SCALE_DEFAULT));
start = new JButton(startIcon);
} else {
start = new JButton("Start");
}
southPanel.add(start);

URL forwardURL = getClass().getResource("assets/forward.png");
if (forwardURL != null) {
ImageIcon forwardIcon = new ImageIcon(forwardURL);
forwardIcon = new ImageIcon(forwardIcon.getImage().getScaledInstance(20, 20, Image.SCALE_DEFAULT));
forward = new JButton(forwardIcon);
} else {
forward = new JButton("Step Forward");
}
southPanel.add(forward);

speed = new JSlider(1, 10);
southPanel.add(speed);

speedLabel = new JLabel();
southPanel.add(speedLabel);
speedLabel.setText("Speed:" + speed.getValue());
}

public JPanel getNorthPanel() {
return northPanel;
}

public JPanel getSouthPanel() {
return southPanel;
}

public String getSortingMethod() {
return (String) sortingMethod.getSelectedItem();
}

public void addChangeListeners(ChangeListener changeListener) {
length.setName("length");
length.addChangeListener(e -> lengthLabel.setText("Length:" + length.getValue()));
length.addChangeListener(changeListener);

speed.setName("speed");
speed.addChangeListener(e -> speedLabel.setText("Speed:" + speed.getValue()));
speed.addChangeListener(changeListener);
}

public void addActionListeners(ActionListener actionListener) {
generate.setActionCommand("generate");
generate.addActionListener(actionListener);

start.setActionCommand("start");
start.addActionListener(actionListener);
backward.setActionCommand("backward");
backward.addActionListener(actionListener);
forward.setActionCommand("forward");
forward.addActionListener(actionListener);
}
}
100 changes: 100 additions & 0 deletions src/SortingPanel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import javax.swing.*;
import java.awt.*;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.stream.IntStream;

public class SortingPanel extends JComponent {

private Map<Integer, Color> map;
private int[] array;
private final Random r;
private int size;
private int speed;

private static final Color CURRENT = Color.ORANGE;
private static final Color SORTED = Color.GREEN;
private static final Color MIN = Color.RED;

public SortingPanel() {
r = new Random(System.nanoTime());
size = MainWindow.MAX / 2;
generateArray();
map = new HashMap<>(size);
speed = 5;
}

public void paint(Graphics g) {
int y = getHeight() -20;
int scalar = getHeight() / MainWindow.MAX - 1;
int width = Math.min(getWidth() / size, 100);
g.setFont(new Font("Monospaced", Font.PLAIN, 16));
for (int i = 0; i < size; i++) {
g.setColor(Color.BLACK);
g.drawString(String.valueOf(array[i]), (int) i * width + width / 4, y + 15);
g.setColor(map.get(i));
g.fillRect(i * width, y, width - 2, -scalar * array[i]);
}
}

public void generateArray(int size) {
this.size = size;
IntStream ints = r.ints(size, 1, MainWindow.MAX);
array = ints.toArray();
map = new HashMap<>(size);
System.out.println(Arrays.toString(array));
this.repaint();
}

public void generateArray() {
generateArray(this.size);
}

public void start(String sortingMethod) {
System.out.println(this.getClass().getSimpleName() + "." + sortingMethod.replace(" ", "") + "()");
selectionSort();
}

public void setSpeed(int speed) {
this.speed = speed;
}

public void updateScreen() {
paintImmediately(0, 0, getWidth(), getHeight());
try {
Thread.sleep((long) (2048 * Math.pow(2, -speed)));
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}

private void selectionSort() {
map.clear();
int numSorted = 0;
for (int n = 0; n < size; n++) {
int minIndex = n;
map.put(minIndex, MIN);
for (int i = numSorted; i < size; i++) {
if (array[i] < array[minIndex]) {
map.remove(minIndex);
map.put(i, MIN);
minIndex = i;
} else {
map.put(i, CURRENT);
}
updateScreen();
if (map.get(i) == CURRENT) map.remove(i);
}
int temp = array[numSorted];
array[numSorted] = array[minIndex];
array[minIndex] = temp;
map.remove(minIndex);
map.put(numSorted, SORTED);
numSorted++;
repaint();
}
}
}
Binary file added src/assets/backward.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/forward.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/random.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/refresh.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/start.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 26a243c

Please sign in to comment.