I'm trying to code battleship in a JFrame with 2 matrices of 2d arrays with JButtons. I have most of the code ready to go, but I'm running into a problem with placing the ships. The problem is that after clicking the "place 2 ship" button, I can't find a way for the code to know that a button in the matrix was clicked telling it to move on to the enable adjacent squares method.
import java.awt.Color;
import java.awt.event.*;
import javax.swing.*;
public class MyFrame extends JFrame implements ActionListener{
Button[][] matrixOp = new Button[10][10];
Button[][] matrixPl = new Button[10][10];
private JButton lastClickedButton = null;
JButton start;
JButton ship2;
JButton ship3;
JButton ship32;
JButton ship4;
JButton ship5;
public MyFrame(){
this.setTitle("BattleShip");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(300,600);
this.setLayout(null);
this.setLocationRelativeTo(null);
//adds start button
start = new JButton();
start.setBounds(0, 280, 20, 10);
//start.setText("Start");
start.setBackground(Color.green);
start.setEnabled(true);
start.setVisible(true);
start.addActionListener(this);//e -> PlayerPlaceShips());
this.add(start);
//adds ship buttons
ship2 = new JButton();
ship2.setBounds(20, 280, 20, 10);
//start.setText("Start");
ship2.setBackground(new Color(152, 151, 169));
ship2.setEnabled(true);
ship2.setVisible(true);
ship2.addActionListener(this);
this.add(ship2);
ship3 = new JButton();
ship3.setBounds(40, 280, 20, 10);
//start.setText("Start");
ship3.setBackground(new Color(152, 151, 169));
ship3.setEnabled(true);
ship3.setVisible(true);
ship3.addActionListener(this);
this.add(ship3);
ship32 = new JButton();
ship32.setBounds(60, 280, 20, 10);
//start.setText("Start");
ship32.setBackground(new Color(152, 151, 169));
ship32.setEnabled(true);
ship32.setVisible(true);
ship32.addActionListener(this);
this.add(ship32);
ship4 = new JButton();
ship4.setBounds(80, 280, 20, 10);
//start.setText("Start");
ship4.setBackground(new Color(152, 151, 169));
ship4.setEnabled(true);
ship4.setVisible(true);
ship4.addActionListener(this);
this.add(ship4);
ship5 = new JButton();
ship5.setBounds(100, 280, 20, 10);
//start.setText("Start");
ship5.setBackground(new Color(152, 151, 169));
ship5.setEnabled(true);
ship5.setVisible(true);
ship5.addActionListener(this);
this.add(ship5);
//creates buttons for matrixPl
{
Button b;
for(int row = 0; row < 10; row++){
for(int col = 0; col < 10; col++){
int rp = 300 + row * 26;
int cp = 14 + col * 26;
b = new Button(cp, rp, 26, 26);
matrixPl[row][col] = b;
matrixPl[row][col].setActive(false);
matrixPl[row][col].getButton().addActionListener(this);
}
}
}
//adds matrixPl buttons to JFrame
for(int row = 0; row< 10; row++){
for(int col = 0; col< 10; col++){
this.add(matrixPl[row][col].getButton());
}
}
//missing code
this.setVisible(true);
}
//Bellow is what does not seem to work
//Player place ships
public void placeShip(int row, int col){
matrixPl[row][col].setShip(true);
}
public void place2Ship(){
PlEnabled(true);
int shipPartsPlaced = 0;
JButton firstButton = null;
while(shipPartsPlaced < 2){
if(clicked){
if(shipPartsPlaced==0){
firstButton = getClickedButton();
PlEnabled(false);
enableAdjacentButtons(firstButton);
} else if (shipPartsPlaced == 1) {
if (!isAdjacent(firstButton)) {
// The second button is not adjacent to the first button
continue;
}
}
placeShip(getClickedRow(), getClickedCol());
shipPartsPlaced++;
clicked = false;
}
}
PlEnabled(false);
}
public void PlayerPlaceShips(){
place2Ship();
}
//method for actionListener
public void actionPerformed(ActionEvent e){
clicked = true;
lastClickedButton = (JButton) e.getSource();
if(start==lastClickedButton){
start.setEnabled(false);
//PlayerPlaceShips();
}
if(ship2 == lastClickedButton){
PlEnabled(true);
int shipPartsPlaced = 0;
JButton firstButton = null;
if(shipPartsPlaced==0){
firstButton = getClickedButton();
PlEnabled(false);
enableAdjacentButtons(firstButton);
} else if (shipPartsPlaced == 1) {
if (!isAdjacent(firstButton)) {
// The second button is not adjacent to the first button
return;
}
}
placeShip(getClickedRow(), getClickedCol());
shipPartsPlaced++;
clicked = false;
}
}
public static void main(String[] args) {
new MyFrame();
}
}
This is the full code above for the game. Note that the problem is in the place ships methos and the actionListener. Note also that in the code above I wrote both methods (the while loop method, and the methodof doing it which I did not finish in the actionListener method)
I tried using a while loop in the method to wait for a button to be clicked, but this makes the JFrame unresponsive. I asked gpt to help and it advised to use a swingworker to allow the loop to be in a protected void or something (I don't know how this works well enough to debug it so I left that idea alone).I then tried adding the place2ship method into the action listener instead of making it into a seperate method. This also does not seem to work as I have no way to know if the button in matrix was pressed for the 2 ship or a later, larger ship. I think it might work to add a variable to show in what "phase" of the placing it is, but I think there must be a better solution than this.