GridBagLayout面板对齐

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

理想的布局 - 图解

为此,我将网格分开如下:

正在进行的工作 - 图解

对于面板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); 

欢迎任何想法和主张!

好问题。 我很少破解它,但我得到了它。 通常情况下,我会将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); } } } 

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

图片

 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); } } 

我从未成为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); 

对于最后两个JPanel ,我建议你只需将它们添加到一个带有GridLayout的新JPanel ,并将带有GridLayoutJPanel具有GridBagLayoutJPanel 。 请看一下代码示例,它实际上产生了与您期望的相同的输出:

 import javax.swing.*; import java.awt.*; /** * Created with IntelliJ IDEA. * User: Gagandeep Bali * Date: 2/7/13 * Time: 10:34 PM * To change this template use File | Settings | File Templates. */ public class GridBagExample { private JPanel contentPane, footerPanel; private JPanel s1, s2, s3, s4, s5, s6, s7, s8, s9; private void displayGUI() { JFrame frame = new JFrame("GridBagLayout Example"); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); contentPane = new JPanel(); contentPane.setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); /* * Constraints for S1 JPanel. */ gbc.anchor = GridBagConstraints.CENTER; gbc.gridx = 0; gbc.gridy = 0; gbc.fill = GridBagConstraints.BOTH; gbc.gridwidth = 1; gbc.gridheight = 2; gbc.weightx = 0.2; gbc.weighty = 0.8; s1 = new JPanel(new GridBagLayout()); s1.setOpaque(true); s1.setBackground(Color.BLUE); s1.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 5)); JLabel s1Label = new JLabel("S1", JLabel.CENTER); s1.add(s1Label); contentPane.add(s1, gbc); /* * Constraints for S2 JPanel. */ gbc.weighty = 0.4; gbc.gridx = 1; gbc.gridheight = 1; s2 = new JPanel(new GridBagLayout()); s2.setOpaque(true); s2.setBackground(Color.GREEN); s2.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 5)); JLabel s2Label = new JLabel("S2", JLabel.CENTER); s2.add(s2Label); contentPane.add(s2, gbc); /* * Constraints for S3 JPanel. */ gbc.gridy = 1; s3 = new JPanel(new GridBagLayout()); s3.setOpaque(true); s3.setBackground(Color.CYAN); s3.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 5)); JLabel s3Label = new JLabel("S3", JLabel.CENTER); s3.add(s3Label); contentPane.add(s3, gbc); /* * Constraints for S4 JPanel. */ gbc.weighty = 0.8; gbc.gridx = 2; gbc.gridy = 0; gbc.gridheight = 2; s4 = new JPanel(new GridBagLayout()); s4.setOpaque(true); s4.setBackground(Color.WHITE); s4.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 5)); JLabel s4Label = new JLabel("S4", JLabel.CENTER); s4.add(s4Label); contentPane.add(s4, gbc); /* * Constraints for S5 JPanel. */ gbc.weighty = 0.4; gbc.gridx = 3; gbc.gridheight = 1; s5 = new JPanel(new GridBagLayout()); s5.setOpaque(true); s5.setBackground(Color.RED); s5.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 5)); JLabel s5Label = new JLabel("S5", JLabel.CENTER); s5.add(s5Label); contentPane.add(s5, gbc); /* * Constraints for S6 JPanel. */ gbc.gridy = 1; s6 = new JPanel(new GridBagLayout()); s6.setOpaque(true); s6.setBackground(Color.MAGENTA); s6.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 5)); JLabel s6Label = new JLabel("S6", JLabel.CENTER); s6.add(s6Label); contentPane.add(s6, gbc); /* * Constraints for S7 JPanel. */ gbc.gridheight = 2; gbc.weighty = 0.8; gbc.gridx = 4; gbc.gridy = 0; s7 = new JPanel(new GridBagLayout()); s7.setOpaque(true); s7.setBackground(Color.ORANGE); s7.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 5)); JLabel s7Label = new JLabel("S7", JLabel.CENTER); s7.add(s7Label); contentPane.add(s7, gbc); footerPanel = new JPanel(); footerPanel.setLayout(new GridLayout(1, 2, 5, 5)); s8 = new JPanel(new GridBagLayout()); s8.setOpaque(true); s8.setBackground(Color.PINK); s8.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 5)); JLabel s8Label = new JLabel("S8", JLabel.CENTER); s8.add(s8Label); footerPanel.add(s8); s9 = new JPanel(new GridBagLayout()); s9.setOpaque(true); s9.setBackground(Color.YELLOW); s9.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 5)); JLabel s9Label = new JLabel("S9", JLabel.CENTER); s9.add(s9Label); footerPanel.add(s9, gbc); /* * Constraints for Footer JPanel. */ gbc.gridheight = 1; gbc.gridwidth = 5; gbc.weightx = 1.0; gbc.weighty = 0.2; gbc.gridx = 0; gbc.gridy = 2; contentPane.add(footerPanel, gbc); frame.setContentPane(contentPane); frame.pack(); //frame.setSize(500, 500); frame.setLocationByPlatform(true); frame.setVisible(true); } public static void main(String... args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { new GridBagExample().displayGUI(); } }); } } 

这是上面代码的输出:

GridBagLayoutExample

通常,我以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 

对于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); 

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

使用边框布局

 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); } }