

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

import java.util.ArrayList;

import java.awt.image.*;

public class ameise extends JFrame {

  JButton BnOk = new JButton("Ok");
  JButton BnStop = new JButton("Stop");
  JButton BnEsc = new JButton("Abbruch");


  private myCanvas canvas;


  public ameise() {
    setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    setGUI();
  }

  private void setGUI() {
    setSize(950, 650);
    setTitle("JFrame als Dialog");

    BnOk.setFont( new Font("Arial", Font.BOLD,18)  );
    BnStop.setFont( new Font("Arial", Font.BOLD,18)  );
    BnEsc.setFont( new Font("Arial", Font.BOLD,18)  );
    BnOk.setPreferredSize( BnEsc.getPreferredSize() );

    this.getContentPane().setLayout( new BorderLayout() );
    canvas = new myCanvas();
    canvas.setBackground(Color.red);
    this.getContentPane().add( canvas, BorderLayout.CENTER);

	JPanel pnButton = new JPanel();
	//pnButton.setBackground(Color.red);
	pnButton.setLayout( new FlowLayout() );
	pnButton.add(BnOk);
        pnButton.add(BnStop);
	pnButton.add(BnEsc);

    this.getContentPane().add( pnButton, BorderLayout.SOUTH );

          BnOk.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
              BnOk_Click();
            }
          });

          BnStop.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
              BnStop_Click();
            }
          });

          BnEsc.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
              BnEsc_Click();
            }
          });


  } // setGUI

    private void BnOk_Click() {
        canvas.createImage();
        this.canvas.start(5, Color.WHITE);
    }

    private void BnStop_Click() {
        this.canvas.bWeiter=false;
        System.out.println("bWeiter=false");
    }
    private void BnEsc_Click() {
        setVisible(false);
        System.exit(0);
    }



  public static void main(String[] args) {
    ameise frame = new ameise();
    frame.setVisible(true);
 }

}  // ameise

class myCanvas extends JPanel {

  private Color _background;
  private int _anzAmeisen;
  private Graphics _g1=null;
  private Graphics _g2=null;
  private BufferedImage _image=null;
  private ArrayList _liste = new ArrayList();

  public boolean bWeiter;

  public myCanvas() {
    _background=Color.BLACK;
    this.setBackground(Color.red);
    _g1 = this.getGraphics();
    bWeiter=true;
    // _image = this.createImage(h, h));
  }

  public void createImage() {
    int w = getWidth();
    int h = this.getHeight();
    if (_image==null) {
        _image = new BufferedImage( w, h, BufferedImage.TYPE_INT_RGB );
        _g2 = _image.getGraphics();
    }
  }  // createImage
  

  private int getRndm(int size) {
    return (int) (  size*Math.random() );
  }
  
  public void start(int anzAmeisen, Color farbe) {
    int w = getWidth();
    int h = this.getHeight();
    int x, y;
    int i, j;
    CAmeise am;
    _background = farbe;
    _g2.setColor(_background);
    _g2.fillRect(0,0, getWidth(), this.getHeight() );
    this.update( this.getGraphics() );  // löschen des Bildschirms
    _liste.clear();
    for (i=0; i<anzAmeisen; i++) {
        am = new CAmeise();
        am.xalt=0;
        am.yalt=0;
        am.x = w >> 1;
        am.y= h >> 1;
        //am.x = getRndm(w);  // Zufall
        //am.y = getRndm(h);
        j = (int) (  4*Math.random() );
        switch (j) {
            case 0: am.xalt++;
            case 1: am.xalt--;
            case 2: am.yalt++;
            case 3: am.yalt--;
        }
        am.farbe = new Color( getRndm(256), getRndm(256), getRndm(256) );
        _image.setRGB(am.x, am.y, am.farbe.getRGB() );
        _liste.add(am);
    } // for
    bWeiter=true;
    repaint();
    invalidate();
    draw();
///    this.update( this.getGraphics() );  // löschen des Bildschirms
  }

  @Override
  public void paintComponent(Graphics g) {
    //System.out.println("in paint1");
    if (_image!=null) {
        g.drawImage(_image, 0,0, this);
        //System.out.println("in paint");
    }
    //System.out.println("in paint2");
  }
  
  private void draw() {
    int w = getWidth();
    int h = this.getHeight();
    int i, j;
    int Generation=0;
    int rx, ry;
    int farbe;

    //_image.setRGB(x, y, new Color(200,200,0).getRGB() );
    CAmeise am;
    while (bWeiter) {
    //for (Generation=0; Generation<10000; Generation++) {
        //Generation++;
        //if ( (Generation % 100) == 0) {
//          try {
//            Thread.sleep(0,10);  // ms ns
//          }
//          catch (InterruptedException e) {
//          }
        //}
        for (i=0; i<_liste.size(); i++) {
            am = (CAmeise) _liste.get(i);
            rx = am.x;
            ry = am.y;
            //System.out.println(am.x+"   "+am.y);
            farbe = _image.getRGB(am.x, am.y);
            if (farbe == _background.getRGB() ) {
                 //wohin soll die Ameise laufen?
                _image.setRGB(am.x, am.y, am.farbe.getRGB() );
                if (am.xalt==0) {
                    if (am.yalt==-1)
                        am.x--;
                    else
                        am.x++;
                }
                else {
                    if (am.xalt==-1)
                        am.y++;
                    else
                        am.y--;
                }
            }
            else {
              _image.setRGB(am.x, am.y, _background.getRGB() );
              if (am.xalt==0) {
                if (am.yalt==-1)
                    am.x++;
                else
                    am.x--;
              }
              else {
                if (am.xalt==-1)
                    am.y--;
                else
                    am.y++;
              }
            }
            am.xalt=rx-am.x;    //richtung speichern
            am.yalt=ry-am.y;
            if (am.x==0)
                am.x=w-2;
            else
                if (am.x==(w-1)) am.x=1;
            if (am.y==0)
             am.y=h-2;
            else
                if (am.y==(h-1)) am.y=1;
        }  // for
        this.update( this.getGraphics() );  // löschen des Bildschirms
        //repaint();
        //invalidate();
    }
  }  // draw


  class CAmeise {
    public int x, y;                //aktuellen koordinaten der ameise
    public int xalt, yalt;          //enthält nicht die alten koordinaten,
                                    //sondern die Richtung aus der die ameise kommt! (-1, 0, 1)
    public Color farbe;             //jede ameise hat eine andere farbe
  }


}