Search code examples
javaswingjframegrid-layoutcardlayout

A Grid layout containing Card layouts - can it be done?


The goal is to display a table of cells, where all cells are independent of one another, and each cell has several optional displays (Imagine a Kakuro board, jeopardy board, ext.)

It's my first attempt at swing. After a lot of reading, I decided that my approach will be to first design each cell independently using a Card Layout (this part I'm happy with), and then to 'wrap' it in a grid layout. This is probably where my lack of understanding in basic Swing raises its head:

When designing each cell I create a frame and add a panel to it:

    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;

    public class Cell extends Component{

    JFrame frame = new JFrame();

    /* we'll use a card layout with a panel for each look of the cell */
    CardLayout cardLayout = new CardLayout();
    JPanel containterPanel = new JPanel();
    JPanel firstPanel = new JPanel();
    JPanel secondPanel = new JPanel();
    JPanel thridpanel = new JPanel();

    public  Cell(){

        /* assign the card layout to the container panel */
        containterPanel.setLayout(cardLayout);

        /* assign objects to the different panels - details not important for the sake of the question */
        //....

        /* add the different panels to the container panel and show the initial one */
        containterPanel.add(firstPanel, "firstPanel");
        containterPanel.add(secondPanel, "secondPanel");
        containterPanel.add(thridpanel, "thridpanel");
        cardLayout.show(containterPanel, "firstPanel");

        /* add the container to the frame and display it*/
        frame.add(containterPanel);
        frame.setVisible(true);
    }
}

This behaves nicely. But my attempt to wrap it in a grid layout where each cell behaves like this is very clumsy:

import java.awt.*;


public class Board{

    private static final int COLUMNS_NUM = 3;
    private static final int ROWS_NUM = 3;

    JFrame frame = new JFrame();
    JPanel panel = new JPanel();
    Cell cells[] = new Cell[COLUMNS_NUM * ROWS_NUM];

    public Board(){

        panel.setLayout(new GridLayout(ROWS_NUM, COLUMNS_NUM));
        for (int i = 0; i <ROWS_NUM * COLUMNS_NUM; i++)
        {
            cells[i] = new Cell();
            panel.add(cells[i]);
        }

        frame.add(panel);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        new Board();
    }

}

What I get is a bunch of unrelated frames, separated from the main board frame. clearly I'm not handling the frames correctly (should I create only one..?). Any help in guiding me to the correct approach will be appreciated.


Solution

  • If Cells are to be added to Board, make them a JPanel, not a JFrame


    An example:

    import java.awt.CardLayout;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    
    //make it a sub class of JPanel for easier implementation. 
    public class Cell extends JPanel{
    
        public  Cell(){
    
            JPanel firstPanel = new JPanel();
            //add a lable just so something is displayed
            firstPanel.add(new JLabel(("Panel 1"))); 
            JPanel secondPanel = new JPanel();
            JPanel thridpanel = new JPanel();
    
            CardLayout cardLayout = new CardLayout();
            /* assign the card layout */
            setLayout(cardLayout);
        
            /* add the different panels to the container panel and show the initial one */
            add(firstPanel, "firstPanel");
            add(secondPanel, "secondPanel");
            add(thridpanel, "thridpanel");
            cardLayout.show(this, "firstPanel");
        }
    }
    

    And a board to hold the cell:

        import java.awt.Dimension;
    import java.awt.GridLayout;
    
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.WindowConstants;
    
    
    //make it a sub class of JFrame for easier implementation.
    public class Board extends JFrame{
    
        private static final int COLUMNS_NUM = 3;
        private static final int ROWS_NUM = 3;
    
        Cell cells[] = new Cell[COLUMNS_NUM * ROWS_NUM];
    
        public Board(){
    
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            setPreferredSize(new Dimension(800, 800));
    
            JPanel panel = new JPanel();
            add(panel);  //or better    getContentPane().add(panel);
            panel.setLayout(new GridLayout(ROWS_NUM, COLUMNS_NUM));
    
            for (int i = 0; i <(ROWS_NUM * COLUMNS_NUM); i++)
            {
                cells[i] = new Cell();
                panel.add(cells[i]);
            }
    
            pack();
            setVisible(true);
        }
    
        public static void main(String[] args) {
            new Board();
        }
    }
    

    That is how it look like:

    enter image description here