Java中使用GridBagLayout时,面板未能正确地调整大小

3
我正在使用GridBagLayout来创建我的GUI,但是它在调整大小时存在问题。在任何人建议使用其他布局之前,我确定要使用GridBagLayout;因为我需要对大量组件进行布局,并确保它们被正确地排列。不过,当前的代码/图像只显示了我现在所拥有的。

无论如何,问题在于它不能正确地自适应大小。我希望它在调整大小时能够保持当前的纵横比,但实际上它并没有这样做。某些面板在调整大小时具有某种优先级,这使得当我调整大小时,它会破坏原本的纵横比。基本上,我有一些面板比另一个面板更大,但在调整大小后,它变得比另一个面板更小,就像这样:

http://i.imgur.com/LWhHm.png

现在,我真正想要的是让它们保持已经呈现的比例。如您所见,我希望 GUI 中的聊天部分比左侧面板中的任何一个都要小,就像它最初的样子一样。
以下是我目前用来生成这个的代码:
jpPack = new JPanel();
    jpCards = new JPanel();
    jpInfo = new JPanel();
    jpChat = new JPanel();


    jpPack.setBackground(Color.red);
    jpCards.setBackground(Color.blue);
    jpInfo.setBackground(Color.green);

    //create the Constraints and set some that will apply to each panel
    GridBagConstraints c = new GridBagConstraints();
    c.fill = GridBagConstraints.BOTH;

    //set the number of columns/rows to use
    c.gridwidth = 1;
    c.gridheight = 1;
    //set the x and y position
    c.gridx = 0;
    c.gridy = 0;
    //set the weight properties
    c.weightx = 1.0;
    c.weighty = 1.0;

    getContentPane().add(jpCards, c);

    //set the number of columns/rows to use
    c.gridwidth = 1;
    c.gridheight = 1;
    //set the x and y position
    c.gridx = 0;
    c.gridy = 1;
    //set the weight properties
    c.weightx = 1.0;
    c.weighty = 1.0;

    getContentPane().add(jpPack, c);

    //set the number of columns/rows to use
    c.gridwidth = 1;
    c.gridheight = 1;
    //set the x and y position
    c.gridx = 1;
    c.gridy = 0;
    //set the weight properties
    c.weightx = 0.2;
    c.weighty = 0.2;

    getContentPane().add(jpInfo, c);

    //set the number of columns/rows to use
    c.gridwidth = 1;
    c.gridheight = 1;
    //set the x and y position
    c.gridx = 1;
    c.gridy = 1;
    //set the weight properties
    c.weightx = 0.2;
    c.weighty = 0.2;

    getContentPane().add(jpChat, c);
    jpChat.setLayout(new GridLayout());
    jpChat.add(client.gui.getContentPane(), c);

    setVisible(true);

在此之际,我也想问另一个问题。 我想为GUI设置最小大小限制,以及对话面板的最小大小限制。 对于前者,我希望它不允许用户将其调整为小于某个特定的x和y。 对于后者,我希望它保持我所说的纵横比,并在我达到两个右侧面板的最小值后,仅调整左面板。 也就是说,它会调整每个面板直到某个大小,然后继续调整整个GUI,但只调整左侧面板,使右侧面板保持其最小大小。

谢谢你的帮助。 这真的很烦人,我花了几个小时尝试做到这一点,玩弄GridBagLayoutConstraints却没有进展。 这是我最好的结果。


你尝试过使用多个GridBagConstraints对象而不是重复使用同一个实例吗? - gobernador
@gobernador Java中关于GridBagLayout的教程会重复使用约束条件,因此除非之前设置有误,否则一切都应该没问题。 - David Kroukamp
2
你们两个都是对的。但是当出现问题时,有时重置约束可以找到问题的症结所在。 - MadProgrammer
2
保持纵横比。嗯...如果用户调整框架大小,使得框架的宽高不再保持纵横比,应该发生什么? - kleopatra
@kleopatra - 这个想法是尽可能地保持宽高比。我知道有些高度/宽度组合会使这变得不可能,但没有理由不能尽可能接近它,或者尽可能多地保持框架的宽高比,然后将额外的空间分配给特定的面板或列/行。 - Michael Yousef
1个回答

3
我尝试为您的问题做出一些努力,我得到了一个简单的解释,可能会引起您的担心。在初始化您在ChatPanel中使用的JTextField时,您必须指定它的列数,这可能会导致这种效果。由于我上面编写代码的方式,这个东西没有给我任何奇怪的行为,在任何意义上都不是。不过对于您的第二个问题,@kleopatra已经给出了一些见解。这是我使用的代码:
import java.awt.*;
import javax.swing.*;

public class ClientGrid
{
    private void displayGUI()
    {
        JFrame frame = new JFrame("Client Grid");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel contentPane = new JPanel();
        contentPane.setLayout(new GridBagLayout());

        JPanel bluePanel = new JPanel();
        bluePanel.setOpaque(true);
        bluePanel.setBackground(Color.BLUE);

        JPanel greenPanel = new JPanel();
        greenPanel.setOpaque(true);
        greenPanel.setBackground(Color.GREEN);

        JPanel redPanel = new JPanel();
        redPanel.setOpaque(true);
        redPanel.setBackground(Color.RED);

        JPanel chatPanel = new JPanel();
        JTextField chatField = new JTextField();
        chatPanel.setLayout(new BorderLayout(5, 5));
        chatPanel.add(chatField, BorderLayout.PAGE_START);

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.FIRST_LINE_START;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weightx = 0.7;
        gbc.weighty = 0.3;

        contentPane.add(bluePanel, gbc);

        gbc.gridx = 1;
        gbc.weightx = 0.3;

        contentPane.add(greenPanel, gbc);

        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.weightx = 0.7;
        gbc.weighty = 0.7;

        contentPane.add(redPanel, gbc);

        gbc.gridx = 1;
        gbc.weightx = 0.3;

        contentPane.add(chatPanel, gbc);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                new ClientGrid().displayGUI();
            }
        });
    }
}

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