package org.cellularautomaton.sample.common;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JPanel;

import org.cellularautomaton.CellularAutomaton;
import org.cellularautomaton.cell.ICell;

public class JAutomatonPanel<T> extends JPanel {
	public static final int CELL_DEFAULT_SIZE = 10;
	private final int height;
	private final int width;
	/**
	 * 
	 */
	private static final long serialVersionUID = -4839521220659722820L;
	private CellularAutomaton<? extends T> automaton;

	public CellularAutomaton<? extends T> getAutomaton() {
		return automaton;
	}

	public static interface CellularRenderer<T> {
		Color getColor(T state);
	}

	private CellularRenderer<? super T> renderer;

	public JAutomatonPanel(CellularAutomaton<? extends T> automaton,
			CellularRenderer<? super T> renderer) {
		this.automaton = automaton;
		this.renderer = renderer;
		int width = 0;
		int height = 0;
		for (ICell<?> cell : automaton.getSpace().getAllCells()) {
			width = Math.max(width, cell.getCoords().get(0));
			height = Math.max(height, cell.getCoords().get(1));
		}
		this.width = width;
		this.height = height;
	}

	@Override
	public void paint(Graphics g) {
		super.paint(g);
		ICell<? extends T> origin = automaton.getSpace().getOrigin();
		double xRate = (double) getWidth() / width;
		double yRate = (double) getHeight() / height;
		for (int y = height - 1; y >= 0; y--) {
			for (int x = 0; x < width; x++) {
				T state = origin.getRelativeCell(x, y).getCurrentState();
				g.setColor(renderer.getColor(state));
				g.fillRect((int) Math.ceil(x * xRate),
						(int) Math.ceil(y * yRate), (int) Math.ceil(xRate),
						(int) Math.ceil(yRate));
			}
		}
	}

	@Override
	public Dimension getPreferredSize() {
		return new Dimension(Math.min(width * CELL_DEFAULT_SIZE, 500),
				Math.min(height * CELL_DEFAULT_SIZE, 500));
	}
}

@@ -114,16 +114,43 @@
 raphics;
+%0Aimport java.util.Iterator;
 %0A%0Aimport
@@ -259,16 +259,58 @@
 l.ICell;
+%0Aimport org.cellularautomaton.util.Coords;
 %0A%0Apublic
@@ -1271,85 +1271,49 @@
 %7B%0A%09%09
-super.paint(g);%0A%09%09ICell%3C? extends T%3E origin = automaton.getSpace().getOrigin(
+g.clearRect(0, 0, getWidth(), getHeight()
 );%0A%09
@@ -1411,148 +1411,270 @@
 ;%0A%09%09
-for (int y = height - 1; y %3E= 0; y--) %7B%0A%09%09%09for (int x = 0; x %3C width; x++) %7B%0A%09%09%09%09T state = origin.getRelativeCell(x, y).getCurrentState();%0A%09
+Iterator%3C?%3E iterator = automaton.getSpace().iterator();%0A%09%09while (iterator.hasNext()) %7B%0A%09%09%09@SuppressWarnings(%22unchecked%22)%0A%09%09%09ICell%3C? extends T%3E cell = (ICell%3C? extends T%3E) iterator.next();%0A%09%09%09T state = cell.getCurrentState();%0A%09%09%09Coords coords = cell.getCoords();%0A
 %09%09%09g
@@ -1713,17 +1713,16 @@
 e));%0A%09%09%09
-%09
 g.fillRe
@@ -1740,17 +1740,29 @@
 th.ceil(
-x
+coords.get(0)
  * xRate
@@ -1756,33 +1756,32 @@
 et(0) * xRate),%0A
-%09
 %09%09%09%09%09(int) Math.
@@ -1785,17 +1785,29 @@
 th.ceil(
-y
+coords.get(1)
  * yRate
@@ -1808,17 +1808,22 @@
  yRate),
- 
+%0A%09%09%09%09%09
 (int) Ma
@@ -1841,15 +1841,9 @@
 te),
-%0A%09%09%09%09%09%09
+ 
 (int
@@ -1867,13 +1867,8 @@
 ));%0A
-%09%09%09%7D%0A
 %09%09%7D%0A

Improve the displaying avoiding the research of all the cells asking relative coords from the origin : we use the iterator of the space to get all the cells.