Search code examples
javaswinglayout-managergrid-layoutgridbaglayout

Spaces between elements in GridLayout and GridBagLayout


I am trying to create a grid of text fields which I envision would look like this:

enter image description here

I am trying to use Swing in order to do this but am having trouble creating the grid. I have tried both GridBagLayout and GridLayout in order to accomplish this but have had the same issue with both - I am unable to remove spaces between the text fields.

enter image description here

The above image is using grid bag layout. I have tried to change the insets as well as the weights of each text field but have not been able to get rid of the spaces between the fields.

The grid layout is slightly better:

enter image description here

But it has the same problem. I tried adding each text field to a JPanel and then created an empty border for each panel but this also did not work.

I have attached the code for both implementations. I am not committed to using a JTextField so if there is some other element that a user can type into I would be willing to try that out as well. Any help getting rid of the spaces between each text field would be greatly appreciated!

GridBagLayoutDemo

class GridBagLayoutDemo {

public static void addComponentsToPane(Container pane) {
    
    GridBagLayout gbl = new GridBagLayout();
    pane.setLayout(gbl);
    GridBagConstraints c = new GridBagConstraints();

    int rows = 2;
    int cols = 2;
    for(int i  = 0; i < (rows + 1) * 3; i++){
        JTextField textField = new JTextField(1);
        textField.setFont( new Font("Serif", Font.PLAIN, 30) );
        JPanel tempPanel = new JPanel();
        tempPanel.setBorder(BorderFactory.createEmptyBorder(0,0,0,0)); 

        tempPanel.add(textField);

        c.gridx = i % (rows + 1);
        c.gridy = i / (cols + 1);
        c.gridheight = 1;
        c.gridwidth = 1;

        c.anchor = GridBagConstraints.FIRST_LINE_START;
        c.fill = GridBagConstraints.HORIZONTAL; 
        pane.add(tempPanel, c);
    }
    gbl.setConstraints(pane, c);
    c.insets = new Insets(0,0,0,0);
}

public void createAndShowGUI() {
    //Create and set up the window.
    JFrame frame = new JFrame("GridBagLayoutDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    //Set up the content pane.
    addComponentsToPane(frame.getContentPane());

    //Display the window.
    frame.pack();
    frame.setVisible(true);
}

public static void main(String[] args) {
    GridBagLayoutDemo demo = new GridBagLayoutDemo();
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            demo.createAndShowGUI();
        }
    });   
}
}

GridLayoutDemo

class GridLayoutDemo {

public void createAndShowGUI() {

    JFrame frame = new JFrame("GridLayout");
    //frame.setOpacity(0L);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


    JPanel parentPanel = new JPanel();
    GridLayout layout = new GridLayout(3, 3, 0, 0);
    layout.setHgap(0);
    layout.setVgap(0);
    parentPanel.setLayout(layout);
    for(int i = 0 ; i < 9; i++){
        JTextField textField = new JTextField();
        textField.setHorizontalAlignment(JTextField.CENTER);
       // JPanel tempPanel = new JPanel();
        //textField.setBounds(0, 0, 10   , 10);
        //textField.setFont( new Font("Serif", Font.PLAIN, 18));
        //tempPanel.setBorder(BorderFactory.createEmptyBorder(0,0,0,0)); 
        //tempPanel.add(textField);
       // tempPanel.add(textField);
        parentPanel.add(textField);
    }

    frame.add(parentPanel);
    frame.pack();
    frame.setVisible(true);
}

public static void main(String[] args) {
    GridLayoutDemo demo = new GridLayoutDemo();
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            demo.createAndShowGUI();
        }
    });
}
}

Solution

  • I think you will find that this is a issue with the MacOS look and feel, as it adds a empty border around the text fields to allow for the focus highlight

    You can see it highlighted below

    Focus Rect

    The simplest way to remove it, is to remove or replace the border, for example...

    Custom Border

    import java.awt.EventQueue;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    
    public class Main {
    
        public static void main(String[] args) {
            new Main();
        }
    
        public Main() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    JFrame frame = new JFrame();
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            public TestPane() {
                setLayout(new GridBagLayout());
    
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.fill = GridBagConstraints.BOTH;
                gbc.weightx = 1;
                gbc.weighty = 1;
    
                int rows = 3;
                int cols = 3;
    
                for (int index = 0; index < (rows * cols); index++) {
                    int row = index % rows;
                    int col = index / cols;
    
                    gbc.gridy = row;
                    gbc.gridx = col;
    
                    JTextField textField = new JTextField(4);
                    textField.setText(col + "x" + row);
                    textField.setBorder(new LineBorder(Color.DARK_GRAY));
    
                    add(textField, gbc);
                }
            }
        }
    }