这就是我所知道的.我有两个JPanels,每个都有GridBagLayout.它们的权重x=0.5,并填充两个方向.因此,基本上该窗口是一个JPanel的一半,另一个的一半.而且它应该保持这种状态.但是,如果我将JButton放入其中之一,则JPanel会变宽,并占用第二个JPanel的一些空间.

我应该做些什么来防止这种行为?有没有其他布局可以像我描述的那样工作?

这是我一直在测试的代码.

JFrame f = new JFrame();
        f.setLayout(new BorderLayout());
        f.setTitle("Start Window");
        f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
        f.setSize(400,300);
        f.setResizable(true);

        JPanel top = new JPanel();
        JPanel right = new JPanel();
        JPanel bottom = new JPanel();
        JPanel left = new JPanel();

        top.setPreferredSize(new Dimension(30,30));
        right.setPreferredSize(new Dimension(30,30));
        bottom.setPreferredSize(new Dimension(30,30));
        left.setPreferredSize(new Dimension(30,30));

        f.add(top,BorderLayout.NORTH);
        f.add(right,BorderLayout.EAST);
        f.add(bottom,BorderLayout.SOUTH);
        f.add(left,BorderLayout.WEST);

        JPanel centerContainer = new JPanel(new GridBagLayout());
        GridBagConstraints centerLayout = new GridBagConstraints();
        centerContainer.setBackground(Color.blue);
        f.add(centerContainer);

        JPanel centerLeft = new JPanel(new GridBagLayout());
        GridBagConstraints centerLeftLayout = new GridBagConstraints();
        centerLayout.gridx=0;
        centerLayout.gridy=0;
        centerLayout.weightx=0.5;
        centerLayout.weighty=1;
        centerLayout.fill = GridBagConstraints.BOTH;
        centerLeft.setBackground(Color.red);
        centerContainer.add(centerLeft,centerLayout);

        JPanel centerRight = new JPanel();
        centerLayout.gridx=1;
        centerLayout.gridy=0;
        centerLayout.weightx=0.5;
        centerLayout.weighty=1;
        centerLayout.fill = GridBagConstraints.BOTH;
        centerRight.setBackground(Color.green);
        centerContainer.add(centerRight,centerLayout);

        JPanel leftElement = new JPanel(new GridBagLayout());
        GridBagConstraints leftElementLayout = new GridBagConstraints();

        centerLeftLayout.gridx=0;
        centerLeftLayout.gridy=0;
        centerLeftLayout.weightx=1;
        centerLeftLayout.weighty=1;
        centerLeftLayout.fill = GridBagConstraints.HORIZONTAL;

        centerLeft.add(leftElement,centerLeftLayout);

        JButton leftBtn = new JButton("CLIIIIICK!!!");
        leftBtn.setLayout(new GridBagLayout());
        leftElementLayout.gridx=0;
        leftElementLayout.gridy=0;
        leftElementLayout.weighty=0;
        leftElementLayout.weightx=1;
        leftElementLayout.fill=GridBagConstraints.HORIZONTAL;


        leftElement.add(leftBtn,leftElementLayout);


        f.setVisible(true);

推荐答案

解决方案:当需要时,您应该使用更简单的布局.在这里,最好将中心的JPanels保存在1行2列的GridLayout中,因为这将确保它们将面板准确地一分为二.如果您想要将按钮放在面板中间,您仍然可以在左侧面板中使用GridBagLayout.

附注:

  • 没有必要(或意义)为JButton提供布局管理器,除非您要向其添加组件,这在某种程度上是不寻常的,但我见过这样的事情,尽管很少.
  • 如果您希望组件周围的边框为30像素,则使用空边框:
int ebGap = 30;
setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));

例如:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.*;

@SuppressWarnings("serial")
public class SwingFoo02 extends JPanel {
    
    private static final int PREF_W = 400;
    private static final int PREF_H = 300;
    
    public SwingFoo02() {
        int ebGap = 30;
        setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
        
        JPanel centerLeft = new JPanel(new GridBagLayout());
        JPanel centerRight = new JPanel();
        
        centerLeft.setBackground(Color.RED);
        centerRight.setBackground(Color.GREEN);        

        JButton leftBtn = new JButton("CLIIIIICK!!!");
        GridBagConstraints gbc = new GridBagConstraints();        
        gbc.anchor = GridBagConstraints.CENTER;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.weightx = 1.0;
        gbc.weighty = 0.0;
        gbc.gridx = 0;
        gbc.gridy = 0;
        centerLeft.add(leftBtn, gbc);
        
        setLayout(new GridLayout(1, 2));
        add(centerLeft);
        add(centerRight);

    }
    

    @Override
    public Dimension getPreferredSize() {
        Dimension supSize = super.getPreferredSize();
        int w = Math.max(supSize.width, PREF_W);
        int h = Math.max(supSize.height, PREF_H);
        return new Dimension(w, h);
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            SwingFoo02 mainPanel = new SwingFoo02();

            JFrame frame = new JFrame("GUI");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(mainPanel);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }

}

Java相关问答推荐

当我用OkHttpClient重写shouldInterceptRequest来发布数据时,Android WebView正在以纯HTML加载URL内容

我的scala文件失败了Scala.g4 ANTLR语法

如何在访问完所有文件后加入所有线程?

在JavaFX项目中注册组合框的控件FX验证器时,模块系统出错

在运行MVN测试时,为什么构建失败,并显示了java.lang.ClassNotFoundException:java.net.http.HttpResponse?

Hibernate EmptyInterceptor可以工作,但不能拦截器

把一条整型短裤和两条短裤装成一条长的

有没有更快的方法在N个容器中删除重复项?

用户填充的数组列表永不结束循环

如何在Microronaut中将 map 读取为 map

使用Jolt将字段转换为列表

在Java中将int[]矩阵添加到ArrayList中,但出现错误

有没有可能在时间范围内得到多种解决方案?

在settings.gradle.kts和Build.gradle.kts中使用公共变量

从LineChart<;字符串、字符串和gt;中删除数据时出现特殊的ClassCastException;

如何在Java springboot中从一个端点发送多个时间响应?

S数学.exp的相同错误保证也适用于StrictMath.exp吗?

协同 routine 似乎并不比JVM线程占用更少的资源

使用@ExceptionHandler的GlobalExceptionHandler还是来自服务器的REST应答的ResponseEntity?

如何在特定关键字后提取与模式匹配的多个值?