java - JFrame 的大小实际上是如何工作的?

标签 java swing jframe

我真正做的事情没有任何目的,只是用 Java Swing 尝试一下。我现在拥有的是这三个变量:

    int[] gridIterations = {10,10}; //how many JButtons are made each row/column
    int[] frameSize = {600,600}; //size of the JFrame
    int[] gridSize = {60,60}; //by gridSize, I mean size of the JButtons

我还有一个嵌套的 for 循环,它使用这些变量来创建 JButton 网格。我期望网格完全适合 JFrame,但这是结果:

Grids cut off at the bottom and right edges of JFrame

经过一些测试后,我意识到如果大小为 (615, 631),框架实际上只会适合所有 JButtons 但我想知道,为什么它只适合这些参数,并且为什么在所有数字中,它会是 那些? 根据我的理解,60 * 10 的简单计算应该等于 600 并成功地让所有按钮适合 JFrame,但我很可能忽略了一些东西。那会是什么?谢谢。

最佳答案

很大程度上取决于内容和布局管理器的要求。与其关注您希望框架“有多大”,不如关注内容需要的空间量。然后框架将围绕它“打包”。

这意味着框架将“内容大小 + 框架边框大小”变大。

JFrame#pack考虑内容的首选大小并自动添加框架边框插入。

因此,您唯一需要做的就是在向其中添加完内容后调用 JFrame#pack

因此,根据您的代码:

public class Testing {

        public static void main(String[] args) {
                JFrame frame = new JFrame("hi");

                for (int i = 0; i < 10; i++) {
                        JButton a = new JButton();
                        a.setSize(20,20);
                        a.setLocation(20*i, 0);
                        frame.getContentPane().add(a);

                }
                frame.setLayout(null);
                frame.pack();
                frame.setVisible(true);
        }

}

您正在使用 null 布局。 JFrame#pack 将使用布局管理器提供的信息来确定整体内容的“首选”大小。

避免使用 null 布局,像素完美布局是现代 ui 设计中的一种错觉。影响组件单个尺寸的因素太多,没有一个是您可以控制的。 Swing 旨在与核心的布局管理器一起工作,丢弃这些将导致无穷无尽的问题和问题,您将花费越来越多的时间来尝试纠正这些问题。

而不是专注于绝对,这在操作系统(甚至不同的 PC 具有相同的操作系统)之间是可变的,而是专注于用户体验。

正如已经演示的那样,您可以使用 GridLayout

轻松实现它

GridLayout

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new GridLayout(10, 10, 0, 0));
            for (int index = 0; index < 10 * 10; index++) {
                JButton btn = new JButton(String.valueOf(index)) {
                    @Override
                    public Dimension getPreferredSize() {
                        return new Dimension(50, 50);
                    }
                };
                add(btn);
            }
        }

    }

}

如果您需要更复杂的管理(即按广度进行深度管理),您可以改用 GridBagLayout

看看Laying Out Components Within a Container , How to Use GridLayoutHow to Use GridBagLayout了解更多详情;)

关于java - JFrame 的大小实际上是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30518728/

相关文章:

java - 创建您自己的 Swing 组件

java - 我有 main 但 java 命令不工作

java - 除了一个复选框之外,屏幕上没有显示任何内容

java - 需要使用 IntelliJ 更改 GUI 的背景,但背景隐藏了按钮

java - 将 double 属性序列化为字符串

Java 线程 : Run method cannot throw checked exception

java - 将静态变量值传递给另一个类

java - 我可以使用已弃用的类吗?

java - 文件似乎总是空的

java - 从 JButton 的 actionListener 关闭 JFrame