Java 布局格式化 (GridBagLayout)

标签 java layout awt layout-manager gridbaglayout

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

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

这是所需布局的图片:

Desired Layout Picture

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

  1. 一个 BorderLayout,中间有 JLabel-图标,还有一个 GridLayout/GridBagLayout 控制休息。
  2. GridBagLayout 4x4,其中 JLabel-icon 占据 3x4 区域,理论上它占空间的 75%。

都没有给我想要的结果。想法/建议?非常感谢所有帮助和建议。

最佳答案

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

以下示例使用单个布局来演示 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...

的需要

关于Java 布局格式化 (GridBagLayout),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16411197/

相关文章:

Html 布局并使正文内容超出设置的宽度并保持在同一行

java - Swing 动画开始停止

java - 如何在 Java 中制作小于 125 x 50 的窗口?

java - 事件监听器和鼠标监听器

css - XHTML/CSS 中的绝对位置与 float 位置

java - Spring Boot 2.2.0 不推荐使用syncBody

Java 正则表达式 : extract function names

java - 使用 Tomcat 运行 Angular 2 应用程序

android - 日/夜主题在 android 中未正确实现

java - OpenJDK 11 和 macOS 不支持 ZGC?