javaswingjpaneljlabelsetbounds

Moving labels in nested panels


enter image description hereI've made two grids and added them to a window using nested panels. The only issue is that I can't move the grid in the center and can't get the labels under their respective grids. Tried using setBounds but that's not working. Any advice? I've added an image of the current state. I want to display the player and opponent label under the first and second grid respectively.

public static void main(String[] args) {
    window = new JFrame();
    window.setTitle("Battleship.exe");
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setPreferredSize(new Dimension(800, 800));
    
    P1_container = new JPanel(new GridLayout(10,10));
    P1_container.setPreferredSize(new Dimension(400, 400));
    P1_container.setBorder(BorderFactory.createLineBorder(Color.black, 5));
    
    compContainer = new JPanel(new GridLayout(10,10));
    compContainer.setPreferredSize(new Dimension(400, 400));
    compContainer.setBorder(BorderFactory.createLineBorder(Color.black, 5));
    
    grid = new JPanel[10][10];
    for (int i =0; i< 10; i++) {
        for (int j =0; j< 10; j++) {
            grid[i][j] = new JPanel();
            grid[i][j].setBackground(Color.white);
            grid[i][j].setBorder(BorderFactory.createLineBorder(Color.blue, 2));
            grid[i][j].setPreferredSize(new Dimension(35,35));
            P1_container.add(grid[i][j]);
        }
    }
    
    enemyGrid = new JPanel[10][10];
    for (int i =0; i< 10; i++) {
        for (int j =0; j< 10; j++) {
            enemyGrid[i][j] = new JPanel();
            enemyGrid[i][j].setBackground(Color.lightGray);
            enemyGrid[i][j].setBorder(BorderFactory.createLineBorder(Color.red, 2));
            enemyGrid[i][j].setPreferredSize(new Dimension(35, 35));
            compContainer.add(enemyGrid[i][j]);
        }
    }
    
    GridLayout layout = new GridLayout(1, 2);
    layout.setHgap(150);
    mainPanel = new JPanel(layout); 
    
    mainPanel.add(P1_container);
    mainPanel.add(compContainer);
    
    player = new JLabel("PLAYER");
    player.setBounds(100, 410, 5, 5);
    
    opponent = new JLabel("OPPONENT");
    opponent.setBounds(100, 410, 5, 5);
    
    panel = new JPanel();
    panel.setPreferredSize(new Dimension(100, 100));
    panel.add(mainPanel, BorderLayout.CENTER);
    panel.add(player, BorderLayout.WEST);
    panel.add(opponent, BorderLayout.WEST);
    
    window.add(panel, BorderLayout.CENTER);
    window.pack();
    window.setVisible(true);
}

Solution

  • Please mark your previous questions as solved if they are. People have taken the time to help you out and it's the least you can do. Read here for more information on What should I do when someone answers my question?

    You are STILL calling setPreferredSize you should instead override getPreferredSize and ONLY where necessary. If your grid JPanels are sized via getPreferredSize there is no need to call setPreferredSize on their respective containers or the JFrame also you are still not creating your Swing components on the EDT.

    As others have mentioned, you cannot use setBounds when using a LayoutManager. To achieve what you want, you need to nest layouts, as you have been told before.

    So you probably want to create two JPanels with a BorderLayout. These two new containers will hold each grid and its label respectively:

    JPanel p1Container = new JPanel(new BorderLayout());
    p1Container.add(P1_container, BorderLayout.CENTER);
    p1Container.add(player, BorderLayout.SOUTH);
    
    JPanel opponentContainer = new JPanel(new BorderLayout());
    opponentContainer.add(compContainer, BorderLayout.CENTER);
    opponentContainer.add(opponent, BorderLayout.SOUTH);
    
    ...
    
    panel.add(p1Container);
    panel.add(opponentContainer);
    

    Also the below code makes no sense:

    panel = new JPanel();
    panel.setPreferredSize(new Dimension(100, 100));
    panel.add(mainPanel, BorderLayout.CENTER);
    panel.add(player, BorderLayout.WEST);
    panel.add(opponent, BorderLayout.WEST);
    

    By default, a JPanel uses FlowLayout so BorderLayout.XXX means nothing here. Again take the time to read A Visual Guide to Layout Managers but the code I showed corrects this by not passing in any extra parameters to add()