Search code examples
javagrid-layout

(JAVA battleships) button/image grid works fine but when I add a second grid next to it they both get messed up


I'm creating a battleships program for java. Using a gridlayout I want to have the player board in the west panel and NPC board in the east panel (as well as some other info and means of input in the centre panel and the south panel).

I started by adding the players board like follows (full code can be found at the bottom of this post as well):

public void placePlyrGrids()
{
    plyrBoard.add(cornerGridLabel); //add an empty grid to the top left
    for(n = 0; n < 10; n++)
        plyrBoard.add(letterGridLabels[n]); //the first row is the first 10 letters of the alphabet
    for (y = 1; y < 11; y++) //For every (y) row...
    {

        for (x = 0; x < 11; x++) //...add ten (x) grids to make columns
        {
            if (x == 0) //To the start of each row, add a number (image JLabel)
            {
                plyrBoard.add(numberGridLabels[numberCounter]);
                numberCounter++;
            }
            else //for the rest of each row, add buttons
            {
                plyrBoard.add(buttonGrids[y-1][x-1]);
            }
        }
    }
}

This worked fine.

Then I tried adding the dealer board in two ways, none of which seemed to work, as they both got messed up, and seemed to mess up the player board as well which had seemed to work fine on its own.

1: Placing both boards simultaneously in the same method.

public void placeBoards()
{
    plyrBoard.add(cornerGridLabel); //add an empty grid to the top left
    NPCBoard.add(cornerGridLabel);
    for(n = 0; n < 10; n++)
        plyrBoard.add(letterGridLabels[n]); //the first row is the first 10 letters of the alphabet
    NPCBoard.add(letterGridLabels[n]);
    for (y = 1; y < 11; y++) //For every (y) row...
    {
        for (x = 0; x < 11; x++) //...add ten (x) grids to make columns
        {
            if (x == 0) //To the start of each row, add a number (image JLabel)
            {
                plyrBoard.add(numberGridLabels[numberCounter]);
                NPCBoard.add(numberGridLabels[numberCounter]);
                numberCounter++;
            }
            else //for the rest of each row, add buttons
            {
                plyrBoard.add(buttonGrids[y-1][x-1]);
                NPCBoard.add(emptyGridLabel);
            }       
        }
    }
}

2: Placing both each in a different method (used in combination with the pladePlyrGrids method at the top)

public void placeNPCGrids()
{
    NPCBoard.add(cornerGridLabel);
    for(n = 0; n < 10; n++)
        NPCBoard.add(letterGridLabels[n]);

    for (y = 1; y < 11; y++) 
    {
        for (x = 0; x < 11; x++)
        {
            if (x == 0)
            {
                NPCBoard.add(numberGridLabels[numberCounter]);
                numberCounter++;
            }
            else
            {
                NPCBoard.add(emptyGridLabel);
            }
        }
    }
}

My full code:

import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;


public class Battleships {

    public static void main(String[] args) 
    {
        Interface Win = new Interface ();   
    }
}

class Interface extends JFrame implements ActionListener
{   
    //Identify variables
    int n;
    int numberCounter = 0;
    int y;
    int x;

    // lengths of the various ships in the game

    //ADD IMAGE COMPONENTS
    //Coordinate axes and empty grids
    ImageIcon emptyGrid = new ImageIcon("EmptyGrid.png");
    ImageIcon cornerGrid = new ImageIcon("CornerGrid.png");
    ImageIcon [] numberGrids = new ImageIcon[11];
    {
        for (n = 0; n < 11; n ++)
            numberGrids[n] = new ImageIcon("Grid" + (n + 1) + ".png");
    }
    ImageIcon [] letterGrids = new ImageIcon [11];
    {
        for (n = 0; n < 11; n ++)
            letterGrids[n] = new ImageIcon("GridA" + (n + 1)+ ".png"); 
    }
    //Ship parts

    //Clickable ships (for placement)
    ImageIcon fullBattleship = new ImageIcon("FullBattleship.png");
    ImageIcon fullCruiser = new ImageIcon("FullCruiser.png");
    ImageIcon fullPatrolBoat1 = new ImageIcon("FullPatrolBoat.png");
    ImageIcon fullPatrolBoat2 = new ImageIcon("FullPatrolBoat.png");

    //JLabels   
    JLabel cornerGridLabel = new JLabel(cornerGrid);
    JLabel [] numberGridLabels = new JLabel[10]; 
    {
        //The first 11 grids are an empty grid followed by letters A-J
        for (n = 0; n < 10; n++)
        {
            numberGridLabels[n] = new JLabel(numberGrids[n]);
        }
    }
    JLabel [] letterGridLabels = new JLabel [10];
    {
        for (n = 0; n < 10; n ++)
        {
            letterGridLabels[n] = new JLabel (letterGrids[n]);
        }
    }
    JLabel emptyGridLabel = new JLabel(emptyGrid);

    JButton [][] buttonGrids = new JButton [10][10];
    {
        for (y = 0; y < 10; y++)
        {
            for (x = 0; x < 10; x++)
            {
                buttonGrids[x][y] = new JButton(emptyGrid);
                buttonGrids[x][y].setPreferredSize(new Dimension(50,50));
            }
        }
    }

    JLabel [] NPCGrids = new JLabel[121]; //grid placements for the dealer board
    {
        for (n = 0; n < 121; n ++)
            NPCGrids[n] = new JLabel (emptyGrid);
    }

    JLabel [] clickableBoats = new JLabel [4];
    {
        clickableBoats[0] = new JLabel (fullBattleship);
        clickableBoats[1] = new JLabel (fullCruiser);
        clickableBoats[2] = new JLabel (fullPatrolBoat1);
        clickableBoats[3] = new JLabel (fullPatrolBoat2);

    }

    JButton [] plyrClickableGrids = new JButton [100];
    {
        for (n = 0; n < 99; n++);
            plyrClickableGrids[n] = new JButton(emptyGrid);
    }


    //Add interface components
    JTextArea playerInformation = new JTextArea(20,5);
    JScrollPane textPane1 = new JScrollPane (playerInformation);
    JButton playTurnBtn = new JButton ("Play Turn");

    //add JPanels
    JPanel plyrBoard = new JPanel (new GridLayout(11,11));
    JPanel infoPanel = new JPanel(new GridLayout(1,1));
    JPanel NPCBoard = new JPanel(new GridLayout(11,11));
    JPanel inputPanel = new JPanel(new GridLayout(1,10));

    public Interface ()
    {
        super ("Battleships"); 
        setSize (1367,729); 
        setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); 

        //Set the background color
        Container contentArea = getContentPane(); 

        //Set each panel to "opaque", so that the background becomes visible
        plyrBoard.setOpaque(false);
        NPCBoard.setOpaque(false);
        inputPanel.setOpaque(false);
        setVisible (true);


        playerInformation.setEditable(false); 



        //Add panels to different compass points on the content area
        contentArea.add("West", plyrBoard);
        contentArea.add("Center", infoPanel);
        contentArea.add("East", NPCBoard);
        contentArea.add("South", inputPanel);

        //Add imageLabels and buttons to panels
        placePlyrGrids();
        numberCounter = 0;
        placeNPCGrids();


        infoPanel.add(playerInformation);

        for (n = 0; n < 4; n++)
        {
            inputPanel.add(clickableBoats[n]);
        }
        inputPanel.add(playTurnBtn);



        // TODO Vanity 
        //Button format
        playTurnBtn.setPreferredSize(new Dimension(1, 141));


    }

    public void placePlyrGrids()
    {
           plyrBoard.add(cornerGridLabel); //add an empty grid to the top left
            //NPCBoard.add(cornerGridLabel);
            for(n = 0; n < 10; n++)
                plyrBoard.add(letterGridLabels[n]); //the first row is the first 10 letters of the alphabet
                //NPCBoard.add(letterGridLabels[n]);

        for (y = 1; y < 11; y++) //For every (y) row...
        {
            for (x = 0; x < 11; x++) //...add ten (x) grids to make columns
            {
                if (x == 0) //To the start of each row, add a number (image JLabel)
                {
                    plyrBoard.add(numberGridLabels[numberCounter]);
                    //NPCBoard.add(numberGridLabels[numberCounter]);
                    numberCounter++;
                }
                else //for the rest of each row, add buttons
                {
                    plyrBoard.add(buttonGrids[y-1][x-1]);
                    //NPCBoard.add(emptyGridLabel);
                }
            }
        }
    }

    public void placeNPCGrids()
    {
        NPCBoard.add(cornerGridLabel);
        for(n = 0; n < 10; n++)
            NPCBoard.add(letterGridLabels[n]);

        for (y = 1; y < 11; y++) 
        {
            for (x = 0; x < 11; x++)
            {
                if (x == 0)
                {
                    NPCBoard.add(numberGridLabels[numberCounter]);
                    numberCounter++;
                }
                else
                {
                    NPCBoard.add(emptyGridLabel);
                }
            }
        }
    }


    public void actionPerformed(ActionEvent e) 
    {

    }
}

As I'm sure you understand by now I am very confused with this and I don't understand at all why this is happening. After all, the first method works fine on its own. Why shouldn't the second one and why are they destroying each other?

Any suggestions or tips to help put me in the right direction would be very appreciated.

Edit:

Solution:

import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;


public class Battleships {


	public static void main(String[] args) 
	
	{
		
		Interface Win = new Interface ();
		
	}

}

class Interface extends JFrame implements ActionListener
{
	
	//Identify variables
	int n;
	int numberCounter = 0;
	int y;
	int x;

	// lengths of the various ships in the game


	//ADD IMAGE COMPONENTS
	//Coordinate axes and empty grids
	ImageIcon emptyGrid = new ImageIcon("EmptyGrid.png");
	ImageIcon cornerGrid = new ImageIcon("CornerGrid.png");
	ImageIcon [] numberGrids = new ImageIcon[11];
	{
		for (n = 0; n < 11; n ++)
			numberGrids[n] = new ImageIcon("Grid" + (n + 1) + ".png");
	}
	ImageIcon [] letterGrids = new ImageIcon [11];
	{
		for (n = 0; n < 11; n ++)
			letterGrids[n] = new ImageIcon("GridA" + (n + 1)+ ".png"); 
	}
	//Ship parts
	
	//Clickable ships (for placement)
	ImageIcon fullBattleship = new ImageIcon("FullBattleship.png");
	ImageIcon fullCruiser = new ImageIcon("FullCruiser.png");
	ImageIcon fullPatrolBoat1 = new ImageIcon("FullPatrolBoat.png");
	ImageIcon fullPatrolBoat2 = new ImageIcon("FullPatrolBoat.png");

	
	//JLabels 	
	JLabel plyrCornerGridLabel = new JLabel(cornerGrid);
	JLabel [] plyrNumberGridLabels = new JLabel[10]; 
	{
		//The first 11 grids are an empty grid followed by letters A-J
		for (n = 0; n < 10; n++)
		{
			plyrNumberGridLabels[n] = new JLabel(numberGrids[n]);
		}
	}
	JLabel [] plyrLetterGridLabels = new JLabel [10];
	{
		for (n = 0; n < 10; n ++)
		{
				plyrLetterGridLabels[n] = new JLabel (letterGrids[n]);
	
		}
	
	}
	
	JLabel NPCCornerGridLabel = new JLabel(cornerGrid);
	JLabel [] NPCNumberGridLabels = new JLabel[10]; 
	{
		//The first 11 grids are an empty grid followed by letters A-J
		for (n = 0; n < 10; n++)
		{
			NPCNumberGridLabels[n] = new JLabel(numberGrids[n]);
		}
	}
	JLabel [] NPCLetterGridLabels = new JLabel [10];
	{
		for (n = 0; n < 10; n ++)
		{
				NPCLetterGridLabels[n] = new JLabel (letterGrids[n]);
	
		}
	
	}
	
	
	JLabel[][] emptyGridLabels = new JLabel [10][10];
	{
		for (y = 0; y < 10; y++)
		{
			for (x = 0; x < 10; x++)
			{
				emptyGridLabels[x][y] = new JLabel(emptyGrid);
			}
		}
	}
	
	JButton [][] buttonGrids = new JButton [10][10];
	{
		for (y = 0; y < 10; y++)
		{
			for (x = 0; x < 10; x++)
			{
				buttonGrids[x][y] = new JButton(emptyGrid);
				buttonGrids[x][y].setPreferredSize(new Dimension(50,50));
			}
		}
	}
	
	JLabel [] NPCGrids = new JLabel[121]; //grid placements for the dealer board
	{
		for (n = 0; n < 121; n ++)
			NPCGrids[n] = new JLabel (emptyGrid);
	}
	
	JLabel [] clickableBoats = new JLabel [4];
	{
		clickableBoats[0] = new JLabel (fullBattleship);
		clickableBoats[1] = new JLabel (fullCruiser);
		clickableBoats[2] = new JLabel (fullPatrolBoat1);
		clickableBoats[3] = new JLabel (fullPatrolBoat2);

	}
	
	JButton [] plyrClickableGrids = new JButton [100];
	{
		for (n = 0; n < 99; n++);
			plyrClickableGrids[n] = new JButton(emptyGrid);
			
	}
	
	
	//Add interface components
	JTextArea playerInformation = new JTextArea(20,5);
	JScrollPane textPane1 = new JScrollPane (playerInformation);
	JButton playTurnBtn = new JButton ("Play Turn");

	//add JPanels
	JPanel plyrBoard = new JPanel (new GridLayout(11,11));
	JPanel infoPanel = new JPanel(new GridLayout(1,1));
	JPanel NPCBoard = new JPanel(new GridLayout(11,11));
	JPanel inputPanel = new JPanel(new GridLayout(1,10));
	
	public Interface ()
	{
		super ("Battleships"); 
		setSize (1367,729); 
		setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); 
		
		//Set the background color
		Container contentArea = getContentPane(); 
	
		//Set each panel to "opaque", so that the background becomes visible
		plyrBoard.setOpaque(false);
		NPCBoard.setOpaque(false);
		inputPanel.setOpaque(false);
		setVisible (true);

		
		playerInformation.setEditable(false); 

        playTurnBtn.setPreferredSize(new Dimension(1, 141));

	    
		//Add panels to different compass points on the content area
		contentArea.add("West", plyrBoard);
		contentArea.add("Center", infoPanel);
		contentArea.add("East", NPCBoard);
		contentArea.add("South", inputPanel);
		
		//Add imageLabels and buttons to panels
	infoPanel.add(playerInformation);
		
		for (n = 0; n < 4; n++)
		{
			inputPanel.add(clickableBoats[n]);
		}
		inputPanel.add(playTurnBtn);
		
		placePlyrGrids();
		numberCounter = 0;
		placeNPCGrids();
	    			
	
	

		
		
		// TODO Vanity 
		//Button format
		
	
	}
	
	public void placePlyrGrids()
	{
		   plyrBoard.add(plyrCornerGridLabel); //add an empty grid to the top left
	 	   	//NPCBoard.add(cornerGridLabel);
	 	   	for(n = 0; n < 10; n++)
	 	   		plyrBoard.add(plyrLetterGridLabels[n]); //the first row is the first 10 letters of the alphabet
		   		//NPCBoard.add(NPCLetterGridLabels[n]);

		for (y = 1; y < 11; y++) //For every (y) row...
	    {
	    	
	    	for (x = 0; x < 11; x++) //...add ten (x) grids to make columns
	    	{
	    		if (x == 0) //To the start of each row, add a number (image JLabel)
	    		{
	    			plyrBoard.add(plyrNumberGridLabels[numberCounter]);
	    			//NPCBoard.add(NPCNumberGridLabels[numberCounter]);
	    			numberCounter++;
	    		}
			
	    		else //for the rest of each row, add buttons
	    		{
	    			plyrBoard.add(buttonGrids[y-1][x-1]);
	    			//NPCBoard.add(emptyGridLabel);

	    		}
	    			
	   		}
	    	
	   	}
	}
	
	public void placeNPCGrids()
	{
		NPCBoard.add(NPCCornerGridLabel);
	   	for(n = 0; n < 10; n++)
	   		NPCBoard.add(NPCLetterGridLabels[n]);

	   	for (y = 1; y < 11; y++) 
    	{
    	
    		for (x = 0; x < 11; x++)
    		{
    			if (x == 0)
    			{
    				NPCBoard.add(NPCNumberGridLabels[numberCounter]);
    				numberCounter++;
    			}
		
    			else
    			{
    			
    				NPCBoard.add(emptyGridLabels[x-1][y-1]);

    			}
    			
   			}
    	
    	}
	}
    

	

	public void actionPerformed(ActionEvent e) 
	{
		
	}
	

}


Solution

  • The issue is that in all the code you are always referring to the same object, E.G.

    public void placeBoards()
    {
        //Both player board and npc board are going to have the same cornerGirdLabel, you should be creating two separate instances of it
        plyrBoard.add(cornerGridLabel); //add an empty grid to the top left
        NPCBoard.add(cornerGridLabel);
    
        //Rest of the code
    }
    

    All the way through your code, you keep using the reference to the same objects, which is not going to help you when you want to build two boards with their own grids!

    It might be better, especially for readability to separate your board building into different classes and have them create their own instances of these objects, rather than trying to fit this all in one class with your main method. Have a look at some best design practice documents. for example, they have some nice tips here