边框布局与网格布局冲突

Posted

技术标签:

【中文标题】边框布局与网格布局冲突【英文标题】:Border Layout Conflicting with Grid Layout 【发布时间】:2016-04-16 11:21:26 【问题描述】:

我有 3 个JPanel 组件。面板 1 设置为 BorderLayout.NORTH,面板 2 设置为 BorderLayout.CENTER,面板 3 设置为 BorderLayout.SOUTH

现在面板 1 有 GridLayout(1,2),面板 2 也有 GridLayout(1,2)。 困扰我的是面板 1 和 2 中的组件对齐,就好像它们在 GridLayout 组合中一样。

具体来说,我在面板 1 中有一组 JTextField 组件,位于 row=0 和 column=1 的位置。

我在JScrollPane 内有一个JTable,位于面板 2 中的 row=0 和 column=1 位置。

无论我尝试什么,这两个组件都以相同的尺寸呈现。

代码太长,无法在此处发布,如果有人能阐明如何从概念上解决此问题,我将不胜感激。

public class PanelTest extends JFrame
    public static void main (String args[]) 
        new PanelTest();
    
    public PanelTest() 
        this.setPreferredSize(new Dimension(800,200));
        JPanel panel1 = new JPanel();
        panel1.setLayout(new GridLayout(1,2));
        JPanel panel2 = new JPanel();
        panel2.setLayout(new GridLayout(1,2));

        JTextField textField1 = new JTextField();
        textField1.setPreferredSize(new Dimension(500, 100));
        JTextField textField2 = new JTextField();
        textField2.setPreferredSize(new Dimension(300, 100));
        panel1.setMinimumSize(new Dimension(800, 100));

        panel1.add(textField1);
        panel1.add(textField2);

        JTable table = new JTable();
        //... 
        JScrollPane jps1 = new JScrollPane(table);
        jps1.setPreferredSize(new Dimension(200, 300));
        JTextField textField3 = new JTextField(10); 
        JScrollPane jps2 = new JScrollPane(textField3);

        panel2.add(jps1);
        panel2.add(jps2);
        setLayout(new BorderLayout());
        add(panel1, BorderLayout.NORTH);
        add(panel2, BorderLayout.SOUTH);
        this.setVisible(true);
        this.pack();
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    

使用 GridBagLayout:

  public PanelTest() 
    this.setPreferredSize(new Dimension(800,200));
    this.setMinimumSize(new Dimension(800,200));
   JPanel panel1 = new JPanel();
    panel1.setLayout(new GridBagLayout());
    JPanel panel2 = new JPanel();
    panel2.setLayout(new GridBagLayout());

    JTextField textField1 = new JTextField();
    textField1.setPreferredSize(new Dimension(500, 100));
    JTextField textField2 = new JTextField();
    textField2.setPreferredSize(new Dimension(300, 100));
    panel1.setMinimumSize(new Dimension(800, 100));

    GridBagConstraints gbc = new GridBagConstraints();
    //      gbc.insets = new Insets(5,100,5,1);
    gbc.gridx=0;
    gbc.gridy=0;
    panel1.add(textField1, gbc);
    gbc.gridx=1;
    panel1.add(textField2, gbc);

    JTable table = new JTable();
    //... 
    JScrollPane jps1 = new JScrollPane(table);
    jps1.setPreferredSize(new Dimension(600, 300));
    jps1.setMinimumSize(new Dimension(600, 300));
    JTextField textField3 = new JTextField(); 

    gbc = new GridBagConstraints();
    //      gbc.insets = new Insets(5,100,5,1);
    gbc.gridx=0;
    gbc.gridy=0;
    panel2.add(jps1, gbc);
    gbc.gridx=1;
    panel2.add(textField3, gbc);
    setLayout(new BorderLayout());
    add(panel1, BorderLayout.NORTH);
    add(panel2, BorderLayout.SOUTH);
    this.setVisible(true);
    this.setVisible(true);
    this.pack();
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

【问题讨论】:

考虑提供一个 runnable example 来证明您的问题。 这不是代码转储,而是你正在做的一个例子,它突出了你遇到的问题。这将导致更少的混乱和更好的响应 很难想象你想得到什么样的布局,而且重现你当前的代码来分析问题。所以需要可运行的例子。 1) 为了尽快获得更好的帮助,请发帖 minimal reproducible example 或 Short, Self Contained, Correct Example。 2) 以最小尺寸提供 ASCII 艺术或 GUI 的 预期 布局的简单绘图,如果可调整大小,则具有更大的宽度和高度。 我已经编辑了上面的问题并添加了一些代码。谢谢 【参考方案1】:

困扰我的是面板 1 和 2 中的组件对齐,就好像它们在 GridLayout 组合中一样。

来自Java docs:

GridLayout simply makes a bunch of components equal in size and displays them in the requested number of rows and columns.

“它将以相同的大小显示它们”,因此,如果您有 2 列并且您的 JFrame 的大小为 900px,那么您将有 2 个 450px 的组件,如果您有 3 个,那么它将是 3 个组件每个 300 像素。

这就是为什么你应该avoid the use of setPreferred|maximum|minimum size methods 并让布局管理器为你选择尺寸,或者如果你真的需要固定尺寸,你应该改写@trashgod 在他的回答中所说的getPreferred|maximum|minimum 尺寸。

您可能想改用GridBagLayout 或不同的Layout Manager,例如FlowLayout 或BoxLayout 并将它们组合起来。

您也应该avoid extending JFrame,除非非常必要。

由于您没有发布 UI 的外观,我可以想象您想要这样的东西:

使用以下代码完成:

import java.awt.*;
import javax.swing.*;
public class LayoutManagerExample 
    JFrame frame;
    JPanel pane1, pane2, pane3;
    JTextField field1, field2, field3;
    JTable table;
    JScrollPane jsp;
    LayoutManagerExample() 
        frame = new JFrame("LayoutManagerExample");
        pane1 = new JPanel();
        pane2 = new JPanel();
        pane3 = new JPanel();
        field1 = new JTextField(10);
        field2 = new JTextField(10);
        field3 = new JTextField(20);
        table = new JTable();
        jsp = new JScrollPane(table);

        pane1.setLayout(new FlowLayout());
        pane2.setLayout(new GridLayout(1, 2));
        pane3.setLayout(new FlowLayout());

        pane1.add(field1);
        pane1.add(field2);
        pane2.add(jsp);
        pane2.add(field3);
        pane3.add(new JLabel("Something else"));

        frame.add(pane1, BorderLayout.NORTH);
        frame.add(pane2, BorderLayout.CENTER);
        frame.add(pane3, BorderLayout.SOUTH);

        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    

    public static void main (String args[]) 
        new LayoutManagerExample();
    

【讨论】:

使用 GridBagLayout 并没有缓解这个问题。即使使用插图,panel2 组件也会居中。代码发布在上面的问题中。谢谢 你没有像@AndrewThompson 在上面的评论中所说的那样发布它的样子 感谢 Frakcool 提供的图片。但我试图指定 table.setMaximumSize(new Dimension(600,300))。我从您的评论中了解到 GridLayout 无法做到这一点。这就是我使用 GridBagLayout 的原因。谢谢。 @user2654788 我很困惑,你的意思是什么?是的,GridLayout 不允许您设置自己的尺寸。 对不起,我的意思是 table.setMinimumSize(new Dimension(600,300)。基本上,我希望表格组件的宽度在其自己的面板中为 600,而不管上面面板中指定的 GridBagLayout。请检查我为上面的 GridBagLayout 发布的代码。谢谢

以上是关于边框布局与网格布局冲突的主要内容,如果未能解决你的问题,请参考以下文章

extjs 5 网格的滚动条在边框布局面板中不起作用

如何在使用网格布局并将重叠小部件定位到距窗口边框特定距离时重叠 qwidgets?

jQuery EasyUI:使数据网格在边框布局中可调整大小

安卓讲课笔记3.4 网格布局

在相对布局内对齐复选框

Recyclerview 网格布局管理器显示不必要的空间