为什么 JFrame setSize() 方法不能正确设置大小?

发布于 2024-11-18 16:26:22 字数 405 浏览 4 评论 0原文

我已经用java编程一个学期左右了,这个问题我已经遇到过几次了,终于抽出时间来问了。

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

如果您需要更多信息,请尽管询问,我会将其提供给您。

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.

If I make a JFrame and then set the size, like setSize(400,800) for example. The frame is not actually 800 pixels long. From what I can tell it is actually more like 770 (or maybe 769) pixels long. 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?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

魂牵梦绕锁你心扉 2024-11-25 16:26:23

框架的上边框大小为 30。您可以使用 MouseInputAdapter 编写代码来打印框架上任意点的坐标。您会发现当光标位于框架上边框的正下方时,y 坐标不为零,其接近30。因此,如果您给框架的尺寸为300 * 300,则可用于将组件放在框架上的尺寸仅为300 * 270。因此,如果您需要尺寸为300 * 300,给出300*330尺寸的框架。

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.

热血少△年 2024-11-25 16:26:22

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

我认为您必须设置其 ContentPane 的大小,

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

因此我建议您使用嵌入在 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();

我正在阅读 Javadoc

JFrame 类稍微有点
框架不兼容。像所有人一样
其他 JFC/Swing 顶级容器,
JFrame 包含一个 JRootPane 作为其
独生子。提供的内容窗格
通常,根窗格应该
包含所有非菜单组件
JFrame 显示。这是
与 AWT 框架的情况不同。为了
例如,将子项添加到 AWT
你会写的框架:

frame.add(child);

但是使用 JFrame 您需要添加
JFrame 内容窗格的子项
相反:

frame.getContentPane().add(child);

JFrame SetSize() contains the the Area + Border.

I think you have to set the size of ContentPane of that

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 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

The JFrame class is slightly
incompatible with Frame. Like all
other JFC/Swing top-level containers,
a JFrame contains a JRootPane as its
only child
. The content pane provided
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 JFrame you need to add
the child to the JFrame's content pane
instead:

frame.getContentPane().add(child);

水中月 2024-11-25 16:26:22

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

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

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

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).

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

只涨不跌 2024-11-25 16:26:22

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

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);
    }
}

}

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);
    }
}

}

云淡风轻 2024-11-25 16:26:22

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

frame.setSize(width, height + 22);

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:

frame.setSize(width, height + 22);
百思不得你姐 2024-11-25 16:26:22

我知道这个问题大约有 6 岁多了,但 @Kyle 的答案不起作用。

使用这个

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

但这总是适用于任何尺寸:

setSize(width + 14, height + 7);

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

setSize(width + 16, height + 39);

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文