Arnout
Arnout

Reputation: 157

Repaint won't work in custom panel

I have a problem with repainting my Panel. My idea for a animation was to fill an Array with int[]'s. That's the part that works. now to animate it I take the Array and fill a variable int[] with the int[] from the array. Then I call repaint to repaint the image with all the numbers. but it doesn't repaint until the last repaint. any one who has an idea? the two classes where I think the problem lies. are given below (the code might be chaotic).

What my idea is, is that I want to press the button shellSort. whan I have pressed this button the code will go through a for loop filling a array in the pannel with integers. then it should repaint my panel which it does not do.

Edited: I think my problem is that it never leaves the for loop until it's finished. how do i stop a for loop to repaint my Panel? and then continue where i left off?

i reconstructed my problem in a small example code:

import java.awt.event.*;
import java.awt.*;
import javax.swing.*;

public class Repainten {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        GUI g = new GUI();
    }
}


public class GUI extends JFrame implements ActionListener{
    private JButton button;
    private Panel p;
    private int[] henk = {10, 6, 4, 2, 3, 7, 9};

    public GUI() {
        this.setTitle("getallen");
        this.setSize(200, 200);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //this.setLayout(new FlowLayout());
        button = new JButton("Button");
        p = new Panel();
        button.addActionListener(this);
        JPanel northPanel = new JPanel();
        northPanel.add(button);
        JPanel centerPanel = new JPanel();
        centerPanel.add(p);
        add(northPanel, BorderLayout.NORTH);
        add(centerPanel, BorderLayout.CENTER);
        //add(button);
        add(p);

        this.setVisible(true);
    }
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == button) {
            animeer();
        }
    }
    public void animeer() {
        for (final int a : henk) {                     
            p.cijfer = a;
            p.repaint();
        }
    }
}
public class Panel extends JPanel{
    public int cijfer = 0;

    public Panel(){

    }
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Font font = new Font("Algerian", Font.PLAIN, 100);
        g.setFont(font);
        System.out.println(cijfer);
        g.drawString(Integer.toString(cijfer), 60,110);

    }

}

Upvotes: 0

Views: 530

Answers (2)

Reimeus
Reimeus

Reputation: 159754

The problem is that repaint is optimized so that multiple calls to the method in quick succession will result in only the last call being made. The solution is to use a Swing Timer

Timer timer = new Timer(2000, new ActionListener() {

      int index = 0;

      @Override
      public void actionPerformed(ActionEvent e) {

      p.cijfer = henk[index];
      index++;
      p.repaint();

      if (index == henk.length) {
         Timer timer = (Timer) e.getSource();
         timer.stop();
      }
   }
});

Upvotes: 2

Bob Flannigon
Bob Flannigon

Reputation: 1294

Component won't always repaint immediately...

http://docs.oracle.com/javase/6/docs/api/java/awt/Component.html#repaint%28%29

Upvotes: 0

Related Questions