Java Swing - JPanel 和 GridLayout 边距/填充
Posted
技术标签:
【中文标题】Java Swing - JPanel 和 GridLayout 边距/填充【英文标题】:Java Swing - JPanel and GridLayout Margins/Padding 【发布时间】:2011-05-18 22:01:13 【问题描述】:我正在用 Java 构建一个国际象棋游戏,但我目前在使用 Swing 以完全按照我想要的方式获取 GUI 时遇到了一些麻烦。我使用GridLayout
来组织8x8 ChessButton
s 的网格(它覆盖JButton
,以便我可以在其中存储额外的信息,例如坐标)。最初,除非我将鼠标悬停在 ChessButton
s 上,否则它们不会出现,但我通过将每个 ChessButton
放置在单独的 JPanel
中并将每个按钮的 setPreferredSize()
设置为设定的高度和宽度来解决这个问题。
现在,我的问题是每个按钮上方(和/或下方?)似乎有一个小的边距或填充。我确保为GridLayout
设置了setHgap(0)
和setVgap(0)
,所以我很确定神秘的边距来自按钮或JPanel
s。但是,我似乎无法摆脱它们,它们似乎导致每个 ChessButton
每当我鼠标移动时都会向上/向下移动一点。
我意识到这个问题的描述可能有点难以形象化,所以我截取了一张截图(使用JButton
s 而不是ChessButton
s,因此差距更容易识别):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 比较陌生,所以如果答案非常明显,我很抱歉,但如果有人提供任何帮助,我将不胜感激!提前致谢!
【问题讨论】:
【参考方案1】:不要添加空边框;请使用setBorderPainted(false)
。
附录:正如@camickr 所说,面板的布局可能包含默认间隙。下面的示例相应地使用了无间隙GridLayout
。
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://***.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();
);
【讨论】:
【参考方案2】:最初,除非我将鼠标悬停在 ChessButtons 上,否则它们不会出现,但我通过将每个 ChessButton 放置在单独的 JPanel 中并将每个按钮的 setPreferredSize() 设置为设定的高度和宽度来解决了这个问题
这不是正确的解决方案。没有理由使用 JPanel 来按住按钮。事实上,这可能是问题的原因。当您将按钮添加到 GridLayout 时,它们应该会显示出来。如果它们没有显示,可能是因为您在使 GUI 可见后将按钮添加到了 GUI。组件应在 GUI 可见之前添加到它。
现在,我的问题是每个按钮上方(和/或下方?)似乎有一个小的边距或填充
我不明白为什么也没有水平间隙。创建 JPanel 时,默认情况下它使用 FlowLayout,其中还包含 5 个像素的水平/垂直间隙。所以我明白为什么你可能有 10 像素的垂直间隙。我不明白为什么没有水平间隙。
如果您需要更多帮助,请发布您的 SSCCE 来展示问题。 SSCCE 应该使用常规的 JButton。在开始使用自定义组件之前,先了解使用标准组件的基础知识。这样您就知道问题是否出在您的自定义代码上。
【讨论】:
这是一个很好的观点。为了避免这个问题,我的例子使用了GridLayout
,没有空格。【参考方案3】:
尝试添加 chessBoard.setPreferredSize(600, 600) 为棋盘创建一个 JPanel,该棋盘只有放置按钮的空间(每个方向 8 个按钮 * 按钮上每个方向 75 大小)。
【讨论】:
嗯,不幸的是,这似乎并没有改变任何东西。事实上,如果我垂直调整窗口大小,无论窗口多小,这些边距/边框都会保留。以上是关于Java Swing - JPanel 和 GridLayout 边距/填充的主要内容,如果未能解决你的问题,请参考以下文章
java swing编程问题:一个jframe中添加一个jpanel后,为jpanel添加一个滚动条,当jpanel中内容过多时滑动
如何从另一个子 JPanel(Java Swing)中的输入触发一个子 JPanel 中的操作?