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

时间:2011-07-06 08:08:02

标签: java swing jframe

所以我已经在java中编程了一个学期左右,我已经有几次这个问题,最后还是要问。

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

如果您需要更多关于任何事情的信息,我会告诉您。

6 个答案:

答案 0 :(得分:19)

JFrame SetSize()包含Area + Border。

我认为您必须设置<{p>}的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课程略有不同   与Frame不兼容。像所有人一样   其他JFC / Swing顶级容器,    JFrame包含JRootPane   独生子女。提供了内容窗格   通常,根窗格应该   包含所有非菜单组件   由JFrame显示。这是   与AWT Frame案例不同。对于   例如,将一个孩子添加到AWT   你写的框架:

     

frame.add(child);

     

但是使用JFrame需要添加   孩子到JFrame的内容窗格   代替:

     

frame.getContentPane().add(child);

答案 1 :(得分:13)

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

  

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

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

答案 2 :(得分:1)

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

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

}

答案 3 :(得分:1)

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

frame.setSize(width, height + 22);

答案 4 :(得分:0)

我知道这个问题已经有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的答案。

答案 5 :(得分:0)

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