有没有办法在 GridBagLayout 的开头放置具有不同空间的按钮?

Is there a way to place JButtons with different spaces in the begining at the GridBagLayout?

我正在尝试做这样的事情:

但是我不能在按钮前留空格。我尝试添加不可见按钮,但没有任何改变。

for (int i = 0; i < gameSize; i++ ){
        c.gridwidth = (i+1)*2;
        c.gridx = 0;
        c.gridy = 4*i;
        JRadioButton temp = new JRadioButton();
        temp.setVisible(false);
        board.add(temp,c);
        for(int j = 0; j < gameSize; j++){
            c.gridwidth = 4;
            c.gridx = 2+(4*j);
            c.gridy = 2+(4*i);
            cells[i][j] = new JButton();
            cells[i][j].setBackground(Color.white);
            board.add(cells[i][j],c); 
        }
    }

看起来像[这个:

当我让它们可见时。我不明白为什么它们的宽度仍然是 4,即使我将它分配给 (i+1)*2.

我是 Java 的新手,也是 Java GUI 的新手。所以,也许我没有弄清楚最基本的东西。谢谢指教!

我创建了以下 GUI。

为了做到这一点,我不得不结合使用 Swing 布局。

每一行的按钮都是在 JPanelGridLayout 中创建的。使用虚拟 JLabel 和按钮行 JPanel.

创建行 JPanelFlowLayout

主要 JPanel 使用 (0, 1) 的 GridLayout 来创建交错效果。每行中的虚拟 JLabel 变大 JButtons.

大小的一半

这是完整的可运行代码。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class GridBagLayoutStaggeredGUI implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new GridBagLayoutStaggeredGUI());
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Staggered Layout");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.add(createMainPanel(), BorderLayout.CENTER);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    private JPanel createMainPanel() {
        int gameSize = 8;
        int buttonSize = 50;
        int inset = 2;
        JButton[][] cells = new JButton[gameSize][gameSize];
        
        JPanel panel = new JPanel(new GridLayout(0, 1));
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        
        for (int i = 0; i < gameSize; i++) {
            JPanel innerPanel = new JPanel(
                    new FlowLayout(FlowLayout.LEADING, 0, 0));
            JLabel label = new JLabel();
            label.setPreferredSize(new Dimension(inset, buttonSize));
            innerPanel.add(label);
            innerPanel.add(createRowPanel(cells[i], buttonSize));   
            
            panel.add(innerPanel);
            
            inset += buttonSize / 2;
        }
        
        return panel;
    }
    
    private JPanel createRowPanel(JButton[] cells, int buttonSize) {
        JPanel panel = new JPanel(new GridLayout(0, cells.length, 0, 0));
        
        for (int i = 0; i < cells.length; i++) {
            cells[i] = new JButton();
            cells[i].setBackground(Color.white);
            cells[i].setPreferredSize(new Dimension(buttonSize, buttonSize));
            panel.add(cells[i]);
        }
        
        return panel;
    }

}

只有在“gridwidth”为1的列中添加了组件,GridBagLayout才能计算出列的宽度

在您的示例中,您有 6 个按钮,每个按钮的“网格宽度”为 2,这意味着您确实需要 12 列。但是每列的宽度应该是多少?

下面的示例显示了如何为每列分配最小宽度。现在,根据指定的值,12 列中的每一列都将具有最小宽度。

import java.awt.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;

public class GridBagLayoutMRE extends JPanel
{
    public GridBagLayoutMRE()
    {
        int gameSize = 6;
        int columnsNeeded = (gameSize * 3);
        int cellSize = 30;
        Dimension buttonSize = new Dimension(cellSize * 2, cellSize);

        GridBagLayout gbl = new GridBagLayout();
        setLayout( gbl );

        int[] columnWidths = new int[columnsNeeded];
        Arrays.fill(columnWidths, cellSize);
        gbl.columnWidths = columnWidths;

        GridBagConstraints gbc = new GridBagConstraints();

        for (int i = 0; i < gameSize; i++)
        {
            gbc.gridx = 0;
            gbc.gridy = i;
            gbc.gridwidth = 1;

            JRadioButton rb = new JRadioButton();
            rb.setPreferredSize( new Dimension(60, cellSize) );
            add(rb, gbc);

            gbc.gridx = i + 1;
            gbc.gridwidth = 2;

            for (int j = 0; j < gameSize; j++)
            {
                JButton button = new JButton();
                button.setPreferredSize( buttonSize );
                add(button, gbc);

                gbc.gridx = gbc.gridx + gbc.gridwidth;
            }
        }
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("GridBagLayoutMRE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout( new GridBagLayout() );
        frame.add(new GridBagLayoutMRE());
        frame.pack();
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args) throws Exception
    {
        java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
    }
}