Search code examples
javaswingjframejbuttongrid-layout

How do I select specific cells into a Java grid GUI?


I'm developing a GUI grid and I need to select specific cells. I used JFrame. My goal is to fulfill the first column and the last row with numbers, like x-y axes.

I have tried to declare an array of JButtons with the exact cell position that I need, setting the text. (The caps-lock comment in code)

import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;

public class GridLayoutTest {

    private static JButton[] arrayBtn;

    public static void main(String[] args ) {

        // the frame that contains the components
        JFrame frame = new JFrame("GridLayoutTest from JCG");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // set the size of the frame
        frame.setSize(1000, 1000);

        // set the rows and cols of the grid, as well the distances 
       between them
        GridLayout grid = new GridLayout(10,14, 0, 0);
        // what layout we want to use for our frame
        frame.getContentPane().setBackground(Color.WHITE);;
        frame.setLayout(grid);

        arrayBtn = new JButton[140];

        // add JButtons dynamically
        for(int i=0; i < arrayBtn.length; i++) {
            arrayBtn[i] = new JButton();  

            arrayBtn[i].setBackground(Color.WHITE);
            arrayBtn[i].setSize(1,1);

               //IF I RUN ONLY THIS WORKS WITH THE FIRST CELL(IF I INSERT OUT 
               // THE FOR CYCLE DOESN'T WORK)
               arrayBtn[0].setText("9");

              // IF I RUN ALSO THIS CODE ROW I HAVE THE SAME ERROR 
               arrayBtn[1].setText("9");



            frame.add(arrayBtn[i]);
        }
        frame.setVisible(true);
    }
}

Exception:

Exception in thread "main" java.lang.NullPointerException
relative to the row of the specific cell selected.

Solution

  • You are setting the second cell (index 1) during every loop iteration, which means even during the first iteration where the second cell is not initialized.

    Let's say we enter the loop the first time. We are going to initialize the first button (index 0). Then you set the text of the second button (index 1) to "9". This button has not been initialized yet, so we are calling a method on an object that is still null. That is the reason why you receive a NullPointerException.

    for (int i = 0; i < arrayBtn.length; i++) {
        arrayBtn[i] = new JButton();
        arrayBtn[i].setBackground(Color.WHITE);
        arrayBtn[i].setSize(1, 1);
    
        // This works (set every button text to "9"):
        arrayBtn[i].setText("9");
    
        // This will NOT work:
        arrayBtn[1].setText("9"); 
    
        frame.add(arrayBtn[i]);
    }
    
    // This works (set the first button text to "9"):
    arrayBtn[0].setText("9");
    

    Keep in mind that array indexing starts with the index 0:

    String[] array = {"first", "second", "third"};
    System.out.println(array[1]); // will print "second"
    

    So in the full context of your question: Maybe you should consider using a two-dimensional array for your array of buttons since that resembles more closely the grid you are trying to build (10x14).

    JButton[][] buttonGrid = new JButton[10][14];
    for (int y = 0; y < 10; y++) {
        for (int x = 0; x < 14; x++) {
            buttonGrid[y][x] = new JButton("Test");
            if (y == 0) {
                // code in here is only executed for the first row
                buttonGrid[y][x].setText(Integer.toString(x));
            }
            if (x == 0) {
                // code in here is only executed for the first column
                buttonGrid[y][x].setText(Integer.toString(y));
            }
        }
    }
    

    This will look somewhat like this:

    [0, 1,    2,    3,    4,    5,    6,    7,    8,    9,    10,   11,   12,   13  ]
    [1, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test]
    [2, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test]
    [3, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test]
    [4, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test]
    [5, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test]
    [6, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test]
    [7, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test]
    [8, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test]
    [9, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test, Test]