繁体   English   中英

如何在算法结束之前重新绘制排序算法的每次迭代?

[英]How do I repaint each iteration of a sorting algorithm before the algorithm ends?

我不熟悉使用 Java Swing 并使用排序算法可视化工具。 我已经设置了矩形并给出了仅用于测试的基础知识,但我遇到了一些困难。 我想使用repaint() function 来重新绘制矩形,每次我在一次排序迭代后更改它时,但程序似乎并没有一步一步地这样做,而是跳到完全排序的数组。 我尝试添加延迟,但这会使程序根本无法运行。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@SuppressWarnings("serial")
class Panel extends JPanel implements ActionListener, KeyListener {
    // All Global varaibles
    private Timer myTimer= new Timer( 30, this );
    int width = 100;
    int height_bounds = 400;
    Random rand = new Random();
    int[] height = new int[width];

    public Panel(){
        for (int i = 0; i < width; i++) {
            height[i] = rand.nextInt(height_bounds)+50;
        }
        myTimer.start();
    }

    public void paintComponent(Graphics gr){
            super.paintComponent(gr);
            //setBackground(new Color(0,0,0));
            for (int i=0; i<width; i++) {
                gr.drawRect(i*10+81, 740-height[i], 4, height[i]);
            }
    }

    @Override
    public void keyPressed(KeyEvent ev) {}
    @Override
    public void keyReleased(KeyEvent arg0) {}
    @Override
    public void keyTyped(KeyEvent arg0) {}
    @Override
    public void actionPerformed(ActionEvent e) {
            
        for (int i = 0; i < width; i++){
            for (int j = 0; j < width-1; j++){
                if (height[j] > height[j+1]) 
                { 
                    // swap arr[j+1] and arr[i] 
                    int temp = height[j]; 
                    height[j] = height[j+1]; 
                    height[j+1] = temp;
                } 
            }
          repaint();
        }
        
    }
}

如果您要在actionPerformed中进行排序,那么您将阻止 UI 重新绘制,因为它是由为您重新绘制 UI 的完全相同的线程执行的。 将处理移动到分离线程并从那里安排重绘,例如

public void actionPerformed(ActionEvent e) {
    new Thread(()=>{    
    for (int i = 0; i < width; i++){
        for (int j = 0; j < width-1; j++){
            if (height[j] > height[j+1]) 
            { 
                // swap arr[j+1] and arr[i] 
                int temp = height[j]; 
                height[j] = height[j+1]; 
                height[j+1] = temp;
            } 
        }
      SwingUtils.invokeLater(()=>repain());
      Thread.sleep(500); // add some meaningfull value
    }
    }).start();
}

显然,您应该使用线程池而不是创建新的线程,在每次单击后阻止多个线程同时启动,并且可能为此使用 SwingWorker,但它应该让您对流程有所了解。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM