1

尝试学习如何做一些优雅和更高级的JFrame布局。我正在尝试做一些我认为相当简单的东西,但我遇到了一些困难。与花几个小时(即使我已经有)试图让布局正常工作相反,我想我会问我要描述的布局的最佳约定是什么。

布局
基本上,我想要 2 列,但第一列比第二列宽。在第一列中只有一个单元格,并且该单元格将JLabel附有一个图标,位于单元格的中心。第二列将有 4 行,每行都有一个JComponent(没关系)。另一个关键是,每个组件都JFrame保留其首选尺寸,并且不会拉伸以适应其单元格或您拥有的东西。

这是所需布局的图片:

所需的布局图片

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

  1. A BorderLayout,中间有JLabel- 图标,而GridLayout/GridBagLayout控制其余部分。
  2. 一个GridBagLayout4x4,其中JLabel-icon 占据了 3x4 的区域,理论上给它 75% 的空间。

也不给我我正在寻找的结果。想法/建议?非常感谢所有帮助和建议。

4

2 回答 2

2

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

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

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

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

于 2013-05-07T04:34:02.720 回答
2

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

以下示例使用单一布局只是为了演示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);

        }

    }

}

这可以很容易地与两个一起使用JPanels,一个用于图像,一个用于选项。这将消除使用gridheight...

于 2013-05-07T04:43:17.433 回答