Search code examples
javaswingjlabellayout-manager

How can i set the interface for the TicTacToe game project?


I am trying to make the interface for the Tic tac toe. I am using the JLabels method for my 9 fields. There is no error in the program but there is something that i don't know how to do it. Please read below for my problem & please give me suggestion

 import javax.swing.*;
 import java.awt.*;
 import java.awt.geom.*;

 public class ticTac extends JFrame
   {
    static JLabel label0 = new JLabel();
    static JLabel label1 = new JLabel();
    static JLabel label2 = new JLabel();
    static JLabel label3 = new JLabel();
    static JLabel label4 = new JLabel();
    static JLabel label5 = new JLabel();
    static JLabel label6 = new JLabel();
    static JLabel label7 = new JLabel();
    static JLabel label8 = new JLabel();
    static JLabel[] choiceLabel = new JLabel[9];

    static ImageIcon burger = new ImageIcon("Cross.jpg");

 public static void main(String []args)
    {
        new ticTac().show();   
    }

 public ticTac()
    {
        setVisible(true);
        setSize(450,450);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     

        getContentPane().setLayout(new GridBagLayout());
        GridBagConstraints myGrid = new GridBagConstraints();

        GridBagConstraints gridConstraints;
        choiceLabel[0] = label0;
        choiceLabel[1] = label1;
        choiceLabel[2] = label2;
        choiceLabel[3] = label3;
        choiceLabel[4] = label4;
        choiceLabel[5] = label5;
        choiceLabel[6] = label6;
        choiceLabel[7] = label7;
        choiceLabel[8] = label8;

This method draws the Labels from 1 to 9 in a horizontal row, so i don't want that, i want my program will draw three box in one row, and three boxes in second row and three boxes. please help me.

        for (int i = 0; i < 9; i++)
            {
              gridConstraints = new GridBagConstraints();
              choiceLabel[i].setPreferredSize(new Dimension(burger.getIconWidth(), burger.getIconHeight()));
              choiceLabel[i].setOpaque(true);
              choiceLabel[i].setBackground(Color.RED);
              gridConstraints.gridx = i;
              gridConstraints.gridy = 0;
              gridConstraints.insets = new Insets(10, 10, 10, 10);
              getContentPane().add(choiceLabel[i], gridConstraints);



        pack();
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((int) (0.5 * (screenSize.width - getWidth())), (int) (0.5 * (screenSize.height - getHeight())), getWidth(), getHeight());
    }
}
}

Solution

  • You could use a GridLayout

    enter image description here

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.EventQueue;
    import java.awt.GridBagConstraints;
    import java.awt.GridLayout;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import static tictactoe.TicTacToe.choiceLabel;
    
    public class LayoutTicTacToe {
    
        public static void main(String[] args) {
            new LayoutTicTacToe();
        }
    
        public LayoutTicTacToe() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new GridLayout(3, 3, 10, 10));
    
                    choiceLabel[0] = new JLabel("_");
                    choiceLabel[1] = new JLabel("_");
                    choiceLabel[2] = new JLabel("_");
                    choiceLabel[3] = new JLabel("_");
                    choiceLabel[4] = new JLabel("_");
                    choiceLabel[5] = new JLabel("_");
                    choiceLabel[6] = new JLabel("_");
                    choiceLabel[7] = new JLabel("_");
                    choiceLabel[8] = new JLabel("_");
    
                    for (int i = 0; i < 9; i++) {
                        choiceLabel[i].setText("_");
                        choiceLabel[i].setHorizontalAlignment(JLabel.CENTER);
                        choiceLabel[i].setVerticalAlignment(JLabel.CENTER);
                        choiceLabel[i].setOpaque(true);
                        choiceLabel[i].setBackground(Color.RED);
                        frame.add(choiceLabel[i]);
                    }
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    }
    

    Or, if you're really stuck on GridBagLayout...

    import java.awt.Color;
    import java.awt.EventQueue;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import static tictactoe.TicTacToe.choiceLabel;
    
    public class LayoutTicTacToe {
    
        public static void main(String[] args) {
            new LayoutTicTacToe();
        }
    
        public LayoutTicTacToe() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new GridBagLayout());
    
                    choiceLabel[0] = new JLabel("_");
                    choiceLabel[1] = new JLabel("_");
                    choiceLabel[2] = new JLabel("_");
                    choiceLabel[3] = new JLabel("_");
                    choiceLabel[4] = new JLabel("_");
                    choiceLabel[5] = new JLabel("_");
                    choiceLabel[6] = new JLabel("_");
                    choiceLabel[7] = new JLabel("_");
                    choiceLabel[8] = new JLabel("_");
    
                    GridBagConstraints gbc = new GridBagConstraints();
                    gbc.insets = new Insets(10, 10, 10, 10);
                    int col = 0;
                    int row = 0;
                    for (int i = 0; i < 9; i++) {
                        gbc.gridx = col;
                        gbc.gridy = row;
                        choiceLabel[i].setText("_");
                        choiceLabel[i].setHorizontalAlignment(JLabel.CENTER);
                        choiceLabel[i].setVerticalAlignment(JLabel.CENTER);
                        choiceLabel[i].setOpaque(true);
                        choiceLabel[i].setBackground(Color.RED);
                        frame.add(choiceLabel[i], gbc);
                        col++;
                        if (col > 2) {
                            col = 0;
                            row++;
                        }
                    }
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    }
    

    Update with feedback

    Just some friendly feedback...

    • There's really no point extending JFrame, you're not adding anything significant to its functionality. Better to use JPanel and then add that to an instance of JFrame. If nothing else, you now have the option to add it to any other container you like.
    • For the most part, there's no need to use JFrame#getContentPane (unless you're using Java 1.4 or lower), as setLayout and add (amongst a whole bunch of others) are mapped to use getContentPane directly.
    • If you want to center the frame in the middle of the screen, use setLocationRelativeTo(null). It's simpler to use. Try and avoid the use of setBounds if you can.
    • You should be ensuring that your UI is launched with the context of the Event Dispatching Thread. Take a look at Initial Threads for further details