Java布局格式(GridBagLayout)

Java布局格式(GridBagLayout),java,layout,awt,layout-manager,gridbaglayout,Java,Layout,Awt,Layout Manager,Gridbaglayout,尝试学习如何做一些优雅和更高级的JFrame布局。我正在尝试做一些我认为很简单的事情,但是我遇到了一些困难。与花几个小时(尽管我已经花了很多时间)试图让布局正常工作相反,我想我应该问一下,我将要描述的布局的最佳惯例是什么 布局 基本上,我想要两列,但是第一列要比第二列宽。在第一列中只有一个单元格,该单元格将有一个JLabel,并在单元格中居中附加一个图标。第二列将有4行,每行中都有一个JComponent(不管是什么)。另一个关键点是,JFrame中的每个组件都保留其首选大小,并且不会拉伸以适合

尝试学习如何做一些优雅和更高级的
JFrame
布局。我正在尝试做一些我认为很简单的事情,但是我遇到了一些困难。与花几个小时(尽管我已经花了很多时间)试图让布局正常工作相反,我想我应该问一下,我将要描述的布局的最佳惯例是什么

布局
基本上,我想要两列,但是第一列要比第二列宽。在第一列中只有一个单元格,该单元格将有一个
JLabel
,并在单元格中居中附加一个图标。第二列将有4行,每行中都有一个
JComponent
(不管是什么)。另一个关键点是,
JFrame
中的每个组件都保留其首选大小,并且不会拉伸以适合其单元格或您所拥有的内容

以下是所需布局的图片:

到目前为止,我已经想到了几种不同的方法:

  • 一个
    BorderLayout
    ,中间有
    JLabel
    -图标,其余部分由
    gridbagloayout
    /
    gridbagloayout
    控制
  • 一个
    GridBagLayout
    4x4,其中
    JLabel
    -图标占据了3x4区域,理论上占75%的空间

  • 也不要告诉我我想要的结果。想法/建议?非常感谢您的帮助和建议。

    您的第一个建议是合理的

    标签可以垂直和水平居中

    对于GridLayout,诀窍是将每个组件添加到使用带有默认gridbag约束的GridBagLayout的JPanel中。然后将面板添加到GridLayout。现在,如果框架确实调整大小,面板将增长,但面板上的组件不会增长,并且组件将在面板中居中


    除了将GridLayout与其他子面板一起使用外,还可以使用垂直BoxLayout并在每个组件之前/之后添加“胶水”。并不是说使用这种方法时,您需要确保每个组件都使用居中的路线。此外,您可能需要将某些组件的最大大小设置为组件的首选大小,以便在空间可用时不会增长。

    您的第一个建议是合理的

    标签可以垂直和水平居中

    对于GridLayout,诀窍是将每个组件添加到使用带有默认gridbag约束的GridBagLayout的JPanel中。然后将面板添加到GridLayout。现在,如果框架确实调整大小,面板将增长,但面板上的组件不会增长,并且组件将在面板中居中


    除了将GridLayout与其他子面板一起使用外,还可以使用垂直BoxLayout并在每个组件之前/之后添加“胶水”。并不是说使用这种方法时,您需要确保每个组件都使用居中的路线。此外,您可能需要将某些组件的最大大小设置为组件的首选大小,以便在空间可用时不会增长。

    为了我自己的理智,我通常会分离布局的各个元素。这有时可以简化流程,因为您只需要关注布局中(对每个部分)重要的区域

    下面的示例使用单个布局来演示
    GridBagLayout

    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.io.File;
    import java.io.IOException;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.imageio.ImageIO;
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class AdvancedLayout {
    
        public static void main(String[] args) {
            new AdvancedLayout();
        }
    
        public AdvancedLayout() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private JLabel image;
            private JButton button;
            private JLabel label;
            private JComboBox comboBox;
            private JButton otherButton;
    
            public TestPane() {
                setLayout(new GridBagLayout());
                image = new JLabel();
                button = new JButton("A button");
                label = new JLabel("A label");
                comboBox = new JComboBox();
                otherButton = new JButton("Other");
                try {
                    image.setIcon(new ImageIcon(ImageIO.read(new File("/path/to/a/image"))));
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridx = 0;
                gbc.gridy = 0;
                gbc.weightx = 0.6666666666666667;
                gbc.weighty = 1f;
                gbc.gridheight = GridBagConstraints.REMAINDER;
                add(image, gbc);
    
                gbc.gridheight = 1;
                gbc.gridx++;
                gbc.weightx = 0.3333333333333333f;
                gbc.weighty = 0.25f;
                add(button, gbc);
                gbc.gridy++;
                add(label, gbc);
                gbc.gridy++;
                add(comboBox, gbc);
                gbc.gridy++;
                add(otherButton, gbc);
    
            }
    
        }
    
    }
    


    这可以很容易地与两个
    jpanel一起使用,一个用于图像,一个用于选项。这样就不需要使用
    gridheight
    ..

    为了我自己的理智,我通常会分离布局的各个元素。这有时可以简化流程,因为您只需要关注布局中(对每个部分)重要的区域

    下面的示例使用单个布局来演示
    GridBagLayout

    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.io.File;
    import java.io.IOException;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.imageio.ImageIO;
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class AdvancedLayout {
    
        public static void main(String[] args) {
            new AdvancedLayout();
        }
    
        public AdvancedLayout() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private JLabel image;
            private JButton button;
            private JLabel label;
            private JComboBox comboBox;
            private JButton otherButton;
    
            public TestPane() {
                setLayout(new GridBagLayout());
                image = new JLabel();
                button = new JButton("A button");
                label = new JLabel("A label");
                comboBox = new JComboBox();
                otherButton = new JButton("Other");
                try {
                    image.setIcon(new ImageIcon(ImageIO.read(new File("/path/to/a/image"))));
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridx = 0;
                gbc.gridy = 0;
                gbc.weightx = 0.6666666666666667;
                gbc.weighty = 1f;
                gbc.gridheight = GridBagConstraints.REMAINDER;
                add(image, gbc);
    
                gbc.gridheight = 1;
                gbc.gridx++;
                gbc.weightx = 0.3333333333333333f;
                gbc.weighty = 0.25f;
                add(button, gbc);
                gbc.gridy++;
                add(label, gbc);
                gbc.gridy++;
                add(comboBox, gbc);
                gbc.gridy++;
                add(otherButton, gbc);
    
            }
    
        }
    
    }
    


    这可以很容易地与两个
    jpanel一起使用,一个用于图像,一个用于选项。这样就不需要使用
    gridheight

    为什么第一个解决方案不起作用?对我来说似乎不错。如果您希望它保持其大小,为什么不使用
    JFrame.setresizeable(false)
    ?组件必须保持其大小。例如,使用
    GridLayout
    (据我所知,如果我错了,请纠正我,这就是我在这里的原因)一个
    JButton
    将占用其单元格的整个空间。不管我把它设置成什么尺寸。这不是我想要的。为什么你的第一个解决方案不起作用?对我来说似乎不错。如果您希望它保持其大小,为什么不使用
    JFrame.setresizeable(false)
    ?组件必须保持其大小。例如,使用
    GridLayout
    (据我所知,如果我错了,请纠正我,这就是我在这里的原因)一个
    JButton
    将占用其单元格的整个空间。不管我把它设置成什么尺寸。这不是我想要的。它有点像,但它似乎太复杂了——多种布局等等。这取决于你的喜好。我更喜欢具有最小约束的多个布局,因为我觉得它们更容易理解。其他人更喜欢单一布局,在使用每个组件时使用多个约束,如GridBagLayout、GroupLayout或MigLayout。我不喜欢需要一个教程来理解所有的限制。我想这是真的。为什么要让它变得比必要的更复杂呢。我想我只是喜欢均匀性。我会检查胶水。谢谢。有点像,但似乎太复杂了——多种布局等等。这取决于你的喜好。我更喜欢具有最小约束的多个布局,因为我觉得它们更容易理解。其他人更喜欢单一布局,在使用每个组件时使用多个约束,如GridBagLayout、GroupLayout或MigLayout。我不喜欢需要一个教程来理解所有的约束条件