Java JPanel仅在for循环完成后更新

Java JPanel仅在for循环完成后更新,java,swing,Java,Swing,我正在制作一个排序可视化工具,一切都很好,直到我尝试在一个按钮上实现排序功能。问题是,当从按钮调用sort函数时,直到for循环完成,屏幕才会刷新(通常,sort函数工作正常) 主要内容: 测试等级: public class Test implements ActionListener { public static int WIN_WIDTH = 1500; public static int WIN_HEIGHT = 750; JButton shuffleBut

我正在制作一个排序可视化工具,一切都很好,直到我尝试在一个按钮上实现排序功能。问题是,当从按钮调用sort函数时,直到for循环完成,屏幕才会刷新(通常,sort函数工作正常)

主要内容:

测试等级:

public class Test implements ActionListener {
    public static int WIN_WIDTH = 1500;
    public static int WIN_HEIGHT = 750;

    JButton shuffleButton;
    JButton bubbleSort;
    JFrame window;
    SortArray sortArray;

    public Test() throws InterruptedException {

        shuffleButton = new JButton();
        shuffleButton.setBounds(WIN_WIDTH + 10, 0, 160, 100);
        shuffleButton.setText("Shuffle!");

        bubbleSort = new JButton();
        bubbleSort.setBounds(WIN_WIDTH + 10, 200, 160, 100);
        bubbleSort.setText("Bubble sort!");


        window = new JFrame("Sort Visualizer");
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setSize(WIN_WIDTH + 200, WIN_HEIGHT);
        window.setVisible(true);

        sortArray = new SortArray();
        window.add(shuffleButton);
        window.add(bubbleSort);
        window.add(sortArray);

        sortArray.repaint();
        sortArray.bubble_sort();

        shuffleButton.addActionListener(this);
        bubbleSort.addActionListener(this);
        
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == shuffleButton){
            sortArray.shuffleArray();
        }else if(e.getSource() == bubbleSort){
            try {
                sortArray.bubble_sort();
            } catch (InterruptedException interruptedException) {
                interruptedException.printStackTrace();
            }
        }
    }
}
排序数组类:

 public class SortArray extends JPanel {
    private static int NM_NM = WIN_WIDTH;
    public static int BAR_WIDTH = WIN_WIDTH / NM_NM;
    private int[] array;

public SortArray() throws InterruptedException {
   shuffleArray();
}

public void shuffleArray(){
    Random rng = new Random();
    array = new int[NM_NM];
    for (int i = 0; i < array.length; i++) {
        repaint();
        array[i] = rng.nextInt(WIN_HEIGHT);
    }
}

public void bubble_sort() throws InterruptedException {
    SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
        @Override
        protected Void doInBackground() throws Exception {
            //bubble sort
            System.out.println("sorting...");
            Boolean not_sorted = true;
            while (not_sorted) {
                TimeUnit.MICROSECONDS.sleep(1);
                not_sorted = false;
                for (int i = 1; i < array.length; i++) {
                    if (array[i] > array[i - 1]) {
                        int temp = array[i];
                        array[i] = array[i-1];
                        array[i-1] = temp;
                        not_sorted = true;
                        repaint();
                    }
                }
                if (!not_sorted) {
                    break;
                }
            }
            return null;
        }
    };
    worker.execute();
}

@Override
protected void paintComponent(Graphics g) {
    Graphics2D graphics2D = (Graphics2D) g;
    super.paintComponent(graphics2D);
    for (int j = 0; j < array.length; j++) {
        graphics2D.setColor(Color.BLACK);
        graphics2D.fillRect(j * BAR_WIDTH, 0, BAR_WIDTH, array[j]);

    }
}
公共类SortArray扩展了JPanel{
专用静态int NM\u NM=WIN\u宽度;
公共静态输入条宽度=WIN\u宽度/NM\u NM;
私有int[]数组;
public SortArray()抛出InterruptedException{
shuffleArray();
}
公共图书馆{
随机rng=新随机();
数组=新整数[NM_NM];
for(int i=0;i数组[i-1]){
int temp=数组[i];
数组[i]=数组[i-1];
阵列[i-1]=温度;
not_sorted=true;
重新油漆();
}
}
如果(!未排序){
打破
}
}
返回null;
}
};
worker.execute();
}
@凌驾
受保护组件(图形g){
Graphics2D Graphics2D=(Graphics2D)g;
超级油漆组件(图形2D);
对于(int j=0;j

}

好的,我解决了它,基本上我所做的就是用SwingWorker将bubbleSort()函数中的所有命令包围起来,然后执行它。(这将创建一个背景线程)。我把代码编辑到正确的地方。

昨天一个同学问了同样的问题:这不是正确的解决方案。是的,SwingWorker是一个良好的开端,但是您需要“发布”阵列的当前状态,以便可以绘制它。在尝试绘制数组时,不希望排序线程更新数组。按照提供的链接阅读评论,以更好地理解完整的解决方案。
 public class SortArray extends JPanel {
    private static int NM_NM = WIN_WIDTH;
    public static int BAR_WIDTH = WIN_WIDTH / NM_NM;
    private int[] array;

public SortArray() throws InterruptedException {
   shuffleArray();
}

public void shuffleArray(){
    Random rng = new Random();
    array = new int[NM_NM];
    for (int i = 0; i < array.length; i++) {
        repaint();
        array[i] = rng.nextInt(WIN_HEIGHT);
    }
}

public void bubble_sort() throws InterruptedException {
    SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
        @Override
        protected Void doInBackground() throws Exception {
            //bubble sort
            System.out.println("sorting...");
            Boolean not_sorted = true;
            while (not_sorted) {
                TimeUnit.MICROSECONDS.sleep(1);
                not_sorted = false;
                for (int i = 1; i < array.length; i++) {
                    if (array[i] > array[i - 1]) {
                        int temp = array[i];
                        array[i] = array[i-1];
                        array[i-1] = temp;
                        not_sorted = true;
                        repaint();
                    }
                }
                if (!not_sorted) {
                    break;
                }
            }
            return null;
        }
    };
    worker.execute();
}

@Override
protected void paintComponent(Graphics g) {
    Graphics2D graphics2D = (Graphics2D) g;
    super.paintComponent(graphics2D);
    for (int j = 0; j < array.length; j++) {
        graphics2D.setColor(Color.BLACK);
        graphics2D.fillRect(j * BAR_WIDTH, 0, BAR_WIDTH, array[j]);

    }
}