Search code examples
javaarraysswingloopsjbutton

Finding the source of an ActionEvent in a JButton[][] array without using nested loops?


I've created a JFrame application with an 8x8 array of JButtons[][] corresponding to an array of selected & deselected ImageIcons. When a button is pressed, it selects that button using setSelection() and deselects any other buttons. However, If any button adjacent to the selected button is pressed, the selected button and the adjacent button will swap ImageIcons.

I've successfully managed to do most of this, however using nested loops within an ActionEvent to determine adjacent buttons, the selected button, and deselected buttons simultaneously becomes a logical nightmare.

public void actionPerformed(ActionEvent event)
{
for (int row = 0; row < 8; row++) {
  for (int col = 0; col < 8; col++) {
    if (event.getSource() == buttons[row][col]) {
      if (row<7) buttonsAdjacent[row+1][col] = true;
      if (row>0) buttonsAdjacent[row-1][col] = true;
      if (col<7) buttonsAdjacent[row][col+1] = true;
      if (col>0) buttonsAdjacent[row][col-1] = true;
      buttons[row][col].setSelected(true);
      }
    }
  }
}

How can I put actionListeners into each adjacent button at array index [row][col] to determine if an adjacent button has actually been pressed? And how can I reassign those actionListeners every time a new button has been selected?


Solution

  • As shown in this complete example, you can calculate the index of a JButton in a List<JButton> as a function of the row and column for a given grid size, e.g. N * N. See the comments and edit history for alternatives.

    private static final int N = 5;
    
    private JButton getGridButton(int r, int c) {
        int index = r * N + c;
        return list.get(index);
    }