【问题标题】:GridBagLayout not coming out as expectedGridBagLayout 没有按预期出现
【发布时间】:2019-07-22 07:14:39
【问题描述】:

我正在创建一个 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 的组件。

【问题讨论】:

  • 您应该在大文本字段之前设置 gridx。您应该像其他控件一样将您的 ordersPanel 和 discesPanel 添加到基本窗口的某个位置。

标签: java swing layout-manager gridbaglayout


【解决方案1】:

考虑将设计拆分为更小、更易于布局的容器。
它使代码清晰简单,并具有很高的灵活性:

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class Window extends JFrame {

    public Window() {

        Container panel = this.getContentPane(); //uses Borderlayout by default

        JPanel buttonsPane = new JPanel(new GridLayout(1, 0));
        JButton ordersButton = new JButton("Orders");
        buttonsPane.add(ordersButton);
        JButton dishesButton = new JButton("Dishes");
        buttonsPane.add(dishesButton);
        JButton ingredientsButton = new JButton("Ingredients");
        buttonsPane.add(ingredientsButton);
        JButton suppliersButton = new JButton("Suppliers");
        buttonsPane.add(suppliersButton);
        JButton staffButton = new JButton("Staff");
        buttonsPane.add(staffButton);
        JButton dronesButton = new JButton("Drones");
        buttonsPane.add(dronesButton);
        JButton usersButton = new JButton("Users");
        buttonsPane.add(usersButton);
        JButton postcodesButton = new JButton("Postcodes");
        buttonsPane.add(postcodesButton);
        JButton configurationButton = new JButton("Configuration");
        buttonsPane.add(configurationButton);
        panel.add(buttonsPane, BorderLayout.PAGE_START); //add to top

        JTextField viewScreen = new JTextField();
        viewScreen.setPreferredSize(new Dimension(650, 200));
        panel.add(viewScreen, BorderLayout.CENTER); //add to center

        JPanel ordersList = new JPanel();
        ordersList.setLayout(new BoxLayout(ordersList, BoxLayout.Y_AXIS));

        JPanel ordersPanel = new JPanel(); //uses FlowLayout by default
        ordersList.add(ordersPanel);
        JLabel orders1Label = new JLabel("order 1");
        ordersPanel.add(orders1Label);
        JTextField orders1TextField = new JTextField(50);
        ordersPanel.add(orders1TextField);

        JPanel ordersPanel1 = new JPanel();
        ordersList.add(ordersPanel1);
        JLabel orders2Label = new JLabel("order 2");
        ordersPanel1.add(orders2Label);
        JTextField orders2TextField = new JTextField(50);
        ordersPanel1.add(orders2TextField);

        JPanel dishesList = new JPanel();
        dishesList.setLayout(new BoxLayout(dishesList, BoxLayout.Y_AXIS));

        JPanel dishesPanel = new JPanel();
        dishesList.add(dishesPanel);
        JLabel dishes1Label = new JLabel("dish 1");
        dishesPanel.add(dishes1Label);
        JTextField dishes1TextField = new JTextField(50);
        dishesPanel.add(dishes1TextField);

        JPanel dishesPanel1 = new JPanel();
        dishesList.add(dishesPanel1);
        JLabel dishes2Label = new JLabel("dish 2");
        dishesPanel1.add(dishes2Label);
        JTextField dishes2TextField = new JTextField(50);
        dishesPanel1.add(dishes2TextField);

        JPanel entryFields = new JPanel();
        CardLayout c1 = new CardLayout();
        entryFields.setLayout(c1);

        entryFields.add("ordersPanel",ordersList);
        entryFields.add("dishesPanel", dishesList);
        c1.show(entryFields, "ordersPanel");
        panel.add(entryFields,BorderLayout.PAGE_END);

        ordersButton.addActionListener(arg0 -> c1.show(entryFields, "ordersPanel"));
        dishesButton.addActionListener(arg0 -> c1.show(entryFields, "dishesPanel"));

        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setVisible(true);

    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(()->new Window());
    }
}

【讨论】:

    【解决方案2】:

    首先我们要说的是,无论您对 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);
    }
    

    我得到了这个布局

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

    【讨论】:

      猜你喜欢
      • 2012-11-18
      • 1970-01-01
      • 2021-09-14
      • 2015-02-06
      • 2015-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多