0
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.Arrays;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class CA extends JFrame
{
    static int[] cells = new int[60];
    static int generation;

    static int[] ruleSet = {0,0,0,0,0,0,0,1};

    int width = 600;
    int w = 15;

    JFrame frame;
    JPanel panel;

    public CA() 
    {
        generation = 0;
        panel = new JPanel();
        this.setSize(1000, 1000);
        this.setVisible(true);
        panel.setLayout(null);
        this.add(panel);
        repaint();
    }

    public static void generate() 
    {
        int[] nextGen = new int[cells.length];
        for(int i = 1; i < cells.length-1; i++) 
        {
            int left = i-1;
            int me = i;
            int right = i+1;
            nextGen[i] = rules(left,me,right);
        }
        for(int i = 0; i < nextGen.length; i++) 
        {
            cells[i] = nextGen[i];
        }
        System.out.println(Arrays.toString(cells));
    }

    public static int rules(int a, int b, int c) 
    {
        if(a == 1 && b ==1 && c == 1)
            return ruleSet[0];
        else if(a == 1 && b ==1 && c == 0)
            return ruleSet[1];
        else if(a == 1 && b ==0 && c == 1)
            return ruleSet[2];
        else if(a == 1 && b ==0 && c == 0)
            return ruleSet[3];
        else if(a == 0 && b ==1 && c == 1)
            return ruleSet[4];
        else if(a == 0 && b ==1 && c == 0)
            return ruleSet[5];
        else if(a == 0 && b ==0 && c == 1)
            return ruleSet[6];
        else
            return ruleSet[7];
    }
    public static void main(String[] args) 
    {
        for(int i = 0 ; i < cells.length; i++) 
        {
            cells[i]=0;
        }
        int num = (int)cells.length / 2;
        cells[num] = 1;
        new CA();
    }

    public void paint(Graphics g) 
    {
        super.paintComponents(g);
        //g2d.drawRect(10, 10, 100, 100);
        //generation = 0;
        System.out.println("generation ......." + generation);
        while(generation < 3) 
        {
            int counter = 0;
            System.out.println("cells...." + Arrays.toString(cells));
            for( int i : cells) 
            {
                if(i == 1) 
                {
                    System.out.println("i == 1");
                    g.fillRect((counter*w) + 300, generation + 300, w, w);
                    //counter++;
                }
                else {
                    System.out.println("not filling rect");
                }
            }
            System.out.println("generation ...in while ...." + generation);
            generate();
            generation++;
        }
        g.drawString("this works", 100, 100);
    }
}

Parts of my paint method work such as the drawString works perfectly fine but all the rest of the paint method does not work the way I want it to. I want to make a Cellular automaton that is similar to the Wolfram cellular automaton. I mostly copied my paint method from other projects that have a working paint method so I don't really know what the method itself is doing.

Narutachi
  • 1
  • 2
  • 1
    Whatever code you've copied this from, discard it, because your code is wrong on many levels. You're drawing directly in a JFrame, something you should never do, you're drawing in a paint method, something you shouldn't do, you're calling the wrong super method,.... and I can go on. Why not read how to draw from the source, the Swing painting tutorials? : [Lesson: Performing Custom Painting](http://docs.oracle.com/javase/tutorial/uiswing/painting/index.html). – Hovercraft Full Of Eels Jun 27 '18 at 02:30
  • 1
    Also, it looks like that while loop doesn't belong within a painting method to begin with, since you appear to be trying to animate the drawing of different generations of the automata, and will only see the last. Instead change the state of the automata data from within a [Swing Timer](http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html), call repaint in the timer, and then use the automata state to tell your drawing JPanel's paintComponent method what to draw and how to draw it. – Hovercraft Full Of Eels Jun 27 '18 at 02:32

1 Answers1

1

Your whole approach is broken, and instead I recommend that you follow these guidelines:

  • First and foremost draw within the paintComponent method of a JPanel, and be sure to call the same super method within your method override. This is all well described in the Swing drawing tutorials: Lesson: Performing Custom Painting.
  • The while loop does not belong within the painting method if your goal is to animate the changes of the display of the cells, and in fact I would venture that your code shouldn't have a while loop
  • Instead use a Swing Timer to help you drive your animation. You'd call the next generation within the Timer's ActionListener, and then call repaint() which would signal the JPanel to redraw itself.
  • In the paintComponent method, use the state of the cellular automata data to help decide what to draw and where.

Also:

  • Never draw directly within a JFrame as this is a complex top-level window container, and drawing directly within it can upset its ability to display the components it holds
  • Don't call super.paintComponents within a paint method override. The super call should match the override call in this situation.
  • Again you shouldn't even be overriding paint but rather a JPanel's paintComponent method.
  • You appear to be covering up your JFrame with the panel JPanel
  • Your class extends JFrame, something that you almost never want to do.
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373