1
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.Console;
import java.util.Scanner;
import javax.swing.JComponent;
import javax.swing.JFrame;


public class CA extends JComponent{

    int[] cells;
    int[] ruleset;
    int w = 10;
    int generation = 0;
    int width = 600; //Pixel length of the window
    private BufferedImage caImage;

    CA()
    {       
        cells = new int[width/w];
        //Rule 90 of Wolfram
        ruleset = new int[]{0,1,0,1,1,0,1,0};


        for (int i = 0; i < cells.length; i++) 
            cells[i] = 0;

        cells[cells.length/2] = 1;
        print(cells, cells.length);
        generate();
    }

    public void generate()
    {
        int [] nextgen = new int[cells.length];

        while(generation<6)
        {

            for(int i=1; i<cells.length-1; i++)
            {
                int left = cells[i-1];
                int middle = cells[i];
                int right = cells[i+1];
                nextgen[i] = rules(left, middle, right);
            }
            cells = nextgen;

            print(cells, cells.length);
            System.out.println();

            paintComponent(this.getGraphics());
            generation++;
        }
    }

    public void print(int[] a, int length)
    {
        System.out.println();
        for(int i=0; i<length; i++)
        {
            System.out.print(a[i]+" ");
        }
    }

    public int rules(int a, int b, int c)
    {
        String s = ""+a+b+c;
        int index = Integer.parseInt(s, 2);
        return ruleset[index];
    }


    public void paintComponent(Graphics g)
    {       
        super.paintComponent(g);

        Graphics2D g2 = (Graphics2D) g;
        for(int i=0; i<cells.length; i++)
        {
            if(cells[i] == 0)       
            {
                Color color = Color.WHITE;
                g2.setColor(color);
            }

            else if(cells[i] == 1)
            {
                Color color = Color.BLACK;
                g2.setColor(color);
            }

            //Rectangle rect = new Rectangle(i*w, generation*2, w, w);
            //g2.fill(rect);
            g2.drawRect(i*w, generation*2, w, w);
        }
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        JFrame frame = new JFrame();
        frame.setSize(600, 600);
        frame.setTitle("Cellular Automaton");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBackground(Color.RED);
        frame.setVisible(true);

        //Scanner input = new Scanner(System.in);
        //String pause = input.nextLine(); 



        CA cellularAutomaton = new CA();
        frame.add(cellularAutomaton);
        frame.setVisible(true);

    }

}

I want to display white or black colored rectangles of 10x10 pixels by getting 1s or 0s from 1D array of 60 elements. I repeat the same operation 6 times for different updated elements of the 1D array. (Implementing cellular automata).

Problem: The problem occurs when I want to display the result on a windows of 600x600. The g2.setColor(Color) line throws a NullPointerException. I could not find the reason why this error occurs.

Octahedron
  • 893
  • 2
  • 16
  • 31
Encinaar
  • 149
  • 3
  • 12

1 Answers1

4

Your Graphics object is null. Don't call getGraphics() on a component to obtain a Graphics instance as it will not persist. It is OK to call this on a BufferedImage, but if you get it from a component, then it will become null with any repaint. Instead use the Graphics instance that the JVM gives you in the paintComponent(...) method's parameter or the Graphics instance from a BufferedImage.

Also, don't call paintComponent(...) directly. That's the JVM's job.

Also, your while loop will not work as it will tie up and lock the Swing Event Dispatch Thread or EDT. You should use a SwingWorker to generate a BufferedImage on a background thread, and then display the Image created on the Swing event thread.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Using SwingWorker is very clever in order not to have your GUI freezed, +1. Invaluable advice. – skuntsel May 11 '13 at 19:26
  • @HovercraftFullOfEels I don't see how can I use SwingWorker here. – Encinaar May 12 '13 at 12:51
  • @user1183220: Why not? Why don't you think a SwingWorker would help? You could create your next generational image on a BufferedImage in the SwingWorker's doInBackground method. – Hovercraft Full Of Eels May 12 '13 at 13:00
  • @HovercraftFullOfEels Could you provide me an example of linking an integer array with BufferedImage ? – Encinaar May 12 '13 at 16:18
  • @user1183220: you're asking for a bit more than most volunteers will have time to commit. Also please realize that this site is not to write code for you but to answer questions. Much better for you and for us would be for you to give it a go and show us your attempt and specific questions you may have about your attempt. This is your question, your problem, and so the major onus of effort should be yours. – Hovercraft Full Of Eels May 12 '13 at 16:23