GridBagLayout panels alignment

后端 未结 7 1553
北荒
北荒 2020-12-07 01:38

I have a little issue with the GridBag Layout Manager. I am trying to display 9 panels like this:

\"Ideal

相关标签:
7条回答
  • 2020-12-07 01:59

    Good question. It took me little to crack it, but I got it. Normally, I would have put setions 1-7 in a top panel, and sections 8-9 in a bottom panel, but I liked the challange of 1 panel with GBL. [bored]

    The problem is that section 4 (column indexes 4 and 5) is not well-defined for GBL, so section 8 doesn't know how far out to go to cover it's fifth column (index 4) so it then just stops after column index 3.

    So, I added 2 zero-height spacers in the columns that make up section 4 and it worked. Comment out the 2 lines marked SPACERS to see what I mean:

    EDIT: added fix suggested by @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);
        }
      }
    }
    
    0 讨论(0)
  • 2020-12-07 02:00

    I never been a big fan of GridBagLayout. So for me I would break your GUI down into multiple panels and would probably use multiple GridLayout to achieve what you want. Something like:

    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);
    
    0 讨论(0)
  • 2020-12-07 02:08

    The accepted answer is appealing, but it causes section 4 to widen faster than the flanking panels as the frame is resized. This variation places panels 8 & 9 in a separate sub-panel of a 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);
        }
    }
    
    0 讨论(0)
  • 2020-12-07 02:14

    For the S9 component, your code is

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

    Since the coordinate system begins at 0 rather than 1, I propose the code be

    //S9
    c.gridx = 5; // I changed this
    c.gridy = 2;
    c.gridwidth = 5;
    c.gridheight = 1;
    workzone.add(S9, c);
    
    0 讨论(0)
  • 2020-12-07 02:14

    I have tried using BorderLayout to check how it works. But just posting here .. :) This process uses multiple panels inside each other. You can try this approach if this example is comfortable.

    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);
        }
    }
    
    0 讨论(0)
  • 2020-12-07 02:16

    Generally, I create and add the components of a GridBagLayout in Y, X position order. I don't know if this is required, but it makes it easier for me to diagnose problems.

    Here's what I came up with for your grid.

    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
    
    0 讨论(0)
提交回复
热议问题