I am developing an application that simulates Cellular Automatons. It happens that I need to draw really fast(each 100ms) a grid of 80x80 squares (6400 squares).
My first approach was using JLabels, but it was really slow. Now I am using Graphics2D and works great, but after drawing about 50 times, it starts getting slow, and goes getting slower as the turns advance.
I need to call repaint() after each turn in order to 'repaint' the squares, but I am guessing that what was drawn before is still in the memory, is that it? How can I discard what was draw so it will not ocupy the buffer ou memory?
A last thing, I saw this post but I can not see the difference between mine and the code provided there: post about repaint
Here's an image to help you understand what it's all about: Application running
And here is my code:
private void drawMatriz(int[][] array, DrawSquare square, int size, AppController contr) {
Color[] configColors = contr.getArrayOfCollors();
int posX = 0;
int posY = 0;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[0].length; j++) {
square.addSquare(posX, posY, size, size, configColors[array[i][j]]);
posX += size;
}
posX = 0;
posY += size;
}
repaint();
}
public AppRun(AppController controller) {
[...]
squares = new DrawSquare();
squares.setBorder(new LineBorder(new Color(0, 0, 0)));
squares.setBounds(209, 11, 640, 640);
getContentPane().add(squares);
squares.setPreferredSize(new Dimension(500, 500));
squares.setLayout(null);
drawMatriz(controller.getVector(), squares, (squares.getBounds().width / controller.getVector().length),
controller);
}
class DrawSquare extends JPanel {
private static final long serialVersionUID = 1L;
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
private List<Rectangle> squares = new ArrayList<Rectangle>();
private List<Color> colors = new ArrayList<Color>();
public void addSquare(int x, int y, int width, int height, Color color) {
Rectangle rect = new Rectangle(x, y, width, height);
squares.add(rect);
colors.add(color);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for (int i = 0; i < squares.size(); i++) {
g2.setColor(colors.get(i));
g2.fill(squares.get(i));
g2.setColor(Color.BLACK);
g2.draw(squares.get(i));
}
}
}
I don't see any problem with your paintComponent
method.
But you seem to never reset the contents of the ArrayList
s in your DrawSquare
class,
for example by calling clear()
on them.
Hence, after the first call of drawMatriz(...)
the ArrayList
s have 6400 entries,
after the second call they have 12800 entries, after 50 calls 320000 entries, ...