Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repaint in for loop [duplicate]

Tags:

java

swing

Possible Duplicate:
How to make an animation with Swing?

in swing, i sort an array and want to animate it. Each time i update array in a loop, i have another while loop for pausing effect and when i call repaint() which actually is not called. Why it doesn't work? Thread.sleep(1000); freezes application and doesn't resume.

    public class Shape extends JPanel  {

    private static final long serialVersionUID = 1L;
    public int col;
    public JButton b2 = new JButton("Sort");
    public Rectangle2D.Double table = null;
    public ArrayList<Integer> arr = null;

    public Shape(){

        initArray(); // initialize array with random number of random numbers
        table = new Rectangle2D.Double(10,10,400,400);
        add(b2); // button sort

        b2.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                            System.out.println("sort it!");
                            Sort(arr);
                            display(arr);
                    }
         });
    }

    public void initArray() {
        col = generateRandom(10,20);            // generate a random number of bars 10 - 20
        arr = new ArrayList<Integer>(col);

        for(int i = 0; i < col; i++){
                // for each bar generate a random height 10 - 300
                int h = generateRandom(10, 390);
                arr.add(h);
        }
    }


    public void paintComponent(Graphics g){
        System.out.println("check");
        clear(g);
        Graphics2D g2d = (Graphics2D)g;
        System.out.println(arr.size());
        for(int j = 0; j < arr.size(); j++) {
                g2d.drawRect(j*20+20,410-arr.get(j),20,arr.get(j));
        }
    }

    protected void clear(Graphics g){
        super.paintComponent(g);
    }

    /*
     * generate random number in the range from 1 to 400
     */
    private int generateRandom(int start, int end){
        return new Random().nextInt(end)+start;
    }

    public void Sort(ArrayList<Integer> arr) {
        int t = 0;

        boolean swap = true;
        do {
                swap = false;
                for(int i = 0; i < arr.size() - 1; i++) {
                        if(arr.get(i).compareTo(arr.get(i+1)) > 0) {
                                int temp = arr.get(i);
                                arr.set(i, arr.get(i+1));
                                arr.set(i+1, temp);
                                swap = true;
                                // iterate to make effect of pausing
                                while(t < 100) {display(arr);t++;}
                                t = 0;
                                // repaint array
                                repaint();
                        }
                }
        } while(swap);
    }

    static void display(ArrayList<Integer> arr) {
        for(int i = 0; i < arr.size()-1; i++)
                System.out.print(arr.get(i) + ", ");
        System.out.println(arr.get(arr.size()-1));
    }

    public static void main(String[] arg){
        WindowUtilities.openInJFrame(new Shape(), 500,500);  
    }
}
like image 700
Alex Avatar asked Jul 04 '26 04:07

Alex


1 Answers

Do not use Thread.sleep for Swing as it will block the UI. Use a javax.swing.Timer instead: each time the timer triggers the action listener, you update your array and schedule a repaint. This will provide you with an animation effect.

See also

  • Concurrency in Swing
  • How to use Swing timers
like image 177
Robin Avatar answered Jul 06 '26 19:07

Robin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!