计算时Java Swing重绘:动画排序算法

Ren*_*Kay 0 java sorting animation swing event-dispatch-thread

http://www.youtube.com/watch?v=M0cNsmjK33E

我想使用Java Swing开发类似于以上链接的内容。我有排序方法,并且在重绘时做了,但是当我触发排序时,没有显示条形图对其进行缓慢排序,而是冻结并随后在数组完全排序后解冻。

我该如何解决?编辑:对不起,忘记了代码。它是一个非常简单的GUI。另一个用于排序的类对整个数组进行排序

public class SortGUI {
JFrame frame;
int frameWidth = 1000, frameHeight = 1000;
int panelWidth, panelHeight;
DrawPanel panel;
JPanel panel2;
JScrollPane scroll;
JViewport view;

static int[] S = new int[50000];

public static void main(String[] args) throws InterruptedException {
    SortGUI app = new SortGUI();
    initializeArray();        
    app.go(); 
}

public static void initializeArray()
{
         for (int i = 0; i < S.length; i++) {
     S[i] = (int) (Math.random() * 16581375);
     }
}

public void go() throws InterruptedException {
    //Frame
    frame = new JFrame();
    frame.setSize(frameWidth, frameHeight);
    frame.setVisible(true); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  

    //panel
    panel = new DrawPanel();
    scroll = new JScrollPane(panel,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);


    //Layout
    frame.add(scroll);
    frame.addKeyListener(new keyListener());

    while(true)
    {               
        panel.repaint();
    }
   }


public class DrawPanel extends JPanel
{   
    public DrawPanel()
    {
        this.setPreferredSize(new Dimension(50000,930));
    }

    public void paintComponent(Graphics g) 
    {          
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, this.getWidth(), this.getHeight());
        for(int i = 0; i < S.length; i++)
        {
            int red = S[i] / 65025;
            int green = (S[i] > 65025)? S[i] % 65025 : 0;
            int blue = green;
            blue %= 255;
            green /= 255;

             g.setColor(new Color(red,green,blue));
            g.fillRect(i, 900 - (S[i] / 18500), 1, S[i] / 18500);
        }
    }
}

  public class keyListener implements KeyListener{


    public void keyTyped(KeyEvent ke) {

    }


    public void keyPressed(KeyEvent ke) {
      if(ke.getKeyChar() == '1')
      {
   sorter.bubbleSort(S);
      }
    }


    public void keyReleased(KeyEvent ke) { 
    }

  }
}
Run Code Online (Sandbox Code Playgroud)

Pau*_*tha 5

注意:我在删除问题之前就开始写这篇文章

您最有可能使用某种循环机制并为每次迭代祈祷ui被更新。这是一个错误的假设。该UI将不会直到循环结束后会更新。您正在做的是我们所谓的阻止事件调度线程(EDT)

请参阅如何使用Swing计时器。让“反复”中的ActionListener回电更新。例如,如果要设置排序算法的动画,则需要确定计时器回调的“迭代”需要更新哪些内容。然后,每次迭代都会重绘ui。

所以您的Timer计时器可能看起来像

Timer timer  = new Timer(40, new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent e) {
        if (sortingIsDone()) {
            ((Timer)e.getSource()).stop();
        } else {
            sortOnlyOneItem();
        }
        repaint();
    }
});
Run Code Online (Sandbox Code Playgroud)

您的sortOnlyOneItem方法应该只对一个项目执行排序。并具有某种标志来检查排序是否完成,然后停止计时器。


其他说明:

  • 如果您不打算自己绘制背景,则应该调用super.paintComponentpaintComponent方法。一般来说,我总是这样做。

这是一个完整的例子。我很高兴您自己弄清楚了。在看到您理解之前,我正在研究此示例。

在此处输入图片说明

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Collections;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class SelectionSortAnimate extends JPanel {

    private static final int NUM_OF_ITEMS = 20;
    private static final int DIM_W = 400;
    private static final int DIM_H = 400;
    private static final int HORIZON = 350;
    private static final int VERT_INC = 15;
    private static final int HOR_INC = DIM_W / NUM_OF_ITEMS;

    private JButton startButton;
    private Timer timer = null;
    private JButton resetButton;

    Integer[] list;
    int currentIndex = NUM_OF_ITEMS - 1;

    public SelectionSortAnimate() {
        list = initList();

        timer = new Timer(200, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (isSortingDone()) {
                    ((Timer) e.getSource()).stop();
                    startButton.setEnabled(false);
                } else {
                    sortOnlyOneItem();
                }
                repaint();
            }
        });
        startButton = new JButton("Start");
        startButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                timer.start();
            }
        });
        resetButton = new JButton("Reset");
        resetButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                list = initList();
                currentIndex = NUM_OF_ITEMS - 1;
                repaint();
                startButton.setEnabled(true);
            }
        });
        add(startButton);
        add(resetButton);
    }

    public boolean isSortingDone() {
        return currentIndex == 0;
    }

    public Integer[] initList() {
        Integer[] nums = new Integer[NUM_OF_ITEMS];
        for (int i = 1; i <= nums.length; i++) {
            nums[i - 1] = i;
        }
        Collections.shuffle(Arrays.asList(nums));
        return nums;
    }

    public void drawItem(Graphics g, int item, int index) {
        int height = item * VERT_INC;
        int y = HORIZON - height;
        int x = index * HOR_INC;
        g.fillRect(x, y, HOR_INC, height);
    }

    public void sortOnlyOneItem() {
        int currentMax = list[0];
        int currentMaxIndex = 0;

        for (int j = 1; j <= currentIndex; j++) {
            if (currentMax < list[j]) {
                currentMax = list[j];
                currentMaxIndex = j;
            }
        }

        if (currentMaxIndex != currentIndex) {
            list[currentMaxIndex] = list[currentIndex];
            list[currentIndex] = currentMax;
        }
        currentIndex--;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (int i = 0; i < list.length; i++) {
            drawItem(g, list[i], i);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(DIM_W, DIM_H);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame("Sort");
                frame.add(new SelectionSortAnimate());
                frame.pack();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)