Java 为什么 JFrame setSize() 方法没有正确设置大小?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6593322/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 08:02:52  来源:igfitidea点击:

Why does the JFrame setSize() method not set the size correctly?

javaswingjframe

提问by convergedtarkus

So I've been programming in java for a semester or so, and I've had this problem a few times and finally got around to asking.

所以我已经用 Java 编程了一个学期左右,我遇到了几次这个问题,最后终于有时间问了。

If I make a JFrameand then set the size, like setSize(400,800)for example. The frame is not actually 800 pixelslong. From what I can tell it is actually more like 770 (or maybe 769) pixelslong. Also, if you set the vertical size very low (below 30), the frame doesn't even show up, only the top window bar from the OS and the frame doesn't get bigger until you go to a value over 30 (so setSize(400,0)looks the same as setSize(400,20)). Why is this, it's not hard to fix but its weird and I'm curious why this is?

如果我制作一个JFrame然后设置大小,setSize(400,800)例如。框架实际上并不800 pixels长。据我所知,它实际上更像是770 (or maybe 769) pixels长。此外,如果您将垂直尺寸设置得非常低(低于 30),则框架甚至不会显示,只有来自操作系统的顶部窗口栏和框架不会变大,直到您的值超过 30(因此setSize(400,0)看起来一样setSize(400,20))。这是为什么,不难解决,但很奇怪,我很好奇这是为什么?

If you need more information about anything just ask and I'll get it to you.

如果您需要有关任何事情的更多信息,请询问,我会为您提供。

采纳答案by Kyle

It's probably because size of a frame includes the size of the border.

这可能是因为框架的大小包括边框的大小。

A Frame is a top-level window with a title and a border. The size of the frame includes any area designated for the border. The dimensions of the border area may be obtained using the getInsets method. Since the border area is included in the overall size of the frame, the border effectively obscures a portion of the frame, constraining the area available for rendering and/or displaying subcomponents to the rectangle which has an upper-left corner location of (insets.left, insets.top), and has a size of width - (insets.left + insets.right) by height - (insets.top + insets.bottom).

框架是具有标题和边框的顶级窗口。框架的大小包括为边界指定的任何区域。可以使用 getInsets 方法获取边框区域的尺寸。由于边框区域包含在框架的整体大小中,边框有效地遮住了框架的一部分,将可用于渲染和/或显示子组件的区域限制在左上角位置为 (insets. left, insets.top),并具有宽度 - (insets.left + insets.right) 乘高 - (insets.top + insets.bottom) 的大小。

Source: http://download.oracle.com/javase/tutorial/uiswing/components/frame.html

来源:http: //download.oracle.com/javase/tutorial/uiswing/components/frame.html

回答by Talha Ahmed Khan

JFrame SetSize() contains the the Area + Border.

JFrame SetSize() 包含区域 + 边框。

I think you have to set the size of ContentPaneof that

我认为你必须设置的大小ContentPane的那

jFrame.getContentPane().setSize(800,400);

So I would advise you to use JPanel embedded in a JFrame and you draw on that JPanel. This would minimize your problem.

因此,我建议您使用嵌入在 JFrame 中的 JPanel,然后在该 JPanel 上进行绘制。这将最大限度地减少您的问题。

JFrame jf = new JFrame();
JPanel jp = new JPanel();
jp.setPreferredSize(new Dimension(400,800));// changed it to preferredSize, Thanks!
jf.getContentPane().add( jp );// adding to content pane will work here. Please read the comment bellow.
jf.pack();

I am reading this from Javadoc

我正在从Javadoc 中阅读此内容

The JFrameclass is slightly incompatible with Frame. Like all other JFC/Swing top-level containers, a JFrame contains a JRootPaneas its only child. The content paneprovided by the root pane should, as a rule, contain all the non-menu components displayed by the JFrame. This is different from the AWT Frame case. For example, to add a child to an AWT frame you'd write:

frame.add(child);

However using JFrameyou need to add the child to the JFrame's content pane instead:

frame.getContentPane().add(child);

JFrame班是略有不符Frame。与所有其他 JFC/Swing 顶级容器一样,JFrame 包含 aJRootPane作为其唯一的子项。根窗格提供的内容窗格通常应包含JFrame. 这与 AWT Frame 情况不同。例如,要将子项添加到 AWT 框架中,您可以编写:

frame.add(child);

但是,使用JFrame您需要将子项添加到JFrame的内容窗格中:

frame.getContentPane().add(child);

回答by xpusostomos

There are lots of good reasons for setting the size of a frame. One is to remember the last size the user set, and restore those settings. I have this code which seems to work for me:

设置框架的大小有很多很好的理由。一种是记住用户设置的最后一个尺寸,并恢复这些设置。我有这个似乎对我有用的代码:

package javatools.swing;
import java.util.prefs.*;
import java.awt.*;
import java.awt.event.*;

import javax.swing.JFrame;

public class FramePositionMemory {
    public static final String WIDTH_PREF = "-width";

    public static final String HEIGHT_PREF = "-height";

    public static final String XPOS_PREF = "-xpos";

    public static final String YPOS_PREF = "-ypos";
    String prefix;
    Window frame;
    Class<?> cls;

    public FramePositionMemory(String prefix, Window frame, Class<?> cls) {
        this.prefix = prefix;
        this.frame = frame;
        this.cls = cls;
    }

    public void loadPosition() {
        Preferences prefs = (Preferences)Preferences.userNodeForPackage(cls);
    //  Restore the most recent mainframe size and location
        int width = prefs.getInt(prefix + WIDTH_PREF, frame.getWidth());
        int height = prefs.getInt(prefix + HEIGHT_PREF, frame.getHeight());
        System.out.println("WID: " + width + " HEI: " + height);
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        int xpos = (screenSize.width - width) / 2;
        int ypos = (screenSize.height - height) / 2;
        xpos = prefs.getInt(prefix + XPOS_PREF, xpos);
        ypos = prefs.getInt(prefix + YPOS_PREF, ypos);
        frame.setPreferredSize(new Dimension(width, height));
        frame.setLocation(xpos, ypos);
        frame.pack();
    }

    public void storePosition() {
        Preferences prefs = (Preferences)Preferences.userNodeForPackage(cls);
        prefs.putInt(prefix + WIDTH_PREF, frame.getWidth());
        prefs.putInt(prefix + HEIGHT_PREF, frame.getHeight());
        Point loc = frame.getLocation();
        prefs.putInt(prefix + XPOS_PREF, (int)loc.getX());
        prefs.putInt(prefix + YPOS_PREF, (int)loc.getY());
        System.out.println("STORE: " + frame.getWidth() + " " + frame.getHeight() + " " + loc.getX() + " " + loc.getY());
    }
}
public class Main {
void main(String[] args) {
        JFrame frame = new Frame();
        // SET UP YOUR FRAME HERE.
        final FramePositionMemory fm = new FramePositionMemory("scannacs2", frame, Main.class);
        frame.setSize(400, 400); // default size in the absence of previous setting
        fm.loadPosition();

        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                fm.storePosition();
            }
        });
        frame.setVisible(true);
    }
}

}

}

回答by ben

On OS X, you need to take into account existing window decorations. They add 22 pixels to the height. So on a JFrame, you need to tell the program this:

在 OS X 上,您需要考虑现有的窗口装饰。它们在高度上增加了 22 个像素。所以在 JFrame 上,你需要告诉程序:

frame.setSize(width, height + 22);

回答by ben

I know that this question is about 6+ years old, but the answer by @Kyle doesn't work.

我知道这个问题大约有 6 年以上的历史,但@Kyle 的答案不起作用。

Using this

使用这个

setSize(width - (getInsets().left + getInsets().right), height - (getInsets().top + getInsets().bottom));

But this always work in any size:

但这总是适用于任何大小:

setSize(width + 14, height + 7);

If you don't want the border to border, and only want the white area, here:

如果您不希望边框有边框,而只想要白色区域,请在此处:

setSize(width + 16, height + 39);

Also this only works on Windows 10, for MacOS users, use @ben's answer.

此外,这仅适用于 Windows 10,对于 MacOS 用户,请使用 @ben 的答案。

回答by ben

The top border of frame is of size 30.You can write code for printing the coordinate of any point on the frame using MouseInputAdapter.You will find when the cursor is just below the top border of the frame the y coordinate is not zero , its close to 30.Hence if you give size to frame 300 * 300 , the size available for putting the components on the frame is only 300 * 270.So if you need to have size 300 * 300 ,give 300 * 330 size of the frame.

框架的上边框大小为 30。您可以使用 MouseInputAdapter 编写打印框架上任意点坐标的代码。您会发现当光标刚好在框架上边框的下方时,y 坐标不为零,它的接近30。因此如果你给frame 300 * 300的大小,可以将组件放在frame上的大小只有300 * 270。所以如果你需要300 * 300的大小,给frame的大小为300 * 330 .