GridBagLayout面板对齐

时间:2013-02-07 16:02:26

标签: java swing jpanel gridbaglayout

我对GridBag布局管理器有一点问题。我试图显示9个这样的面板:

Ideal Layout - Illustrated

为此,我将网格分开:

Work In Progress - Illustrated

对于面板1到7没有问题,它们就像我想要的那样出现。但问题始于专家组S8S9。正如您所看到的,S8S9占据了一半的帧,但我不能让它显示为这样。 S8S4开始时结束,S9S4结束时结束,我无法处理半空间。

我想出的唯一方法是将S8S9面板放在另一个采用所有框架宽度的面板中 - 但是必须有一个正确的方法来显示这两个面板而不放置它们在另一个小组中!

以下是代码:

workzone.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.NORTHWEST;
c.fill = GridBagConstraints.BOTH;
c.weightx = 0.5;
c.weighty = 0.5;
c.insets = new Insets(0,0,0,0);

//S1
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 2;
c.gridheight = 2;
workzone.add(S1, c);

//S2
c.gridx = 2;
c.gridy = 0;
c.gridwidth = 2;
c.gridheight = 1;
workzone.add(S2, c);

//S3
c.gridx = 2;
c.gridy = 1;
c.gridwidth = 2;
c.gridheight = 1;
workzone.add(S3, c);

//S4
c.gridx = 4;
c.gridy = 0;
c.gridwidth = 2;
c.gridheight = 2;
workzone.add(S4, c);

//S5
c.gridx = 7;
c.gridy = 0;
c.gridwidth = 1;
c.gridheight = 1;
workzone.add(S5, c);

//S6
c.gridx = 7;
c.gridy = 1;
c.gridwidth = 2;
c.gridheight = 1;
workzone.add(S6, c);

//S7
c.gridx = 8;
c.gridy = 0;
c.gridwidth = 2;
c.gridheight = 2;
workzone.add(S7, c);

//S8
c.gridx = 0;
c.gridy = 2;
c.gridwidth = 5;
c.gridheigth = 1;
workzone.add(S8, c);

//S9
c.gridx = 6;
c.gridy = 2;
c.gridwidth = 5;
c.gridheight = 1;
workzone.add(S9, c);

欢迎任何想法和主张!

7 个答案:

答案 0 :(得分:9)

好问题。我很少破解它,但我得到了它。通常情况下,我会将1-7位置放在顶部面板中,将8-9放在底部面板中,但我喜欢使用GBL的1个面板的挑战。 [无聊]

问题是第4节(列索引4和5)没有为GBL定义好,因此第8节不知道要用多长时间来覆盖它的第五列(索引4),所以它只是停止在列索引3之后。

所以,我在构成第4部分的列中添加了2个零高度的垫片,它起作用了。注释掉标记为SPACERS的2行,看看我的意思:

编辑:@SheridanVespo

建议添加修复程序
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class GridBagDemo2 implements Runnable
{
  private Color[] colors = {Color.BLACK, Color.BLUE, Color.CYAN, Color.GRAY,
                            Color.GREEN, Color.MAGENTA, Color.ORANGE,
                            Color.PINK, Color.RED, Color.YELLOW};

  private JPanel panel;
  private GridBagConstraints gbc;

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

  public void run()
  {
    panel = new JPanel(new GridBagLayout());
    gbc = new GridBagConstraints();

    add(0,0, 2,2, "1");
    add(2,0, 2,1, "2");
    add(2,1, 2,1, "3");
    add(4,0, 2,2, "4");
    add(6,0, 2,1, "5");
    add(6,1, 2,1, "6");
    add(8,0, 2,2, "7");
    add(0,2, 5,1, "8");
    add(5,2, 5,1, "9");

    // SPACERS: define the 2 columns that is section "4"
    add(4,3, 1,1, "");
    add(5,3, 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(int x, int y, int colspan, int rowspan, String name)
  {
    gbc.gridx = x;
    gbc.gridy = y;
    gbc.gridwidth = colspan;
    gbc.gridheight = rowspan;
    gbc.weightx = .1;
    gbc.weighty = .1;
    gbc.anchor = GridBagConstraints.CENTER;
    gbc.fill = GridBagConstraints.BOTH;

    // using another panel for illustrative purposes only
    JPanel p = new JPanel();

    if (!name.equals(""))
    {
      gbc.weightx = 1;                          // @SheridanVespo fix
      int index = Integer.parseInt(name);
      JLabel label = new JLabel("Panel " + name);
      p.add(label);
      p.setBackground(colors[index]);
      panel.add(p, gbc);
    }
    else
    {
      gbc.weightx = 0.5;                        // @SheridanVespo fix
      gbc.weighty = 0;  // don't allow the spacer to grow 
      gbc.fill = GridBagConstraints.NONE;
      panel.add(Box.createHorizontalGlue(), gbc);
    }
  }
}

答案 1 :(得分:4)

接受的answer很有吸引力,但是当框架调整大小时,它会使第4部分比侧翼面板更宽。这种变化将面板8和8放置在一起。 9在BoxLayout的单独子面板中。

image

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

/** @see https://stackoverflow.com/q/14755487/261156 */
public class GridBagDemo implements Runnable {

    private JPanel panel;

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

    @Override
    public void run() {
        JFrame frame = new JFrame("GridBag");
        frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
        panel = new JPanel(new GridBagLayout());
        add(1, 0, 0, 1, 2);
        add(2, 1, 0, 1, 1);
        add(3, 1, 1, 1, 1);
        add(4, 2, 0, 1, 2);
        add(5, 3, 0, 1, 1);
        add(6, 3, 1, 1, 1);
        add(7, 4, 0, 1, 2);
        frame.add(panel);
        panel = new JPanel(new GridBagLayout());
        add(8, 0, 0, 1, 1);
        add(9, 1, 0, 1, 1);
        frame.add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private void add(int i, int x, int y, int w, int h) {
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = x;
        gbc.gridy = y;
        gbc.gridwidth = w;
        gbc.gridheight = h;
        gbc.weightx = .1;
        gbc.weighty = .1;
        gbc.anchor = GridBagConstraints.CENTER;
        gbc.fill = GridBagConstraints.BOTH;
        JPanel p = new JPanel();
        p.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
        p.add(new JLabel("Panel " + i));
        p.setBackground(Color.getHSBColor((i - 1) / 9f, 0.75f, 0.95f));
        panel.add(p, gbc);
    }
}

答案 2 :(得分:2)

我从未成为GridBagLayout的忠实粉丝。所以对我来说,我会将你的GUI分解为多个面板,并且可能会使用多个GridLayout来实现你想要的。类似的东西:

JPanel top = new JPanel( new GridLayout(0, 5) );
top.add(s1);
JPanel s23 = new JPanel( new GridLayout(2, 0) );
s23.add(s2);
s23.add(s3);
top.add(s23);
...

JPanel bottom = new JPanel( new GridLayout(0, 2) );
bottom.add(s8);
bottom.add(s9);

JPanel main = new JPanel( appropriate layout manager );
main.add(top);
main.add(bottom);

答案 3 :(得分:2)

对于最后两个JPanel,我建议您只使用JPanel将其添加到新的GridLayout,并将此JPanelGridLayout一起设置有JPanel的{​​{1}}。请看一下代码示例,它实际上产生了与您期望的相同的输出:

GridBagLayout

以下是上述代码的输出:

GridBagLayoutExample

答案 4 :(得分:1)

通常,我以Y,X位置顺序创建和添加GridBagLayout的组件。我不知道这是否是必需的,但这使我更容易诊断出问题。

这是我为你的网格想出的。

Component   xPosition   yPosition   xWidth   yHeight
---------   ---------   ---------   ------   -------
S1              0           0          2        2
S2              2           0          2        1
S4              4           0          2        2
S5              6           0          2        1
S7              8           0          2        2
S8              0           2          5        1
S3              2           2          2        1
S9              5           2          5        1
S6              6           2          2        1

答案 5 :(得分:1)

对于S9组件,您的代码是

//S9
c.gridx = 6;
c.gridy = 2;
c.gridwidth = 5;
c.gridheight = 1;
workzone.add(S9, c);

由于坐标系从0开始而不是1,我建议代码为

//S9
c.gridx = 5; // I changed this
c.gridy = 2;
c.gridwidth = 5;
c.gridheight = 1;
workzone.add(S9, c);

答案 6 :(得分:1)

我尝试使用BorderLayout检查其工作原理。但只是发布在这里.. :)这个过程使用彼此内部的多个面板。如果这个例子很舒服,你可以尝试这种方法。

Using Border Layout

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;


public class BorderAndGridBag {
    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                new GridWithBorder().createUI();
            }
        };

        EventQueue.invokeLater(r);
    }
}

class GridWithBorder {
    public void createUI() {
        JFrame frame = new JFrame();

        JPanel motherPanel = new JPanel(new BorderLayout());

        JPanel topPanel = new  JPanel();
        topPanel.setBorder(LineBorder.createBlackLineBorder());

        JPanel bottomPanel = new JPanel(new BorderLayout());
        bottomPanel.setBorder(LineBorder.createBlackLineBorder());

        JPanel topLeftPanel = new JPanel();
        topLeftPanel.setBorder(LineBorder.createBlackLineBorder());

        JPanel topRightPanel = new JPanel();
        topRightPanel.setBorder(LineBorder.createBlackLineBorder());

        JPanel topMiddlePanel = new JPanel();
        topMiddlePanel.add(new JLabel("Top Middle"));
        topMiddlePanel.setBorder(LineBorder.createBlackLineBorder());

        JPanel bottomLeftPanel = new JPanel();
        bottomLeftPanel.add(new JLabel("Bottom Left"));
        bottomLeftPanel.setBorder(LineBorder.createBlackLineBorder());

        JPanel bottomRightPanel = new JPanel();
        bottomRightPanel.add(new JLabel("Bottom Right"));
        bottomRightPanel.setBorder(LineBorder.createBlackLineBorder());

        JPanel topLeftLeft = new JPanel();
        topLeftLeft.add(new JLabel("Top Left"));
        topLeftLeft.setBorder(LineBorder.createBlackLineBorder());


        JPanel topLeftRight = new JPanel(new BorderLayout());

        JPanel topLeftRightTop = new JPanel();
        topLeftRightTop.add(new JLabel("Top Left's Right Top"));
        topLeftRight.setBorder(LineBorder.createBlackLineBorder());

        JPanel topLeftRightBottom = new JPanel();
        topLeftRightBottom.add(new JLabel("Top Left's Right Bottom"));

        JPanel topRightLeft = new JPanel(new BorderLayout());
        topRightLeft.setBorder(LineBorder.createBlackLineBorder());

        JPanel topRightRight = new JPanel();
        topRightRight.add(new JLabel("Top Right Right"));
        topRightRight.setBorder(LineBorder.createBlackLineBorder());

        JPanel topRightLeftTop = new JPanel();
        topRightLeftTop.add(new JLabel("Top Right Left Top"));

        JPanel topRightLeftBottom = new JPanel();
        topRightLeftBottom.add(new JLabel("Top Right Left Bottom"));

        topLeftPanel.add(topLeftLeft, BorderLayout.WEST);

        // Top panel sub alignment.
        topLeftPanel.add(topLeftRight, BorderLayout.EAST);
        topLeftRight.add(topLeftRightTop, BorderLayout.NORTH);
        topLeftRight.add(topLeftRightBottom, BorderLayout.CENTER);


        topRightLeft.add(topRightLeftTop, BorderLayout.NORTH);
        topRightLeft.add(topRightLeftBottom, BorderLayout.SOUTH);
        topRightPanel.add(topRightLeft, BorderLayout.WEST);
        topRightPanel.add(topRightRight, BorderLayout.EAST);

        // Top Panel main alignment.
        topPanel.add(topLeftPanel, BorderLayout.WEST);
        topPanel.add(topMiddlePanel, BorderLayout.CENTER);
        topPanel.add(topRightPanel, BorderLayout.EAST);

        // Bottom Panel main alignment.
        bottomPanel.add(bottomLeftPanel, BorderLayout.WEST);
        bottomPanel.add(bottomRightPanel, BorderLayout.EAST);

        motherPanel.add(topPanel, BorderLayout.NORTH);
        motherPanel.add(bottomPanel, BorderLayout.CENTER);

        frame.add(motherPanel);
        frame.pack();
        frame.setTitle("Layout Manager");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}