Java Swing GridBagLayout - 不留间隔添加按钮

3

我该如何消除由gridBagLayout引起的间距,使它们紧贴在一起?
这是我简单添加3个按钮的代码。 我看过这个问题,但没有完整的解决方案How to fix gap in GridBagLayout
我只想把所有的按钮放在JFrame的顶部。

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MyProblem {

    private JFrame frame = new JFrame();

    public static void main(String[] args) {
        new MyProblem();
    }

    public MyProblem() {
        frame.setLayout(new GridBagLayout());
        GridBagConstraints gc = new GridBagConstraints();
        gc.weightx = 1;
        gc.weighty = 1;
        gc.gridx = 0;
        gc.gridy = 0;
        gc.fill = GridBagConstraints.HORIZONTAL;
        gc.anchor = GridBagConstraints.NORTH;
        for (int i = 0; i < 3; i++) {
            JPanel jPanel = new JPanel(new BorderLayout());
            jPanel.setSize(80, 80);
            jPanel.add(new JButton("Button " + i),BorderLayout.PAGE_START);
            frame.add(jPanel, gc);
            gc.gridy++;
        }

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500, 500);
        frame.setVisible(true);
    }

}

我的按钮长这样:
enter image description here
我希望我的按钮看起来像这样: enter image description here


感谢Borr先生的修订 :)。 - Iman
请参考这个问题获取有关JLabel的信息,以及这个问题获取有关JButton的信息。 - goncalotomas
谢谢,但是在这个问题中他/她想要添加空格,而我想要删除空格。第二个方法也没有起作用。 - Iman
请检查第二个链接。我相信您可以向边距值提供负值。 - goncalotomas
为了更快地获得帮助,请发布一个MCVE(Minimal Complete Verifiable Example,最小完整可验证示例)或SSCCE(Short,Self Contained,Correct Example,简短,自包含,正确的示例)。 - Andrew Thompson
我将它设为负数,按钮的一些内容消失了。 - Iman
3个回答

4
布局使得按钮只在单列中显示,因此需要改变:
        gc.fill = GridBagConstraints.HORIZONTAL;

致:

        gc.fill = GridBagConstraints.BOTH;

编辑 1

我希望将按钮保持与图片中描述的高度相同,并将它们放置在顶部。

使用组合布局将它们限制在顶部相当容易。在这种情况下,我们可以将带有按钮的面板添加到具有 BorderLayout 的面板的 PAGE_START 中。该边框布局的一部分将拉伸子组件(我们的带有 GridLayout 的面板)的宽度以填充可用空间,但它将尊重其中的任何内容的高度 - 只给予组件所需的垂直空间。

编辑 2

这是一个实现上述想法的 MCVE。外部面板(带有青色边框)用于限制按钮面板(带有橙色边框)的高度。有关其工作原理的更多详细信息,请参见源代码中的注释。

enter image description here enter image description here enter image description here

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

public class MyProblem {

    private JFrame frame = new JFrame();

    public static void main(String[] args) {
        new MyProblem();
    }

    public MyProblem() {
        frame.setLayout(new BorderLayout()); // actually the default

        // we will use this panel to constrain the panel with buttons
        JPanel ui = new JPanel(new BorderLayout());
        frame.add(ui);
        ui.setBorder(new LineBorder(Color.CYAN, 3));

        // the panel (with GridLayout) for the buttons
        JPanel toolPanel = new JPanel(new GridLayout(0,1,0,4)); // added some gap
        toolPanel.setBorder(new LineBorder(Color.ORANGE, 3));
        // toolPanel will appear at the top of the ui panel
        ui.add(toolPanel, BorderLayout.PAGE_START); 
        for (int i = 0; i < 3; i++) {
            toolPanel.add(new JButton("Button " + i));
        }

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //frame.setSize(500, 500); // instead..
        frame.pack(); // pack will make it as small as it can be.
        frame.setMinimumSize(frame.getSize()); // nice tweak..
        frame.setVisible(true);
    }
}

我真的不明白我的两个面板是什么以及它们的布局管理器是什么。 - Iman
面板1使用GridBagLayout或(更简单的)GridLayout来将按钮放在单列中。面板2在PAGE_START中有一个单一组件(面板1)。 - Andrew Thompson
你能把你的代码放进来吗? 我没有成功。我更新了我的问题,说明了我想让它们看起来像什么。 - Iman
在你展示出最佳尝试的MCVE之后(正如我23小时前建议你发布的那样),我会考虑添加我的代码。 - Andrew Thompson
我在使用边框布局的JPanel中添加了按钮,但仍然无法正常工作。 - Iman
显示剩余3条评论

3
这段代码可以完成任务:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;

public class MyProblem {

    private JFrame frame = new JFrame();

    public static void main(String[] args) {
        new MyProblem();
    }

    public MyProblem() {
        frame.setLayout(new GridBagLayout());
        GridBagConstraints gc = new GridBagConstraints();
        gc.weightx = 1;
        gc.weighty = 0;
        gc.gridx = 0;
        gc.gridy = 0;
        gc.ipadx = 0;
        gc.ipady = 0;
        gc.fill = GridBagConstraints.HORIZONTAL;
        gc.anchor = GridBagConstraints.NORTH;
        for (int i = 0; i < 3; i++) {
            JButton button = new JButton("Button " + i);
            frame.add(button, gc);
            gc.gridy++;
        }
        gc.weighty = 1;
        frame.add(Box.createGlue(), gc); //Adding a component to feel the area.
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500, 500);
        frame.setVisible(true);
    }

}

Box.createGlue() ... <head-desk/> 我有一种模糊的感觉,好像我忘记了关于GBL的某些重要事情,而那就是它。为最佳解决方案加一分(并且在没有我的帮助下发现它!)。很高兴你解决了它。 :) - Andrew Thompson
2
非常感谢,您的解决方案也非常有趣。;-) - Iman
1
什么?为什么你的答案比我更好,却把采纳标记给了我?!你不能立即接受自己的答案(记忆中是2天),但当你这样做时,你会获得一个闪亮的新徽章(类似于“自学成才”)。 - Andrew Thompson

0
运行这段代码,我认为它会对你有所帮助。
import java.awt.*;
import javax.swing.JButton;
import javax.swing.JFrame;

public class Think {

public static void addComponentsToPane(Container pane) {

    JButton jbnButton;
    pane.setLayout(new GridBagLayout());
    GridBagConstraints gBC = new GridBagConstraints();
    gBC.fill = GridBagConstraints.HORIZONTAL;

    jbnButton = new JButton("Button 1");
    gBC.weightx = 0.5;
    gBC.gridx = 0;
    gBC.gridy = 0;
    pane.add(jbnButton, gBC);

    jbnButton = new JButton("Button 3");
    gBC.gridx = 2;
    gBC.gridy = 0;
    pane.add(jbnButton, gBC);

    jbnButton = new JButton("Button 4");
    gBC.ipady = 40;     //This component has more breadth compared to other buttons
    gBC.weightx = 0.0;
    gBC.gridwidth = 3;
    gBC.gridx = 0;
    gBC.gridy = 1;
    pane.add(jbnButton, gBC);

}

private static void createAndShowGUI() {

    JFrame.setDefaultLookAndFeelDecorated(true);
    JFrame frame = new JFrame("GridBagLayout Source Demo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    //Set up the content pane.
    addComponentsToPane(frame.getContentPane());

    frame.pack();
    frame.setVisible(true);
}

public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
        }
    });
 }
}

这不是我想要的。 - Iman

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