为什么我的计时器不延迟我的代码?我试图延迟我的图形排序以创建我的排序可视化器迭代
Why Doesn't My Timer Delay My Code? I am attemping to delay my graph from sorting to create my iteration of a sorting visualizer
我正在尝试创建一个计时器,它会延迟我的 GUI 对代表随机整数的条形进行排序。这将使排序可见,并且类似于在 YouTube 上看到的样式。我在网上读到 Swing Timers 被推荐用于 GUI,所以我选择了一个。如果你还不知道,这是我的第二个项目,所以如果我的代码看起来很糟糕,请不要向我发送死亡威胁。
无论如何,当 运行 我的代码并按下对图表进行排序的按钮时,尽管有一个定时器被编程为每次延迟 frame.repaint() 调用,但图表会立即排序。再一次,请对我宽容点。这是我第二次在 Whosebug 上提问,我看到有人对忘记分号的人进行恶毒的抨击。让我知道我的 Swing 计时器是否编程错误,或者它是否完全不同
谢谢
主程序
import java.util.Random;
import java.util.Scanner;
public class SortVisualizerShell {
public static int[] unsortedArray = arrayGenerator();
public static String requestedSort;
public static int[] arrayGenerator() {
int $N = 500;
int[] array = new int[$N];
Random rand = new Random();
for (int i = 0; i < $N; i++) {
int random_num = rand.nextInt($N);
array[i] = random_num;
}
return array;
}
public static void selectionSort(int[] array, int n) {
for (int i = 0; i < (n - 1); i++) {
int min = i;
for (int j = (i + 1); j < n; j++) {
if (array[min] > array[j]) {
min = j;
}
}
int key = array[min];
while (min > i) {
array[min] = array[min - 1];
min = min - 1;
}
array[i] = key;
}
}
public static void bubbleSort(int[] array, int n) {
boolean swapped;
int i, j, temp;
for (i = 0; i < (n - 1); i++) {
swapped = false;
for (j = 0; j < ((n - 1) - 1); j++) {
if (array[j] > array[j + 1]) {
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
swapped = true;
}
}
if (swapped == false) {
break;
}
}
}
public static void insertionSort(int[] array) {
int n = array.length;
for (int i = 1; i < n; i++) {
int key = array[i];
int j = i - 1;
while (j >= 0 && array[j] > key) {
array[j + 1] = array[j];
j = j - 1;
}
array[j + 1] = key;
}
}
public static void quickSort(int[] array, int left, int right) {
if (left < right) {
int pivot = partition(array, left, right);
quickSort(array, left, pivot - 1);
quickSort(array, pivot + 1, right);
}
}
public static int partition(int[] array, int low, int high) {
int pivot = array[high];
int i = (low - 1);
for (int j = low; j <= high - 1; j++) {
if (array[j] < pivot) {
i++;
swap(array, i, j);
}
}
swap(array, i + 1, high);
return (i + 1);
}
public static void swap(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
public static void mergeSort(int[] array, int len) {
if (len < 2) {
return;
}
int middle = len / 2;
int[] left_arr = new int[middle];
int[] right_arr = new int[len - middle];
int k = 0;
for (int i = 0; i < len; i++) {
if (i < middle) {
left_arr[i] = array[i];
}
else {
right_arr[k] = array[i];
k = k + 1;
}
}
mergeSort(left_arr, middle);
mergeSort(right_arr, len - middle);
merge(left_arr, right_arr, array, middle, (len - middle));
}
public static void merge(int[] left_arr, int[] right_arr, int[] array, int left_side,
int right_side) {
int i = 0;
int left = 0;
int right = 0;
while (left < left_side && right < right_side) {
if (left_arr[left] < right_arr[right]) {
array[i++] = left_arr[left++];
}
else {
array[i++] = right_arr[right++];
}
}
while (left < left_side) {
array[i++] = left_arr[left++];
}
while (right < right_side) {
array[i++] = right_arr[right++];
}
}
public static void userInputFrame(String requestedSort, int[] array) {
if (requestedSort.equals("merge sort")) {
mergeSort(array, array.length);
}
else if (requestedSort.equals("quick sort")) {
quickSort(array, 0, array.length - 1);
}
else if (requestedSort.equals("insertion sort")) {
insertionSort(array);
}
else if (requestedSort.equals("bubble sort")) {
bubbleSort(array, array.length);
}
else if (requestedSort.equals("selection sort")) {
selectionSort(array, array.length);
}
}
public static void activateSort(String requestedSort, int[] unsortedArray) {
userInputFrame(requestedSort, unsortedArray);
}
public static int[] unsort(int[] sortedArray) {
int[] unsortedArray = arrayGenerator();
return unsortedArray;
}
public static void main(String[] args) {
Scanner myScanner = new Scanner(System.in);
System.out.println("Welcome to my sort visualizer");
System.out.println("");
System.out.println("Which sort would you like to see in action? ");
requestedSort = myScanner.nextLine();
requestedSort = requestedSort.toLowerCase();
Drawer.createGUI();
myScanner.close();
}
}
GUI 程序
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Drawer extends JPanel {
public static SortVisualizerShell sort;
public static int[] y = SortVisualizerShell.unsortedArray;
public static String requestedSort;
public static Timer timer;
public static int delay = 1000;
public static void createGUI() {
JFrame frame = new JFrame();
JButton sortButton = new JButton("Sort");
JButton unsortButton = new JButton("Randomize Array");
JPanel panel = new JPanel();
Drawer draw = new Drawer();
requestedSort = SortVisualizerShell.requestedSort;
panel.setOpaque(false);
panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
panel.add(Box.createRigidArea(new Dimension(0, 5)));
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
panel.add(draw);
panel.add(sortButton);
panel.add(unsortButton);
frame.add(panel);
frame.getContentPane().setBackground(Color.BLACK);
frame.setVisible(true);
frame.pack();
frame.setSize(550, 650);
sortButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
SortVisualizerShell.activateSort(requestedSort, y);
frame.repaint();
}
});
unsortButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
y = SortVisualizerShell.unsort(y);
frame.repaint();
}
});
Timer timer = new Timer(1000, sortButton.getAction());
timer.setInitialDelay(1000);
timer.setDelay(1000);
timer.setRepeats(true);
timer.start();
}
public void paintComponent(Graphics g) {
for (int i = 0; i < y.length; i++) {
Graphics2D g2d = (Graphics2D) g;
g2d.drawRect(i, 0, 5, y[i]);
g2d.setColor(Color.WHITE);
g2d.fillRect(i, 0, 5, y[i]);
}
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createGUI();
}
});
}
}
首先,关于您问题中的代码需要注意的几点。
您不应将控制台应用程序与 GUI 应用程序混合使用。
我会添加一个 JComboBox
来选择所需的排序方法。
在代码的下面一行中,sortButton.getAction()
returns null.
Timer timer = new Timer(1000, sortButton.getAction());
因此您的计时器基本上什么都不做。
- 通常重写的
paintComponent
方法的第一行应该是
super.paintComponent(g);
请参阅 Oracle Java 教程中 Creating a GUI With Swing trail 的 Performing Custom Painting 课。
现在我认为您想在所选排序算法的每一步之后执行重绘,以显示排序算法的可视化。在下面的代码中,每个排序算法都是一个单独的 class,每个 class 实现一个 sortStep
方法,该方法在接口 IntsSort
.
中声明
我定义了一个enum
对于不同的排序算法。
单击 排序 按钮后,将启动一个 [Swing] timer,它会调用 sortStep
方法每秒选择排序算法。当 sortStep
方法 returns true 表示排序完成时停止计时器。
作为一个额外的视觉辅助,我在排序时将光标设置为 等待 光标
执行并显示 JOptionPane 通知用户排序已终止。
请注意,下面的代码缺少实现合并排序的 classes 和
快速排序。希望你能根据
下面的代码。
IntsSort
接口:
/**
* Sorts array of {@code int}.
*/
public interface IntsSort {
/**
* Performs a single, sorting step.
*
* @return <tt>true</tt> if there are no more sorting steps required indicating that the sort
* has completed.
*/
public boolean sortStep();
}
冒泡排序实现IntsSort
:
public class BublSort implements IntsSort {
private int[] array;
private int i;
public BublSort(int[] arr) {
array = arr;
i = -1;
}
@Override
public boolean sortStep() {
boolean swapped = false;
i++;
if (i < array.length - 1) {
int temp;
for (int j = 0; j < ((array.length - 1) - 1); j++) {
if (array[j] > array[j + 1]) {
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
swapped = true;
}
}
}
return !swapped;
}
}
插入排序实现IntsSort
:
public class InsrtSrt implements IntsSort {
private int[] array;
private int i;
public InsrtSrt(int[] arr) {
array = arr;
i = -1;
}
public boolean sortStep() {
boolean stopSorting;
i++;
int n = array.length;
if (i < n) {
stopSorting = false;
int key = array[i];
int j = i - 1;
while (j >= 0 && array[j] > key) {
array[j + 1] = array[j];
j = j - 1;
}
array[j + 1] = key;
}
else {
stopSorting = true;
}
return stopSorting;
}
}
接口IntsSort
的选择排序实现:
public class SlctnSrt implements IntsSort {
private int[] array;
private int i;
public SlctnSrt(int[] arr) {
array = arr;
i = -1;
}
@Override
public boolean sortStep() {
boolean stopSorting;
i++;
if (i < array.length - 1) {
stopSorting = false;
int min = i;
for (int j = (i + 1); j < array.length; j++) {
if (array[min] > array[j]) {
min = j;
}
}
int key = array[min];
while (min > i) {
array[min] = array[min - 1];
min = min - 1;
}
array[i] = key;
}
else {
stopSorting = true;
}
return stopSorting;
}
}
Swing GUI 应用程序:
请注意,randomizeButton
没有 ActionListener
,因为我的印象是您已经知道该怎么做。
此外,sortButton
的 ActionListener
使用 method reference。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;
public class SortDraw extends JPanel implements Runnable {
private JComboBox<SortExec.SortMethod> sortAlgorithmsCombo;
private JFrame frame;
private Timer timer;
public SortDraw() {
setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
setBackground(Color.darkGray);
setOpaque(false);
}
@Override
public void run() {
createAndDisplayGui();
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int[] y = SortExec.getArray();
if (y != null) {
for (int i = 0; i < y.length; i++) {
Graphics2D g2d = (Graphics2D) g;
g2d.drawRect(i, 0, 5, y[i]);
g2d.setColor(Color.WHITE);
g2d.fillRect(i, 0, 5, y[i]);
}
}
}
private void createAndDisplayGui() {
frame = new JFrame("Algos");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createTopPanel(), BorderLayout.PAGE_START);
frame.add(this, BorderLayout.CENTER);
frame.add(createButtonsPanel(), BorderLayout.PAGE_END);
frame.setSize(550, 650);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createButtonsPanel() {
JPanel buttonsPanel = new JPanel();
JButton sortButton = new JButton("Sort");
sortButton.setMnemonic(KeyEvent.VK_S);
sortButton.addActionListener(this::launchSort);
buttonsPanel.add(sortButton);
JButton randomizeButton = new JButton("Randomize");
buttonsPanel.add(randomizeButton);
return buttonsPanel;
}
private JPanel createTopPanel() {
JPanel topPanel = new JPanel();
JLabel label = new JLabel("Sort Algorithm");
topPanel.add(label);
sortAlgorithmsCombo = new JComboBox<>(SortExec.SortMethod.values());
topPanel.add(sortAlgorithmsCombo);
return topPanel;
}
private void launchSort(ActionEvent event) {
SortExec.SortMethod requestedSort = (SortExec.SortMethod) sortAlgorithmsCombo.getSelectedItem();
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try {
SortExec.initSort(requestedSort);
}
catch (RuntimeException xRuntime) {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
throw xRuntime;
}
timer = new Timer(1000, this::performSort);
timer.setInitialDelay(0);
timer.start();
}
private void performSort(ActionEvent event) {
boolean stopSorting = SortExec.performSort();
repaint();
if (stopSorting) {
timer.stop();
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
JOptionPane.showMessageDialog(frame,
"Sorting completed.",
"Complete",
JOptionPane.INFORMATION_MESSAGE);
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new SortDraw());
}
}
最后,SortExec
实用程序 class(包括排序算法 enum
):
import java.util.Random;
public class SortExec {
public enum SortMethod {
BUBBLE, INSERTION, MERGE, QUICK, SELECTION;
@Override
public String toString() {
String str;
switch (this) {
case BUBBLE:
str = "bubble sort";
break;
case INSERTION:
str = "insertion sort";
break;
case MERGE:
str = "merge sort";
break;
case QUICK:
str = "quick sort";
break;
case SELECTION:
str = "selection sort";
break;
default:
str = "unknown: " + this.ordinal();
}
return str;
}
}
private static int[] arr;
private static IntsSort sorter;
public static int[] getArray() {
return arr;
}
public static void initSort(SortMethod sortMethod) {
arr = arrayGenerator();
sorter = null;
switch (sortMethod) {
case BUBBLE:
sorter = new BublSort(arr);
break;
case INSERTION:
sorter = new InsrtSrt(arr);
break;
case SELECTION:
sorter = new SlctnSrt(arr);
break;
default:
throw new RuntimeException(sortMethod.toString());
}
}
public static boolean performSort() {
return sorter.sortStep();
}
private static int[] arrayGenerator() {
int $N = 500;
int[] array = new int[$N];
Random rand = new Random();
for (int i = 0; i < $N; i++) {
int random_num = rand.nextInt($N);
array[i] = random_num;
}
return array;
}
}
我正在尝试创建一个计时器,它会延迟我的 GUI 对代表随机整数的条形进行排序。这将使排序可见,并且类似于在 YouTube 上看到的样式。我在网上读到 Swing Timers 被推荐用于 GUI,所以我选择了一个。如果你还不知道,这是我的第二个项目,所以如果我的代码看起来很糟糕,请不要向我发送死亡威胁。
无论如何,当 运行 我的代码并按下对图表进行排序的按钮时,尽管有一个定时器被编程为每次延迟 frame.repaint() 调用,但图表会立即排序。再一次,请对我宽容点。这是我第二次在 Whosebug 上提问,我看到有人对忘记分号的人进行恶毒的抨击。让我知道我的 Swing 计时器是否编程错误,或者它是否完全不同
谢谢
主程序
import java.util.Random;
import java.util.Scanner;
public class SortVisualizerShell {
public static int[] unsortedArray = arrayGenerator();
public static String requestedSort;
public static int[] arrayGenerator() {
int $N = 500;
int[] array = new int[$N];
Random rand = new Random();
for (int i = 0; i < $N; i++) {
int random_num = rand.nextInt($N);
array[i] = random_num;
}
return array;
}
public static void selectionSort(int[] array, int n) {
for (int i = 0; i < (n - 1); i++) {
int min = i;
for (int j = (i + 1); j < n; j++) {
if (array[min] > array[j]) {
min = j;
}
}
int key = array[min];
while (min > i) {
array[min] = array[min - 1];
min = min - 1;
}
array[i] = key;
}
}
public static void bubbleSort(int[] array, int n) {
boolean swapped;
int i, j, temp;
for (i = 0; i < (n - 1); i++) {
swapped = false;
for (j = 0; j < ((n - 1) - 1); j++) {
if (array[j] > array[j + 1]) {
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
swapped = true;
}
}
if (swapped == false) {
break;
}
}
}
public static void insertionSort(int[] array) {
int n = array.length;
for (int i = 1; i < n; i++) {
int key = array[i];
int j = i - 1;
while (j >= 0 && array[j] > key) {
array[j + 1] = array[j];
j = j - 1;
}
array[j + 1] = key;
}
}
public static void quickSort(int[] array, int left, int right) {
if (left < right) {
int pivot = partition(array, left, right);
quickSort(array, left, pivot - 1);
quickSort(array, pivot + 1, right);
}
}
public static int partition(int[] array, int low, int high) {
int pivot = array[high];
int i = (low - 1);
for (int j = low; j <= high - 1; j++) {
if (array[j] < pivot) {
i++;
swap(array, i, j);
}
}
swap(array, i + 1, high);
return (i + 1);
}
public static void swap(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
public static void mergeSort(int[] array, int len) {
if (len < 2) {
return;
}
int middle = len / 2;
int[] left_arr = new int[middle];
int[] right_arr = new int[len - middle];
int k = 0;
for (int i = 0; i < len; i++) {
if (i < middle) {
left_arr[i] = array[i];
}
else {
right_arr[k] = array[i];
k = k + 1;
}
}
mergeSort(left_arr, middle);
mergeSort(right_arr, len - middle);
merge(left_arr, right_arr, array, middle, (len - middle));
}
public static void merge(int[] left_arr, int[] right_arr, int[] array, int left_side,
int right_side) {
int i = 0;
int left = 0;
int right = 0;
while (left < left_side && right < right_side) {
if (left_arr[left] < right_arr[right]) {
array[i++] = left_arr[left++];
}
else {
array[i++] = right_arr[right++];
}
}
while (left < left_side) {
array[i++] = left_arr[left++];
}
while (right < right_side) {
array[i++] = right_arr[right++];
}
}
public static void userInputFrame(String requestedSort, int[] array) {
if (requestedSort.equals("merge sort")) {
mergeSort(array, array.length);
}
else if (requestedSort.equals("quick sort")) {
quickSort(array, 0, array.length - 1);
}
else if (requestedSort.equals("insertion sort")) {
insertionSort(array);
}
else if (requestedSort.equals("bubble sort")) {
bubbleSort(array, array.length);
}
else if (requestedSort.equals("selection sort")) {
selectionSort(array, array.length);
}
}
public static void activateSort(String requestedSort, int[] unsortedArray) {
userInputFrame(requestedSort, unsortedArray);
}
public static int[] unsort(int[] sortedArray) {
int[] unsortedArray = arrayGenerator();
return unsortedArray;
}
public static void main(String[] args) {
Scanner myScanner = new Scanner(System.in);
System.out.println("Welcome to my sort visualizer");
System.out.println("");
System.out.println("Which sort would you like to see in action? ");
requestedSort = myScanner.nextLine();
requestedSort = requestedSort.toLowerCase();
Drawer.createGUI();
myScanner.close();
}
}
GUI 程序
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Drawer extends JPanel {
public static SortVisualizerShell sort;
public static int[] y = SortVisualizerShell.unsortedArray;
public static String requestedSort;
public static Timer timer;
public static int delay = 1000;
public static void createGUI() {
JFrame frame = new JFrame();
JButton sortButton = new JButton("Sort");
JButton unsortButton = new JButton("Randomize Array");
JPanel panel = new JPanel();
Drawer draw = new Drawer();
requestedSort = SortVisualizerShell.requestedSort;
panel.setOpaque(false);
panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
panel.add(Box.createRigidArea(new Dimension(0, 5)));
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
panel.add(draw);
panel.add(sortButton);
panel.add(unsortButton);
frame.add(panel);
frame.getContentPane().setBackground(Color.BLACK);
frame.setVisible(true);
frame.pack();
frame.setSize(550, 650);
sortButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
SortVisualizerShell.activateSort(requestedSort, y);
frame.repaint();
}
});
unsortButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
y = SortVisualizerShell.unsort(y);
frame.repaint();
}
});
Timer timer = new Timer(1000, sortButton.getAction());
timer.setInitialDelay(1000);
timer.setDelay(1000);
timer.setRepeats(true);
timer.start();
}
public void paintComponent(Graphics g) {
for (int i = 0; i < y.length; i++) {
Graphics2D g2d = (Graphics2D) g;
g2d.drawRect(i, 0, 5, y[i]);
g2d.setColor(Color.WHITE);
g2d.fillRect(i, 0, 5, y[i]);
}
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createGUI();
}
});
}
}
首先,关于您问题中的代码需要注意的几点。
您不应将控制台应用程序与 GUI 应用程序混合使用。
我会添加一个JComboBox
来选择所需的排序方法。在代码的下面一行中,
sortButton.getAction()
returns null.
Timer timer = new Timer(1000, sortButton.getAction());
因此您的计时器基本上什么都不做。
- 通常重写的
paintComponent
方法的第一行应该是
super.paintComponent(g);
请参阅 Oracle Java 教程中 Creating a GUI With Swing trail 的 Performing Custom Painting 课。
现在我认为您想在所选排序算法的每一步之后执行重绘,以显示排序算法的可视化。在下面的代码中,每个排序算法都是一个单独的 class,每个 class 实现一个 sortStep
方法,该方法在接口 IntsSort
.
我定义了一个enum 对于不同的排序算法。
单击 排序 按钮后,将启动一个 [Swing] timer,它会调用 sortStep
方法每秒选择排序算法。当 sortStep
方法 returns true 表示排序完成时停止计时器。
作为一个额外的视觉辅助,我在排序时将光标设置为 等待 光标 执行并显示 JOptionPane 通知用户排序已终止。
请注意,下面的代码缺少实现合并排序的 classes 和 快速排序。希望你能根据 下面的代码。
IntsSort
接口:
/**
* Sorts array of {@code int}.
*/
public interface IntsSort {
/**
* Performs a single, sorting step.
*
* @return <tt>true</tt> if there are no more sorting steps required indicating that the sort
* has completed.
*/
public boolean sortStep();
}
冒泡排序实现IntsSort
:
public class BublSort implements IntsSort {
private int[] array;
private int i;
public BublSort(int[] arr) {
array = arr;
i = -1;
}
@Override
public boolean sortStep() {
boolean swapped = false;
i++;
if (i < array.length - 1) {
int temp;
for (int j = 0; j < ((array.length - 1) - 1); j++) {
if (array[j] > array[j + 1]) {
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
swapped = true;
}
}
}
return !swapped;
}
}
插入排序实现IntsSort
:
public class InsrtSrt implements IntsSort {
private int[] array;
private int i;
public InsrtSrt(int[] arr) {
array = arr;
i = -1;
}
public boolean sortStep() {
boolean stopSorting;
i++;
int n = array.length;
if (i < n) {
stopSorting = false;
int key = array[i];
int j = i - 1;
while (j >= 0 && array[j] > key) {
array[j + 1] = array[j];
j = j - 1;
}
array[j + 1] = key;
}
else {
stopSorting = true;
}
return stopSorting;
}
}
接口IntsSort
的选择排序实现:
public class SlctnSrt implements IntsSort {
private int[] array;
private int i;
public SlctnSrt(int[] arr) {
array = arr;
i = -1;
}
@Override
public boolean sortStep() {
boolean stopSorting;
i++;
if (i < array.length - 1) {
stopSorting = false;
int min = i;
for (int j = (i + 1); j < array.length; j++) {
if (array[min] > array[j]) {
min = j;
}
}
int key = array[min];
while (min > i) {
array[min] = array[min - 1];
min = min - 1;
}
array[i] = key;
}
else {
stopSorting = true;
}
return stopSorting;
}
}
Swing GUI 应用程序:
请注意,randomizeButton
没有 ActionListener
,因为我的印象是您已经知道该怎么做。
此外,sortButton
的 ActionListener
使用 method reference。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;
public class SortDraw extends JPanel implements Runnable {
private JComboBox<SortExec.SortMethod> sortAlgorithmsCombo;
private JFrame frame;
private Timer timer;
public SortDraw() {
setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
setBackground(Color.darkGray);
setOpaque(false);
}
@Override
public void run() {
createAndDisplayGui();
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int[] y = SortExec.getArray();
if (y != null) {
for (int i = 0; i < y.length; i++) {
Graphics2D g2d = (Graphics2D) g;
g2d.drawRect(i, 0, 5, y[i]);
g2d.setColor(Color.WHITE);
g2d.fillRect(i, 0, 5, y[i]);
}
}
}
private void createAndDisplayGui() {
frame = new JFrame("Algos");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createTopPanel(), BorderLayout.PAGE_START);
frame.add(this, BorderLayout.CENTER);
frame.add(createButtonsPanel(), BorderLayout.PAGE_END);
frame.setSize(550, 650);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createButtonsPanel() {
JPanel buttonsPanel = new JPanel();
JButton sortButton = new JButton("Sort");
sortButton.setMnemonic(KeyEvent.VK_S);
sortButton.addActionListener(this::launchSort);
buttonsPanel.add(sortButton);
JButton randomizeButton = new JButton("Randomize");
buttonsPanel.add(randomizeButton);
return buttonsPanel;
}
private JPanel createTopPanel() {
JPanel topPanel = new JPanel();
JLabel label = new JLabel("Sort Algorithm");
topPanel.add(label);
sortAlgorithmsCombo = new JComboBox<>(SortExec.SortMethod.values());
topPanel.add(sortAlgorithmsCombo);
return topPanel;
}
private void launchSort(ActionEvent event) {
SortExec.SortMethod requestedSort = (SortExec.SortMethod) sortAlgorithmsCombo.getSelectedItem();
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try {
SortExec.initSort(requestedSort);
}
catch (RuntimeException xRuntime) {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
throw xRuntime;
}
timer = new Timer(1000, this::performSort);
timer.setInitialDelay(0);
timer.start();
}
private void performSort(ActionEvent event) {
boolean stopSorting = SortExec.performSort();
repaint();
if (stopSorting) {
timer.stop();
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
JOptionPane.showMessageDialog(frame,
"Sorting completed.",
"Complete",
JOptionPane.INFORMATION_MESSAGE);
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new SortDraw());
}
}
最后,SortExec
实用程序 class(包括排序算法 enum
):
import java.util.Random;
public class SortExec {
public enum SortMethod {
BUBBLE, INSERTION, MERGE, QUICK, SELECTION;
@Override
public String toString() {
String str;
switch (this) {
case BUBBLE:
str = "bubble sort";
break;
case INSERTION:
str = "insertion sort";
break;
case MERGE:
str = "merge sort";
break;
case QUICK:
str = "quick sort";
break;
case SELECTION:
str = "selection sort";
break;
default:
str = "unknown: " + this.ordinal();
}
return str;
}
}
private static int[] arr;
private static IntsSort sorter;
public static int[] getArray() {
return arr;
}
public static void initSort(SortMethod sortMethod) {
arr = arrayGenerator();
sorter = null;
switch (sortMethod) {
case BUBBLE:
sorter = new BublSort(arr);
break;
case INSERTION:
sorter = new InsrtSrt(arr);
break;
case SELECTION:
sorter = new SlctnSrt(arr);
break;
default:
throw new RuntimeException(sortMethod.toString());
}
}
public static boolean performSort() {
return sorter.sortStep();
}
private static int[] arrayGenerator() {
int $N = 500;
int[] array = new int[$N];
Random rand = new Random();
for (int i = 0; i < $N; i++) {
int random_num = rand.nextInt($N);
array[i] = random_num;
}
return array;
}
}