Java布局格式(GridBagLayout)

时间:2013-05-07 04:28:20

标签: java layout awt layout-manager gridbaglayout

尝试学习如何做一些优雅且更高级的JFrame布局。我正在尝试制作一些我认为相当简单的东西,但我遇到了一些困难。而不是乱搞几个小时(尽管我已经有)试图让布局工作,我想我会问我将要描述的布局的最佳约定是什么。

布局
基本上,我想要2列,但第一列要比第二列宽。在第一列中,将只有一个单元格,该单元格将具有JLabel,其中附有图标,以单元格为中心。第二列将有4行,每行包含JComponent(无关紧要)。另一个关键是JFrame中的每个组件都保留其首选大小,并且不会伸展以适应其单元格或者您拥有的内容。

这是所需布局的图片:

Desired Layout Picture

到目前为止,我已经想过以不同的方式做这件事:

  1. BorderLayout,中间有JLabel - 图标,其余为GridLayout / GridBagLayout
  2. GridBagLayout 4x4,其中JLabel - 图标占据3x4区域,理论上占据了75%的空间。
  3. 既没有给我我正在寻找的结果。思考/建议?非常感谢所有的帮助和建议。

2 个答案:

答案 0 :(得分:2)

你的第一个建议是合理的。

标签可以垂直和水平居中。

对于GridLayout,技巧是将每个组件添加到使用具有默认网格包约束的GridBagLayout的JPanel。然后将面板添加到GridLayout。现在,如果框架调整大小,面板将增长,但面板上的组件不会增长,组件将在面板中居中。

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

答案 1 :(得分:2)

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

以下示例仅使用一个布局来演示GridBagLayout

的强大功能

enter image description here

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

        }

    }

}

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