删除GridBagLayout中按钮周围的空间

时间:2015-09-12 16:12:50

标签: java swing jbutton layout-manager gridbaglayout

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

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

enter image description here

注意红色水平线。这是面板显示的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);
    }
}

1 个答案:

答案 0 :(得分:6)

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

在标签高度为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);