首页 > 解决方案 > GridBagLayout 没有按预期出现

问题描述

我正在创建一个 GUI,顶部应该有按钮,中间有一个视图屏幕,底部有一个带有标签和文本输入字段的区域,这些字段会根据按下的按钮而变化。放置所有东西的主面板是 GridBagLayout。包含文本输入字段的面板是 CardLayout。我觉得好像我已经设置了 GridBagConstraints 和其他所有东西,但它没有按预期出现。我想我设置 GridBagConstraints 的方式有问题,或者大小可能有问题,但我不确定。我会附上一张我运行它时得到的图片以及我想要得到的图片。

编码:

import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Container;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.text.JTextComponent;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import java.awt.GridBagLayout;
import java.util.concurrent.Executors;
import java.awt.CardLayout;
import java.awt.GridBagConstraints;
import javax.swing.JLabel;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Dimension;
import java.awt.Insets;

public class Window extends JFrame {

    public Window() {
        Container panel = this.getContentPane();
        panel.setLayout(new GridBagLayout());
        panel.setSize(1000,1000);
        GridBagConstraints gbc = new GridBagConstraints();

        JButton ordersButton = new JButton("Orders");
        gbc.gridx = 0;
        gbc.gridy = 0;
        panel.add(ordersButton, gbc);
        JButton dishesButton = new JButton("Dishes");
        gbc.gridx = 1;
        gbc.gridy = 0;
        panel.add(dishesButton, gbc);
        JButton ingredientsButton = new JButton("Ingredients");
        gbc.gridx = 2;
        gbc.gridy = 0;
        panel.add(ingredientsButton, gbc);
        JButton suppliersButton = new JButton("Suppliers");
        gbc.gridx = 3;
        gbc.gridy = 0;
        panel.add(suppliersButton, gbc);
        JButton staffButton = new JButton("Staff");
        gbc.gridx = 4;
        gbc.gridy = 0;
        panel.add(staffButton, gbc);
        JButton dronesButton = new JButton("Drones");
        gbc.gridx = 5;
        gbc.gridy = 0;
        panel.add(dronesButton, gbc);
        JButton usersButton = new JButton("Users");
        gbc.gridx = 6;
        gbc.gridy = 0;
        panel.add(usersButton, gbc);
        JButton postcodesButton = new JButton("Postcodes");
        gbc.gridx = 7;
        gbc.gridy = 0;
        panel.add(postcodesButton, gbc);
        JButton configurationButton = new JButton("Configuration");
        gbc.gridx = 8;
        gbc.gridy = 0;
        panel.add(configurationButton, gbc);

        JTextField viewScreen = new JTextField();
        gbc.gridy = GridBagConstraints.RELATIVE;
        gbc.gridwidth = 9;
        gbc.gridheight = 2;
        viewScreen.setPreferredSize(new Dimension(650, 200));
        panel.add(viewScreen, gbc);


        JPanel ordersPanel = new JPanel();
        JPanel dishesPanel = new JPanel();

        ordersPanel.setLayout(new GridBagLayout());
        dishesPanel.setLayout(new GridBagLayout());

        ordersPanel.setSize(new Dimension(900, 500));
        dishesPanel.setSize(new Dimension(900, 500));

        JLabel orders1Label = new JLabel("order 1");
        gbc.gridx = 0;
        gbc.gridy = 0;
        ordersPanel.add(orders1Label, gbc);
        JLabel orders2Label = new JLabel("order 2");
        gbc.gridx = 0;
        gbc.gridy = 1;
        ordersPanel.add(orders2Label, gbc);
        JLabel dishes1Label = new JLabel("dish 1");
        gbc.gridx = 0;
        gbc.gridy = 0;
        dishesPanel.add(dishes1Label, gbc);
        JLabel dishes2Label = new JLabel("dish 2");
        gbc.gridx = 0;
        gbc.gridy = 1;
        dishesPanel.add(dishes2Label, gbc);

        JTextField orders1TextField = new JTextField();
        gbc.gridx = 1;
        gbc.gridy = 0;
        gbc.weightx = 1;
        gbc.gridwidth = 4;
        ordersPanel.add(orders1TextField, gbc);
        JTextField orders2TextField = new JTextField();
        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.weightx = 1;
        gbc.weighty = 1;
        gbc.gridwidth = 4;
        ordersPanel.add(orders2TextField, gbc);
        JTextField dishes1TextField = new JTextField();
        gbc.gridx = 1;
        gbc.gridy = 0;
        gbc.weightx = 1;
        gbc.gridwidth = 4;
        dishesPanel.add(dishes1TextField, gbc);
        JTextField dishes2TextField = new JTextField();
        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.weightx = 1;
        gbc.weighty = 1;
        gbc.gridwidth = 4;
        dishesPanel.add(dishes2TextField, gbc); 

        orders1TextField.setPreferredSize(new Dimension(400, 20));
        orders2TextField.setPreferredSize(new Dimension(400, 20));
        dishes1TextField.setPreferredSize(new Dimension(400, 20));
        dishes2TextField.setPreferredSize(new Dimension(400, 20));

        JPanel entryFields = new JPanel();
        CardLayout c1 = new CardLayout();
        entryFields.setLayout(c1);
        entryFields.setSize(new Dimension(900, 600));
        gbc.gridheight = 7;
        gbc.gridwidth = 9;
        gbc.weighty = 1;

        gbc.gridy = GridBagConstraints.RELATIVE;
        entryFields.add("ordersPanel",ordersPanel);
        entryFields.add("dishesPanel", dishesPanel);
        c1.show(entryFields, "ordersPanel");
        panel.add(entryFields, gbc);

        ordersButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent arg0) {
                c1.show(entryFields, "ordersPanel");
            }
        });


        dishesButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent arg0) {
                c1.show(entryFields, "dishesPanel");
            }
        });


        //Display window
        setSize(800,600);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);

    }

        public static void main(String[] args) {    
            Window win = new Window();

        }


}

出现什么:

在此处输入图像描述

我想要的是:

在此处输入图像描述

我应该补充一点,在将窗口大小调整为计算机屏幕大小之前,我得到了以下图片。你可以在这里看到标签,虽然你不能在全尺寸版本中看到,而且它们聚集在一起,所以可能是我设置权重的方式有问题,我只是这样做了,至少每一行和每一列都有至少一个权重为 1 的组件。

在此处输入图像描述

标签: javaswinglayout-managergridbaglayout

解决方案


好吧,让我们首先说您对GridBagConstraints实例所做的任何修改都将保留在该实例的以下任何用法中。
因此,如果您这样gbc.gridwidth = 9做,请确保将其重置为gbc.gridwidth = 1,否则添加的每个元素都将应用 9 的网格宽度。并且无需gridy = 0每次在同一行添加按钮时都进行设置,这只会添加不必要的代码行。

现在我刚刚清理了您的Window()代码,以向您展示正确使用GridBagConstraints并删除了重复的分配。您将不得不ActionListeners再次添加您的

public Window() {
    Container panel = this.getContentPane();
    panel.setLayout(new GridBagLayout());
    panel.setSize(1000,1000);

    GridBagConstraints gbc = new GridBagConstraints();
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.weightx = 1;
    gbc.weighty = 1;

    gbc.gridy = 0; // First row

    JButton ordersButton = new JButton("Orders");
    gbc.gridx = 0;
    panel.add(ordersButton, gbc);

    JButton dishesButton = new JButton("Dishes");
    gbc.gridx = 1;
    panel.add(dishesButton, gbc);

    JButton ingredientsButton = new JButton("Ingredients");
    gbc.gridx = 2;
    panel.add(ingredientsButton, gbc);

    JButton suppliersButton = new JButton("Suppliers");
    gbc.gridx = 3;
    panel.add(suppliersButton, gbc);

    JButton staffButton = new JButton("Staff");
    gbc.gridx = 4;
    panel.add(staffButton, gbc);

    JButton dronesButton = new JButton("Drones");
    gbc.gridx = 5;
    panel.add(dronesButton, gbc);

    JButton usersButton = new JButton("Users");
    gbc.gridx = 6;
    panel.add(usersButton, gbc);

    JButton postcodesButton = new JButton("Postcodes");
    gbc.gridx = 7;
    panel.add(postcodesButton, gbc);

    JButton configurationButton = new JButton("Configuration");
    gbc.gridx = 8;
    panel.add(configurationButton, gbc);

    JTextField viewScreen = new JTextField();
    gbc.gridx = 0;
    gbc.gridy = 1;
    gbc.gridwidth = 9;
    viewScreen.setPreferredSize(new Dimension(650, 200));
    viewScreen.setMinimumSize(new Dimension(650, 200));
    panel.add(viewScreen, gbc);
    gbc.gridwidth = 1;  // Reset the gridwidth

    // Third row
    JLabel orders1Label = new JLabel("order 1");
    gbc.gridx = 1;
    gbc.gridy = 2;
    panel.add(orders1Label, gbc);
    JLabel orders2Label = new JLabel("order 2");
    gbc.gridx = 1;
    gbc.gridy = 3;
    panel.add(orders2Label, gbc);
    JLabel dishes1Label = new JLabel("dish 1");
    gbc.gridx = 1;
    gbc.gridy = 4;
    panel.add(dishes1Label, gbc);
    JLabel dishes2Label = new JLabel("dish 2");
    gbc.gridx = 1;
    gbc.gridy = 5;
    panel.add(dishes2Label, gbc);

    gbc.gridwidth = 4; // Textfield width
    JTextField orders1TextField = new JTextField();
    gbc.gridx = 2;
    gbc.gridy = 2;
    panel.add(orders1TextField, gbc);
    JTextField orders2TextField = new JTextField();
    gbc.gridx = 2;
    gbc.gridy = 3;
    panel.add(orders2TextField, gbc);
    JTextField dishes1TextField = new JTextField();
    gbc.gridx = 2;
    gbc.gridy = 4;
    panel.add(dishes1TextField, gbc);
    JTextField dishes2TextField = new JTextField();
    gbc.gridx = 2;
    gbc.gridy = 5;
    panel.add(dishes2TextField, gbc); 

    orders1TextField.setPreferredSize(new Dimension(400, 20));
    orders2TextField.setPreferredSize(new Dimension(400, 20));
    dishes1TextField.setPreferredSize(new Dimension(400, 20));
    dishes2TextField.setPreferredSize(new Dimension(400, 20));

    //Display window
    setSize(800,600);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);
}

我得到了这个布局

生成的图像

布局可能不是您想要的,但我希望您可以继续使用此示例进行工作。;)


推荐阅读