Java Swing – JPanel and GridLayout Margins/Padding

bordergrid layoutjavamarginswing

I'm working on building a chess game in Java, and I'm currently having a bit of trouble getting the GUI exactly the way I want it with Swing. I'm using a GridLayout to organize a grid of 8×8 ChessButtons (which override the JButton so that I can store extra information inside of them such as coordinates). Originally, the ChessButtons wouldn't appear unless I moused over them, but I solved that problem by placing each ChessButton inside a separate JPanel and setting each button's setPreferredSize() to a set height and width.

Now, my problem is that there seems to be a small margin or padding above (and/or below?) each button. I've made sure to set setHgap(0) and setVgap(0) for the GridLayout, so I'm pretty sure the mysterious margin is coming from either the buttons or the JPanels. But, I can't seem to get rid of them, and they seem to be causing each ChessButton to shift a little bit up/down whenever I mouse of them.

I realize this description of the problem might be a little hard to visualize, so I've taken a screenshot (using JButtons rather than ChessButtons so the gaps are slightly easier to recognize): http://img3.imageshack.us/img3/6656/jbuttonmargins.png

Here is the code I used to initialize each ChessButton:

    chessBoard = new JPanel(new GridLayout(8, 8, 0, 0));
    chessBoard.setBorder(BorderFactory.createEmptyBorder());

    for (int i = 0; i <= 65; i++) {
            //Create a new ChessButton
            ChessButton button = new ChessButton("hi");
            button.setBorder(BorderFactory.createEmptyBorder());
            button.setPreferredSize(new Dimension(75, 75));
            button.setMargin(new Insets(0, 0, 0, 0));

            //Create a new JPanel that the ChessButton will go into
            JPanel buttonPanel = new JPanel();
            buttonPanel.setPreferredSize(new Dimension(75, 75));
            buttonPanel.setBorder(BorderFactory.createEmptyBorder());
            buttonPanel.add(button);

            //Add the buttonPanel to the grid
            chessBoard.add(buttonPanel);
    }

So, how can I get rid of these vertical spaces between buttons? I'm relatively new to Swing, so I'm sorry if the answer is extremely obvious, but I'd appreciate any help anyone might have to offer! Thanks in advance!

Best Answer

Don't add an empty border; do use setBorderPainted(false).

Addendum: As @camickr notes, the panel's layout may include default gaps. The example below uses no-gap GridLayout accordingly.

alt text

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

/** @see http://stackoverflow.com/questions/4331699 */
public class ButtonBorder extends JPanel {

    private static final int N = 8;
    private static final int SIZE = 75;

    public ButtonBorder() {
        super(new GridLayout(N, N));
        this.setPreferredSize(new Dimension(N * SIZE, N * SIZE));
        for (int i = 0; i < N * N; i++) {
            this.add(new ChessButton(i));
        }
    }

    private static class ChessButton extends JButton {

        public ChessButton(int i) {
            super(i / N + "," + i % N);
            this.setOpaque(true);
            this.setBorderPainted(false);
            if ((i / N + i % N) % 2 == 1) {
                this.setBackground(Color.gray);
            }
        }
    }

    private void display() {
        JFrame f = new JFrame("ButtonBorder");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ButtonBorder().display();
            }
        });
    }
}