Coding battleship in java using Jbuttons in a Jframe

41 views Asked by At

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.

0

There are 0 answers