Swing JForm冻结直到动作完成

我想创建一个Java应用程序,使用swing组件可视化合并排序。 到目前为止我写的这个:

import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Random; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextArea; public class MergeSort extends JFrame { private int[] helper; private int[] heights; private JPanel mainPanel; private JTextArea[] areas; private JTextArea txtSpeed; private JLabel lblSpeed; private JButton btnStart; private Random rnd; private final int FRAME_HEIGHT = 550; private final int FRAME_WIDTH = 1100; private final int ELEMENTS_TO_SORT = 100; private final int BAR_WIDTH = 7; private final int SPACING = 10; private int SLEEP_TIME = 50; public MergeSort() { super("Merge Sort Visualisation"); helper = new int[ELEMENTS_TO_SORT]; mainPanel = new JPanel(); mainPanel.setLayout(null); rnd = new Random(); areas = new JTextArea[ELEMENTS_TO_SORT]; heights = new int[areas.length]; for (int i = 0; i = 0) { SLEEP_TIME = x; } else { SLEEP_TIME = 0; } } public void sort() throws InterruptedException { mergesort(0, heights.length - 1); } private void mergesort(int low, int high) throws InterruptedException { if (low < high) { int middle = low + (high - low) / 2; mergesort(low, middle); mergesort(middle + 1, high); merge(low, middle, high); } } private void merge(int low, int middle, int high) throws InterruptedException { for (int i = low; i <= high; i++) { helper[i] = heights[i]; } int i = low; int j = middle + 1; int k = low; while (i <= middle && j <= high) { if (helper[i] <= helper[j]) { heights[k] = helper[i]; updateAreaX(k); Thread.currentThread().sleep(SLEEP_TIME); i++; } else { heights[k] = helper[j]; updateAreaX(k); Thread.currentThread().sleep(SLEEP_TIME); j++; } k++; } // Copy the rest of the left side of the array into the target array while (i  0) { bdr.insert(0, Integer.toString(a % 10) + String.format("%n")); a /= 10; } if (bdr.length() > 0) { bdr.setLength(bdr.length() - 1); } return bdr.toString(); } private void updateAreaX(int x) { areas[x].setSize(BAR_WIDTH, heights[x]); areas[x].setLocation(areas[x].getLocation().x, FRAME_HEIGHT - areas[x].getHeight() - 40); areas[x].setText(toDigits(heights[x])); } public static void main(String[] args) throws InterruptedException { MergeSort sorter = new MergeSort(); sorter.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); sorter.setVisible(true); } } 

问题是,当我单击开始按钮时,整个JFrame会冻结,直到所有内容都被排序,然后显示结果。 如果我不通过按钮启动sort()方法,但在public static void main()中编写sorter.sort() ()则可以正常工作。 我该如何解决? 我想我需要将排序放在另一个线程或其他东西,但我不知道如何。

你的问题在下一个:你在ActionListener阻止EDT ,因为你的帧会冻结,直到退出actionPerformed()方法。 当您使用Thread.sleep(...)它无助于Swing重绘您的帧。

似乎您需要使用Swing Timer进行更新。 您也可以使用SwingWorker进行长时间的后台处理。

阅读Swing中的Concurency 。