Java Swing - JPanel和GridLayout的边距/内边距

3
我正在使用Java构建一个象棋游戏,目前在使用Swing组件时遇到了一些问题。我使用GridLayout布局管理器将8x8个ChessButton(重写了JButton以存储额外的信息,如坐标)组织成网格。最初,ChessButton按钮只有当鼠标悬停在其上方时才会出现,但我通过将每个ChessButton放置在单独的JPanel中,并将每个按钮的setPreferredSize()设置为固定的高度和宽度来解决了这个问题。
现在,我的问题是似乎每个按钮上方(和/或下方?)都有一小段空白区域。我已经确保为GridLayout设置setHgap(0)setVgap(0),因此我相信神秘的边距来自于按钮或JPanel之一。但是,我无法摆脱它们,而且当我将鼠标移动到它们上面时,它们似乎会使每个ChessButton向上/向下移动一点。
我意识到这个问题的描述可能有点难以想象,因此我已经拍了一张屏幕截图(使用JButton而不是ChessButton,因此间隙稍微容易识别):http://img3.imageshack.us/img3/6656/jbuttonmargins.png 这是我用来初始化每个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);
    }

那么,我该如何消除这些按钮之间的垂直空间呢?我对Swing相对较新,如果答案非常明显,我很抱歉,但我会感激任何人提供的帮助!提前谢谢!
3个回答

16

不要添加空边框;请使用setBorderPainted(false)

补充说明:如@camickr所述,面板的布局可能包含默认间隙。以下示例因此使用无间隙的GridLayout

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 https://dev59.com/iFLTa4cB1Zd3GeqPZlUI */
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();
            }
        });
    }
}

3
起初,ChessButtons 没有出现,除非我将鼠标悬停在它们上面,但我通过将每个 ChessButton 放置在单独的 JPanel 中,并将每个按钮的 setPreferredSize() 设置为一定的高度和宽度来解决了这个问题。
那不是正确的解决方案。没有理由使用 JPanel 来容纳按钮。事实上,这可能是问题的原因。当您将它们添加到 GridLayout 中时,按钮应该显示出来。如果它们没有显示出来,那么很可能是因为您在使 GUI 可见之后才将按钮添加到 GUI 中。组件应该在 GUI 可见之前添加到 GUI 中。
现在,我的问题是每个按钮上方(和/或下方?)似乎有一个小的边距或填充。
我不明白为什么也没有水平间隙。当您创建一个 JPanel 时,默认情况下它使用 FlowLayout,其中还包含 5 像素的水平/垂直间隙。因此,我理解为什么您可能有 10 像素的垂直间隙。我不明白为什么没有水平间隙。
如果您需要更多帮助,请发布 SSCCE以展示问题。SSCCE应该使用常规的JButtons。在开始使用自定义组件之前,应首先使用标准组件来使基本功能正常工作。这样您就可以知道问题是否与您的自定义代码有关。

这是一个很好的观点。为了避免问题,我的示例使用没有间隙的GridLayout - trashgod

1
尝试添加chessBoard.setPreferredSize(600,600),创建一个JPanel供棋盘使用,只有足够的空间来放置按钮(每个方向8个按钮*每个按钮在每个方向上的75大小)。

嗯,不幸的是似乎什么都没有改变。事实上,如果我调整窗口大小的垂直方向,这些边距/边框将保持不变,无论窗口多小。 - dwat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接