GridBagLayout网格无法正常工作

时间:2014-06-18 16:47:18

标签: java swing layout layout-manager gridbaglayout

我正在尝试创建以下GUI:

enter image description here

但我制作的GUI是:

enter image description here

我的网格是什么样的:

图片:THE GRIDLAYOUT FOR THIS

我不明白为什么我得到这个输出,因为我绘制了一个图表以帮助代码,它似乎有用。

addComp添加方法将输入组件添加到给定(x,y)位置和给定组件宽度和高度的输入面板。

代码:

import javax.swing.*;
import java.awt.*;

public class GUIError extends JFrame {

    //initialise all the components
    JPanel mainPanel = new JPanel();
    JTextField txtDisplay = new JTextField();
    JButton btnA = new JButton("A");
    JButton btnB = new JButton("B");
    JButton btnC = new JButton("C");
    JButton btnD = new JButton("D");
    JButton btnE = new JButton("E");
    JButton btnF = new JButton("F");
    JButton btnWA = new JButton("WA");
    JButton btnWB = new JButton("WB");
    JButton btnWC = new JButton("WC");
    JButton btnWD = new JButton("WD");

    private void addComp(JPanel panel, JComponent comp, int xPos, int yPos, int compWidth, int compHeight) {

        GridBagConstraints gridConstraints = new GridBagConstraints();

        gridConstraints.gridx = xPos;
        gridConstraints.gridy = yPos;
        gridConstraints.gridwidth = compWidth;
        gridConstraints.gridheight = compHeight;
        gridConstraints.weightx = 0.5;
        gridConstraints.weighty = 0.5;
        gridConstraints.insets = new Insets(5, 5, 5, 5);
        gridConstraints.anchor = GridBagConstraints.CENTER;
        gridConstraints.fill = GridBagConstraints.BOTH;

        panel.add(comp, gridConstraints);

    }


    public static void main(String[] args) {
        try {
            for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        }
        catch (Exception e) { }

        SwingUtilities.invokeLater(new Runnable() {

            public void run() {

                // create frame
                JFrame frame = new JFrame("Calculator");
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                frame.setLocationRelativeTo(null);
                Container c = frame.getContentPane();

                // create GUI within frame              
                new GUIError(c);

                // finish frame definition
                frame.pack();
                frame.setResizable(false);
                frame.setVisible(true);

            }

        });
    }

    public GUIError(Container cont) {

        cont.setPreferredSize(new Dimension(610, 250));

        // parent panel containes every other panel
        mainPanel.setLayout(new GridBagLayout());

        // text display
        txtDisplay.setEditable(false);
        addComp(mainPanel, txtDisplay, 0, 0, 12, 2); // width 16, height 2


        addComp(mainPanel, btnA, 0, 2, 2, 1);
        addComp(mainPanel, btnB, 2, 2, 2, 1);
        addComp(mainPanel, btnC, 4, 2, 2, 1);
        addComp(mainPanel, btnD, 6, 2, 2, 1);
        addComp(mainPanel, btnE, 8, 2, 2, 1);
        addComp(mainPanel, btnF, 10, 2, 2, 1);
        addComp(mainPanel, btnWA, 0, 3, 3, 1);
        addComp(mainPanel, btnWB, 3, 3, 3, 1);
        addComp(mainPanel, btnWC, 6, 3, 3, 1);
        addComp(mainPanel, btnWD, 9, 3, 3, 1);

        cont.add(mainPanel);
    }
}

4 个答案:

答案 0 :(得分:5)

使用GridBagLayout可以很容易地实现,如下面的示例所示。您只需为每个 ROW 分别取两个JPanel个。两者都使用GridBagLayout,并将组件添加到第一行, weightx = 0.16 ,因为每个JButton假定占用这么多区域,而第二行 weightx = 0.25 因为,这是每个JButton沿着 X方向占据的区域

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class GridBagExample {
    private static final int SIZE = 10;
    private JButton[] buttons;
    private GridBagConstraints gbc;

    public GridBagExample() {
        buttons = new JButton[SIZE];
        gbc = new GridBagConstraints();
        gbc.insets = new Insets(5, 5, 5, 5);
    }

    private void createAndDisplayGUI() {
        JFrame frame = new JFrame("Grid Game");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel();
        contentPane.setLayout(new GridLayout(2, 1, 5, 5));
        contentPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        JPanel topPanel = new JPanel();
        JTextField textField = new JTextField(10);
        //topPanel.add(textField);

        JPanel buttonPanel = new JPanel(new GridLayout(2, 1, 5, 5));
        JPanel headerPanel = new JPanel(new GridBagLayout());
        buttons[0] = new JButton("A");
        addComp(headerPanel, buttons[0], 0, 0, 0.16, 1.0, 1, 1, GridBagConstraints.BOTH);        
        buttons[1] = new JButton("B");
        addComp(headerPanel, buttons[1], 1, 0, 0.16, 1.0, 1, 1, GridBagConstraints.BOTH);
        buttons[2] = new JButton("C");
        addComp(headerPanel, buttons[2], 2, 0, 0.16, 1.0, 1, 1, GridBagConstraints.BOTH);
        buttons[3] = new JButton("D");
        addComp(headerPanel, buttons[3], 3, 0, 0.16, 1.0, 1, 1, GridBagConstraints.BOTH);
        buttons[4] = new JButton("E");
        addComp(headerPanel, buttons[4], 4, 0, 0.16, 1.0, 1, 1, GridBagConstraints.BOTH);
        buttons[5] = new JButton("F");
        addComp(headerPanel, buttons[5], 5, 0, 0.16, 1.0, 1, 1, GridBagConstraints.BOTH);

        JPanel footerPanel = new JPanel(new GridBagLayout());
        buttons[6] = new JButton("WA");
        addComp(footerPanel, buttons[6], 0, 0, 0.25, 1.0, 1, 1, GridBagConstraints.BOTH);
        buttons[7] = new JButton("WB");
        addComp(footerPanel, buttons[7], 1, 0, 0.25, 1.0, 1, 1, GridBagConstraints.BOTH);
        buttons[8] = new JButton("WC");
        addComp(footerPanel, buttons[8], 2, 0, 0.25, 1.0, 1, 1, GridBagConstraints.BOTH);
        buttons[9] = new JButton("WD");
        addComp(footerPanel, buttons[9], 3, 0, 0.25, 1.0, 1, 1, GridBagConstraints.BOTH);
        buttonPanel.add(headerPanel);
        buttonPanel.add(footerPanel);

        contentPane.add(textField);
        contentPane.add(buttonPanel);

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

    private void addComp(JPanel panel, JComponent comp, int x, int y,
                                    double wx, double wy, int gw, int gh, int fill) {
        gbc.gridx = x;
        gbc.gridy = y;
        gbc.weightx = wx;
        gbc.weighty = wy;
        gbc.gridwidth = gw;
        gbc.gridheight = gh;
        gbc.fill = fill;

        panel.add(comp, gbc);
    }

    public static void main(String... args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new GridBagExample().createAndDisplayGUI();
            }
        });
    }
}

输出: 的的GridBagLayout:

gridbagexample

GridLayout可以实现相同的输出,如果GridBagLayout在这种情况下不是必需的话,如下例所示:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class GridBagExample {
    private static final int SIZE = 10;
    private JButton[] buttons;

    public GridBagExample() {
        buttons = new JButton[SIZE];
    }

    private void createAndDisplayGUI() {
        JFrame frame = new JFrame("Grid Game");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel();
        contentPane.setLayout(new GridLayout(2, 1, 5, 5));
        contentPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        JPanel topPanel = new JPanel();
        JTextArea tArea = new JTextArea(5, 30);
        JScrollPane scroller = new JScrollPane();
        scroller.setViewportView(tArea);
        topPanel.add(scroller);

        JPanel buttonPanel = new JPanel(new GridLayout(2, 1, 5, 5));
        JPanel headerPanel = new JPanel(new GridLayout(1, 0, 5, 5));
        buttons[0] = new JButton("A");
        headerPanel.add(buttons[0]);
        buttons[1] = new JButton("B");
        headerPanel.add(buttons[1]);
        buttons[2] = new JButton("C");
        headerPanel.add(buttons[2]);
        buttons[3] = new JButton("D");
        headerPanel.add(buttons[3]);
        buttons[4] = new JButton("E");
        headerPanel.add(buttons[4]);
        buttons[5] = new JButton("F");
        headerPanel.add(buttons[5]);
        JPanel footerPanel = new JPanel(new GridLayout(1, 0, 5, 5));
        buttons[6] = new JButton("WA");
        footerPanel.add(buttons[6]);
        buttons[7] = new JButton("WB");
        footerPanel.add(buttons[7]);
        buttons[8] = new JButton("WC");
        footerPanel.add(buttons[8]);
        buttons[9] = new JButton("WD");
        footerPanel.add(buttons[9]);
        buttonPanel.add(headerPanel);
        buttonPanel.add(footerPanel);

        contentPane.add(topPanel);
        contentPane.add(buttonPanel);

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

    public static void main(String... args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new GridBagExample().createAndDisplayGUI();
            }
        });
    }
}

输出: 的 GridLayout的: GridBagExample

答案 1 :(得分:5)

通常我会制作单独的面板,但嘿,谁不喜欢挑战?

问题在于某些列没有为GBL定义好(没有单个组件定义其宽度),因此按钮WA不知道要覆盖按钮B的一半等多远,等等。 / p>

因此,我在构成所需部分的列中添加了一些零宽度的间隔符。

全部在一个小组中:

enter image description here

import java.awt.*;
import javax.swing.*;

public class GridBagDemo3 implements Runnable
{
  private JPanel panel;

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

  public void run()
  {
    JTextArea text = new JTextArea(10,10);
    JButton btnA = new JButton("A");
    JButton btnB = new JButton("B");
    JButton btnC = new JButton("C");
    JButton btnD = new JButton("D");
    JButton btnE = new JButton("E");
    JButton btnF = new JButton("F");
    JButton btnWA = new JButton("WA");
    JButton btnWB = new JButton("WB");
    JButton btnWC = new JButton("WC");
    JButton btnWD = new JButton("WD");

    panel = new JPanel(new GridBagLayout());

    add(text,   0,0, 12,1);
    add(btnA,   0,1, 2,1);
    add(btnB,   2,1, 2,1);
    add(btnC,   4,1, 2,1);
    add(btnD,   6,1, 2,1);
    add(btnE,   8,1, 2,1);
    add(btnF,  10,1, 2,1);
    add(btnWA,  0,2, 3,1);
    add(btnWB,  3,2, 3,1);
    add(btnWC,  6,2, 3,1);
    add(btnWD,  9,2, 3,1);

    // SPACERS: define the 2 columns that button B spans
    //          so that WA and WB can split B, and same for button E
    add(null,   2,2, 1,1);
    add(null,   3,2, 1,1);
    add(null,   8,2, 1,1);
    add(null,   9,2, 1,1);

    JFrame frame = new JFrame("Grig Bag");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(panel);
    frame.pack();
    frame.setVisible(true);
  }

  private void add(Component comp, int x, int y, int colspan, int rowspan)
  {
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.gridx = x;
    gbc.gridy = y;
    gbc.gridwidth = colspan;
    gbc.gridheight = rowspan;
    gbc.weighty = .1;
    gbc.anchor = GridBagConstraints.CENTER;
    gbc.fill = GridBagConstraints.BOTH;
    gbc.insets = new Insets(5,5,5,5);

    if (comp != null)
    {
      gbc.weightx = 1;
    }
    else
    {
      comp = Box.createHorizontalGlue();
      gbc.fill = GridBagConstraints.NONE;
      gbc.weightx = 0.1;
      gbc.weighty = 0;
    }

    panel.add(comp, gbc);
  }
}

答案 2 :(得分:4)

@Matthieu写道 -

  

你能详细说明GBC是基于列吗?听起来像是一个   我注意到一个问题的解释......

我认为这种方式是GridBagLayout设计的,我总是使用JLabel(没有Borders :-)作为矩阵...

enter image description here

import java.awt.*;
import javax.swing.*;

public class CopyTextNorthPanel extends JPanel {

    private static final long serialVersionUID = 1L;
    private JLabel hidelLabel;
    private JLabel firstLabel;
    private JTextField firstText;

    public CopyTextNorthPanel() {

        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
        for (int k = 0; k < 50; k++) {
            hidelLabel = new JLabel("     ");
            hidelLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.weightx = 0.5;
            gbc.weighty = 0.5;
            gbc.gridx = k;
            gbc.gridy = 0;
            add(hidelLabel, gbc);
        }
        for (int k = 0; k < 5; k++) {
            firstLabel = new JLabel("Testing Label : ", SwingConstants.RIGHT);
            firstLabel.setFont(new Font("Serif", Font.BOLD, 20));
            firstLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.insets = new Insets(0, 0, 5, 0);
            gbc.gridx = 0;
            gbc.gridwidth = 8;
            gbc.gridy = k + 1;
            add(firstLabel, gbc);
        }
        for (int k = 0; k < 5; k++) {
            firstText = new JTextField("Testing TextField");
            firstText.setFont(new Font("Serif", Font.BOLD, 20));
            firstText.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.insets = new Insets(0, 0, 5, 0);
            gbc.gridx = 9;
            gbc.gridwidth = k + 8;
            gbc.gridy = k + 1;
            add(firstText, gbc);
        }
        for (int k = 0; k < 5; k++) {
            firstLabel = new JLabel("Testing Label : ", SwingConstants.RIGHT);
            firstLabel.setFont(new Font("Serif", Font.BOLD, 20));
            firstLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.insets = new Insets(0, 0, 5, 0);
            gbc.gridx = 20 + k;
            gbc.gridwidth = 8;
            gbc.gridy = k + 1;
            add(firstLabel, gbc);
        }
        for (int k = 0; k < 5; k++) {
            firstText = new JTextField("Testing TextField");
            firstText.setFont(new Font("Serif", Font.BOLD, 20));
            firstText.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.insets = new Insets(0, 0, 5, 0);
            gbc.gridx = 29 + k;
            gbc.gridwidth = 21 - k;
            gbc.gridy = k + 1;
            add(firstText, gbc);
        }
    }
}

答案 3 :(得分:3)

如果您仍然有兴趣了解您的错误: 格&#39;布局不是FlowLayout,你不能简单地添加组件,它会在程序读取它的同一时刻绘制对象。在网格的情况下,虚拟机首先读取所有对象而不是构建网格,列的数量是在具有最大列数的行的基础上确定的。因此,您最好选择12列(因此您可以避免创建新的&#34; Panel&#34;以及备用系统资源),但为了做到这一点,您应该添加12个空格(不仅仅是空的)其中一行中的零大小)

    // text display
    txtDisplay.setEditable(false);
    addComp(mainPanel, txtDisplay, 0, 0, 12, 2); // width 16, height 2



    //now go with empty spaces
    for(int i=0;i<12;i++){
        GridBagConstraints gridConstraints = new GridBagConstraints();
        gridConstraints.gridx = i;    //12 times "i"
        gridConstraints.gridy = 1;  //you left y=1 empty, so why don't use it
        gridConstraints.gridwidth = 1;  //one column = one space in grid
        gridConstraints.gridheight = 0;  //we don't want it to occupied any space
        gridConstraints.weightx = 0.5;
        gridConstraints.weighty = 0.5;
        gridConstraints.insets = new Insets(0, 0, 0, 0); //same reason, we don't want it to occupied any space
        gridConstraints.anchor = GridBagConstraints.CENTER;
        gridConstraints.fill = GridBagConstraints.BOTH ;

        mainPanel.add(Box.createHorizontalGlue(), gridConstraints);
    }


    addComp(mainPanel, btnA, 0, 2, 2, 1);
    addComp(mainPanel, btnB, 2, 2, 2, 1);
    addComp(mainPanel, btnC, 4, 2, 2, 1);
    addComp(mainPanel, btnD, 6, 2, 2, 1);
    addComp(mainPanel, btnE, 8, 2, 2, 1);
    addComp(mainPanel, btnF, 10, 2, 2, 1);
    addComp(mainPanel, btnWA, 0, 3, 3, 1);
    addComp(mainPanel, btnWB, 3, 3, 3, 1);
    addComp(mainPanel, btnWC, 6, 3, 3, 1);
    addComp(mainPanel, btnWD, 9, 3, 3, 1);