Repainting a JPanel in a loop with a delay

荒凉一梦 提交于 2020-01-15 08:35:10

问题


I'm trying to create a program which will visualize different sorting algorithms by drawing a set of bars representing an array along for each time the sort loops. However, when I set the array from within the sorter class which in turn repaints the panel, it seems that it only calls paintComponent() for the first and last iteration, not showing the steps in between.

Here is the sort code which calls the setNumberArray() method:

public void bubbleSort() {
    int[] x = getNumberArray();
    boolean doMore = true;
    while (doMore) {
        doMore = false;
        for (int count = 0; count < x.length - 1; count++) {
            if (x[count] > x[count+1]) {
               int temp = x[count];  x[count] = x[count+1];  x[count+1] = temp;
               doMore = true;
            }
        }
        // Update the array
        SorterGUI.getSorterPanel().setNumberArray(x);
        // Pause
        try {
            Thread.sleep(500);
        } catch (InterruptedException ex) {
            Logger.getLogger(Sorter.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

Which calls:

public void setNumberArray(int[] numberArray) {
    this.numberArray = numberArray;
    repaint();
}

Finally drawing the bars:

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    int length = numberArray.length;
    Graphics2D g2d = (Graphics2D) g;

    g2d.setColor(Color.white);
    g2d.fillRect(0, 0, getWidth(), getHeight());

    g2d.setColor(Color.gray);
    for(int count = 0; count < length; count++) {
        g2d.fill3DRect((getWidth() / length) * (count + 1), 0, 
               getWidth() / length, getHeight() - (numberArray[count] * 3), 
               true);
        playSound(numberArray[count]);
    }
    System.out.print(".");
}

I know it's not repainting in between (with or without the delay) because it only prints one "." when I start sorting.


回答1:


Forget the paintImmediately as that won't solve your problem. The issue is that you're calling Thread.sleep on the EDT, the main Swing thread known as the event dispatch thread, and this will put your Swing app to sleep (as you're finding out). Instead use a Swing Timer for your delay and all will work well. Either that or do your Thread.sleep in a background thread.




回答2:


You can use JComponent.paintImmediately to force immediate painting



来源:https://stackoverflow.com/questions/4917383/repainting-a-jpanel-in-a-loop-with-a-delay

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!