删除GridBagLayout中按钮周围的空间

我写了这个令人头疼的来源,以展示另一个问题中提到的游戏画面的布局。 它将按钮(或标签,可在启动时选择)放入GridBagLayout

如果您在提示时(在GUI出现之前)选择不使用按钮,则整个GUI非常紧凑且没有间隙。 但是如果你选择使用按钮(如果你的设置就像我的那样)看起来像这样……

在此处输入图像描述

注意红色水平线。 这是面板显示的BG颜色。 当GUI使用标签时,不会看到这些行。 稍微拉伸GUI以查看它甚至没有在每行之后放置一条红线(有九行) – 尽管每行使用按钮(相同的组件)。

如何在使用按钮时删除额外的垂直空间?

我认为它必须是我在配置按钮或行权重时忘记做的事情,但我无法弄清楚是什么!

 import java.awt.*; import java.awt.image.BufferedImage; import javax.swing.*; import java.net.URL; import javax.imageio.ImageIO; public class SoccerField { private JPanel ui = null; int[] x = {0, 35, 70, 107, 142, 177, 212, 247, 282, 315}; int[] y = {0, 45, 85, 140, 180, 225, 265, 280, 320, 345}; boolean buttons; SoccerField() { initUI(); } public void initUI() { int result = JOptionPane.showConfirmDialog(ui, "Use buttons?"); buttons = result == JOptionPane.OK_OPTION; if (ui != null) { return; } ui = new JPanel(new GridBagLayout()); ui.setBackground(Color.RED); try { URL url = new URL("http://i.stack.imgur.com/9E5ky.jpg"); BufferedImage img = ImageIO.read(url); BufferedImage field = img.getSubimage(100, 350, 315, 345); BufferedImage[] bi = subSampleImageColumns(field); BufferedImage[][] fieldParts = new BufferedImage[bi.length][]; for (int ii=0; ii<bi.length; ii++) { fieldParts[ii] = subSampleImageRows(bi[ii]); } for (int ii=0; ii<fieldParts[0].length; ii++) { for (int jj=0; jj<fieldParts.length; jj++) { addImageToPanel(ui, fieldParts[ii][jj], ii, jj); } } } catch (Exception ex) { ex.printStackTrace(); } } private void addImageToPanel(JPanel panel, BufferedImage img, int row, int col) { Insets insets = new Insets(0,0,0,0); GridBagConstraints gbc = new GridBagConstraints( row, col, 1, 1, .5, .5, GridBagConstraints.CENTER, GridBagConstraints.BOTH, insets, 0, 0); ImageIcon ii = new ImageIcon(img); JButton b = new JButton(ii); b.setBorder(null); b.setBorderPainted(false); b.setContentAreaFilled(false); Component c = buttons ? b : new JLabel(ii); panel.add(c, gbc); } private BufferedImage[] subSampleImageColumns(BufferedImage img) { System.out.println("Image Size: " + img.getWidth() + "," + img.getHeight()); BufferedImage[] imageRows = new BufferedImage[x.length - 1]; for (int ii = 0; ii < x.length - 1; ii++) { BufferedImage bi = img.getSubimage( x[ii], 0, x[ii + 1] - x[ii], img.getHeight()); imageRows[ii] = bi; } return imageRows; } private BufferedImage[] subSampleImageRows(BufferedImage img) { BufferedImage[] imageRows = new BufferedImage[y.length - 1]; for (int ii = 0; ii < y.length - 1; ii++) { BufferedImage bi = img.getSubimage( 0, y[ii], img.getWidth(), y[ii + 1] - y[ii]); imageRows[ii] = bi; } return imageRows; } public JComponent getUI() { return ui; } public static void main(String[] args) { Runnable r = new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception useDefault) { } SoccerField o = new SoccerField(); JFrame f = new JFrame(o.getClass().getSimpleName()); f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); f.setLocationByPlatform(true); f.setContentPane(o.getUI()); f.pack(); //f.setMinimumSize(f.getSize()); f.setVisible(true); } }; SwingUtilities.invokeLater(r); } } 

注意到按钮的首选高度似乎没有正确计算按钮(在某些情况下)。

在标签高度为40的情况下,按钮的高度为41。

它就像按钮一直会调整为奇数?

我更改了代码:

 //int[] y = {0, 45, 85, 140, 180, 225, 265, 280, 320, 345}; int[] y = {0, 45, 86, 139, 180, 225, 266, 279, 320, 345}; 

它似乎工作。

啊,刚刚找到原因。 你还需要:

 b.setFocusPainted(false);