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

Java JFrame的大小实际上是如何工作的?,java,swing,jframe,Java,Swing,Jframe,我对我正在做的事情没有任何目的,只是用JavaSwing来尝试一下。我现在有三个变量: 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 JButton

我对我正在做的事情没有任何目的,只是用JavaSwing来尝试一下。我现在有三个变量:

    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,但结果是:


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

JFrame的大小包括其插图。这基本上意味着标题栏和边框

将以更少的努力为您完美完成此任务

class GridButtons implements Runnable {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new GridButtons(4, 5));
    }

    final int rows;
    final int cols;

    GridButtons(int rows, int cols) {
        this.rows = rows;
        this.cols = cols;
    }

    @Override
    public void run() {
        JFrame frame = new JFrame();
        JPanel grid = new JPanel(new GridLayout(rows, cols));

        for (int i = 0; i < (rows * cols); ++i) {
            grid.add(new JButton() {
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(60, 60);
                }
            });
        }

        frame.setContentPane(grid);
        frame.pack();
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

类GridButtons实现可运行{
公共静态void main(字符串[]args){
调用器(新的GridButtons(4,5));
}
最终整数行;
最终整数cols;
网格按钮(整数行、整数列){
this.rows=行;
this.cols=cols;
}
@凌驾
公开募捐{
JFrame=新JFrame();
JPanel grid=新JPanel(新网格布局(行、列));
对于(int i=0;i<(行*列);+i){
add(新的JButton(){
@凌驾
公共维度getPreferredSize(){
返回新维度(60,60);
}
});
}
frame.setContentPane(网格);
frame.pack();
frame.setresizeable(false);
frame.setLocationRelativeTo(空);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}

很多都取决于内容和布局管理器的要求。与其看你希望框架有多大,不如关注内容所需的空间大小。然后,框架将围绕此“打包”

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

考虑到内容的首选大小,并自动在框架中添加边框插入

因此,您只需在完成内容添加后调用
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);
        }

}
如果您需要更复杂的管理(即深度和宽度),您可以使用
GridBagLayout


查看,并获取更多详细信息;)

我不太擅长措辞;我为这个模糊的标题道歉。如果有人可以编辑它,使更多。。。感觉我将非常感激:)实际的帧大小也可以解释边框。我尝试过使用
frame.getContentPane().setSize()
,但这只是在左上角的超小窗口中启动帧。因为这样你就不会将帧的大小设置为任何值-只设置内容的大小。@madcromer True,但它适用于这个特殊的例子。另一方面,如果按钮有文本或图标,我会反对。(但是,和往常一样,设置“绝对大小”意味着窗口在不同的屏幕分辨率上会显示不同的大小…)是的,但我们试着不要鼓励人们走上会给他们带来(更多)麻烦的道路;)您可以替代
JButton
getPreferredSize
方法;)只是将使用
setPreferred/Minimum/maximumsizese
的人们的代码绑定在一起,所以我越不鼓励它,就越好;)-答案的重点是正确的,很好的,尽管我的小麻烦,我还是给了它一个+1;)谢谢你!在我的情况下,我不能使用GridLayout(我试图将
setLayout
设置为
null
),但我真诚地感谢你给我这个关于未来任何项目的建议:)嘿,这是不是意味着要使用OctorOpe/hash(tag)/tictactoe符号/数字符号?因为它对我来说是“无效字符”:哦,顺便说一句,对不起,我仍然在学习很多关于Java的新东西。
#
只是我说它是一个“实例”字段或方法(不是静态的)。是的,它通常应该是
instanceOfJFrame.pack()
;)哦,我明白你的意思了。这与常量所做的第二个选项有什么区别?主要区别是允许内容(和子内容)自然地计算其首选大小,而不是通过使用
setPreferredSize
强加一个大小,这通常是不鼓励的
frame.setLayout(null)
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);
            }
        }

    }

}